Difference Between Unistd.H and Sys/Types.H in Linux

Difference between unistd.h and sys/types.h in linux

The division of the POSIX and C header in fine grained files probably comes from the old days when compilation might take a long time, and adding unnecesary header files made the time longer.

If you only need the OS types, say for the prototypes of your functions, then just #include <sys/types.h>. However if you need the function definitions, then you #include <unistd.h> or any of the other system headers, as needed.

Naturally there are types that are in both headers, as you cannot declare some functions without their necessary types.

But these different declarations of the same type are guaranteed to be the same, so there is no problem if you include both.

What is the difference between the various unistd.h under /usr/include in Linux?

linux/unistd.h actually points to asm/unistd.h, which in turn points to either asm/unistd_32.h or asm/unistd_64.h, which is where system call numbers are defined and presented to user space depending on the system's architecture. These come from the kernel.

bits/unistd.h is a collection of macros that augment unistd.h (mostly stuff to help prevent buffer overflows), which is conditionally included via:

/* Define some macros helping to catch buffer overflows.  */
#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
# include <bits/unistd.h>
#endif

In essence, the only POSIX required header is in fact, just unistd.h, the rest are either extensions, or definitions from the kernel. So, just including unistd.h is all you have to worry about doing, everything you need will be pulled in depending on your architecture and whatever build options you've selected.

Why file sys/types.h doesn't contain function definition of major(dev_t dev)?

The BSD include file <sys/types.h> originally created in 1982.

On Linux, the helper include <sys/types.h> also includes the <features.h> file. The provided function of this file has changed over time on Linux. That documentation is old, as it refers to BSD_SOURCE. In current versions, BSD_SOURCE is an alias for _DEFAULT_SOURCE.

To obtain those macros, you must include the <sys/sysmacros.h> file.

various header files and their uses

If you want to know what's in a header file, try looking at it, seriously: most will start with some comment describing the content if it's not obvious anyway.

If you want to know what part of a header file is being used by the program that's including, try removing it and looking at the error messages. That may also sound glib, but sadly there's generally not a better way to find this out. But, it may be that on one platform some functionality requires including two headers, whereas on some other platform only one of them is required (perhaps because the second header is indirectly picked up by some earlier include anyway): if you test on the platform where one header is needed and decide to remove the second include, you may break the build on the other platform. So, when you find stuff that is needed, consult the man pages for the required headers - they may be specified by some Standard that both platforms honour.

If you want to know which header files to use yourself, then again - you have to look at the documentation for the functions you need to call. Even then, as a C++ programmer you should prefer the C++ versions of certain C headers, and standard documentation tools like man - given the C function name - won't tell you about the C++ headers. Have a read of e.g. http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch03s02.html - it's GCC documentation but describes C++ Standard requirements for these headers.

Why are the mkdir() and rmdir() POSIX system calls in different header files?

The reason is, that with mkdir(2) you specify the permissions in the second argument:

  int mkdir(const char *pathname, mode_t mode);

These mode-flags and the type mode_t are defined in sys/stat.h (at least indirectly by including bits/stat.h and bits/types.h on my system), so it seems appropriate to define mkdir() there, too. Otherwise, including unistd.h would lead to an error, since the type mode_t is unknown there.

In contrast, rmdir(2) doesn't take any arguments besides the filename, so it can remain in unistd.h, since there are no other dependencies.

Where is sys/types.h located?

My Debian box (and hopefully Ubuntu haven't butchered it too much in their zeal) has it in /usr/include/sys/types.h.

Your best bet is to execute:

find /usr/include -name types.h
find / -name types.h # if not found by one above

However, keep in mind that the development stuff may not even be installed on a server. Unless it's a server for a compiler farm, it wouldn't surprise me if the compiler and a bunch of other stuff was not part of the default install.

If the compiler is locating it somewhere and you just don't know where, you can use something like:

echo "#include <sys/types.h>" | gcc -E -x c - | grep /types.h

to find out where it's getting it from.

That gcc command line:

  • stops after the pre-processing phase (-E);
  • forces the file to be treated as C source code (-x c); and
  • retrieves the program from standard input (-), in this case from the echo statement.

The final grep just strips out the unimportant lines leaving the ones that are likely to contain the location of the included file.



Related Topics



Leave a reply



Submit