Include files, what do these do and where to get them?

Guy Harris guy at auspex.auspex.com
Thu Jul 27 08:11:07 AEST 1989


(This is really a UNIX question - all the include files relate to OS
features - so this is being cross-posted to "comp.unix.wizards" and
"comp.unix.questions".  Followups are redirected to
"comp.unix.questions", because wizards presumably only need to read this
article and they will immediately understand it; there are some points
that they may not be aware of, though, which is why it's posted to
"comp.unix.wizards", as a reminder....

If you're getting this through mailing lists, this will probably appear
in INFO-C, INFO-UNIX, and UNIX-WIZARDS.  Ignore any duplicate copies,
and send replies to INFO-UNIX.)

> In trying to compile various programs from across the net, I have come across
> some include files that were needed but I do not have.  I am running UNIX V.3
> (Interactive 1.0.5) and I don't know if I have any other files that are the
> same (I am new to C).  Anyway, if there are substitutes, or public domain
> versions of these, I would appreciate it if someone could point me in their
> direction or mail them to me.

Every now and then, a posting says "I'm trying to compile some program,
and it needs some header files I don't have on my machine.  If anybody
has them, could they send me copies?"

The problem is that the lack of the header file isn't the problem, it's
only a symptom of the problem.  The underlying problem may be that your
system may be missing some particular *feature* that the program needs,
in which case getting the header file may not do you any good
whatsoever.

Given that, the correct fix for a missing header file depends on the
missing header file, so:

> Here they are:

> 	sys/time.h	sys/timeb.h	sys/file.h	syslog.h
> 	sys/wait.h

These fall into several categories.

Category 1: Gratuitous Berkeley Changes

This category holds <sys/file.h> and <sys/wait.h>.

4.2BSD picked up the "three-argument 'open'" call, and the "fcntl" call,
from System III, albeit with some, well, gratuitous changes to the
semantics of O_NODELAY.  The more annoying gratuitous change, however,
was that they suggested including <sys/file.h>, rather than <fcntl.h>,
to get the flags for "open" and "fcntl".  (Some versions of the
documentation may also have suggested using the F* rather than the O_*
versions of the flags; at least the 4.3-tahoe OPEN(2) doesn't commit
that particular sin.)

4.3BSD, and, if I remember correctly, 4.2BSD, has an <fcntl.h> file. 
System V has it as well; its <sys/file.h> (yes, it has one) does NOT
define the O_* flags.  POSIX specifies that the flags are to be defined
by <fcntl.h>.

The fix, in most cases, to problems with <sys/file.h> is to fix the
program to include <fcntl.h>, which renders it more portable.  You may
have to change, say, references to 

<sys/file.h> also defines a few other items:

	It defines LOCK_*; if the program uses them (LOCK_SH, LOCK_EX,
	LOCK_NB, LOCK_UN), the program depends on the 4.xBSD "flock"
	call, which means to get that program to run under a system
	without "flock", such as System V, you'll have to change it to
	use something else (e.g., "lockf" or the locks provided by
	"fcntl").

	It defines F_OK, X_OK, W_OK, and R_OK, for use with the "access"
	call, and L_SET, L_INCR, and L_XTND, for use with the "lseek"
	and "fseek" calls.  In older versions of UNIX, there were no
	#define constants for those values, so programs used the
	numerical values directly; as such, using values other than the
	traditional UNIX ones is likely to break code.  Furthermore,
	AT&T-derived UNIX systems, including 4.xBSD, all use the same
	values.  They are:

	#define	F_OK		0	/* does file exist */
	#define	X_OK		1	/* is it executable by caller */
	#define	W_OK		2	/* writable by caller */
	#define	R_OK		4	/* readable by caller */

	#define	L_SET		0	/* absolute offset */
	#define	L_INCR		1	/* relative to current offset */
	#define	L_XTND		2	/* relative to end of file */

	so you can either #define them yourself or replace them with
	their numeric values.

