ANSI vs POSIX on <sys/types.h>

Doug Gwyn gwyn at smoke.brl.mil
Wed May 30 22:13:38 AEST 1990


From:  Doug Gwyn <gwyn at smoke.brl.mil>

In article <711 at longway.TIC.COM> Andy Tanenbaum <ast at cs.vu.nl> writes:
>We have gone through this before, but I still haven't gotten an unambiguous
>answer.  Let me try a specific example to make it clearer.

I'm sure I've given unambiguous answers.
The rules are really quite clear and simple.

>Suppose you want to write a routine raise() that is ANSI conformant and also
>POSIX conformant.  Raise calls the POSIX kill function, so it includes
><signal.h>.  The <signal.h> header contains the prototype for kill(), which
>uses pid_t, a type defined in <sys/types.h>.  POSIX mandates <sys/types.h>
>but ANSI does not require it.  Thus it is probably not ANSI-legal to put
>#include <sys/types.h>
>in raise(), since an ANSI routine cannot depend on something that ANSI
>doesn't require.  The raise routine would not be portable then, and maybe
>not even conformant.  On the other hand, putting the #include in <signal.h>
>probably isn't legal either, and certainly not portable to non POSIX
>systems.  
>The question is: it has to go somewhere, but where?  I have thought about
>putting it in <signal.h> but protected by #ifdef _POSIX_SOURCE, just as
>the prototype for kill is.  However, our earlier discussion in this group
>suggested that this wasn't legal either.  Does anybody know what the story
>is?

The above description makes no sense.  The run-time code for raise
does not "include <signal.h>".  In fact, it must not even (in a
conventional linkage environment) invoke the POSIX kill() function,
because the external identifier "kill" is not in the name space
reserved for ANSI C implementations (and thus is reserved for use
by programs, with perhaps totally non-POSIX meaning).  It could,
however, invoke a function named "_kill" or some other such name
reserved for use by implementations.

<signal.h> must not define extra garbage such as the kill() interface
or the POSIX *_t typedefs, except under control of some "feature test
macro" such as _POSIX_SOURCE.  In the case of the typedefs, I would
urge that they not be defined as a side effect of #including <signal.h>
even in the presence of _POSIX_SOURCE.  You don't need pid_t to properly
declare getpid() or kill() in an implementation; instead, simply use the
equivalent type derived from basic types (in this case, probably "int").
Note that this is essential also for the ANSI C declaration of vprintf()
in <stdio.h>, since the va_* identifiers must NOT be defined as a side
effect of #including <stdio.h>, so the implementation of <stdio.h> must
not #include <stdarg.h>.

On the other hand, the implementation of an ANSI C library routine can
certainly depend on things not mentioned in the C standard, such as
for example _kill() and <sys/types.h>.  The following is valid source
code to implement ANSI C conformant raise() in a hypothetical POSIX
implementation:

/*
	raise() -- send a signal to the current process

	public-domain implementation

	last edit:	16-Jan-1990	Gwyn at BRL.MIL

	complies with the following standards:
		ANSI X3.159-1989
		IEEE Std 1003.1-1988
		SVID Issue 3
 */
#define	getpid	_getpid			/* required support for ANSI C */
#define	kill	_kill			/* required support for ANSI C */

#include	<sys/types.h>		/* for pid_t */

extern pid_t	getpid();		/* UNIX/POSIX system call */
extern int	kill();			/* UNIX/POSIX system call */

int
raise(sig)
	int	sig;
	{
	return kill(getpid(), sig);	/* set errno to EINVAL if sig invalid */
	}

Volume-Number: Volume 20, Number 21



More information about the Comp.std.unix mailing list