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.

error: sys/acl.h: No such file or directory

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.

error: sys/capability.h: No such file or directory

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.

error: selinux/selinux.h: No such file or directory

If you encounter the error selinux/selinux.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 libselinux1-dev

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

Errors and warnings when compiling individual files

lib/cap_functions.c

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

lib/userns_functions.c

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

acl/acl_update.c

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

acl/acl_view.c

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

cap/cap_launcher.c

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

cap/cap_text.c

If you encounter the error sys/capability.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, look here.

cap/demo_file_caps.c

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

cap/view_cap_xattr.c

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

dirs_links/list_files_readdir_r.c

When compiling this program, you may encounter the warning 'readdir_r' is deprecated [-Wdeprecated-declarations] when building with glibc version 2.24 or later. (How do I find out what version of glibc is on my system?) This is because readdir_r() has been deprecated since glibc 2.24. See the erratum for page 357 for further details.

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.

shlibs/dynload.c

If you encounter the error #pragma GCC diagnostic not allowed inside functions, it is because you are using an older version of the GNU C compiler that does not support the use of #pragma to suppress a compiler warning that would otherwise be generated for the program.

If possible, upgrade to gcc 4.6 (Mar 2011) or later. Otherwise, edit the program to remove all of the lines beginning with #pragma and recompile (at which point you will see the previously suppressed warning message).

signals/nonatomic_uint64.c.c

If you encounter the error bits/wordsize.h: No such file or directory or sys/cdefs.h: No such file or directory, you are probably running a distribution (e.g., Ubuntu or Debian) that requires installation of the gcc-multilib package in order to build this program. Something like the following should work:

$ sudo apt-get install gcc-multilib

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_t 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.

sockets/scm_security_send.c

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

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 a 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.sh. 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 -sr
Linux 5.10.23-200.fc33.x86_64

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.26

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 (GNU libc) stable release version 2.26, by Roland McGrath et al.
Copyright (C) 2017 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 7.3.1 20180303 (Red Hat 7.3.1-5).
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.gnu.org/software/libc/bugs.html>

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. The simplest fix for this problem is to download the latest code tarball, which fixes the problem by modifying the Makefile.inc file to add -D_DEFAULT_SOURCE to the definition of the IMPL_CFLAGS macro.