Debian Interix technical issues


Manually unpacking .deb archives

The binary packages provided here have standard Debian deb format. For those who want to manually unpack such a .deb package (NOT necessary when installing Debian for Interix, of course): .deb files are normal ar archives, to unpack do the following:
$ ar x any.deb data.tar.gz control.tar.gz
$ tar xzf data.tar.gz
$ tar xzf control.tar.gz
The data.tar.gz contains the files to install while the control.tar.gz contains all the meta information.


How to build .deb packages for Debian/Interix

To build your own packages for Debian/Interix follow these steps:
  1. make sure you have the following lines in your /etc/apt/sources.list: deb-src http://ftp.de.debian.org/debian unstable main deb-src http://debian-interix.net/debian-interix unreleased35 main non-free (of course you should use an appropiate debian mirror for the first line) and after that update the package cache with $ apt-get update
  2. Install the following build tools: $ apt-get install \ perl \ dpkg-dev/unreleased35 \ debhelper/unreleased35 \ debian-archive-keyring \ build-essential \ ms-libc3.5-sfu3.5-dev \ binutils \ gcc-4.2 \ g++-4.2 \ libm-newlib-dev \ libiconv-dev \ gettext \ cdbs \ patchutils \ dpatch \
  3. Do some modifications: In /usr/share/cdbs/1/rules/buildcore.mk comment out the test for root, and to /usr/bin/dpatch apply this patch until it gets accepted in standard Debian to allow spaces in $HOME.
  4. Set the modified arch:all packages on hold: $ dpkg --set-selections <<END debhelper hold dpkg-dev hold cdbs hold dpatch hold END
  5. You'll probably need cp, ln, install from the not-yet-packaged coreutils you can currently only download separately, for the GNU cmd line options: http://www.debian-interix.net/debian-interix/bootstrap-tools/coreutils/bin.tgz
  6. Now create a new scratch directory, say /srv/packages. For each package make a subdir. The easiest package to (re-)build seems to be athena-jot, so for the beginning: $ mkdir /srv/packages/athena-jot $ cd /srv/packages/athena-jot
  7. Download the source package $ apt-get --download-only source athena-jot Be sure to use the source package name, not the binary package name, they may differ. You can find the source package name via http://packages.debian.org/. You now should receive 3 files:
    athena-jot_9.0-5.diff.gz
    athena-jot_9.0-5.dsc
    athena-jot_9.0.orig.tar.gz
    
  8. Now extract the source package $ dpkg-source -x athena-jot_9.0-5.dsc
  9. As athena-jot is a very simple package, you can build it for Interix without modifications: $ cd athena-jot-9.0 $ dpkg-buildpackage -B -d -us -uc 2>&1 | tee ../build.log You should get a *.deb file now in .., which you can install via $ cd .. $ dpkg -i *.deb
  10. If modifications are necessary, remove (or rename) the extracted source tree again, re-extract it, modify it, build a new source package, then build the extracted and modified source package. If the build goes wrong, you can re-extract the new source package, modify it further, repack it to save the changes and try again. So: $ rm -rf athena-jot-9.0/ $ dpkg-source -x athena-jot_9.0-5.dsc $ editor athena-jot-9.0/debian/changelog add a new changelog entry, increasing the version number, to the front of the file, say: athena-jot (9.0-5+interix.1) unstable; urgency=low * Non-maintainer upload. * patches for interix-i386 -- Martin Koeppe <mkoeppe@gmx.de> Wed, 5 Sep 2007 18:38:48 +0200
  11. Do other modifications and repack source: $ dpkg-source -b athena-jot-9.0/ You get a new *.diff.gz and a new *.dsc which you can use later to re-extract your changes.
  12. Build the package again as in 9. You don't need to make a new changelog entry every time you do further mods, only 1 time to have a new source package different from standard Debian.
  13. If the package is ok now, then you could create the interdiff like this: $ interdiff -z \ athena-jot_9.0-5.diff.gz \ athena-jot_9.0-5+interix.1.diff.gz \ | gzip > athena-jot.interdiff.gz and, if you want to contribute to Debian/Interix, send me the *.interdiff.gz as well as the build.log.
