[comp.lang.c] SVR2-to-overlapping-standards programming transition

gwyn@brl-smoke.ARPA (Doug Gwyn ) (10/08/87)

As I promised some time ago, here is my attempt at guidelines for
what is "universally" available in C library routines and headers
for portable programming targeted at a UNIX System V Release 2.0
environment (including the BRL UNIX System V emulation for 4.nBSD).
I've organized it so that both available and unavailable facilities
are explicitly listed, and facilities common to ANSI C or POSIX
environments are listed separately from those found in the SVID.
I've included some occasional usage comments, too.

I hope you find this useful in making the transition from where we
are now to the forthcoming standard environment(s), but if not just
ignore it.  Please send corrections to Gwyn@BRL.MIL.



	C LIBRARY FUNCTIONS AND HEADERS, CATEGORIZED BY STANDARD


Portable applications shall be written so that they use only functions
and headers from ANSI C insofar as is reasonably possible; if necessary,
they may use POSIX functions and headers; only if absolutely necessary
may they use SVID functions and headers.  Furthermore, the functions and
headers used must appear in the "generally available" list below.
Functionality beyond that requires specific approval on a case-by-case
basis, and access to such extended functions shall be isolated in small
modules that share a common interface across all systems, though of
course implementation of such modules will necessarily be system-
specific.  Obviously, one should also avoid using library or language
features that are known to be buggy in existing implementations.

This list assumes that a UNIX System V Release 2.0 environment is used.
Since currently available implementations of UNIX System V Release 2.0
(including the BRL UNIX System V emulation for 4.nBSD) do not provide
some of the facilities specified in the standards, only those that can
be relied upon are listed in the first section; additional as-yet-
unimplemented facilities are listed in the second section.  Minor
differences in interfaces or semantics have been ignored for purposes
of this availability summary, although in practice they could pose a
problem.  (This is not a tutorial on defensive portable programming.)

In the following lists, functions that require the inclusion of specific
headers are listed after the corresponding headers.  Functions that do
not differ appreciably from ones already listed for a previous standard
level are not repeated, unless a special note is necessary.

Some facilities, such as POSIX directory access routines, while not
supplied as a standard part of some System V implementations are
nevertheless available in the public domain and can be installed as
libraries and headers that can be used to augment the supplied system
environment without requiring modifications to the supplied system;
these are considered to be available and are specially noted.



	FACILITIES GENERALLY AVAILABLE IN SYSTEM V ENVIRONMENTS:


ANSI C (ANS X3.159-198x):

Standard C language, except as noted in later "not available" section.

int main(void) { ... }
int main(int argc, char *argv[]) { ... }
	Must be provided by the application (second form recommended).

#include <errno.h>
	defines	EDOM, ERANGE, errno

#include <assert.h>
	Non-trivial expansion depends on NDEBUG being undefined.
void assert(int expression);