<sys/wait.h> was part of a presumably well-intentioned, but not
well-thought-out, attempt to improve the interface to the "wait" call. 
The "wait" call in 4.xBSD is an upward-compatible extension of the one
in V7, so, the manual page and "lint" library nonwithstanding, there is
no need to use "union wait" as the argument to a "wait" call - "int"
will do quite nicely.  Code that looks at various members of the union
can be changed to look at the "int" as follows:

	union.w_termsig		(int & 0177)
	union.w_coredump	(int & 0200)
				(actually, ((int & 0200) >> 7), if you
				want to be picky, but since it's really
				a 1-bit flag, testing (int & 0200) should
				be sufficient)
	union.w_retcode		((int >> 8) & 0377)
	union.w_stopval		(int & 0377)
	union.w_stopsig		((int >> 8) & 0377)

WSTOPPED is just a #define for 0177, and the WIF* macros can be replaced
by:

	WIFSTOPPED(union)	((int & 0377) == 0177)
	WIFSIGNALED(union)	((int & 0377) != 0177
				    && (int & 0177) != 0)
	WIFEXITED(union)	((int & 0377) != 0177
				    && (int & 0177) == 0)

If the program uses WNOHANG or WUNTRACED, it depends on a BSD feature
not present in vanilla System V.

Category 2: V7isms

<sys/timeb.h> refers to a call in V7, and thus in BSD, but not in System
V.  This call lets you get wall-clock time with a resolution of less
than 1 second, as well as information about the local time zone and
daylight savings time.  The former can't be gotten with vanilla System
V; however, you *can* get time in clock ticks (as defined as HZ in
<sys/param.h>) from some arbitrary point in the past, so if the only
reason the higher-resolution time is being used is to find the real time
between two events with a resolution of less than one second, you can do
that.  The "times()" call in System V returns said time in clock ticks.

The "timezone" and "dstflag" members of a "struct timeb" shouldn't be
needed by most programs; the "localtime" routine does time zone
conversions for you.

Category 3: BSD features (as opposed to obviously gratuitous changes; I
	shall avoid debating whether these particular features are
	gratuitious or not)

Some of the stuff in the category 1 list above falls in this category. 
In addition:

<syslog.h> refers to an error-message-logging routine from 4.xBSD.  It
logs messages to an error log daemon which can append them to a log
file, send them to the system console (as opposed to your terminal), or
various other things, under the control of a configuration file.

This mechanism is not present in vanilla System V; I think there is an
implementation for System V that attempts to match the BSD one (albeit
in a limited fashion, since I don't think it has a "syslog" daemon), in
one of the "comp.sources.*" archive (written by, as I remember, Arnold
Robbins).

<sys/time.h> refers to some calls in BSD for handling time at a
resolution of less than a second.  It includes "gettimeofday", which is
similar to the "ftime" routine from System V to which <sys/timeb.h>
belongs; as such, the fix for code that uses it would be similar to the
fix for code that uses <sys/timeb.h>.  (It also includes "settimeofday",
but you can't the sub-second-resolution part of the vanilla S5 clock;
the best you can do is use "stime".)

It also refers to a generalization of "alarm" for getting a signal after
some amount of time, specified with sub-second resolution - either real
time, process user-mode CPU time, or process overall CPU time.  The
latter two aren't available in vanilla S5; the former is available with
"alarm()", but *only* with one-second resolution, so if the program
depends on lower resolution for alarms, you're out of luck.

It also includes #defines for a now-obsolete generalization of the
V7-vintage time zone stuff, but as indicated above "localtime()" handles
that in 99.44% of the cases.

> With the Cnews distribution I got some needed files, sysexits.h, sys/timeb.h,
> but are they totally compatible with the originals?

<sysexits.h> 1) doesn't depend on any OS features - certain mailer
programs may depend on it - so it should, with any luck, be *identical*
to the original, especially since it's not AT&T-licensed and thus can be
sent around freely (modulo the restrictions in the copyright notice:

 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

)

So, in summary:

	1) if something won't compile because it can't find some header
	   file, be warned that the absence of the header file may not
	   be the problem, and getting the header file might not fix the
	   problem;

	2) don't include <sys/file.h> in user-mode programs - include
	   <fcntl.h> to get O_RDWR, O_APPEND, etc., and use hardcoded
	   constants rather than the L_* and F_* stuff listed above
	   (yes, it violates some rules of Good Style, but it really
	   *improves* the portability of the code - more systems
	   probably lack those defines than give them values other than
	   the ones UNIX gives them);

	3) don't use the "union wait" stuff to crack exit statuses from
	   "wait".

Oh yes, and when you post code, you might want to make a note of OS
features it depends on....



More information about the Comp.lang.c mailing list