There are also Debian native packages which only have 2 files as source package: *.dsc and *.tar.gz. Only if you wonder about them. When modifications are necessary to these, say e.g. dpatch-2.0.27, then add "-0+interix.1" to the version string in changelog, and make a symlink *.orig.tar.gz pointing to the *.tar.gz before building the source package. This way the package gets a normal package, and the interix mods are all in the *.diff.gz.

For more details on Debian packages you may refer to the Debian Policy.

For building X packages you may need to change the symlink /usr/include/X11 from pointing to ../X11R6/include to pointing to ../X11R6/include/X11 at least on SFU 3.5 this is necessary for some ruby lib to build correctly.


The Data Execution Prevention (DEP) issue

Newer AMD and Intel CPUs have hardware support for marking parts of the memory as non-executable. The existence of the NX flag (no execute) on AMD CPUs or the XD flag (execute disable) on Intel CPUs indicates that this feature is available. More information about DEP can be found here.

Problem

On Interix there are 2 problems with DEP: The DEP problem has only been seen on SFU 3.5 running on Windows XP or Server 2003 so far and shows as:
Memory fault (core dumped)
While I don't yet know the exact problem with ld.so, GCC compiled programs (original gcc-3.3 as well as Debian/Interix gcc-4.2) may work with DEP turned on if: I successfully run a simple hello world program as well as a statically linked bash. A sample program that uses nested functions and therefore crashes: #include <stdio.h> int main() { int values[] = { 3, 2, 4, 6, 7, 1, 8, 0 }; int num_comparisons = 0; int comparison_function(const void* a, const void* b) { int first = *(const int*)a; int second = *(const int*)b; num_comparisons++; /* look, we're accessing a variable from our parent function */ if (first < second) return -1; else return first > second; } qsort(values, 8, sizeof *values, comparison_function); printf( "%d %d %d %d %d %d %d %d, %d comparisons\n", values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], num_comparisons ); return 0; }

More about nested functions with GCC can be found here and here.

Solution

If you need shared libraries (for Debian/Interix you do) or need GCC's nested functions, you can disable DEP completely, see also /Tools FAQ.

Alternatively, you can use the contribution from /Tools member franz (Franz Fischer), which disables DEP only for Interix processes, so that you don't lose the protection for Win32 processes. According to franz, the same thing is done on Interix 5.2 and up, and therefore the DEP issue is not found on these systems. I successfully verified franz's contribution on SFU 3.5 on Windows XP.


The long double incompatibility

Microsoft has decided to remove support for the 80-bit long double type from their compilers entirely. They now simply alias long double to double for source code compatibility. For MSVC is therefore sizeof(long double)==8. On the other hand, the GCC that comes with Interix has sizeof(long double)==12, the same as on Linux/i386. So GCC can handle 80-bit long double.

Problem

When one compiles a function taking a long double argument with one compiler, and the call to this function with another, this will result in wrong data being computed, and may even crash the application. This is because the say MSVC compiled function expects an 8-byte argument, but the GCC compiled call to the function generates a 12-byte argument. If other arguments follow, they get messed up. This problem especially can occur with the *printf style functions. The Interix libc is build with MSVC, so expects long double to be 8-byte in size. If you call sprintf("%Lg", (long double) 42) in GCC compiled code, it'll fail to print the expected string.

Problem 2

