UNIX system interfaces
----------------------

UNIX systems often have many system interfaces versions.
These various system interfaces usually conform:
- on BSD platforms to BSD 4.4 which is pretty stable and implements POSIX
  standards;
- on System V platforms to various Open Group standards which in turn
  implement POSIX standards.

You may find more information about standards by studying the standards(5)
or stdsyms(5) manual page of some commercial UNIX platforms or by reading
the POSIX and Open Group standards, starting for example from these Open
Group sites:
	http://www.opengroup.org/
	http://www.UNIX-systems.org/

Important standards and specifications are summarized in the following table:

XPG4
	superset of POSIX.1-1990, POSIX.2-1992, and POSIX.2a-1992 containing
	extensions to POSIX standards from XPG3

Single UNIX Specification (1995) / SUS / XPG4v2
	superset of XPG4 containing historical BSD interfaces widely used by
	common application packages

XNS4
	networking services (sockets) included in SUS/XPG4v2

POSIX.1c-1996
	POSIX threads extensions

Single UNIX Specification (1998) / SUSv2 / XPG5
	superset of Single UNIX Specification (1995) extended to support
	POSIX.1b-1993, POSIX.1c-1996, and ISO/IEC 9899 Amendment 1

XNS5
	superset and LP64-clean derivative of XNS4 included in SUSv2/XPG5



System V default system interfaces
----------------------------------

Today's System V platforms offer recent enough interfaces (SUS/XPG4v2),
although not always the most recent ones (SUSv2/XPG5). As an example, here
are the first releases of a selection of platforms to support some Open Group
and POSIX standards:

AIX
	XPG4			AIX 4.1
	SUS/XPG4v2		AIX 4.2
	XNS4			AIX 4.2
	SUSv2/XPG5		AIX 4.3
	XNS5			AIX 4.3
	POSIX.1c-Draft 7	AIX 4.1
	POSIX.1c-1996		AIX 4.3

Solaris
	XPG4			Solaris 2.4
	SUS/XPG4v2		Solaris 2.6
	XNS4			Solaris 2.6
	POSIX.1c-1996		Solaris 2.6
	SUSv2			Solaris 7
	XNS5			Solaris 7

Tru64
	XPG4v2			Tru64 4.0
	XNS4			Tru64 4.0
	POSIX.1c-1996		Tru64 4.0
	SUSv2			Tru64 5.0
	XNS5			Tru64 5.0

A system can switch to any of the supported standards or even mix them. The
internal magic is based on macros, usually defined in header file <unistd.h>
or a header file included by <unistd.h>. Sometimes the implementation directly
defines feature test macros documented by Open Group standards, and sometimes
the implementation defines internal undocumented macros, thus adding a level
of indirection. The default, implicit systems interfaces may usually be
explictly triggered using platform-dependant macros. This is an important
issue and is therefore covered in detail. Here is an overview for a selection
of platforms:

AIX		<standards.h>

	By default AIX defines user-space feature test macros:

		AIX 4.1		_XOPEN_SOURCE
				_POSIX_SOURCE
				_ANSI_C_SOURCE
				_ALL_SOURCE

		AIX 4.2		_XOPEN_SOURCE
				_POSIX_SOURCE
				_ANSI_C_SOURCE
				_XOPEN_SOURCE_EXTENDED 1
				_ALL_SOURCE

		AIX 4.3		_XOPEN_SOURCE  500
				_XOPEN_SOURCE_EXTENDED 1
				_POSIX_SOURCE
				_ANSI_C_SOURCE
				_ALL_SOURCE

	All this is explicitly specified by defining:

		AIX		_ALL_SOURCE


GNU		<features.h>

	By default the GNU C library defines internal macros:

		glibc 2.0	_BSD_SOURCE     1
				_SVID_SOURCE    1
				_POSIX_SOURCE   1

		glibc 2.2	_BSD_SOURCE     1
				_SVID_SOURCE    1
				_POSIX_SOURCE   1
				_POSIX_C_SOURCE 199506L

	All this - and more! - is explicitly specified by defining:

		glibc		_GNU_SOURCE

	The above _GNU_SOURCE also defines these additional macros:

		glibc 2.0	_POSIX_SOURCE           1
				_POSIX_C_SOURCE	        199309L
				_XOPEN_SOURCE           1
				_XOPEN_SOURCE_EXTENDED  1
				_BSD_SOURCE             1
				_SVID_SOURCE            1

		glibc 2.1	_ISOC9X_SOURCE          1
				_POSIX_SOURCE           1
				_POSIX_C_SOURCE	        199506L
				_XOPEN_SOURCE           500
				_XOPEN_SOURCE_EXTENDED  1
				_BSD_SOURCE             1
				_SVID_SOURCE            1

		glibc 2.2	_ISOC99_SOURCE          1
				_POSIX_SOURCE           1
				_POSIX_C_SOURCE	        199506L
				_XOPEN_SOURCE           600
				_XOPEN_SOURCE_EXTENDED  1
				_BSD_SOURCE             1
				_SVID_SOURCE            1

	Thus _GNU_SOURCE could be of interest to specify broader interfaces
	than the default interfaces.


