Skip to content

Assignment Makes Pointer From Integer Without A Cast Getenv 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 http://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 http://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
-lrpclib -ldl'

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

Ubuntu Forums > The Ubuntu Forum Community > Ubuntu Specialised Support > Development & Programming > Programming Talk > C & getenv


PDA

View Full Version : C & getenv



cl333r

January 16th, 2009, 04:20 AM

Hi,
does anyone know why I get the warning "main.c:29: warning: initialization makes pointer from integer without a cast" for line


char *home = getenv("HOME");

and writing "char *home = (char *)getenv("HOME");" cancels the warning. The API states that a (char *) is being returned from getenv, why do I have to explicitly cast it?


dwhitney67

January 16th, 2009, 04:30 AM

Maybe because you forgot to include <stdlib.h>?

P.S. You should also consider declaring your variable as a const char*.


const char* home = getenv("HOME");


cl333r

January 16th, 2009, 05:08 AM

Thanks, that solved the issue.
The ability to reward the user seems to have been abolished.


Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.