While GCC stores long double numbers as 12-byte in memory, it doesn't use by default the extended precision for calculations, because the FPU gets initialized by the interix libc / crt0.o to only double precision. See the following program: #include <stdio.h> #include <math.h> int main (void) { #ifdef __GNUC__ long long int i; #else _int64 i; #endif long double d; i = 0xdeadbeef; i = (i << 32) | i; printf ("given: i=0x%lx%lx\n", (long) (i >> 32), (unsigned long) (i & 0xffffffff)); printf ("now do i-=1 via long double\n"); d = i; d -= 1.0; i = d; printf ("expected: i=0xdeadbeefdeadbeee\n"); printf ("got: i=0x%lx%lx\n", (long) (i >> 32), (unsigned long) (i & 0xffffffff)); printf ("\nnow setting extended precision explicitely\n"); _control87 (_PC_64, _MCW_PC); i = 0xdeadbeef; i = (i << 32) | i; printf ("given: i=0x%lx%lx\n", (long) (i >> 32), (unsigned long) (i & 0xffffffff)); printf ("now do i-=1 via long double\n"); d = i; d -= 1.0; i = d; printf ("expected: i=0xdeadbeefdeadbeee\n"); printf ("got: i=0x%lx%lx\n", (long) (i >> 32), (unsigned long) (i & 0xffffffff)); } The output is:
given:    i=0xdeadbeefdeadbeef
now do i-=1 via long double
expected: i=0xdeadbeefdeadbeee
got:      i=0xdeadbeefdeadbe00

now setting extended precision explicitely
given:    i=0xdeadbeefdeadbeef
now do i-=1 via long double
expected: i=0xdeadbeefdeadbeee
got:      i=0xdeadbeefdeadbeee
see also: /Tools forum


Hardlinks, Symlinks and Junctions on NTFS

Hardlinks

Symbolic links

Junctions

Windows supported on Unix equivalent note create with
hardlink every NTFS version hardlink exact equivalent CreateHardlink(), BackupWrite()
Interix symlink every Windows FS symlink exact equivalent, but only available in the Interix subsystem or via NFS symlink(2), wcs_symlink(2)
junction Windows 2000 NTFS and up mount --bind not available in Interix or via NFS Sysinternal's junction.exe
Windows symlink Windows Vista NTFS and up symlink On Windows there are 2 different kinds of symlinks, one pointing to files, and another pointing to directories. Windows symlinks are not available in Interix or via NFS. cmd.exe's mklink


Case sensitive file names on NTFS

NTFS is per se a case sensitive file system, i.e. the file names FILE, File and file can all exist in one directory and refer to different files. The Win32 subsystem is case preserving for file names, but case insensitive when opening existing files or directories. The Windows kernel which handles the requests from the Win32 subsystem, is case insensitive by default, too. It can be made case sensitive, however, if support for Interix or NFS server is required. To enable case sensitive file names in the kernel, while still having case insensitive file names in the Win32 subsystem, you need to set HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\kernel\obcaseinsensitive = 0 in the registry. When you now have created some files with names differing only in case via Interix or NFS clients, you may want to copy or backup these from within the Win32 subsystem, which is always case insensitive. Fortunately there are a few Win32 API functions, which can operate in a case sensitive manner if the kernel has been switched to case sensitiveness and which can be used to enumerate, open and delete files case sensitive. These functions are: To delete files or create hard links with case sensitive names, you need to use CreateFile() with FILE_SHARE_DELETE for deletion and BackupWrite() to create hard links. Moving within the same file system is done via creating a hard link and deleting the original afterwards. Creating directories in case sensitive manner is also done with CreateFile(), with flags FILE_FLAG_POSIX_SEMANTICS, FILE_FLAG_BACKUP_SEMANTICS and FILE_ATTRIBUTE_DIRECTORY set.


Users with root privileges in the Interix subsystem

There are only 3 privileged user ids in Interix. The well-known UIDs for users with root-equivalent rights within Interix are: Most notably, users in the local Administrators group don't have root-equivalent rights in Interix (and with them domain Admins don't have, either).



Last update of this document: Friday, 23-Apr-2010 23:21:22 CEST Copyright 2007-2010 Martin Köppe <mkoeppe 'at' gmx . de>