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