#include <ctype.h>
int isalnum(int c);
int isalpha(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
int tolower(int c);
int toupper(int c);

#include <math.h>
	Don't rely on the returned values of math functions
	(HUGE_VAL, etc.) in error cases.
double acos(double x);
double asin(double x);
double atan(double x);
double atan2(double y, double x);
	Warning: arguments (0.,0.) are considered to be an error.
double ceil(double x);
double cos(double x);
double cosh(double x);
double exp(double x);
double fabs(double x);
double floor(double x);
double fmod(double x, double y);
double frexp(double value, int *exp);
double ldexp(double x, int exp);
double log(double x);
double log10(double x);
double modf(double value, double *iptr);
double pow(double x, double y);
double sin(double x);
double sinh(double x);
double sqrt(double x);
double tan(double x);
double tanh(double x);

#include <setjmp.h>
	defines	jmp_buf
void longjmp(jmp_buf env, int val);
int setjmp(jmp_buf env);

#include <signal.h>
	defines SIG_DFL, SIG_IGN, SIGFPE, SIGILL, SIGINT, SIGSEGV,
		SIGTERM
void (*signal(int sig, void (*func)(int)))(int);
	Note: many implementations misdeclare this ("int" for "void");
	the resulting type clash warning should normally be ignorable.

#include <stdio.h>
	defines	_IOFBF, _IOLBF, _IONBF, BUFSIZ, EOF, FILE, L_tmpnam,
		stderr, stdin, stdout
	Many of the following functions do not usually have function
	versions (fgetc() and fputc() are guaranteed to be functions).
void clearerr(FILE *stream);
int fclose(FILE *stream);
int feof(FILE *stream);
int ferror(FILE *stream);
int fflush(FILE *stream);
int fgetc(FILE *stream);
char *fgets(char *s, int n, FILE *stream);
FILE *fopen(const char *filename, const char *mode);
int fprintf(FILE *stream, const char *format, ...);
int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
FILE *freopen(const char *filename, const char *mode, FILE *stream);
int fscanf(FILE *stream, const char *format, ...);
int fseek(FILE *stream, long int offset, int whence);
	POSIX requires fseek() past EOF to extend a file open for
	writing.
long int ftell(FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int getc(FILE *stream);
int getchar(void);
char *gets(char *s);
void perror(const char *s);
	Not usually declared by <stdio.h>.  This function is scheduled
	to vanish, according to the SVID, and should be avoided.
int printf(const char *format, ...);
int putc(int c, FILE *stream);
int putchar(int c);
int puts(const char *s);
void rewind(FILE *stream);
int scanf(const char *format, ...);
void setbuf(FILE *stream, char *buf);
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
	Most SVR2 implementations of this are quite buggy.  A correct
	public-domain version for SVR2 is available from BRL.  If you
	use setvbuf(), make allowances for using a separate library in
	the Makefile rules.
int sprintf(char *s, const char *format, ...);
int sscanf(const char *s, const char *format, ...);
FILE *tmpfile(void);
char *tmpnam(char *s);
int ungetc(int c, FILE *stream);

	The following would be declared in <stdlib.h> if it existed:
void abort(void);
int abs(int j);
double atof(const char *nptr);
int atoi(const char *nptr);
long int atol(const char *nptr);
void *bsearch(const void *key, const void *base, size_t nmemb,
		size_t size, int (*compar)(const void *, const void *));
void *calloc(size_t nmemb, size_t size);
void exit(int status);
	atexit() registration is not usually supported; although a
	public-domain implementation is available from BRL, it requires
	modification of the system C library and therefore cannot be
	considered generally available.
void free(void *ptr);
char *getenv(const char *name);
	Environment strings required by POSIX to have name=value form.
void *malloc(size_t size);
void qsort(void *base, size_t nmemb, size_t size,
		int (*compar)(const void *, const void *));
int rand(void);
	The SVID *rand48() functions are much more random.
void *realloc(void *ptr, size_t size);
void srand(unsigned int seed);
double strtod(const char *nptr, char **endptr);
long int strtol(const char *nptr, char **endptr, int base);
int system(const char *string);
	The SVID guarantees Bourne shell semantics for interpretation
	of the string.

#include <string.h>
	Usually, mem*() functions are declared in <memory.h> instead.
void *memchr(const void *s, int c, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
void *memcpy(void *s1, const void *s2, size_t n);
void *memset(void *s, int c, size_t n);
char *strcat(char *s1, const char *s2);
char *strchr(const char *s, int c);
int strcmp(const char *s1, const char *s2);
char *strcpy(char *s1, const char *s2);
size_t strcspn(const char *s1, const char *s2);
size_t strlen(const char *s);
char *strncat(char *s1, const char *s2, size_t n);
int strncmp(const char *s1, const char *s2, size_t n);
char *strncpy(char *s1, const char *s2, size_t n);
char *strpbrk(const char *s1, const char *s2);
char *strrchr(const char *s, int c);
size_t strspn(const char *s1, const char *s2);
char *strtok(char *s1, const char *s2);

#include <time.h>
	defines	struct tm
char *asctime(const struct tm *timeptr);
clock_t clock(void);
char *ctime(const time_t *timer);
struct tm *gmtime(const time_t *timer);
struct tm *localtime(const time_t *timer);
time_t time(time_t *timer);
	time_t, which is usually defined (as a long int) in
	<sys/types.h> instead, is required by POSIX to be in seconds
	since the epoch.


POSIX (IEEE 1003.1):

NOTE:  The POSIX use of headers is not well specified.  Don't count
on functions being declared by them unless specifically noted here.

#include <sys/types.h>
#include <dirent.h>
	defines	DIR, struct dirent
int closedir(DIR *dirp);
DIR *opendir(const char *dirname);
struct dirent *readdir(DIR *dirp);
void rewinddir(DIR *dirp);
	A public-domain implementation is available from BRL.  If you
	use these functions, make allowances for possibly including a
	separate header directory and library in the Makefile rules.

<errno.h> definitions	E2BIG, EACCES, EAGAIN, EBADF, EBUSY, ECHILD,
			EEXIST, EFAULT, EFBIG, EINTR, EINVAL, EIO,
			EISDIR, EMFILE, EMLINK, ENFILE, ENODEV, ENOENT,
			ENOEXEC, ENOMEM, ENOSPC, ENOTDIR, ENOTTY, ENXIO,
			EPERM, EPIPE, EROFS, ESPIPE, ESRCH, EXDEV

	POSIX also specifies inclusion of <sys/types.h> and <sys/stat.h>
	for open().
#include <fcntl.h>
	defines	F_DUPFD, F_GETFD, F_GETFL, F_SETFD, F_SETFL, O_APPEND,
		O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY
int fcntl(int fildes, int cmd, ...);
	FD_CLOEXEC is not normally defined but must be precisely 1.
int open(const char *path, int oflag, ...);
	Assume the appropriate variadic declarations are in <fcntl.h>.
	For O_CREAT, "mode_t" should be replaced by "int".

#include <grp.h>
	defines	struct group
void endgrent(void);
struct group *getgrent(void);
struct group *getgrgid(uid_t gid);
	uid_t is not normally defined; use int.
struct group *getgrnam(const char *name);
void setgrent(void);

#include <pwd.h>
	defines	struct passwd
void endpwent(void);
struct passwd *getpwent(void);
struct passwd *getpwnam(const char *name);
struct passwd *getpwuid(uid_t uid);
	uid_t is not normally defined; use int.
void setpwent(void);

<signal.h> definitions	SIGALRM, SIGFPE, SIGHUP, SIGILL, SIGINT,
			SIGKILL, SIGPIPE, SIGQUIT, SIGSEGV, SIGTERM,
			SIGTRAP, SIGUSR1, SIGUSR2

#include <stdio.h>
	defines	L_ctermid, L_cuserid
char *ctermid(char *s);
char *cuserid(char *s);
FILE *fdopen(int fildes, const char *type);
int fileno(const FILE *stream);

#include <sys/types.h>
#include <sys/stat.h>
	defines	S_ISGID, S_ISUID, struct stat

#include <sys/types.h>
#include <sys/times.h>
	defines	struct tms

#include <sys/types.h>
	defines	dev_t, ino_t, off_t, time_t
	Note that time_t is also defined in ANSI C <time.h>.

#include <sys/utsname.h>
	defines	struct utsname

	The following are probably not declared in any header:
void _exit(int status);
int access(const char *path, int amode);
	The access() function exists, but not usually the *_OK symbols.
unsigned int alarm(unsigned int sec);
int chdir(const char *path);
int chmod(const char *path, mode_t mode);
	"mode_t" is not usually defined and should be replaced by "int".
int chown(const char *path, uid_t owner, uid_t group);
	"uid_t" is not usually defined in <sys/types.h>; it should
	normally be replaced by "unsigned short".
	The "saved set-*-ID" feature should not be relied on.
int close(int fildes);
int creat(const char *path, mode_t mode);
	"mode_t" is not usually defined and should be replaced by "int".
int dup(int fildes);
char **environ;
int execl(const char *path, const char *arg0, .../*, (char *)0*/);
int execle(const char *path, const char *arg0, ...
		/*, (char *)0, const char *envp[]*/);
int execlp(const char *file, const char *arg0, .../*, (char *)0*/);
int execv(const char *path, const char *argv[]);
int execve(const char *path, const char *argv[], const char *envp[]);
int execvp(const char *file, const char *argv[]);
int fork(void);
int fstat(int fildes, struct stat *buf);
char *getcwd(char *buf, int size);
uid_t getegid(void);
uid_t geteuid(void);
uid_t getgid(void);
char *getlogin(void);
char *getpass(const char *prompt);
	getpass() is of little value and should be avoided.
int getpgrp(void);
int getpid(void);
int getppid(void);
uid_t getuid(void);
int isatty(int fildes);
int kill(int pid, int sig);
int link(const char *path1, const char *path2);
off_t lseek(int fildes, off_t offset, int whence);
	SEEK_SET, SEEK_CUR, and SEEK_END are not normally defined but
	must be precisely 0, 1, and 2, respectively.
int pause(void);
int pipe(int fildes[2]);
int read(int fildes, char *buf, unsigned nbyte);
uid_t setgid(uid_t gid);
	"uid_t" is not usually defined in <sys/types.h>; it should
	normally be replaced by "unsigned short".
int setpgrp(void);
uid_t setuid(uid_t uid);
	"uid_t" is not usually defined in <sys/types.h>; it should
	normally be replaced by "unsigned short".
unsigned int sleep(unsigned int seconds);
int stat(const char *path, struct stat *buf);
clock_t times(struct tms *buffer);
	"clock_t" is not usually defined; it should normally be
	replaced by "long".
char *ttyname(int fildes);
int umask(mode_t cmask);
	"mode_t" is not usually defined and should be replaced by "int".
int uname(struct utsname *name);
	Note: The information returned has no standard form or meaning.
int unlink(const char *path);
int wait(int *stat_loc);
int write(int fildes, const char *buf, unsigned nbyte);


SVID (Issue 2, Vols. 1-3):

HOME, PATH, TERM environment variables

/dev/null
/dev/tty
/etc/passwd
	The various getpw*() functions should be used instead.
/tmp
/usr/tmp
	Applications should always use /usr/tmp, never /tmp.

#include <ctype.h>
int _tolower(int c);
int _toupper(int c);
	Although these exist, they may vanish and should not be used.
int isascii(int c);
int toascii(int c);
	These are non-portable and should be avoided.

#include <errno.h>
	also defines	ENOTBLK, ETXTBSY

#include <ftw.h>
	defines	FTW_D, FTW_DNR, FTW_F, FTW_NS
int ftw(const char *path, int (*fn)(const char *, struct stat *, int),
		int param);

#include <grp.h>
#include <stdio.h>
struct group *fgetgrent(FILE *f);

#include <math.h>
	also defines	DOMAIN, OVERFLOW, PLOSS, SING, TLOSS,
			UNDERFLOW, struct exception
double erf(double x);
double erfc(double x);
double gamma(double x);
double hypot(double x, double y);
double j0(double x);
double j1(double x);
double jn(int n, double x);
int matherr(struct exception *x);
	This function is (optionally) supplied by the application.
int signgam;
double y0(double x);
double y1(double x);
double yn(int n, double x);

#include <memory.h>
	This header is scheduled for merger with <string.h>.
	It declares all the mem*() functions.
void *memccpy(void *s1, const void *s2, int c, int n);
	The SVID actually says "char *" instead of "void *".

#include <mon.h>
	defines	WORD
void monitor(int (*lowpc)(), int (*highpc)(), WORD *buffer,
		int bufsize, int nfunc);
	This is not normally required; cc -p uses default parameters.

#include <nlist.h>
	defines	struct nlist
int nlist(const char *file_name, struct nlist nl[]);
	This is unlikely to be useful for portable applications.

#define MARK
#include <prof.h>
	defines	MARK(name)

#include <pwd.h>
#include <stdio.h>
struct passwd *fgetpwent(FILE *f);
int putpwent(const struct passwd *p, FILE *f);

#define ERROR(val) ...
#define GETC() ...
#define INIT ...
#define PEEK() ...
#define RETURN(ptr) ...
#define UNGETC(c) ...
	The above must be defined by the application before including
	<regexp.h>.  The SVID doesn't show the argument to UNGETC, but
	it's required.
#include <regexp.h>
	This really intrudes on the application name space; the SVID
	mentions that circf, sed, and nbra are reserved (as externs),
	but several other names are also stolen -- therefore this
	header is best used in a small, isolated module.
int advance(const char *string, const char *expbuf);
char *compile(const char *instring, char *expbuf, const char *endbuf,
		int eof);
char *loc1;
char *loc2;
char *locs;
int step(const char *string, const char *expbuf);

#include <search.h>
	defines	ACTION, ENTER, ENTRY, FIND, VISIT, endorder, leaf,
		postorder, preorder
	The SVID actually says "char *" instead of "void *" for the
	following; this should be changed, but who knows...
int hcreate(unsigned nel);
void hdestroy(void);
ENTRY *hsearch(ENTRY item, ACTION action);
void *lfind(const void *key, const void *base, unsigned *nelp,
		unsigned width, int (*compar)(const void *,
		const void *));
void *lsearch(const void *key, void *base, unsigned *nelp,
		unsigned width, int (*compar)(const void *,
		const void *));
void *tdelete(const void *key, void **rootp,
		int (*compar)(const void *, const void *));
void *tfind(const void *key, void *const *rootp,
		int (*compar)(const void *, const void *));
void *tsearch(const void *key, void **rootp,
		int (*compar)(const void *, const void *));
void twalk(const void *root, void (*action)(void *, VISIT, int));

#include <signal.h>
	also defines	SIGSYS
int gsignal(int sig);
int (*ssignal(int sig, int (*action)(int)))(int);
	These are scheduled to vanish; avoid them.

#include <stdio.h>
	also defines	NULL, P_tmpdir
int getw(FILE *stream);
int pclose(FILE *stream);
FILE *popen(const char *command, const char *type);
int putenv(const char *string);
int putw(int w, FILE *stream);
char *tempnam(const char *dir, const char *pfx);

#include <termio.h>
	defines	B0, B50, B75, B110, B134, B150, B200, B300, B600,
		B1200, B1800, B2400, B4800, B9600, B19200, BRKINT,
		BS0, BS1, BSDLY, CBAUD, CLOCAL, CR0, CR1, CR2, CR3,
		CRDLY, CREAD, CS5, CS6, CS7, CS8, CSIZE, CSTOPB,
		ECHO, ECHOE, ECHOK, ECHONL, FF0, FF1, FFDLY, HUPCL,
		ICANON, ICRNL, IGNBRK, IGNCR, IGNPAR, INLCR, INPCK,
		ISIG, ISTRIP, IUCLC, IXANY, IXOFF, IXON, NCC, NLDLY,
		NL0, NL1, NOFLSH, OCRNL, OFDEL, OFILL, OLCUC, ONLCR,
		ONLRET, ONOCR, OPOST, PARENB, PARMRK, PARODD, TAB0,
		TAB1, TAB2, TAB3, TABDLY, TCFLSH, TCGETA, TCSBRK,
		TCSETA, TCSETAF, TCSETAW, TCXONC, VEOF, VEOL,
		VERASE, VINTR, VKILL, VMIN, VQUIT, VT0, VT1, VTDLY,
		VTIME, XCASE, struct termio
	Many terminal modes may be incompletely supported by the
	underlying system.  Applications should try to isolate any
	terminal mode manipulations into small separate modules.

#include <time.h>
int daylight;
long timezone;
char *tzname[2];
void tzset(void);
	Although these exist, they are insufficient to deal with
	the actual complexity of timezones.

	The following are not declared in any header:
long a64l(const char *s);
int chroot(const char *path);
	chroot() isn't useful for non-privileged applications.
double drand48(void);
double erand48(unsigned short xsubi[3]);
int getopt(int argc, const char *argv[], const char *optstring);
int ioctl(int fildes, int request, ...);
long jrand48(unsigned short xsubi[3]);
char *l64a(long l);
void lcong48(unsigned short param[7]);
long lrand48(void);
int mknod(const char *path, int mode, int dev);
	mknod() isn't useful for non-privileged applications.
char *mktemp(char *template);
int mount(const char *spec, const char *dir, int rwflag);
	mount() isn't useful for non-privileged applications.
long mrand48(void);
int nice(int incr);
long nrand48(unsigned short xsubi[3]);
char *optarg;
int opterr;
int optind;
void profil(short *buff, int bufsiz, void (*offset)(), int scale);
	It is better to use the cc -p option.
int ptrace(int request, int pid, int *addr, int data);
	Use of ptrace() is not recommended for normal applications.
unsigned short *seed48(unsigned short seed16v[3]);
void srand48(long seedval);
int stime(const long *tp);
	stime() isn't useful for non-privileged applications.
void swab(void *from, void *to, int nbytes);
	The SVID actually says "char *" instead of "void *".
void sync(void);
char *sys_errlist[];
int sys_nerr;
	Don't assume anything about the format of error messages.
	sys_* are scheduled to vanish and should be avoided.
long ulimit(int cmd, long newlimit);
int umount(const char *spec);
	umount() isn't useful for non-privileged applications.
int utime(const char *path; struct utimbuf *times);
	Although this function exists, the struct definition doesn't;
	the SVID requires the application to define this:
	struct utimbuf {
		time_t actime;	/* access time */
		time_t modtime;	/* modification time */
	};



	FACILITIES NOT GENERALLY AVAILABLE -- DO NOT USE FOR NOW:


ANSI C (ANS X3.159-198x):

Various subtle aspects of semantic behavior differs from the standard.
??x [trigraph sequences].
\a [escape sequence and character constant].
const, signed, volatile [keywords].
Function prototypes.
long double [type].
nnnu, nnnU [unsigned-constant suffix].
\xnnn [hexadecimal character constants].
void * [generic pointer type].
Many library functions normally exist only as macros.
#, ## [preprocessing operators]
#elif, #error, #pragma [preprocessing commands]
__DATE__, __TIME__, __STDC__ predefined macros
	Watch out for nonstandard predefined macros [e.g. "unix"].
	__STDC__ may be used to determine the presence or absence of
	an ANSI C environment, for example for variadic-argument
	functions.

#include <float.h>
	defines	DBL_DIG, DBL_EPSILON, DBL_MANT_DIG, DBL_MAX,
		DBL_MAX_EXP, DBL_MAX_10_EXP, DBL_MIN, DBL_MIN_EXP,
		DBL_MIN_10_EXP, FLT_DIG, FLT_EPSILON, FLT_MANT_DIG,
		FLT_MAX, FLT_MAX_EXP, FLT_MAX_10_EXP, FLT_MIN,
		FLT_MIN_EXP, FLT_MIN_10_EXP, FLT_RADIX, FLT_ROUNDS,
		LDBL_DIG, LDBL_EPSILON, LDBL_MANT_DIG, LDBL_MAX,
		LDBL_MAX_EXP, LDBL_MAX_10_EXP, LDBL_MIN,
		LDBL_MIN_EXP, LDBL_MIN_10_EXP

#include <limits.h>
	defines	CHAR_BIT, CHAR_MAX, CHAR_MIN, INT_MAX, INT_MIN,
		LONG_MAX, LONG_MIN, SCHAR_MAX, SCHAR_MIN, SHRT_MAX,
		SHRT_MIN, UCHAR_MAX, UINT_MAX, ULONG_MAX, USHRT_MAX

#include <locale.h>
	defines	LC_ALL, LC_COLLATE, LC_CTYPE, LC_NUMERIC, LC_TIME
char *setlocale(int category, const char *locale);

<math.h> definitions	EDOM, ERANGE, HUGE_VAL
	E* are also defined in <errno.h>.

<signal.h> definitions	SIG_ERR, SIGABRT, sig_atomic_t
int raise(int sig);

#include <stdarg.h>
	defines	va_list
type va_arg(va_list ap, type);		/* macro */
void va_end(va_list ap);
void va_start(va_list ap, parmN);	/* macro */
	Most implementations provide a similar facility <varargs.h>;
	key on __STDC__ and use <stdarg.h> only in ANSI C environments.

#include <stddef.h>
	defines	NULL, offsetof(type, identifier), ptrdiff_t, size_t
	Implementations usually define NULL in <stdio.h>.

<stdio.h> definitions	OPEN_MAX, PATH_MAX, SEEK_CUR, SEEK_END,
			SEEK_SET, TMP_MAX, fpos_t
"b" in modes [binary files]
%i, %p, %n [*printf(), *scanf() formats]
h, L [*printf() format size modifiers]
L [*scanf() format size modifier]
int fgetpos(FILE *stream, fpos_t *pos);
int fsetpos(FILE *stream, const fpos_t *pos);
int remove(const char *filename);
int rename(const char *old, const char *new);
int vfprintf(FILE *stream, const char *format, va_list arg);
int vprintf(const char *format, va_list arg);
int vsfprintf(char *s, const char *format, va_list arg);
	Usually, v*printf() routines for <varargs.h> are provided.

#include <stdlib.h>
	defines	ERANGE, EXIT_FAILURE, EXIT_SUCCESS, HUGE_VAL,
		RAND_MAX, div_t, ldiv_t
	ERANGE is also defined in <errno.h>.
int atexit(void (*func)(void));
div_t div(int numer, int denom);
long int labs(long int j);
ldiv_t ldiv(long int numer, long int denom);
unsigned long int strtoul(const char *nptr, char **endptr, int base);

<string.h> functions:
void *memmove(void *s1, const void *s2, size_t n);
int strcoll(const char *s1, const char *s2);
char *strerror(int errnum);
char *strstr(const char *s1, const char *s2);
size_t strxfrm(char *s1, const char *s2, size_t n);


<time.h> definitions	CLK_TCK, clock_t, time_t
	time_t and clock_t are required by the SVID to be long ints;
	time_t is also defined by POSIX <sys/types.h>.
double difftime(time_t time1, time_t time0);
time_t mktime(struct tm *timeptr);
size_t strftime(char *s, size_t maxsize, const char *format,
	const struct tm *timeptr);


POSIX (IEEE 1003.1):

<errno.h> definitions	EDEADLK, ENAMETOOLONG, ENOLCK, ENOTEMPTY

<fcntl.h> definitions	F_GETLK, F_RDLCK, F_SETLK, F_SETLKW, F_UNLCK,
			F_WRLCK, FD_CLOEXEC, O_ACCMODE, O_NONBLOCK,
			struct flock
	The System V O_NDELAY is similar to O_NONBLOCK.

#include <limits.h>
	defines	ARG_MAX, CHILD_MAX, CHILD_MAX_CEIL, CLK_TCK,
		CUR_MAX_LET, FCHR_MAX, LINK_MAX, MAX_CANON, MAX_CHAR,
		MAX_LET, NAME_MAX, NGROUPS_MAX, OPEN_MAX,
		OPEN_MAX_CEIL, PASS_MAX, PATH_MAX, PID_MAX, PIPE_BUF,
		PIPE_MAX, UID_MAX
	Note that CLK_TCK is also defined by ANSI C <time.h>.

#include <setjmp.h>
	defines	sigjmp_buf
int sigsetjmp(sigjmp_buf env, int savemask);
void siglongjmp(sigjmp_buf env, int val);

<signal.h> definitions	SA_CLDSTOP, SIG_BLOCK, SIG_SETMASK,
			SIG_UNBLOCK, SIGCLD, SIGCONT, SIGSTOP,
			SIGTSTP, SIGTTIN, SIGTTOU, sigset_t,
			struct sigaction
int siginitset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(sigset_t *set, int signo);
int sigaction(int sig, struct sigaction *act, struct sigaction *oact);
int sigprocmask(int how, sigset_t *set, sigset_t *oset);
int sigpending(sigset_t *set);
int sigsuspend(sigset_t *sigmask);

<sys/stat.h> definitions	S_IRGRP, S_IROTH, S_IRUSR, S_IRWXG,
				S_IRWXO, S_IRWXU, S_ISBLK, S_ISCHR,
				S_ISDIR, S_ISFIFO, S_ISREG, S_IWGRP,
				S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH,
				S_IXUSR
	Some of these are sometimes defined, but not always.

#include <sys/types.h>
	defines	clock_t, mode_t, nlink_t, uid_t

#include <sys/wait.h>
	defines	WNOHANG, WUNTRACED

#include <tar.h>
	defines	AREGTYPE, BLKTYPE, CHRTYPE, CONTTYPE, DIRTYPE, FIFOTYPE,
		LNKTYPE, NAMSIZ, PFXSIZ, REGTYPE, SYMTYPE, TBLOCK,
		TCKSLEN, TDEVLEN, TGEXEC, TGIDLEN, TGNMLEN, TGREAD,
		TGWRITE, TMAGIC, TMAGLEN, TMODLEN, TMTMLEN, TOEXEC,
		TOREAD, TOWRITE, TSGID, TSIZLEN, TSUID, TSVTX, TUEXEC,
		TUIDLEN, TUNMLEN, TUREAD, TUWRITE, TVERSION, TVESLEN,
		union hblock
	The "cpio" archive format definitions do not appear to have a
	header associated with them.

#include <termios.h>
	defines	B0, B50, B75, B110, B134, B150, B200, B300, B600,
		B1200, B1800, B2400, B4800, B9600, B19200, B38400,
		BRKINT, CLOCAL, [CR], CREAD, CS5, CS6, CS7, CS8,
		CSIZE, CSTOPB, ECHO, ECHOE, ECHOK, ECHONL, EOF, EOL,
		ERASE, HUPCL, ICANON, ICRNL, IGNBRK, IGNCR, IGNPAR,
		INLCR, INPCK, INTR, ISIG, ISTRIP, IXOFF, IXON, KILL,
		MIN, NCCS, NL, NOFLSH, OPOST, PARENB, PARMRK, PARODD,
		QUIT, START, STOP, SUSP, TCIFLUSH, TCIOFF, TCIOFLUSH,
		TCION, TCOFLUSH, TCOOFF, TCOON, TCSADFLUSH, TCSADRAIN,
		TCSANOW, TIME, TOSTOP, VEOF, VEOL, VERASE, VINTR,
		VKILL, VMIN, VQUIT, VSUSP, VTIME, struct termios
int cf_getospeed(const struct termios *termios_p);
int cf_setospeed(struct termios *termios_p, int speed);
int cf_getispeed(const struct termios *termios_p);
int cf_setispeed(struct termios *termios_p, int speed);
int tcgetattr(int fildes, struct termios *termios_p);
int tcsetattr(int fildes, int optional_actions,
		const struct termios *termios_p);
int tcsendbreak(int fildes, int duration);
int tcdrain(int fildes);
int tcflush(int fildes, int queue_selector);
int tcflow(int fildes, int action);
int tcgetpgrp(int fildes);
int tcsetpgrp(int fildes, int pgrp_id);

#include <unistd.h>
	defines	_PC_ACTIME, _PC_DIR_DOTS, _PC_FCHR_MAX,
		_PC_GROUP_PARENT, _PC_LINK_DIR, _PC_LINK_MAX,
		_PC_MAX_CANON, _PC_MAX_CHAR, _PC_NAME_MAX, _PC_PIPE_BUF,
		_PC_PIPE_MAX, _PC_READ_ONLY, _PC_STAT_TIME,
		_PC_TIO_KILL_NL, _POSIX_ACTIME, _POSIX_CHOWN_ROOT,
		_POSIX_CRYPT_CHARS, _POSIX_CTERMIO, _POSIX_DIR_DOTS,
		_POSIX_GID_SAVED, _POSIX_GID_SET, _POSIX_GROUP_PARENT,
		_POSIX_KILL_PID_NEG1, _POSIX_KILL_PID_ZERO,
		_POSIX_KILL_SAVED, _POSIX_LINK_DIR, _POSIX_MAIN_ENVP,
		_POSIX_PATHNAME_NULL, _POSIX_PGID_CLEAR, _POSIX_PUTENV,
		_POSIX_STAT_TIME, _POSIX_TIO_KILL_NL, _POSIX_UID_SAVED,
		_POSIX_UID_SET, _POSIX_UTIME_OWNER,_POSIX_V_DISABLE,
		_SC_ARG_MAX, _SC_CHILD_MAX, _SC_CHILD_MAX_CEIL,
		_SC_CHOWN_ROOT, _SC_CLK_TCK, _SC_CRYPT_CHARS,
		_SC_CTERMIO, _SC_GID_SAVED, _SC_GID_SET, _SC_IEEE1003,
		_SC_IEEE1003job, _SC_KILL_PID_NEG1, _SC_KILL_PID_ZERO,
		_SC_KILL_SAVED, _SC_MAIN_ENVP, _SC_NGROUPS_MAX,
		_SC_OPEN_MAX, _SC_OPEN_MAX_CEIL, _SC_PASS_MAX,
		_SC_PATH_MAX, _SC_PATHNAME_NULL, _SC_PGID_CLEAR,
		_SC_PID_MAX, _SC_PUTENV, _SC_UID_MAX, _SC_UID_SAVED,
		_SC_UID_SET, _SC_UTIME_OWNER, F_OK, IEEE1003,
		IEEE1003job, R_OK, READ_ONLY, SEEK_CUR, SEEK_END,
		SEEK_SET, W_OK, X_OK

#include <sys/types.h>
#include <utime.h>
	defines	struct utimbuf

	The following are probably not defined in any header:
char *crypt(const char *key, const char *salt);
int dup2(int fildes, int fildes2);
	Use fcntl() instead.
int fpathconf(int fildes, int name);
int getgroups(int gidsetsize, uid_t *grouplist);
int jcsetpgrp(int pgrp);
int mkdir(const char *path, mode_t mode);
int mkfifo(const char *path, mode_t mode);
int pathconf(const char *path, int name);
int rename(const char *old, const char *new);
int rmdir(const char *path);
int sysconf(int name);
int wait2(int *stat_loc, int options);


SVID (Issue 2, Vols. 1-3):

Do not assume an ASCII/ISO character set.

int main(int argc, char **argv, char **envp) { ... }
	Don't rely on the presence of the third argument.

/dev/console
/etc/profile
/usr/lib/terminfo/?/*
TZ environment variable

#include <curses.h>
	[This defines so many things that I decided not to list them.]

<errno.h> definitions	EBADMSG, ECOMM, EDEADLK, EIDRM, ELIBACC,
			ELIBBAD, ELIBEXEC, ELIBMAX, ELIBSCN, EMULTIHOP,
			ENOLCK, ENOLINK, ENOMSG, ENOSR, ENOSTR, EPROTO,
			EREMOTE, ETIME

<fcntl.h> definitions	O_NDELAY, O_SYNC
	Although this may be defined, the functionality may be limited.

#include <malloc.h>
	defines	M_GRAIN, M_KEEP, M_MXFAST, M_NLBLKS, struct mallinfo
struct mallinfo mallinfo(void);
int mallopt(int cmd, int value);

#include <stropts.h>
#include <poll.h>
	defines	POLLERR, POLLHUP, POLLIN, POLLNVAL, POLLOUT, POLLPRI,
		struct pollfd
int poll(struct pollfd pollfds[], unsigned long nfds, int timeout);

<signal.h> definition	SIGPOLL

#include <string.h>
char *strdup(const char *s1);

#include <stropts.h>
	defines	FLUSHR, FLUSHRW, FLUSHW, I_FDINSERT, I_FIND, I_FLUSH,
		I_GETSIG, I_GRDOPT, I_LINK, I_LOOK, I_NREAD, I_POP,
		I_PUSH, I_SETSIG, I_SRDOPT, I_STR, I_UNLINK, MORECTL,
		MOREDATA, RMSGD, RMSGN, RNORM, RS_HIPRI, S_HIPRI,
		S_INPUT, S_MSG, S_OUTPUT, struct strbuf,
		struct strioctl, struct strpeek
int getmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr,
		int *flags);
int putmsg(int fd, const struct strbuf *ctlptr,
		const struct strbuf *dataptr, int flags);

#include <sys/acct.h>
	defines	ACCTF, AFORK, ASU, comp_t, struct acct

#include <sys/conf.h>
	defines	FMNAMESZ

#include <sys/types.h>
#include <sys/ipc.h>
	defines	IPC_CREAT, IPC_EXCL, IPC_NOWAIT, IPC_PRIVATE,
		IPC_RMID, IPC_SET, IPC_STAT, struct ipc_perm

#include <sys/lock.h>
	defines	DATLOCK, PROCLOCK, TXTLOCK, UNLOCK
int plock(int op);

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
	defines	MSG_NOERROR, struct msqid_ds
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
int msgget(key_t key, int msgflg);
int msgrcv(int msqid, void *msgp, int msgsz, long msgtyp, int msgflg);
int msgsnd(int msqid, const void *msgp, int msgsz, int msgflg);

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
	defines	GETALL, GETNCNT, GETPID, GETVAL, GETZCNT, SEM_UNDO,
		SETALL, SETVAL, struct sembuf, struct semid_ds,
		union semun
int semctl(int semid, int semnum, int cmd, union semun arg);
int semget(key_t key, int nsems, int semflg);
int semop(int semid, struct sembuf ops[], int nsops);

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
	defines	SHM_RDONLY, SHM_RND, SHMLBA, struct shmid_ds
	The SVID actually says "char *" instead of "void *" in the
	following declarations.
void *shmat(int shmid, void *shmaddr, int shmflg);
int shmdt(void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
int shmget(key_t key, int size, int shmflg);

<sys/stat.h> definition	S_ENFMT

<sys/types.h> definition	key_t

#include <tiuser.h>
	This defines so many things that I decided not to list them;
	this is Release 3.0 functionality anyway.

#define <unistd.h>
	defines	F_LOCK, F_TEST, F_TLOCK, F_ULOCK
int lockf(int fildes, int function, long size);

#include <sys/types.h>
#include <ustat.h>
	defines	struct ustat
int ustat(dev_t dev, struct ustat *buf);
	This may exist, but it is often worthless.

#include <utmp.h>
	defines	ACCOUNTING, BOOT_TIME, DEAD_PROCESS, EMPTY,
		INIT_PROCESS, LOGIN_PROCESS, NEW_TIME, OLD_TIME,
		RUN_LVL, USER_PROCESS, struct utmp
void endutent(void);
struct utmp *getutent(void);
struct utmp *getutid(struct utmp *id);
struct utmp *getutline(struct utmp *line);
void pututline(struct utmp *utmp);
void setutent(void);
void utmpname(const char *file);

	The following are not defined in any header:
int acct(const char *path);
void encrypt(char *block, int edflag);
void setkey(const char *key);
long sgetl(const char *buffer);
void sputl(long value, char *buffer);
	sgetl() and sputl() are in the "ld" library.