Source Code FAQ for The Linux Programming Interface

Below is a list of frequently asked questions for the program source code in the book The Linux Programming Interface. Improvements and additions to this list are welcome.

Please take a look at the README file and the BUILDING file for general information about the source code and how to compile it.

General errors and warnings

Warning: "_XOPEN_SOURCE" redefined

The "book" versions of some of the example programs yield the following compilation warning when built with the supplied makefiles:

warning: "_XOPEN_SOURCE" redefined

To understand why this warning occurs, it is useful to note two pieces of background information:

Some of the interfaces used in the sample programs require that _XOPEN_SOURCE be defined. If programs using these interfaces are compiled with -std=c99 -D_XOPEN_SOURCE=600, then all is well. However, if such programs are compiled without the _XOPEN_SOURCE definition, but with warnings enabled as described above, then errors or warnings will result (e.g., messages such as implicit declaration of function 'xxxxxx').

The solution I decided on for these programs was to include a preprocessor #define statement that defines _XOPEN_SOURCE suitably. The limitation of this solution is that when these programs are compiled using -D_XOPEN_SOURCE=600, and the source file redefines _XOPEN_SOURCE with a different value, the compiler warns about the redefinition.

A more complete solution that avoids the compiler warnings is demonstrated by these two examples:

#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE
#endif

#if ! defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 500
#define _XOPEN_SOURCE 500
#endif

For reasons of code compactness, this approach was not employed in the "book" versions of the programs, but it is employed in the "distribution" versions.

See also Section 3.6.1 in the book.

Errors and warnings when compiling individual files

acl/acl_update.c

If you encounter the error sys/acl.h: No such file or directory, it is because the required ACL package is not installed on your system.

On Debian or Ubuntu, something like the following should work:

$ sudo apt-get install libacl1-dev

On RPM-based systems, you'll need to install the libacl-devel package.

acl/acl_view.c

If you encounter the error sys/acl.h: No such file or directory, look here.

cap/check_password_caps.c

For an explanation of the "_XOPEN_SOURCE" redefined warning that occurs when compiling the "book" version of this program, look here.

If you encounter the error sys/capability.h: No such file or directory, it is because a required package is not installed on your system.

On Debian or Ubuntu, something like the following should work:

$ sudo apt-get install libcap-dev

On RPM-based systems, you'll need to install the libcap-devel package.

filesys/t_mount.c

When compiling the "book" version of this program, you may encounter errors staying that various MS_* constants are undeclared. This error will occur if the GNU C library on your system is earlier than version 2.12, because older glibc versions did not define some of the required constants. (How do I find out what version of glibc is on my system?)

The solution is either to compile the program on a system with a more recent version of glibc, or to compile the "distribution" version of the program.

The problem does not occur for the "distribution" version of this program, which includes code to conditionally define the required constants if they are not defined in the glibc headers. See the diff of the two program versions.

pgsjc/catch_SIGHUP.c

For an explanation of the "_XOPEN_SOURCE" redefined warning that occurs when compiling the "book" version of this program, look here.

pgsjc/t_setsid.c

For an explanation of the "_XOPEN_SOURCE" redefined warning that occurs when compiling the "book" version of this program, look here.

proc/setjmp_vars.c

The variable 'rvar' might be clobbered by 'longjmp' or 'vfork' warning that occurs when compiling this program is expected. The GNU C compiler is diagnosing exactly the problem that this program demonstrates. See page 137 of the book.

threads/thread_multijoin.c

When compiling on 64-bit systems, you'll see warnings about casts between pointers and integers of different sizes. I should have used the intptr_r type in this program. However, I've opted not to make any changes to the code or the text for the reasons described at the end of the erratum for page 649.

time/strtime.c

For an explanation of the "_XOPEN_SOURCE" redefined warning that occurs when compiling the "book" version of this program, look here.

time/t_stime.c

For an explanation of the "_XOPEN_SOURCE" redefined warning that occurs when compiling the "book" version of this program, look here.

users_groups/check_password.c

For an explanation of the "_XOPEN_SOURCE" redefined warning that occurs when compiling the "book" version of this program, look here.

General questions

Why are there "book" and "distribution" versions of the example source code?

The example source code is provided in two versions. The reasons for this are explained here.

Where is the file lib/ename.c.inc?

Some readers have noted that the file lib/ename.c.inc, shown in Listing 3-4 on page 58 of TLPI, is not present in the code tarball downloaded from the book website. That's because this file is automatically built via script when invoking make(1) in the lib directory (or in the root directory of the source code). See lib/Makefile, which invokes Build_ename.s. Things are done this way because the set of error names can vary across kernel and glibc versions and across hardware architectures.

What version of the Linux kernel do I have on my system?

To determine the version of the Linux kernel running on your system, use the following command:

$ uname -a
Linux konstanz 3.0.0-15-generic-pae #26-Ubuntu SMP Fri Jan 20 17:07:31 UTC 2012 i686 i686 i386 GNU/Linux

What version of glibc do I have on my system?

On a sufficiently recent system, you can determine the version of glibc running on your system using the following command:

$ getconf GNU_LIBC_VERSION
glibc 2.13

If that command doesn't work (perhaps because you have an older system), then you can obtain the glibc version by executing the library shared object. On many systems, this is as simple as the following:

$ /lib/libc.so.6

The first line of output of this command shows the glibc version on your system.

However, on some systems, glibc resides at a different path, so that the above command won't work. The following command obtains the pathname of the library by applying ldd to a dynamically linked executable at a known location, and then nests the resulting output inside command substitution to execute that pathname, producing the same results as the simpler command above.

$ ldd /bin/ls | grep libc.so | awk '{print $3}'
/lib/i386-linux-gnu/libc.so.6
$ $(ldd /bin/ls | grep libc.so | awk '{print $3}')
GNU C Library (Ubuntu EGLIBC 2.13-20ubuntu5) stable release version 2.13, by Roland McGrath et al.
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.6.1.
Compiled on a Linux 3.0.4 system on 2011-10-04.
Available extensions:
	crypt add-on version 2.1 by Michael Glad and others
	GNU Libidn by Simon Josefsson
	Native POSIX Threads Library by Ulrich Drepper et al
	BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.

Why do I get warnings "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"?

You are compiling the code on a system that has glibc 2.20 or later installed. In glibc 2.20, the _BSD_SOURCE and _SVID_SOURCE feature test macros were deprecated. They continue to expose the definitions that they exposed in earlier glibc versions, but their use produces the warning noted above. Instead, the _DEFAULT_SOURCE macro should be used. There are a few possible workarounds to avoid these warnings: