+2.16. I have /usr/include/net and /usr/include/scsi as symlinks
+ into my Linux source tree. Is that wrong?
+
+{PB} This was necessary for libc5, but is not correct when using glibc.
+Including the kernel header files directly in user programs usually does not
+work (see question 3.5). glibc provides its own <net/*> and <scsi/*> header
+files to replace them, and you may have to remove any symlink that you have
+in place before you install glibc. However, /usr/include/asm and
+/usr/include/linux should remain as they were.
+
+
+2.17. Programs like `logname', `top', `uptime' `users', `w' and
+ `who', show incorrect information about the (number of)
+ users on my system. Why?
+
+{MK} See question 3.2.
+
+
+2.18. After upgrading to glibc 2.1 with symbol versioning I get
+ errors about undefined symbols. What went wrong?
+
+{AJ} The problem is caused either by wrong program code or tools. In the
+versioned libc a lot of symbols are now local that were global symbols in
+previous versions. It seems that programs linked against older versions
+often accidentally used libc global variables -- something that should not
+happen.
+
+The only way to fix this is to recompile your program. Sorry, that's the
+price you might have to pay once for quite a number of advantages with
+symbol versioning.
+
+
+2.19. When I start the program XXX after upgrading the library
+ I get
+ XXX: Symbol `_sys_errlist' has different size in shared
+ object, consider re-linking
+ Why? What should I do?
+
+{UD} As the message says, relink the binary. The problem is that a few
+symbols from the library can change in size and there is no way to avoid
+this. _sys_errlist is a good example. Occasionally there are new error
+numbers added to the kernel and this must be reflected at user level,
+breaking programs that refer to them directly.
+
+Such symbols should normally not be used at all. There are mechanisms to
+avoid using them. In the case of _sys_errlist, there is the strerror()
+function which should _always_ be used instead. So the correct fix is to
+rewrite that part of the application.
+
+In some situations (especially when testing a new library release) it might
+be possible that a symbol changed size when that should not have happened.
+So in case of doubt report such a warning message as a problem.
+
+
+2.20. What do I need for C++ development?
+
+{HJ,AJ} You need either egcs 1.0.2 or gcc-2.8.1 with libstdc++ 2.8.1 (or
+more recent versions). libg++ 2.7.2 (and the Linux Versions 2.7.2.x) doesn't
+work very well with the GNU C library due to vtable thunks. If you're
+upgrading from glibc 2.0.x to 2.1 you have to recompile libstdc++ since the
+library compiled for 2.0 is not compatible due to the new Large File Support
+(LFS) in version 2.1.
+
+
+2.21. Even statically linked programs need some shared libraries
+ which is not acceptable for me. What can I do?
+
+{AJ} NSS (for details just type `info libc "Name Service Switch"') won't
+work properly without shared libraries. NSS allows using different services
+(e.g. NIS, files, db, hesiod) by just changing one configuration file
+(/etc/nsswitch.conf) without relinking any programs. The only disadvantage
+is that now static libraries need to access shared libraries. This is
+handled transparently by the GNU C library.
+
+A solution is to configure glibc with --enable-static-nss. In this case you
+can create a static binary that will use only the services dns and files
+(change /etc/nsswitch.conf for this). You need to link explicitly against
+all these services. For example:
+
+ gcc -static test-netdb.c -o test-netdb.c \
+ -lc -lnss_files -lnss_dns -lresolv
+
+The problem with this approach is that you've got to link every static
+program that uses NSS routines with all those libraries.
+
+{UD} In fact, one cannot say anymore that a libc compiled with this
+option is using NSS. There is no switch anymore. Therefore it is
+*highly* recommended *not* to use --enable-static-nss since this makes
+the behaviour of the programs on the system inconsistent.
+
+\f
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+
+3. Source and binary incompatibilities, and what to do about them
+
+3.1. I expect GNU libc to be 100% source code compatible with
+ the old Linux based GNU libc. Why isn't it like this?
+
+{DMT,UD} Not every extension in Linux libc's history was well thought-out.
+In fact it had a lot of problems with standards compliance and with
+cleanliness. With the introduction of a new version number these errors can
+now be corrected. Here is a list of the known source code
+incompatibilities:
+
+* _GNU_SOURCE: glibc does not make the GNU extensions available
+ automatically. If a program depends on GNU extensions or some
+ other non-standard functionality, it is necessary to compile it
+ with the C compiler option -D_GNU_SOURCE, or better, to put
+ `#define _GNU_SOURCE' at the beginning of your source files, before
+ any C library header files are included. This difference normally
+ manifests itself in the form of missing prototypes and/or data type
+ definitions. Thus, if you get such errors, the first thing you
+ should do is try defining _GNU_SOURCE and see if that makes the
+ problem go away.
+
+ For more information consult the file `NOTES' in the GNU C library
+ sources.
+
+* reboot(): GNU libc sanitizes the interface of reboot() to be more
+ compatible with the interface used on other OSes. reboot() as
+ implemented in glibc takes just one argument. This argument
+ corresponds to the third argument of the Linux reboot system call.
+ That is, a call of the form reboot(a, b, c) needs to be changed into
+ reboot(c). Beside this the header <sys/reboot.h> defines the needed
+ constants for the argument. These RB_* constants should be used
+ instead of the cryptic magic numbers.
+
+* swapon(): the interface of this function didn't change, but the
+ prototype is in a separate header file <sys/swap.h>. This header
+ file also provides the SWAP_* constants defined by <linux/swap.h>;
+ you should use them for the second argument to swapon().
+
+* errno: If a program uses the variable "errno", then it _must_
+ include <errno.h>. The old libc often (erroneously) declared this
+ variable implicitly as a side-effect of including other libc header
+ files. glibc is careful to avoid such namespace pollution, which,
+ in turn, means that you really need to include the header files that
+ you depend on. This difference normally manifests itself in the
+ form of the compiler complaining about references to an undeclared
+ symbol "errno".
+
+* Linux-specific syscalls: All Linux system calls now have appropriate
+ library wrappers and corresponding declarations in various header files.
+ This is because the syscall() macro that was traditionally used to
+ work around missing syscall wrappers are inherently non-portable and
+ error-prone. The following table lists all the new syscall stubs,
+ the header-file declaring their interface and the system call name.
+
+ syscall name: wrapper name: declaring header file:
+ ------------- ------------- ----------------------
+ bdflush bdflush <sys/kdaemon.h>
+ syslog ksyslog_ctl <sys/klog.h>
+
+* lpd: Older versions of lpd depend on a routine called _validuser().
+ The library does not provide this function, but instead provides
+ __ivaliduser() which has a slightly different interface. Simply
+ upgrading to a newer lpd should fix this problem (e.g., the 4.4BSD
+ lpd is known to be working).
+
+* resolver functions/BIND: like on many other systems the functions of
+ the resolver library are not included in libc itself. There is a
+ separate library libresolv. If you get undefined symbol errors for
+ symbols starting with `res_*' simply add -lresolv to your linker
+ command line.
+
+* the `signal' function's behavior corresponds to the BSD semantic and
+ not the SysV semantic as it was in libc-5. The interface on all GNU
+ systems shall be the same and BSD is the semantic of choice. To use
+ the SysV behavior simply use `sysv_signal', or define _XOPEN_SOURCE.
+ See question 3.7 for details.
+
+
+3.2. Why does getlogin() always return NULL on my Linux box?
+
+{UD} The GNU C library has a format for the UTMP and WTMP file which differs
+from what your system currently has. It was extended to fulfill the needs
+of the next years when IPv6 is introduced. The record size is different and
+some fields have different positions. The files written by functions from
+the one library cannot be read by functions from the other library. Sorry,
+but this is what a major release is for. It's better to have a cut now than
+having no means to support the new techniques later.
+
+{MK} There is however a (partial) solution for this problem. Please take a
+look at the file `login/README.utmpd'.
+
+
+3.3. Where are the DST_* constants found in <sys/time.h> on many
+ systems?
+
+{UD} These constants come from the old BSD days and are not used anymore
+(libc5 does not actually implement the handling although the constants are
+defined).
+
+Instead GNU libc contains zone database support and compatibility code for
+POSIX TZ environment variable handling.
+
+
+3.4. The prototypes for `connect', `accept', `getsockopt',
+ `setsockopt', `getsockname', `getpeername', `send',
+ `sendto', and `recvfrom' are different in GNU libc from
+ any other system I saw. This is a bug, isn't it?
+
+{UD} No, this is no bug. This version of GNU libc already follows the new
+Single Unix specifications (and I think the POSIX.1g draft which adopted the
+solution). The type for a parameter describing a size is now `socklen_t', a
+new type.
+
+
+3.5. On Linux I've got problems with the declarations in Linux
+ kernel headers.
+
+{UD,AJ} On Linux, the use of kernel headers is reduced to the minimum. This
+gives Linus the ability to change the headers more freely. Also, user
+programs are now insulated from changes in the size of kernel data
+structures.
+
+For example, the sigset_t type is 32 or 64 bits wide in the kernel. In
+glibc it is 1024 bits wide. This guarantees that when the kernel gets a
+bigger sigset_t (for POSIX.1e realtime support, say) user programs will not
+have to be recompiled. Consult the header files for more information about
+the changes.
+
+Therefore you shouldn't include Linux kernel header files directly if glibc
+has defined a replacement. Otherwise you might get undefined results because
+of type conflicts.
+
+
+3.6. I don't include any kernel headers myself but the compiler
+ still complains about redeclarations of types in the kernel
+ headers.
+
+{UD} The kernel headers before Linux 2.1.61 and 2.0.32 don't work correctly
+with glibc. Compiling C programs is possible in most cases but C++ programs
+have (due to the change of the name lookups for `struct's) problems. One
+prominent example is `struct fd_set'.
+
+There might be some problems left but 2.1.61/2.0.32 fix most of the known
+ones. See the BUGS file for other known problems.
+
+
+3.7. Why don't signals interrupt system calls anymore?
+
+{ZW} By default GNU libc uses the BSD semantics for signal(), unlike Linux
+libc 5 which used System V semantics. This is partially for compatibility
+with other systems and partially because the BSD semantics tend to make
+programming with signals easier.
+
+There are three differences:
+
+* BSD-style signals that occur in the middle of a system call do not
+ affect the system call; System V signals cause the system call to
+ fail and set errno to EINTR.
+
+* BSD signal handlers remain installed once triggered. System V signal
+ handlers work only once, so one must reinstall them each time.
+
+* A BSD signal is blocked during the execution of its handler. In other
+ words, a handler for SIGCHLD (for example) does not need to worry about
+ being interrupted by another SIGCHLD. It may, however, be interrupted
+ by other signals.
+
+There is general consensus that for `casual' programming with signals, the
+BSD semantics are preferable. You don't need to worry about system calls
+returning EINTR, and you don't need to worry about the race conditions
+associated with one-shot signal handlers.
+
+If you are porting an old program that relies on the old semantics, you can
+quickly fix the problem by changing signal() to sysv_signal() throughout.
+Alternatively, define _XOPEN_SOURCE before including <signal.h>.
+
+For new programs, the sigaction() function allows you to specify precisely
+how you want your signals to behave. All three differences listed above are
+individually switchable on a per-signal basis with this function.
+
+If all you want is for one specific signal to cause system calls to fail and
+return EINTR (for example, to implement a timeout) you can do this with
+siginterrupt().
+
+
+3.8. I've got errors compiling code that uses certain string
+ functions. Why?
+
+{AJ} glibc 2.1 has special string functions that are faster than the normal
+library functions. Some of the functions are additionally implemented as
+inline functions and others as macros.
+
+The optimized string functions are only used when compiling with
+optimizations (-O1 or higher). The behavior can be changed with two feature
+macros:
+
+* __NO_STRING_INLINES: Don't do any string optimizations.
+* __USE_STRING_INLINES: Use assembly language inline functions (might
+ increase code size dramatically).
+
+Since some of these string functions are now additionally defined as macros,
+code like "char *strncpy();" doesn't work anymore (and is unnecessary, since
+<string.h> has the necessary declarations). Either change your code or
+define __NO_STRING_INLINES.
+
+{UD} Another problem in this area is that gcc still has problems on machines
+with very few registers (e.g., ix86). The inline assembler code can require
+almost all the registers and the register allocator cannot always handle
+this situation.
+
+One can disable the string optimizations selectively. Instead of writing
+
+ cp = strcpy (foo, "lkj");
+
+one can write
+
+ cp = (strcpy) (foo, "lkj");
+
+This disables the optimization for that specific call.
+
+
+3.9. I get compiler messages "Initializer element not constant" with
+ stdin/stdout/stderr. Why?
+
+{RM,AJ} Constructs like:
+static FILE *InPtr = stdin;
+
+lead to this message. This is correct behaviour with glibc since stdin is
+not a constant expression. Please note that a strict reading of ISO C does
+not allow above constructs.
+
+One of the advantages of this is that you can assign to stdin, stdout, and
+stderr just like any other global variable (e.g. `stdout = my_stream;'),
+which can be very useful with custom streams that you can write with libio
+(but beware this is not necessarily portable). The reason to implement it
+this way were versioning problems with the size of the FILE structure.
+
+
+3.10. I can't compile with gcc -traditional (or
+ -traditional-cpp). Why?
+
+{AJ} glibc2 does break -traditional and -traditonal-cpp - and will continue
+to do so. For example constructs of the form:
+
+enum {foo
+#define foo foo
+}
+
+are useful for debugging purposes (you can use foo with your debugger that's
+why we need the enum) and for compatibility (other systems use defines and
+check with #ifdef).
+
+
+3.11. I get some errors with `gcc -ansi'. Isn't glibc ANSI compatible?
+
+{AJ} The GNU C library is compatible with the ANSI/ISO C standard. If
+you're using `gcc -ansi', the glibc includes which are specified in the
+standard follow the standard. The ANSI/ISO C standard defines what has to be
+in the include files - and also states that nothing else should be in the
+include files (btw. you can still enable additional standards with feature
+flags).
+
+The GNU C library is conforming to ANSI/ISO C - if and only if you're only
+using the headers and library functions defined in the standard.
+
+
+3.12. I can't access some functions anymore. nm shows that they do
+ exist but linking fails nevertheless.
+
+{AJ} With the introduction of versioning in glibc 2.1 it is possible to
+export only those identifiers (functions, variables) that are really needed
+by application programs and by other parts of glibc. This way a lot of
+internal interfaces are now hidden. nm will still show those identifiers
+but marking them as internal. ISO C states that identifiers beginning with
+an underscore are internal to the libc. An application program normally
+shouldn't use those internal interfaces (there are exceptions,
+e.g. __ivaliduser). If a program uses these interfaces, it's broken. These
+internal interfaces might change between glibc releases or dropped
+completely.
+