Porting Applications in C
Services for UNIX 3.0 Technical Note
Abstract
This paper is in addition to the information presented in the Interix Software Development Kit User's Guide. After a brief discussion of methods used to make code portable and how they affect the porting process, this paper reviews the differences and similarities between Interix and traditional open systems, and discusses some means of dealing with those differences. It ends with a list of APIs supported in Interix 2.2.
On This Page
Porting Applications in C
Examples
Summary of Interfaces
For More Information
Porting Applications in C
This paper is in addition to the information presented in the Windows Services for Unix 3.0 Software Development Kit User's Guide. After a brief discussion of methods used to make code portable and how they affect the porting process, this note reviews the differences and similarities between Interix and traditional open systems, and discusses some means of dealing with those differences. This document provides a number of examples of porting Unix application and ends with a list of APIs supported in Interix 2.2.
The topics of configuration scripts, porting daemons, and X Window System code deserve separate discussions and will be given their own technical notes.
The usual method for porting an application to Interix is to move the source to an Interix system and then recompile. If a Makefile exists, porting may be as simple as typing make.
Although Interix is a POSIX.1-conforming system, it takes different approaches in some areas than traditional systems, and there are differences outside the areas defined by the standard. Some of these are discussed in the User's Guide.
Code Portability Strategies
There are several basic approaches to porting code. Most applications use more than one of these.
Write a custom library of functions for each platform. The application always calls the private version of the function, which in the compilation stage is linked to a platform-specific library. This is a great deal of work, though it may be the appropriate method for a large body of source.
Define an extensive set of platform-specific macros that expand to the correct functions and names.
Use #ifdef statements to isolate sections of code based on the platform. For example, Interix supports POSIX.1, ANSI/ISO C and many interfaces from both historical BSD and SVR4 systems. Older code written using #ifdefs may make assumptions about the platform that aren't valid. For example, code built around #ifdef BSD will usually try to include <sgtty.h> rather than <termios.h>. By labeling blocks of code with the platform name, you're often trying to hit a moving target; for example, BSD4.4 has some different APIs than BSD4.3, but they're both BSD.
If you're porting an application that provides configurations for different platforms, the closest configuration to Interix is another POSIX system. Depending upon which POSIX features are supported, you may find it useful to try the code in an #ifdef BSDI386. If there's a lot of terminal code and no POSIX support, you may find it easier to start with the SVR4 configuration.
- Use #ifdef statements where code compilation is dependent upon features. This is the most common approach.
The advantage of this method is that sets of feature test macros can be gathered into a configuration block; new platforms can be defined with a single block of code in one file. Another advantage is to create a record of changes that can be refered to in other projects.
When porting a package for redistribution, remember that Makefiles may also need modifications.
The Interix Environment
Interix is a POSIX.1 system with extensions taken from both BSD and System V. Interix is "more like" a BSD system in some ways, but the POSIX terminal handling is very much like System V. If the application being ported makes extensive use of terminal interfaces or shared memory IPC, you may want to start with the System V version of the code.
When porting a new program, examine the application for features that aren't yet supported in the Interix subsystem. Depending upon the feature, you can use #ifdef statements to isolate them, or you could use a feature-based macro such as HAVE_MEMPCPY for to avoid an unsupported function (in this case mempcpy).
At the end of this paper is a list of the APIs supported by Service for Unix/Interix 3.0. See the reference pages and the Interix SDK User's Guide for more details.
SDK User's Guide
This note extends information found in the Interix SDK User's Guide. Please also refer there. The SDK User's Guide discusses the following:
A system overview of Interix
Writing POSIX-standard code, including
compile-time macros and manifest constants
getting system information (<limits.h>, confstr(), fpathconf(), pathconf(), sysconf())
POSIX APIs that supplant historical APIs: advisory file locking with fcntl() rather than flock() or lockf(); getcwd() rather than getwd(); mkfifo() rather than mknod(); utime() rather than utimes(); regular expressions with the functions declared in <regex.h>; <stdarg.h> rather than <varargs.h>
POSIX terminal I/O with the termios interface
POSIX signals, including sigaction()
Extensions to POSIX.1 included in Interix:
Header files aligned with the Single UNIX Specification
Memory-mapped files, System V IPC mechanisms
Sockets
Pseudoterminals
Controlling terminals
dynamic linking
Interix-specific issues regarding user authentication and absolute pathnames on the Windows NT® operating system.
Unsupported Features
There are several features which Interix does not yet support. They may be supported in future releases. Most of these are mentioned in the SDK User's Guide, but are repeated here.
- Many ioctl() request are not supported, particularly the disk label and magnetic tape I/O requests.
Sample Configuration Blocks
As an example of a configuration block, here is the one added to apache, the Internet http server:
#elif defined(__INTERIX) #define USE_FCNTL_SERIALIZED_ACCEPT #undef HAS_GMTOFF #define NO_SETSID #define JMP_BUF sigjmp_buf #include <sys/time.h> #define getwd(d) getcwd(d,MAX_STRING_LEN)
Dealing with Missing Header Files
If you can't build your application because Interix is missing header files, do not blindly copy header files from another platform. You need to determine why the header file is being used in the application and whether the same information may be in a different header file on Interix. This is the essence of porting.
If the information is supported on Interix in a different header file, you need to #include that header file. If the information is not supported on Interix, you need to figure out a different way to achieve the same ends. In software that has been ported to many platforms, you can usually achieve the same result by changing configuration options. In custom software, you may need to write a new supporting library function.
Reading the Interix documentation and reference pages will be useful.
Handling Filenames
Earlier versions of the Interix environment did not have a single rooted filesystem. On Windows NT, or Windows2000, multiple filesystems are accessible through drive letters. Access to these are available using the syntax "//L" where L is an uppercase letter. This affected configure scripts, a number of popular software packages, Makefiles, and widgets such as file selection boxes in X applications, none of which make allowances for the special "//" prefix.
With the 3.0 version of Services for Unix, this is no longer an issue, Interix has a single rooted filesystem where "/" is the directory where Services for Unix was installed. This change makes porting much, much easier as we will see in the example section below.
Reserved Filenames (only with c89 and cc)
The compiler interfaces (c89 and cc) pass the list of files to the Microsoft Visual C/C++® compiler. Files to be compiled with c89 and cc must have names that are acceptable to the Microsoft compiler in the Win32® environment. This is not a problem when compiling with gcc; the gcc compiler operates entirely in the Interix environment, where the filenames are not reserved.
The following names are reserved under Win32, regardless of case or file extension.
AUX
LCOMn (where n is a digit)
CON
LPTn (where n is a digit)
NUL
PRN
For example, files named AUX.C, aux.c, aux.h, AUx.h or any other permutation will not compile. This is because the compiler is a Win32 program.
If you have files by these names (aux.c is particularly common), you must rename them.
About Configure Scripts
The ability of a configure script to work out the characteristics of Interix depends almost entirely on how clever the script is and what assumptions it makes. It's not possible to give a recipe for "fixing" configure scripts because each script is different—the heuristics used by configure scripts vary with the version.
Suggestions:
On systems such as SVR4 and BSD, the compiler is silent if there is no problem. The Microsoft Visual C/C++ compiler always writes the name of the compiled file to standard output. Because of this, configure scripts may "decide" that APIs aren't present because there was output from the compiler. The version of cc/c89 included in release 2.1 and later catches this output. This is not a problem for gcc.
Interix libraries are distributed differently on the system. For example, the ELM configure script searches through libc.a — but many of the interfaces are found in libpsxdll.a. Once the configure script is finished, it has not found many of the APIs that are actually provided. However, searching through libc.so will find these apis because the architecture of libc.so includes functions in libpsxdll.a
Depending on the script, it may be faster to manually change the derived configuration description rather than changing the logic of the configuration script. This is not a portable or reusable solution, but it is sometimes needed. The first apache port for Interix was done this way.
Configure scripts are more thoroughly discussed in the Configure Scripts paper available at https://www.microsoft.com/windows2000/interix.
Interface Conversions
This section describes some of the conversions which may be required in porting code. Most of these are required to run on any POSIX.1 system. The references listed in the Interix SDK User's Guide are a good source of information on these conversions.
ioctl() Calls
The ioctl() interface has many uses. The POSIX.1 committee did not standardize the ioctl() interface because the last argument ca not be type-checked (its type depends upon the request). Instead, the committee broke out certain pieces of functionality and assigned them to other interfaces.
The Interix API set contains only a few ioctl() operations, including window re-sizing.
The ioctl() interface historically was used to handle disk labels, file I/O, magnetic tape I/O, socket I/O, and terminal I/O. The disk label and magnetic tape I/O requests are not supported in the Interix environment.
File Control
The only ioctl() requests defined for file control are FIONREAD, to get the number of bytes available to read, and FIONBIO, to set and unset non-blocking I/O.
On Interix, the FIONREAD request is equivalent to the fcntl() F_GETNREAD request.
The FIOCLEX and FIONCLEX requests (usually found in <filio.h>) are not provided. They can be replaced with the fcntl() FD_CLOEXEC request.
For example:
#ifndef __INTERIX (void) ioctl(fd, FIOCLEX, NULL) #else (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFD) | FD_CLOEXEC)); #endif
Sockets
The only ioctl() request defined for sockets is SIOCATMARK. Other socket control requests are handled through fcntl() or through functions such as setsockopt().
Terminal Control
In POSIX.1, many of the terminal control calls that used to be handled with ioctl() requests were given separate interfaces (as listed on page 27 of the Interix SDK User's Guide).
For example, the ioctl() requests TIOCGATC, TIOCGATC, TIOCGLTC, and TCGETA all translate to the tcgetattr() call, filling in the termios structure. The requests TIOCSATC, TIOCSATC, TIOCSLTC, and TCSETA translate to the tcsetattr() call.
Allocating a Controlling Terminal
On SVR4, the controlling terminal is allocated when the session leader opens the first terminal device that is not already associated with a session and the open() call does not specify O_NOCTTY. On BSD systems 4.3+, processes allocate the controlling terminal with an ioctl() call, using the request TIOCSCTTY. Interix follows the SVR4 practice.
setpgrp()
Both BSD and System V have a setpgrp() interface, but they have different semantics and behaviors. The System V call changes the caller's process group ID to its own process ID. The BSD call detaches a process from its process group but doesn't change the controlling terminal.
The System V call takes no arguments. It is properly replaced by the POSIX setsid() call. When a process calls setsid() successfully, it creates a new session, which in turn contains a new process group, which contains one process — the calling process. The calling process is now the session and process group leader. The process also disposes of its controlling terminal. (In fact, the setsid() call is used to dispose of a controlling terminal.)
The BSD call takes two arguments, a process ID and a process group ID. It is replaced by the POSIX setpgid() call, which has identical semantics.
Debugging the Ported Code
There are a couple of differences in behavior between Interix and traditional systems such as Solaris that might show up when debugging your ported code.
Segmentation Faults
Some users porting code notice that their application memory faults more often than it did on the original platform. Experience has shown that this usually exposes a defect in the code, not in the Interix subsystem. (A subsystem segmentation fault is a different issue.)
A common cause is trying to de-reference an uninitialized pointer. An uninitialized pointer contains some random bit pattern. An attempt to read or write at the memory address indicated by that bit pattern will succeed or fail, depending on whether the user is allowed access to that address. If it fails, it fails with a segmentation fault. Even if it succeeds, it may cause problems for other applications which are using that chunk of memory.
On Windows NT, Windows 2000 and Windows XP, most of the four-gigabyte address space is off-limits to the user program. Any attempt to read or write in that space causes an application segmentation fault.
For example, this code is incorrect and will behave unexpectedly on a traditional system. It will segmentation-fault on an Interix system:
#include <stdio.h> struct foo { int one; int two; }; main() { int i1, i2, i3, i4; struct foo *t1; t1->one = 7; printf ("%d\n", t1->one); }
There are two problems here: first, foo is defined but no actual structure is declared; second, the variable t1 is not initialized. The attempt to de-reference t1, assigning the member one to the value 7, actually points to some random memory location offset to give the access to the structure member. The following two fixes correct the problem:
#include <stdio.h> struct foo { int one; } bar; main() { int i1, i2, i3, i4; struct foo *t1; t1=&bar; t1->one = 7; printf ("%d\n", t1->one); }
A structure (bar) is now declared, and t1 is initialized to its address.
Porting code is often an exercise in discovering assumptions.
This should include some hint as to addresses of shared objects though they should be qualified with "these addresses may change at any time." For example, as of this writing:
The addresses of the other .so's are:
libdb.so |
= 0x77c00000 |
# to 77c30000 |
libm.so |
= 0x77c30000 |
# to 77c80000 |
librpc.so |
= 0x77c80000 |
# to 77cb0000 |
libform.so |
= 0x77cb0000 |
# to 77d00000 |
libcurses |
= 0x77d00000 |
# to 77d80000 |
libc.so |
= 0x77d80000 |
# to 77ea0000 |
SDK User's Guide (and probably plain User's Guide) should mention core files.
SDK User's Guide should mention problems with literal strings in read-only data
By default, gcc generates code for literal strings inline (such as in foo("hithere")) in read-only data. MSVC does not. (They're writeable.)
Such a situation occurred in ps where it was writing into such a string (the old "temporary '\0'" trick), and of course it fell over when compiled with gcc. The command line option -fwritable-strings will convince gcc otherwise. The primary reason for this note, however, is to get it fresh in peoples mind that as we use gcc more if nothing else, to create PIC libc.a) we'll have to be careful about that. (An easy way out of this is to declare the string as a static char[] initialized to that value.)
The GDB Debugger
The GDB debugger is available as part of the Interix Software Development Kit. It is possible
Examples
Introduction
In this section outlines a number of porting examples to show some of the issues that can arise in porting Unix applications to Interix.
zlib-1.1.4
zlib 1.1.4 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files https://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). These documents are also available in other formats from
ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
unarchive the package
$ gunzip < zlib-1.1.4.tgz | tar xf - $ ls ChangeLog amiga infblock.c infutil.c zconf.h FAQ compress.c infblock.h infutil.h zlib.3 INDEX configure infcodes.c maketree.c zlib.h Make_vms.com contrib infcodes.h minigzip.c zlib.html Makefile crc32.c inffast.c msdos zutil.c Makefile.in deflate.c inffast.h nt zutil.h Makefile.riscos deflate.h inffixed.h os2 README descrip.mms inflate.c trees.c adler32.c example.c inftrees.c trees.h algorithm.txt gzio.c inftrees.h uncompr.c
This archive has a configure script, but it is not the usual GNU configure script, so we need to execute this as follows:
$ ./configure --prefix=/usr/local Checking for gcc... Building static library libz.a version 1.1.4 with gcc. Checking for unistd.h... Yes. Checking for errno.h... Yes. Checking for mmap support... Yes. $
Now we can try a make
$ make gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c example.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c adler32.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c compress.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c crc32.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c gzio.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c uncompr.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c deflate.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c trees.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c zutil.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c inflate.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c infblock.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c inftrees.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c infcodes.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c infutil.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c inffast.c ar rc libz.a adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -o example example.o -L. -lz gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -c minigzip.c gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -o minigzip minigzip.o -L. -l $
just to be sure, we will "make test"
$ make test hello world uncompress(): hello, hello! gzread(): hello, hello! gzgets() after gzseek: hello! inflate(): hello, hello! large_inflate(): OK after inflateSync(): hello, hello! inflate with dictionary: hello, hello! _** zlib test OK **_ $
everything looks ok, now we'll make install
$ make install cp zlib.h zconf.h /usr/local/include chmod 644 /usr/local/include/zlib.h /usr/local/include/zconf.h cp libz.a /usr/local/lib cd /usr/local/lib; chmod 755 libz.a $
all done, ready for use!
gdbm 1.8.0
This library will be used by PERL in a later example. GNU dbm is a set of database routines that use extendible hashing and works similar to the standard UNIX dbm routines.
$ gunzip < gdbm-
bzip2 1.0.1
"bzip2" compresses files using the Burrows-Wheeler block-sorting text compression algorithm, and Huffman coding. Compression is generally considerably better than that achieved by more conventional LZ77/LZ78-based compressors, and approaches the performance of the PPM family of statistical compressors. It provides a library, two headers and a set of binaries. The library is used in other packages.
As usual, we will unarchive the package:
$ gunzip < bzip2-1.0.1.tgz | tar xf - |
|
|
$ cd bzip2-1.0.1 |
|
|
$ ls |
|
|
CHANGES |
bzlib_private.h |
manual_4.html |
LICENSE |
compress.c |
manual_toc.html |
Makefile |
crctable.c |
randtable.c |
Makefile-libbz2_so |
decompress.c |
sample1.bz2 |
README |
dlltest.c |
sample1.ref |
README.COMPILATION.PROBLEMS |
dlltest.dsp |
sample2.bz2 |
Y2K_INFO |
huffman.c |
sample2.ref |
blocksort.c |
libbz2.def |
sample3.bz2 |
bzip2.1 |
libbz2.dsp |
sample3.ref |
bzip2.1.preformatted |
makefile.msc |
spewG.c |
bzip2.c |
manual.ps |
unzcrash.c |
bzip2.txt |
manual.texi |
words0 |
bzip2recover.c |
manual_1.html |
words1 |
bzlib.c |
manual_2.html |
words2 |
bzlib.h |
manual_3.html |
words3 |
|
|
|
As we can see, there is no "configure" script, however there is a Makefile, so we will just attempt a make.
$ make If compilation produces errors, or a large number of warnings,please read README.COMPILATION.PROBLEMS -- you might be able to adjust the flags in this Makefile to improve matters. gcc -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce … Doing 6 tests (3 compress, 3 uncompress) ... If there's a problem, things might stop at this point. ./bzip2 -1 < sample1.ref > sample1.rb2 ./bzip2 -2 < sample2.ref > sample2.rb2 … cmp sample2.tst sample2.ref cmp sample3.tst sample3.ref If you got this far and the "cmp"s didn't complain, it looks like you're in business. To install in /usr/bin, /usr/lib, /usr/man and /usr/include, type make install To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type make install PREFIX=/xxx/yyy If you are (justifiably) paranoid and want to see what 'make install' is going to do, you can first do make -n install or make -n install PREFIX=/xxx/yyy respectively. The -n instructs make to show the commands it would execute, but not actually execute them. Instructions for use are in the preformatted manual page, in the file bzip2.txt. For more detailed documentation, read the full manual. It is available in Postscript form (manual.ps) and HTML form (manual_toc.html). You can also do "bzip2 --help" to see some helpful information. "bzip2 -L" displays the software license. $
That seemed to compile ok, and as we can see by the output, it works correctly too. So we will follow the installation instructions and run "make install". Since we've decided to install everything in /usr/local, we'll set the PREFIX to that.
$ make install PREFIX=/usr/local if ( test ! -d /usr/local/bin ) ; then mkdir /usr/local/bin ; fi if ( test ! -d /usr/local/lib ) ; then mkdir /usr/local/lib ; fi if ( test ! -d /usr/local/man ) ; then mkdir /usr/local/man ; fi if ( test ! -d /usr/local/man/man1 ) ; then mkdir /usr/local/man/man1 ; fi if ( test ! -d /usr/local/include ) ; then mkdir /usr/local/include ; fi cp -f bzip2 /usr/local/bin/bzip2 cp -f bzip2 /usr/local/bin/bunzip2 cp -f bzip2 /usr/local/bin/bzcat cp -f bzip2recover /usr/local/bin/bzip2recover chmod a+x /usr/local/bin/bzip2 chmod a+x /usr/local/bin/bunzip2 chmod a+x /usr/local/bin/bzcat chmod a+x /usr/local/bin/bzip2recover cp -f bzip2.1 /usr/local/man/man1 chmod a+r /usr/local/man/man1/bzip2.1 cp -f bzlib.h /usr/local/include chmod a+r /usr/local/include/bzlib.h cp -f libbz2.a /usr/local/lib chmod a+r /usr/local/lib/libbz2.a $
This package is complete and installed!
gettext 0.10.40
The gettext package is interesting for authors or maintainers of other packages or programs which they want to see internationalized. As one step the handling of messages in different languages should be implemented. For this task GNU gettext provides the needed tools and library functions.
This package configuration is driven by the configure script, like many GNU packages, running configure with the proper arguments ensures a successful configuration.
$ CFLAGS="-D_ALL_SOURCE" ./configure \ --prefix=/usr/local \ --host=intel-pclocal-interix checking for a BSD compatible install... /bin/install -c checking whether build environment is sane... yes checking whether make sets ${MAKE}... yes checking for working aclocal... missing checking for working autoconf... missing checking for working automake... missing … updating cache ./config.cache creating ./config.status creating Makefile creating lib/Makefile creating intl/Makefile creating src/Makefile creating po/Makefile.in creating doc/Makefile creating man/Makefile creating tests/Makefile creating m4/Makefile creating misc/Makefile creating misc/gettextize creating config.h creating po/POTFILES creating po/Makefile $
This looks promising so far, let's attempt a make.
$ make make all-recursive Making all in doc cd . && env LANG= LANGUAGE= /bin/sh /dev/fs/C/src/gettext-0.11.1/missing --run makeinfo `echo gettext.texi | sed 's,.*/,,'` Making all in intl /bin/sh ../libtool --mode=compile gcc -c - DLOCALEDIR=\"/usr/local/share/locale\" -DLOCALE_ALIAS_PATH=\"/usr/local/share/locale\" - DLIBDIR=\"/usr/local/lib\" -DIN_LIBINTL -DHAVE_CONFIG_H -I.. -I. - I../intl -D_ALL_SOURCE -I/usr/local/include -g -D_ALL_SOURCE - I/usr/local/include intl-compat.c gcc -c -DLOCALEDIR=\"/usr/local/share/locale\" - DLOCALE_ALIAS_PATH=\"/usr/local/share/locale\" - DLIBDIR=\"/usr/local/lib\" -DIN_LIBINTL -DHAVE_CONFIG_H -I.. -I. - I../intl -D_ALL_SOURCE -I/usr/local/include -g -D_ALL_SOURCE - I/usr/local/include intl-compat.c -o intl-compat.o echo timestamp > intl-compat.lo … gcc -g -D_ALL_SOURCE -I/usr/local/include -o tstngettext tstngettext.o setlocale.o -L/usr/local/lib ../lib/.libs/libgettextlib.a /dev/fs/C/src/gettext-0.11.1/intl/.libs/libintl.a ../intl/.libs/libintl.a -lc gcc -DLOCALEDIR=\"\" -DHAVE_CONFIG_H -I. -I. -I.. -I.. -I../lib -I../lib -I../intl -D_ALL_SOURCE -I/usr/local/include -g -D_ALL_SOURCE - I/usr/local/include -c plural-1-prg.c /bin/sh ../libtool --mode=link gcc -g -D_ALL_SOURCE -I/usr/local/include -L/usr/local/lib -o cake plural-1-prg.o setlocale.o ../lib/libgettextlib.la ../intl/libintl.la gcc -g -D_ALL_SOURCE -I/usr/local/include -o cake plural-1-prg.o setlocale.o -L/usr/local/lib ../lib/.libs/libgettextlib.a /dev/fs/C/src/gettext-0.11.1/intl/.libs/libintl.a ../intl/.libs/libintl.a -lc $
This looks like a successful build, let's attempt a "make check" to see if we have a good build.
$ make check Making check in doc … make check-TESTS PASS: test-names.sh ================== All 1 tests passed ================== Making check in src Making check in po Making check in man Making check in m4 Making check in projects Making check in misc WARNING: Warnings can be ignored. :-) if test no != no; then EMACS=no /bin/sh ./elisp-comp po-mode.el; else : ; fi Making check in tests make check-TESTS PASS: gettext-1 … PASS: msgcat-1 msgcat: Cannot convert from "ISO-8859-1" to "UTF-8". msgcat relies on iconv(). This version was built without iconv(). FAIL: msgcat-2 msgcat: Cannot convert from "ISO-8859-1" to "UTF-8". msgcat relies on iconv(). This version was built without iconv(). FAIL: msgcat-3 msgcat: Cannot convert from "ISO-8859-1" to "UTF-8". msgcat relies on iconv(). This version was built without iconv(). FAIL: msgcat-4 PASS: msgcat-5 … PASS: msgcomm-3 msgcomm: Cannot convert from "ASCII" to "ISO-8859-1". msgcomm relies on iconv(). This version was built without iconv(). FAIL: msgcomm-4 msgcomm: Cannot convert from "ASCII" to "ISO-8859-1". msgcomm relies on iconv(). This version was built without iconv(). FAIL: msgcomm-5 msgcomm: Cannot convert from "ASCII" to "ISO-8859-1". msgcomm relies on iconv(). This version was built without iconv(). FAIL: msgcomm-6 msgcomm: Cannot convert from "ASCII" to "ISO-8859-1". msgcomm relies on iconv(). This version was built without iconv(). FAIL: msgcomm-7 PASS: msgcomm-8 … PASS: msgcomm-15 msgcomm: Cannot convert from "ISO-8859-1" to "UTF-8". msgcomm relies on iconv(). This version was built without iconv(). FAIL: msgcomm-16 PASS: msgcomm-17 … PASS: msgcomm-23 msgconv: Cannot convert from "BIG5" to "UTF-8". msgconv relies on iconv(). This version was built without iconv(). FAIL: msgconv-1 msgconv: Cannot convert from "UTF-8" to "BIG5". msgconv relies on iconv(). This version was built without iconv(). FAIL: msgconv-2 PASS: msgconv-3 … PASS: plural-2 Couldn't set locale. SKIP: lang-c Couldn't set locale. SKIP: lang-c++ … SKIP: lang-pascal PASS: lang-ycp msgfmt: Cannot convert from "ISO-8859-1" to "UTF-8". msgfmt relies on iconv(). This version was built without iconv(). FAIL: lang-tcl PASS: lang-po … PASS: rpath-2bbd ====================== 11 of 159 tests failed ====================== *** Error code 1 Stop. *** Error code 1 Stop. *** Error code 1 Stop. $
This looks less promising, and we need to investigate the failures. In this case, most of the failures are a result of Interix not providing the iconv API. The other issues are due to the fact that Interix currently only supports the C and POSIX locales (check the setlocale manpage), the lang-c, lang-c++ and lang-pascal attempt to set the locale to fr_FR which is not possible with Interix. This is found by examining the lang-* files for the tests that were SKIPPED. It is likely that future releases of Interix will support multiple locales. However, more than 90% of this package is operational. It may be that some issues may arise as we continue to use this package, but we can measure this as a qualified success.
xpm 3.4k
XPM (X PixMap) is a format for storing/retrieving X pixmaps to/from files. If we look at the file listing, we will notice that there is no configure script at all. This is a package built for the X-Windows system and it uses a different process for building. With X-Windows applications, the Imakefile is the "configure" counterpart. A different tool is used to construct the Makefiles, xmkmf (create a Makefile from an Imakefile). That tool is also part of the Interix utility set, so we should be able to use this to build this package.
$ ls -CF CHANGES FILES README.AMIGA cxpm/ namecvt* COPYRIGHT Imakefile README.MSW doc/ sxpm/ FAQ.html Makefile.noX README.html lib/
There is a README.html, we can read this file to help us understand what the package does and whether there are any instructions on compiling the package. The instructions in the README.html state that we should use "xmkmf -a" to start if the platform supports it, we will try!
$ xmkmf -a imake -DUseInstalled -I/usr/X11R5/lib/X11/config make Makefiles making Makefiles in ./lib... rm -f lib/Makefile.bak cd lib; imake -DUseInstalled -I/usr/X11R5/lib/X11/config -DTOPDIR=../. - DCURDIR=./lib; make UPPREFIX=../ NEWTOP=../ MAKEFILE_SUBDIR=lib NEW_CURRENT_DIR=./lib Makefiles making Makefiles in ./sxpm... rm -f sxpm/Makefile.bak cd sxpm; imake -DUseInstalled -I/usr/X11R5/lib/X11/config -DTOPDIR=../. -DCURDIR=./sxpm; make UPPREFIX=../ NEWTOP=../ MAKEFILE_SUBDIR=sxpm NEW_CURRENT_DIR=./ sxpm Makefiles making Makefiles in ./cxpm... rm -f cxpm/Makefile.bak cd cxpm; imake -DUseInstalled -I/usr/X11R5/lib/X11/config -DTOPDIR=../. -DCURDIR=./cxpm; make UPPREFIX=../ NEWTOP=../ MAKEFILE_SUBDIR=cxpm NEW_CURRENT_DIR=./ cxpm Makefiles make includes including in ./lib... including in ./sxpm... including in ./cxpm... make depend depending in ./lib... makedepend -s "# DO NOT DELETE" -- -I. -I/usr/X11R5/include -Dopennt -- data.c create.c misc.c rgb.c scan.c parse.c hashtab.c CrBufFrI.c CrDatFrP.c CrPFrBuf.c RdFToI.c WrFFrI.c CrBufFrP.c CrIFrBuf.c CrPFrDat.c RdFToP .c WrFFrP.c CrDatFrI.c CrIFrDat.c RdFToDat.c WrFFrDat.c Attrib.c CrIFrP.c CrPFrI.c Image.c Info.c RdFToBuf.c WrFFrBuf.c depending in ./sxpm... makedepend -s "# DO NOT DELETE" -- -I.././X11 -I.. -I/usr/X11R5/include -Dopennt -- sxpm.c depending in ./cxpm... makedepend -s "# DO NOT DELETE" -- -I.././X11 -I.. -I/usr/X11R5/include -Dopennt -- cxpm.c
As we can see, the Interix xmkmf utility does support the "-a" flag, so we should now just be able to build the package with "make"
$ make making all in ./lib... rm -f data.o … making all in ./sxpm... … making all in ./cxpm... … gcc -fstrength-reduce -fpcc-struct-return -O -O -static -L/usr/X11R5/lib -o cxpm cxpm.o $
Everything built ok, so now, we can install by "make install"
$ make install installing in ./lib... install -c -m 0644 libXpm.a /usr/X11R5/lib + install -c -m 0444 xpm.h /usr/X11R5/include/X11 install in ./lib done installing in ./sxpm... install -c sxpm /usr/X11R5/bin install in ./sxpm done installing in ./cxpm... install -c cxpm /usr/X11R5/bin install in ./cxpm done $
Another package built and installed!
groff 1.17.2
Many UNIX packages deliver documentation in nroff format. GNU groff is an Open Source replacement for the AT&T nroff package. As usual, we unarchive the package, and run the configure command. If you are building many of the GNU packages, you may want to create a shell script that provides the parameters to the configuration file. This can be very useful for consistency and avoid typing mistakes. The following is an example:
$ cat /usr/local/bin/runconfig set -x CPPFLAGS="-D_ALL_SOURCE -I/usr/local/include" \ CXXFLAGS="-D_ALL_SOURCE -I/usr/local/include" \ CFLAGS="-D_ALL_SOURCE -I/usr/local/include" \ LDFLAGS="-L/usr/local/lib" \ ./configure --prefix=/usr/local \ --host=intel-pclocal-interix $*
This script sets the compilation flags for C, C++ and CPP, it also includes the /usr/local directory for both include and library files, so the libraries we built above, will be found. Using this script to run the groff configure script we get a good configure and we should be able to make without difficulties.
$ runconfig + ./configure --prefix=/usr/local --host=intel-pclocal-interix + CPPFLAGS=-D_ALL_SOURCE -I/usr/local/include CXXFLAGS=-g -D_ALL_SOURCE - I/usr/l ocal/include CFLAGS=-g -D_ALL_SOURCE -I/usr/local/include LDFLAGS=- L/usr/local/lib configure: WARNING: If you wanted to set the --build type, don't use – host. If a cross compiler is detected then cross compile mode will be used. checking for intel-pclocal-interix-gcc... no checking for gcc... gcc checking for C compiler default output... a.out checking whether the C compiler works... yes … checking for prefix of system macro packages... checking which system macro packages should be made available... configure: creating ./config.status config.status: creating Makefile config.status: creating src/xditview/Imakefile $
This looks fine, so let's attempt a make
$ make g++ -I. -I/dev/fs/C/src/groff-1.17.2/src/libs/libgroff - I/dev/fs/C/src/groff-1.17.2/src/include -I/dev/fs/C/src/groff- 1.17.2/src/include -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_SYS_DIR_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MATH_H=1 -DRET_TYPE_SRAND_IS_VOID=1 -DHAVE_CC_OSFCN_H=1 - DHAVE_CC_LIMITS_H=1 -DRETSIGTYPE=void -DHAVE_STRUCT_EXCEPTION=1 -DHAVE _STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_FMOD=1 - DHAVE_STRTOL=1 -DHAVE_GETCWD=1 -DHAVE_STRERROR=1 -DHAVE_PUTENV=1 - DHAVE_RENAME=1 -DHAVE_STRCASECMP=1 -DHAVE_STRNCASECMP=1 -DHAVE_STRSEP=1 - DHAVE_STRDUP=1 -DHAVE_MKSTEMP=1 -DHAVE_MKSTEMP_PROTO=1 -g -D_ALL_SOURCE - I/usr/local/include -c assert.cc g++ -I. -I/dev/fs/C/src/groff-1.17.2/src/libs/libgroff - I/dev/fs/C/src/groff-1.17.2/src/include -I/dev/fs/C/src/groff- 1.17.2/src/include -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_SYS_DIR_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MATH_H=1 -DRET_TYPE_SRAND_IS_VOID=1 -DHAVE_CC_OSFCN_H=1 - DHAVE_CC_LIMITS_H=1 -DRETSIGTYPE=void -DHAVE_STRUCT_EXCEPTION=1 - DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_FMOD=1 - DHAVE_STRTOL=1 -DHAVE_GETCWD=1 -DHAVE_STRERROR=1 -DHAVE_PUTENV=1 - DHAVE_RENAME=1 -DHAVE_STRCASECMP=1 -DHAVE_STRNCASECMP=1 -DHAVE_STRSEP=1 - DHAVE_STRDUP=1 -DHAVE_MKSTEMP=1 -DHAVE_MKSTEMP_PROTO=1 -g -D_ALL_SOURCE - I/usr/local/include -c change_lf.cc … Making pfbtops.n from pfbtops.man rm -f DESC cat /dev/fs/C/src/groff-1.17.2/font/devps/DESC.in >DESC echo broken 7 >>DESC if test "letter" = A4; then echo "paperlength 841890" >>DESC; else echo "paperlength 792000" >>DESC; fi test -z 'lp' || echo print 'lp' >>DESC rm -f prologue sed -f /dev/fs/C/src/groff-1.17.2/font/devps/psstrip.sed prologue.ps >prologue rm -f symbolsl.pfa sed -f /dev/fs/C/src/groff-1.17.2/font/devps/psstrip.sed symbolsl.ps >symbolsl.pfa rm -f zapfdr.pfa sed -f /dev/fs/C/src/groff-1.17.2/font/devps/psstrip.sed zapfdr.ps >zapfdr.pfa cat /dev/fs/C/src/groff-1.17.2/font/devdvi/DESC.in >DESC test -z 'lp' || echo print 'lp' >>DESC rm -f DESC echo "res 600" >DESC echo "unitwidth `expr 7620000 / 600`" >>DESC cat /dev/fs/C/src/groff-1.17.2/font/devlj4/DESC.in >>DESC if test "letter" = A4; then echo "papersize a4" >>DESC; else echo "papersize letter" >>DESC; fi test -z 'lp' || echo print 'lp' >>DESC Making R … chmod +x nroff Making nroff.n from nroff.man rm -f mmroff sed -e 's;/usr/bin/perl;/bin/perl;' /dev/fs/C/src/groff- 1.17.2/contrib/mm/mmroff.pl >mmroff chmod +x mmroff Making groff_mm.n from groff_mm.man Making groff_mmse.n from groff_mmse.man Making mmroff.n from mmroff.man $
It looks like we've got a good build, but there some things that we should take the time to look at. Sometimes, GNU packages create a config.h file that contains different constant definitions. In this case, those constants are defined in the compilation. By reviewing these compile flags we can learn some things about the Interix. For example, the "-DHAVE_*_H" flags indicate that we have a particular header file. "-DHAVE_STRSEP" means that we have the strsep(2) API (separate strings). Sometimes, we may have functionality not found by the configure script. This would be the case for the makedev() function. For example, on Solaris8, this is implemented as a function, but in Interix, it is defined as a macro in /usr/include/sys/makedev.h. A configure script that is testing for makedev, may not include the correct header file and thus not determine that makedev() is available with Interix. In this case, you would need to either alter the CFLAGS (as in this build) or modify the config.h file.
Since we have a good build, let's try a "make check"
$ make check $
That didn't seem to do anything, however, there is a test-groff file in the directory, by inspection, it looks like it could be used, and there is a description in the INSTALL file that describes how to use it.
$ ./test-groff -man -Tascii src/roff/groff/groff.n | less
Running this command, we get what looks like a man page, so we've probably got a good build. At this point, we should attempt a make install.
$ make install test -d /usr/local/man || /dev/fs/C/src/groff-1.17.2/mkinstalldirs /usr/local/man test -d /usr/local/man/man1 || /dev/fs/C/src/groff-1.17.2/mkinstalldirs /usr/local/man/man1 test -d /usr/local/man/man5 || /dev/fs/C/src/groff-1.17.2/mkinstalldirs /usr/local/man/man5 test -d /usr/local/man/man7 || /dev/fs/C/src/groff-1.17.2/mkinstalldirs /usr/local/man/man7 test -d /usr/local/bin || /dev/fs/C/src/groff-1.17.2/mkinstalldirs /usr/local/bin rm -f /usr/local/bin/groff /bin/install -c groff /usr/local/bin/groff … rm -f /usr/local/bin/mmroff /bin/install -c mmroff /usr/local/bin/mmroff test -d /usr/local/share/groff/1.17.2/tmac || /dev/fs/C/src/groff- 1.17.2/mkinstalldirs /usr/local/share/groff/1.17.2/tmac rm -f /usr/local/share/groff/1.17.2/tmac/tmac.m rm -f /usr/local/share/groff/1.17.2/tmac/m.tmac /bin/install -c -m 644 /dev/fs/C/src/groff-1.17.2/contrib/mm/m.tmac /usr/local/share/groff/1.17.2/tmac/m.tmac test -d /usr/local/share/groff/1.17.2/tmac/mm || /dev/fs/C/src/groff- 1.17.2/mkinstalldirs /usr/local/share/groff/1.17.2/tmac/mm for f in 0.MT 5.MT 4.MT ms.cov se_ms.cov; do rm -f /usr/local/share/groff/1.17.2/tmac/mm/$f; /bin/install -c -m 644 /dev/fs/C/src/groff-1.17.2/contrib/mm/mm/$ f /usr/local/share/groff/1.17.2/tmac/mm/$f; done for f in locale se_locale; do test -f /usr/local/share/groff/1.17.2/tmac/mm/$f || touch /usr/local/share/groff/1.17.2/tmac/mm/$f; done
Another application compiled, tested and installed in minutes!
perl 5.6.1
Now that we have a number of applications and libraries built, we should look at something more complicated. PERL is a fairly complicated package that runs on a large number of UNIX systems as well as a native Win32 port. However, there are some differences between the UNIX and Windows releases. For example, the Windows release does not support the UNIX model for shared memory and does not provide an "exec" function. PERL also has a different configure script, that is somewhat different than the GNU configure script. This Configure script is interactive, and allows for choices to be made as the configuration progresses. For purposes of this document, I have decided to use the non-interactive mode and describe the flags that are set to provide the best PERL port. In order to configure PERL, we will use the following flags:
$ ./Configure -dOes -Ddosuid=undef -Dprefix=/usr/local \ -Dd_bincompat3=undef -Dcc=gcc -Dcflags="-D_ALL_SOURCE" -Dd_poll=undef \ -Dldflags="--dynamic -Wl,-E" -Dusenm=define -Dld="gcc" \ -Dlddlflags="--shared" -Ddont_use_nlink=define -Dusemymalloc="undef" \ -Dcccdlflags="none" libpth='/usr/local/lib /usr/lib' \ -Dinstallusrbinperl=undef -Dcf_email="support@microsoft.com" \ libs='-ldb -lm -lcrypt -lgdbm -lrpclib -ldl' \ perllibs='-ldb -lm -lcrypt -lgdbm -lrpclib -ldl' $
Going through the flags one by one:
Oes |
|
dosuid |
Do not provide a setuid perl |
prefix |
set the installation directory to /usr/local |
d_bincompat3=undef |
Don't be binary compatible with earlier releases |
cc=gcc |
Use the gcc compiler |
cflags="-D_ALL_SOURCE" |
Add "_ALL_SOURCE" to CFLAGS. This flag is used to get access to more than the standard POSIX APIs. |
d_poll=undef |
Do not use the poll API. With Interix, this API is only usefull with the /proc filesystem. The reason that this is disabled in PERL is because PERL will try to use this as a general purpose poll API. |
ldflags="--dynamic -Wl,-E" |
In order to take advantage of dynamic linking, we need to provide the appropriate flags to gcc. The "--dynamic" flag instructs gcc to link against the dynamic libaries provided by Inteirx. the "-Wl, -E" ensures that the linker will add all symbols to the dynamic-symbol table. This will be required for proper operation of the dynamic modules. |
ld="gcc" |
Use gcc as a linker. For Interix, this is the easiest way to build shared libraries. |
usenm=define |
Use NM to determine what symbols and routines are available |
lddlflags="--shared" |
add "--shared" to the command line when building shared libraries |
dont_use_nlink=define |
PERL will check the nlink member of the stat structure to determine whether the file is a directory. Interix does not use the nlink member to designate a directory. |
usemymalloc="undef" |
Do not use the PERL malloc |
cccdlflags="none" |
no additional flags are necessary for dynamic linking |
installusrbinperl=undef |
do not install /usr/bin/perl |
cf_email="myname@somewhere.com" |
set the email address of the builder |
libpth='/usr/local/lib /usr/lib' |
use this as the library path when looking for libraries. |
libs='-ldb -lm -lcrypt -lgdbm |
Use these libraries when linking PERL |
If these flags are used, a build of perl should be successful.
$ ./Configure -dOes -Ddosuid=undef -Dprefix=/usr/local \ -Dd_bincompat3=undef -Dcc=gcc -Dcflags="-D_ALL_SOURCE" -Dd_poll=undef \ -Dldflags="--dynamic -Wl,-E" -Dusenm=define -Dld="gcc" \ -Dlddlflags="--shared" -Ddont_use_nlink=define -Dusemymalloc="undef" \ -Dcccdlflags="none" libpth='/usr/local/lib /usr/lib' \ -Dinstallusrbinperl=undef -Dcf_email="support@microsoft.com" \ libs='-ldb -lm -lcrypt -lgdbm -lrpclib -ldl' \ perllibs='-ldb -lm -lcrypt -lgdbm -lrpclib -ldl' (I see you are using the Korn shell. Some ksh's blow up on Configure, mainly on older exotic systems. If yours does, try the Bourne shell instead.) First let's make sure your kit is complete. Checking... Locating common programs... Checking compatibility between /bin/echo and builtin echo (if any)... Symbolic links are supported. … Finding dependencies for hash.o. Finding dependencies for str.o. Finding dependencies for util.o. Finding dependencies for walk.o. echo Makefile.SH cflags.SH | tr ' ' '\n' >.shlist Updating makefile... Now you must run 'make'. If you compile perl5 on a different machine or from a different object directory, copy the Policy.sh file from this object directory to the new one before you run Configure -- this will help you with most of the policy defaults.
OK, now let's try to build PERL
$ make `sh cflags libperl.a miniperlmain.o` miniperlmain.c CCCMD = gcc -DPERL_CORE -c -I/usr/local/include -O `sh cflags libperl.a perl.o` perl.c CCCMD = gcc -DPERL_CORE -c -I/usr/local/include -O perl.c: In function `S_open_script': perl.c:2573: warning: assignment makes pointer from integer without a cast `sh cflags libperl.a gv.o` gv.c CCCMD = gcc -DPERL_CORE -c -I/usr/local/include -O `sh cflags libperl.a toke.o` toke.c CCCMD = gcc -DPERL_CORE -c -I/usr/local/include -O … chmod 644 re.bs rm -f ../../lib/auto/re/re.so LD_RUN_PATH="" gcc --shared -L/usr/local/lib re_exec.o re_comp.o re.o - o ../.. /lib/auto/re/re.so chmod 755 ../../lib/auto/re/re.so cp re.bs ../../lib/auto/re/re.bs chmod 644 ../../lib/auto/re/re.bs Making Errno (nonxs) Writing Makefile for Errno ../../miniperl -I../../lib -I../../lib -I../../lib -I../../lib Errno_pm.PL Errno .pm cp Errno.pm ../../lib/Errno.pm Everything is up to date. 'make test' to run test suite. $
This looks very promising, now let's attempt a test
$ make test AutoSplitting perl library ./miniperl -Ilib -e 'use AutoSplit; aut */*.pm Making DynaLoader (static) gcc -o perl --dynamic -Wl,-E -L/usr/loca naLoader.a libperl.a `cat ext.libs` -ls Making utilities … Making attrs (dynamic) Making re (dynamic) Making Errno (nonxs) cd t && (rm -f perl; /bin/ln -s ../perl if (true </dev/tty) >/dev/null 2>&1; the cd t && PERL_SKIP_TTY_TEST=1 ./perl T base/cond............ok … io/openpid...........Hangup $
Oh, oh. This could be a problem. The PERL test is exiting and the test is reporting a Hangup. By inspecting the test, we see that SIGPIPE is being ignored, perhaps we should also ignore SIGHUP.
To attempt a work-around, we add
$SIG{HUP} = 'IGNORE';
after the
$SIG{PIPE} = 'IGNORE';
and rerun our make test.
$ make test AutoSplitting perl library … op/goto_xs...........ok op/grent.............FAILED at test 1 op/grep..............ok
apache
rpm
ssh
Summary of Interfaces
These are the interfaces documented with Interix 2.2. This list is a guide, not an absolute reference. Some of the APIs are provided for compatibility and may follow either the BSD or System V behavior. See the reference pages for more information.
This list does not include macro definitions. For example, getdtablesize() is available as a macro in <unistd.h>; it is not listed here. (The macro actually calls sysconf(_SC_OPEN_MAX).)
This list also does not include the X11R5 routines or the Motif 1.2.4 routines. The X11R5 libraries come with the Interix SDK.
Because the list spans several pages, the table is organized alphabetically across rows.
System Interfaces, Standard C, Math, DB, RPC, Lex, Yacc and dl Libraries
a64l |
floorf |
isalnum |
realpath |
strcoll |
clntudp_bufcreate |
abort |
fmod |
isalpha |
recv |
strcpy |
clntudp_create |
abs |
fnmatch |
isascii |
recvfrom |
strcspn |
dbm_clearerr |
accept |
fopen |
isatty |
regcomp |
strdup |
dbm_close |
access |
fork |
isblank |
regerror |
strerror |
dbm_delete |
acos |
fpathconf |
iscntrl |
regexec |
strftime |
dbm_error |
acosh |
fprintf |
isdigit |
regfree |
strlcat |
dbm_fetch |
alarm |
fpurge |
isgraph |
remainder |
strlcpy |
dbm_firstkey |
asctime |
fputc |
isinf |
remove |
strlen |
dbm_nextkey |
asin |
fputs |
isinff |
rename |
strmode |
dbm_open |
asinh |
fread |
islower |
renamewtmpx |
strncasecmp |
dbm_store |
assert |
free |
isnan |
rewind |
strncat |
endrpcent |
atan |
freopen |
isnanf |
rewinddir |
strncmp |
get_myaddress |
atan2 |
frexp |
isprint |
rexec |
strncpy |
getrpcbyname |
atan2f |
fscanf |
ispunct |
rindex |
strpbrk |
getrpcbynumber |
atanf |
fseek |
isspace |
rint |
strptime |
getrpcent |
atanh |
fsetpos |
isupper |
rmdir |
strrchr |
getrpcport |
atexit |
fstat |
isxdigit |
rresvport |
strsep |
longjmp |
atof |
fstatvfs |
j0 |
ruserok |
strsignal |
pmap_getmaps |
atoi |
fsync |
j1 |
sbrk |
strsigname |
pmap_getport |
atol |
ftell |
jn |
scalb |
strspn |
pmap_rmtcall |
basename |
ftime |
jrand48 |
scalbn |
strstr |
pmap_set |
bcmp |
ftok |
kill |
scalbnf |
strtod |
pmap_unset |
bcopy |
ftruncate |
killpg |
scanf |
strtok |
registerrpc |
bind |
fts_children |
l64a |
seed48 |
strtol |
setjmp |
brk |
fts_close |
labs |
seekdir |
strtoul |
setrpcent |
bsearch |
fts_open |
lchown |
select |
strunvis |
svc_getreq |
bzero |
fts_read |
lcong48 |
semctl |
strvis |
svc_getreqset |
cabs |
fts_set |
ldexp |
semget |
strvisx |
svc_register |
calloc |
ftw |
ldiv |
semop |
strxfrm |
svc_run |
catclose |
fwrite |
lfind |
send |
swab |
svc_sendreply |
catgets |
gamma |
lgamma |
sendto |
symlink |
svc_unregister |
catopen |
gamma_r |
lgamma_r |
setbuf |
sysconf |
svcerr_auth |
cbrt |
gcvt |
link |
setbuffer |
syslog |
svcerr_decode |
ceil |
getbsize |
listen |
setegid |
system |
svcerr_noproc |
cfgetispeed |
getc |
localeconv |
setenv |
tan |
svcerr_noprog |
cfgetospeed |
getchar |
localtime |
seteuid |
tanf |
svcerr_progvers |
cfsetispeed |
getcwd |
lockf |
setgid |
tanh |
svcerr_systemerr |
cfsetospeed |
getdtablesize |
log |
setgrent |
tcdrain |
svcerr_weakauth |
chdir |
getegid |
log10 |
sethostent |
tcflow |
svcfd_create |
chmod |
getenv |
log1p |
setitimer |
tcflush |
svcraw_create |
chown |
geteuid |
logb |
setjmp |
tcgetattr |
svctcp_create |
chroot |
getgid |
login |
setlinebuf |
tcgetpgrp |
svcudp_bufcreate |
clearerr |
getgrent |
longjmp |
setlocale |
tcsendbreak |
t_accept |
clock |
getgrgid |
lrand48 |
setlogmask |
tcsetattr |
t_alloc |
close |
getgrnam |
lsearch |
setmode |
tcsetpgrp |
t_bind |
closedir |
getgroups |
lseek |
setnetent |
tdelete |
t_close |
closelog |
gethostbyaddr |
lstat |
setpgid |
telldir |
t_connect |
confstr |
gethostbyname |
madvise |
setpriority |
tempnam |
t_error |
connect |
gethostent |
malloc |
setprotoent |
tfind |
t_free |
copysign |
gethostname |
mctl |
setpwent |
time |
t_getinfo |
copysignf |
getitimer |
memccpy |
setregid |
times |
t_getprotaddr |
cos |
getlogin |
memchr |
setreuid |
tmpfile |
t_getstate |
cosf |
getmode |
memcmp |
setrlimit |
tmpnam |
t_listen |
cosh |
getnetbyaddr |
memcntl |
setservent |
toascii |
t_look |
creat |
getnetbyname |
memcpy |
setsid |
truncate |
t_open |
ctermid |
getnetent |
memmove |
setsockopt |
tsearch |
t_optmgmt |
ctime |
getopt |
memset |
setstate |
ttyname |
t_rcv |
cuserid |
getpass |
mkdir |
settimeofday |
ttyslot |
t_rcvconnect |
daemon |
getpeername |
mkfifo |
setuid |
twalk |
t_rcvdis |
difftime |
getpgrp |
mknod |
setutxent |
tzset |
t_rcvrel |
dirfd |
getpid |
mkstemp |
setvbuf |
ualarm |
t_rcvudata |
dirname |
getppid |
mktemp |
shmat |
ulimit |
t_rcvuderr |
div |
getpriority |
mktime |
shmctl |
umask |
t_snd |
drand48 |
getprotobyname |
mmap |
shmdt |
uname |
t_snddis |
drem |
getprotobynumber |
modf |
shmget |
ungetc |
t_sndrel |
dup |
getprotoent |
mprotect |
shutdown |
unlink |
t_sndudata |
dup2 |
getpwent |
mrand48 |
sigaction |
unlockpt |
t_strerror |
ecvt |
getpwnam |
msgctl |
sigaddset |
unsetenv |
t_sync |
endgrent |
getpwuid |
msgget |
sigblock |
unvis |
t_unbind |
endhostent |
getrlimit |
msgrcv |
sigdelset |
usleep |
xdr_accepted_reply |
endnetent |
getrusage |
msgsnd |
sigemptyset |
utime |
xdr_array |
endprotoent |
gets |
msync |
sigfillset |
verr |
xdr_authunix_parms |
endpwent |
getservbyname |
munmap |
sighold |
verrx |
xdr_bool |
endservent |
getservbyport |
nextafter |
sigignore |
vfork |
xdr_bytes |
endutxent |
getservent |
nftw |
sigismember |
vfprintf |
xdr_callhdr |
erand48 |
getsockname |
nice |
siglongjmp |
vis |
xdr_callmsg |
erf |
getsockopt |
nrand48 |
signal |
vprintf |
xdr_char |
erfc |
gettimeofday |
ntohl |
significand |
vscanf |
xdr_double |
err |
getuid |
ntohs |
sigpause |
vsnprintf |
xdr_enum |
errx |
getutxent |
open |
sigpending |
vsprintf |
xdr_float |
execl |
getutxid |
opendir |
sigprocmask |
vsscanf |
xdr_free |
execle |
getutxline |
openlog |
sigrelse |
vsyslog |
xdr_int |
execlp |
glob |
openpty |
sigset |
vwarn |
xdr_long |
execv |
globfree |
pathconf |
sigsetjmp |
vwarnx |
xdr_opaque |
execve |
gmtime |
pause |
sigsetmask |
wait |
xdr_opaque_auth |
execvp |
grantpt |
pclose |
sigsuspend |
waitpid |
xdr_pmap |
exp |
hcreate |
perror |
sigvec |
warn |
xdr_pmaplist |
expm1 |
hcreate_r |
pipe |
sin |
warnx |
xdr_pointer |
fabs |
hdestroy |
poll |
sinf |
write |
xdr_reference |
fabsf |
hdestroy_r |
popen |
sinh |
writev |
xdr_rejected_reply |
fchdir |
hsearch |
pow |
sleep |
y0 |
xdr_replymsg |
fchmod |
hsearch_r |
printf |
snprintf |
y1 |
xdr_short |
fchown |
htonl |
ptsname |
socket |
yn |
xdr_string |
fclose |
htons |
putc |
socketpair |
z_abs |
xdr_u_char |
fcntl |
hypot |
putchar |
sprintf |
authnone_create |
xdr_u_int |
fcvt |
ilogb |
putenv |
sqrt |
authunix_create |
xdr_u_long |
fdopen |
index |
puts |
sqrtf |
authunix_create_default |
xdr_u_short |
feof |
inet_addr |
pututxline |
sradixsort |
bindresvport |
xdr_union |
ferror |
inet_aton |
qsort |
srand |
callrpc |
xdr_vector |
fflush |
inet_lnaof |
radixsort |
srand48 |
clnt_broadcast |
xdr_void |
ffs |
inet_makeaddr |
raise |
srandom |
clnt_create |
xdr_wrapstring |
fgetc |
inet_netof |
rand |
sscanf |
clnt_pcreateerror |
xdrmem_create |
fgetln |
inet_network |
random |
stat |
clnt_perrno |
xdrrec_create |
fgetpos |
inet_ntoa |
rcmd |
statvfs |
clnt_perror |
xdrrec_endofrecord |
fgets |
init |
read |
strcasecmp |
clnt_spcreateerror |
xdrrec_eof |
fileno |
initstate |
readdir |
strcasestr |
clnt_sperrno |
xdrrec_skiprecord |
finite |
ioctl |
readlink |
strcat |
clnt_sperror |
xdrstdio_create |
finitef |
ipcs |
readv |
strchr |
clntraw_create |
xprt_register |
flock |
iruserok |
realloc |
strcmp |
clnttcp_create |
xprt_unregister |
floor |
isalnum |
realpath |
strcoll |
clntudp_bufcreate |
dlopen |
dlsym |
dlerror |
dlclose |
|
|
|
Curses, Menus, Panels ,Forms and Terminfo APIs
The following APIs make up the ported ncurses libraries:
addch |
init_color |
mvinsch |
ripoffline |
ungetch |
addchnstr |
init_pair |
mvinsnstr |
savetty |
ungetmouse |
addchstr |
initscr |
mvinsstr |
scanw |
unpost_menu |
addnstr |
innstr |
mvinstr |
scr_dump |
untouchwin |
addstr |
insch |
mvprintw |
scr_init |
update_panels |
attr_get |
insdelln |
mvscanw |
scr_restore |
use_env |
attr_off |
insertln |
mvwaddch |
scr_set |
vidattr |
attr_on |
insnstr |
mvwaddchnstr |
scrl |
vidputs |
attr_set |
insstr |
mvwaddchstr |
scroll |
vline |
attroff |
instr |
mvwaddnstr |
scrollok |
vw_printw |
attron |
intrflush |
mvwaddstr |
set_current_item |
vw_scanw |
attrset |
is_linetouched |
mvwchgat |
set_curterm |
vwprintw |
baudrate |
is_wintouched |
mvwdelch |
set_item_init |
vwscanw |
beep |
isendwin |
mvwgetch |
set_item_opts |
waddch |
bkgd |
item_count |
mvwgetstr |
set_item_term |
waddchnstr |
bkgdset |
item_description |
mvwin |
set_item_userptr |
waddchstr |
border |
item_index |
mvwinch |
set_item_value |
waddnstr |
bottom_panel |
item_init |
mvwinchnstr |
set_menu_back |
waddstr |
box |
item_name |
mvwinchstr |
set_menu_fore |
wattr_get |
can_change_color |
item_opts |
mvwinnstr |
set_menu_format |
wattr_off |
cbreak |
item_opts_off |
mvwinsch |
set_menu_grey |
wattr_on |
chgat |
item_opts_on |
mvwinsnstr |
set_menu_init |
wattr_set |
clear |
item_term |
mvwinsstr |
set_menu_items |
wattroff |
clearok |
item_userptr |
mvwinstr |
set_menu_mark |
wattron |
clrtobot |
item_value |
mvwprintw |
set_menu_opts |
wattrset |
clrtoeol |
item_visible |
mvwscanw |
set_menu_pad |
wbkgd |
color_content |
keyname |
napms |
set_menu_pattern |
wbkgdset |
copywin |
keypad |
new_item |
set_menu_sub |
wborder |
current_item |
killchar |
new_menu |
set_menu_term |
wchgat |
curs_set |
leaveok |
new_panel |
set_menu_userptr |
wclear |
def_prog_mode |
longname |
newpad |
set_panel_userptr |
wclrtobot |
def_shell_mode |
menu_back |
newterm |
set_term |
wclrtoeol |
del_curterm |
menu_driver |
newwin |
set_top_row |
wcursyncup |
del_panel |
menu_fore |
nl |
setscrreg |
wdelch |
delay_output |
menu_format |
nocbreak |
setupterm |
wdeleteln |
delch |
menu_grey |
nodelay |
show_panel |
wechochar |
deleteln |
menu_init |
noecho |
slk_clear |
werase |
delscreen |
menu_items |
nonl |
slk_init |
wgetch |
delwin |
menu_mark |
noqiflush |
slk_label |
wgetstr |
derwin |
menu_opts |
noraw |
slk_noutrefresh |
whline |
doupdate |
menu_opts_off |
notimeout |
slk_refresh |
winch |
dupwin |
menu_opts_on |
overlay |
slk_restore |
winchnstr |
echo |
menu_pad |
overwrite |
slk_set |
winchstr |
echochar |
menu_pattern |
pair_content |
slk_touch |
winnstr |
endwin |
menu_sub |
panel_above |
standend |
winsch |
erasechar |
menu_term |
panel_below |
standout |
winsdelln |
filter |
menu_userptr |
panel_hidden |
start_color |
winsertln |
flash |
menu_win |
panel_userptr |
subpad |
winsnstr |
flushinp |
meta |
panel_window |
subwin |
winsstr |
free_item |
mousemask |
pechochar |
syncok |
winstr |
free_menu |
move |
pnoutrefresh |
termattrs |
wmove |
getch |
move_panel |
pos_menu_cursor |
termname |
wnoutrefresh |
getmouse |
mvaddch |
post_menu |
tgetent |
wprintw |
getstr |
mvaddchnstr |
prefresh |
tgetflag |
wredrawln |
getwin |
mvaddchstr |
printw |
tgetnum |
wrefresh |
halfdelay |
mvaddnstr |
putp |
tgetstr |
wresize |
has_colors |
mvaddstr |
putwin |
tgoto |
wscanw |
has_ic |
mvchgat |
qiflush |
tigetflag |
wscrl |
has_il |
mvcur |
raw |
tigetnum |
wsetscrreg |
hide_panel |
mvdelch |
redrawwin |
tigetstr |
wstandend |
hline |
mvderwin |
refresh |
timeout |
wstandout |
idcok |
mvgetch |
replace_panel |
top_panel |
wsyncdown |
idlok |
mvgetstr |
reset_prog_mode |
top_row |
wsyncup |
immedok |
mvinch |
reset_shell_mode |
tparm |
wtimeout |
inch |
mvinchnstr |
resetty |
tputs |
wtouchln |
inchnstr |
mvinchstr |
restartterm |
typeahead |
wvline |
inchstr |
mvinnstr |
ripoffline |
unctrl |
|
Interix-Specific APIs
The following APIs are unique to Interix:
_getInstallPath |
_getInstallPath_Win |
_prefixInstallPath |
_prefixInstallPath_Win |
authenticateuser |
chpass |
env_alloc |
env_array |
env_cron |
env_expand_win |
env_free |
env_get |
env_login |
env_put |
env_putarray |
env_set |
env_strfree |
env_unset |
env_winlogin |
execl_asuser |
execle_asuser |
execlp_asuser |
execv_asuser |
execve_asuser |
execvp_asuser |
fullqualname |
getgrent_nomembers |
getgrgid_ex |
getgrgid_nomembers |
getgrnam_nomembers |
getloginenv |
getpdomain |
getpwuid_ex |
getreg_strvalue |
getreg_wstrvalue |
getsecret |
gettzenv |
group_from_gid |
ntpath2posix |
path_casesensitive |
path_convert |
setsecret |
setuser |
stripdomainprefix |
uidtontsid |
unixpath2win |
user_from_uid |
winpath2unix |
The routines _getInstallPath() and _prefixInstallPath() retrieve the Interix install root ($INTERIX_ROOT) and prefix it to a string, respectively. They are discussed in the Interix SDK User's Guide.
The authenticateuser() and exec*_asuser() routines are used to login as another user. They are discussed in the Interix SDK User's Guide. These APIs are now deprecated in favor of the setuser() call; the man page for the setuser() call is included in this note, because it was not included in the 2.2 Service Pack 1 release.
The uidtontsid() routine converts a POSIX-style user ID number into the user's Windows NT security ID.
The remaining routines are convenience routines:
The _ntpath2posix() routine converts a Windows NT-style pathname such as C:\Interix to its Interix equivalent, //C/Interix.
The stripdomainprefix() routine removes the domain prefix from a user name, so that a string such as "ADMIN+jo" becomes "jo".
The gettzenv() routine retrieves the value of the Win32 system's TZ environment variable.
For more information about the routines, see the relevant reference pages using the man command or using the Adobe Acrobat documents.
setuser() Reference
NAME
setuser() — change effective and real uid and gid of process
SYNOPSIS
#include <opennt/security.h> int setuser(char *username, char *password, int flags)
DESCRIPTION
The setuser() function changes the effective and real uid and gid of the current process to that of the specified username. All of the security attributes and permissions become those of username. However, the process' current working directory does not change.
The setuser() utility takes the following arguments:
username
The name of the user. If the username is not fully qualified with a domain name (that is, "domain+name"), it is not changed. On a system configured for workgroups, specify the domain as NULL: that is, the string "+name".
password
The plaintext password for the specified username.
flags
Control flags. These possible values for flags are defined in <opennt/security.h>:
SU_COMPLETE
Change the real and effective user and group IDs and all security attributes to the default for the specified user.
SU_CHECK
Check that the process will be able to perform a setuser() action using SU_COMPLETE for the specified username and password. This is a quick way to verify a password for a user. This action is equivalent to the older Interix call, authenticateuser().
There can be a performance degradation if a process changes identity to a user who does not have permission to be located in the current working directory. The best solution is, after a call to setuser(), to chdir() to a directory known to be permitted for the new identity.
RETURN VALUE
On success, the setuser() function returns 0. On failure, it returns -1 and sets errno.
ERRORS
The setuser() function can fail for the following reasons:
[EINVAL]
An argument is invalid or is missing.
[ENOMEM]
Not enough memory to complete the request.
[EPERM]
The requesting process does not have permission to change to the new user. One or both of the username or password were incorrectly specified.
NOTES:
This function replaces authenticateuser(). In fact, the version of authenticateuser() in this release is a wrapper around setuser().
SEE ALSO
setuid(), setgid(), exec_asuser(), authenticateuser()
For More Information
For more information about Interix, see the Interix Web site at: https://www.microsoft.com/windows2000/interix.