HP-UX		<sys/stdsyms.h>

	By default HP-UX defines internal macros:

		HP-UX 10.20	_INCLUDE__STDC__
				_INCLUDE_POSIX_SOURCE
				_INCLUDE_POSIX2_SOURCE
				_INCLUDE_POSIX4_SOURCE
				_INCLUDE_XOPEN_SOURCE
				_INCLUDE_XOPEN_SOURCE_EXTENDED
				_INCLUDE_AES_SOURCE
				_INCLUDE_HPUX_SOURCE

	All this is explicitly specified by defining:

		HP-UX		_HPUX_SOURCE


Irix		<standards.h>

	By default Irix defines internal macros:

		Irix 6.3	_POSIX90
				_POSIX2
				_POSIX93
				_POSIX1C
				_XOPEN4
				_SGIAPI
				_ABIAPI

		Irix 6.4	_POSIX90
				_POSIX2
				_POSIX93
				_POSIX1C
				_XOPEN4
				_SGIAPI
				_ABIAPI
				_LFAPI

		Irix 6.5	_POSIX90
				_POSIX2
				_POSIX93
				_POSIX1C
				_XOPEN4
				_XOPEN5
				_SGIAPI
				_ABIAPI
				_LFAPI

	All this is explicitly specified by defining:

		Irix		_SGI_SOURCE

	Both the MIPSpro and the GCC compilers define _SGI_SOURCE.

	Note that the internal macro _XOPEN4UX is not defined by _SGI_SOURCE.
	Also note that Irix 6.5 is not really SUSv2/XPG5 compliant. For
	example socket functions still use 'int' instead of 'socklen_t'.


Reliant		<unistd.h>	

	By default Reliant defines no macros, just like Solaris.

	The system header files always check against _POSIX_SOURCE,
	_XOPEN_SOURCE or _XOPEN_SOURCE_EXTENDED.

	Once one of the above macros is defined, there's unfortunately
	no way to return to the default environment.


Solaris		<sys/feature_tests.h>	

	By default Solaris defines no macros!

	The system header files always check against _POSIX_C_SOURCE,
	_POSIX_C_SOURCE, _XOPEN_SOURCE_EXTENDED or __EXTENSIONS__.

	The default behaviour is specified by defining:

		Solaris 	__EXTENSIONS__


SCO		<unistd.h>	

	By default SCO Openserver defines no macros, just like Solaris.

	The system header files always check against _XOPEN_SOURCE,
	_XOPEN_SOURCE_EXTENDED or _POSIX_SOURCE.

	Once one of the above macros is defined, there's unfortunately
	no way to return to the default environment.


Tru64		<standards.h>

	By default Tru64 defines user-space feature test macros:

		Tru64 4.0F	_AES_SOURCE
				_XOPEN_SOURCE
				_POSIX_C_SOURCE 199506L
				_POSIX_SOURCE
				_OSF_SOURCE

		Tru64 5.0A	_AES_SOURCE
				_XOPEN_SOURCE   400
				_POSIX_C_SOURCE 199506L
				_POSIX_SOURCE
				_OSF_SOURCE

	If any feature test macro is explicitly defined by the user,
	such as _POSIX_C_SOURCE set to 199506L or _XOPEN_SOURCE set
	to 500, then _all_ the above must be defined to recover the
	default environment. There's no shortcut on Tru64.


Unixware	<unistd.h>	

	By default Unixware defines no macros, just like Solaris.

	The system header files always check against _XOPEN_SOURCE,
	_POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE_EXTENDED.

	Once one of the above macros is defined, there's unfortunately
	no way to return to the default environment.


QNX		<sys/platform.h>

	I am not yet sure what _QNX_SOURCE specifies:

		QNX 6.00	_QNX_SOURCE



And now what with all this?
---------------------------

To configure a system, follow these simple steps.

1) Avoid defining any of the above macros. By default the system should
   be providing appropriate interfaces.

2) POSIX and Open Group standards more recent than the default standard
   provided by the system have sometimes to be specified. This is done
   by defining well known macros such as _POSIX_C_SOURCE or _XOPEN_SOURCE.
   Be very careful when defining such macros. They specify strict respect
   of a given standard. They hide interfaces that are outside of the scope
   of the standard but otherwise available by default when no macro is
   defined.
   If you have to use such a macro, don't forget to define along with
   it the platform dependant macro that explicitly specifies the default
   interface:
   	GNU		_GNU_SOURCE
   	HP-UX		_HPUX_SOURCE
   	Irix		_SGI_SOURCE
   	Solaris		__EXTENSIONS__
   The case of Tru64 is complicated as by default it defines a lot of
   macros that additionally depend on the release. If possible do not
   define any macro on this platform!

3) Sometimes interfaces may be specified by macros that do not limit
   the scope of other interfaces. _FILE_OFFSET_BITS is such a macro.
   These are usually not dangerous. They do not involve explicitly
   respecifying the default interface.

4) Avoid defining internal undocumented macros such as
   	GNU		_UNIX98
   	Irix		_SGIAPI
   	Solaris		_XPG5
   This may solve a problem in the short term but is guaranteed to
   a be maintainance nightmare in the long term. If you don't know
   the canonical way of respecifying the default interfaces on a
   given platform, ask someone who knows the platform, have a look
   at the system header files and especially at <unistd.h> and the
   first file included by it. Do ask for these files if needed.

5) There are some macros with very limited impact such as BSD_COMP
   on Solaris, only used in <sys/ioctl.h>. Such toy macros are
   better defined before including the relevant header file, inside
   the source.
