summaryrefslogtreecommitdiff
path: root/patches/glibc/2.1.3/rh62-00-glibc-2.1.3.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/glibc/2.1.3/rh62-00-glibc-2.1.3.patch')
-rw-r--r--patches/glibc/2.1.3/rh62-00-glibc-2.1.3.patch117574
1 files changed, 0 insertions, 117574 deletions
diff --git a/patches/glibc/2.1.3/rh62-00-glibc-2.1.3.patch b/patches/glibc/2.1.3/rh62-00-glibc-2.1.3.patch
deleted file mode 100644
index 7f93a4f..0000000
--- a/patches/glibc/2.1.3/rh62-00-glibc-2.1.3.patch
+++ /dev/null
@@ -1,117574 +0,0 @@
-diff -Naur ../glibc-2.1.3/ChangeLog glibc-2.1.3/ChangeLog
---- ../glibc-2.1.3/ChangeLog 2000-02-24 18:05:16.000000000 -0800
-+++ glibc-2.1.3/ChangeLog 2000-02-29 13:15:05.000000000 -0800
-@@ -1,3 +1,16 @@
-+2000-02-28 David S. Miller <davem@redhat.com>
-+
-+ * sysdeps/unix/sysv/linux/sparc/getsysstats.c: New file.
-+
-+2000-02-24 Ulrich Drepper <drepper@redhat.com>
-+
-+ * locale/C-ctype.c (_nl_C_LC_CTYPE): Move comma to correct place
-+ for big endian machines.
-+
-+2000-02-24 Andreas Jaeger <aj@suse.de>
-+
-+ * locale/programs/ld-ctype.c (ctype_output): Add missing &.
-+
- 2000-02-24 Ulrich Drepper <drepper@cygnus.com>
-
- * locale/C-ctype.c: Add table pointer for both endianesses.
-@@ -42,6 +55,10 @@
- conditions so as not to clobber the final '\0' when there is only one
- element in the vector.
-
-+2000-02-23 Cristian Gafton <gafton@redhat.com>
-+
-+ * locale/programs/ld-ctype.c (CTYPE_DATA): Make sure we keep the alignment
-+
- 2000-02-22 Ulrich Drepper <drepper@redhat.com>
-
- * libio/stdio.h: Define macros stdin, stdout, and stderr.
-@@ -230,6 +247,11 @@
- Rebel-NetWinder to platform table so _ioperm platform lookup via
- /proc/cpuinfo works on later version NetWinders.
-
-+2000-02-14 Cristian Gafton <gafton@redhat.com>
-+
-+ * timezone/aliases: New file
-+ * timezone/Makefile (tzlinks): Add aliases
-+
- 2000-02-13 Ulrich Drepper <drepper@redhat.com>
-
- * sysdeps/i386/fpu/s_cosf.S: Domain of opcode is not large enough
-@@ -406,6 +428,12 @@
-
- * sysdeps/unix/sysv/linux/arm/mmap64.S: Correct check for ENOSYS.
-
-+2000-02-01 Cristian Gafton <gafton@redhat.com>
-+
-+ * misc/syslog.c (closelog): reset LogType to SOCK_DGRAM
-+ (openlog_internal): retry with SOCK_DGRAM if we are in SOCK_STREAM
-+ mode and we get a connection refused.
-+
- 2000-01-25 Ulrich Drepper <drepper@cygnus.com>
-
- * sysdeps/unix/sysv/linux/i386/Dist: Add sys/io.h.
-diff -Naur ../glibc-2.1.3/Makeconfig glibc-2.1.3/Makeconfig
---- ../glibc-2.1.3/Makeconfig 1999-11-29 11:19:20.000000000 -0800
-+++ glibc-2.1.3/Makeconfig 2000-01-10 14:11:06.000000000 -0800
-@@ -789,7 +789,8 @@
- $(patsubst $<,/dev/null,$^) > $@-tmp
- mv -f $@-tmp $@
-
--all-Depend-files = $(wildcard $(..)*/Depend)
-+all-Depend-files = $(wildcard $(patsubst %,$(..)%/Depend,$(add-ons)))
-+
- $(common-objpfx)sysd-sorted: $(..)scripts/gen-sorted.awk $(all-Depend-files) \
- $(common-objpfx)sysd-dirs $(..)Makeconfig
- { { dirs='$(patsubst $(..)%/Depend,$(..)%,$(filter %/Depend,$^))';\
-diff -Naur ../glibc-2.1.3/Makefile.in glibc-2.1.3/Makefile.in
---- ../glibc-2.1.3/Makefile.in 1998-02-26 06:51:55.000000000 -0800
-+++ glibc-2.1.3/Makefile.in 1998-03-12 12:17:58.000000000 -0800
-@@ -1,4 +1,4 @@
--# Generated from $Id: Makefile.in,v 1.6 1998/02/26 14:51:55 drepper Exp $.
-+# Generated from $Id: Makefile.in,v 1.1.1.1 1998/03/12 20:17:58 gafton Exp $.
-
- srcdir = @srcdir@
-
-diff -Naur ../glibc-2.1.3/README-alpha glibc-2.1.3/README-alpha
---- ../glibc-2.1.3/README-alpha 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/README-alpha 1999-06-16 15:30:43.000000000 -0700
-@@ -0,0 +1,287 @@
-+ GNU libc SNAPSHOT SYSTEM
-+ (general info)
-+ Updated 1997-9-26
-+
-+WHAT ARE GNU libc SNAPSHOTS
-+---------------------------
-+
-+Snapshots are an "image" of the main glibc development tree, captured at a
-+particular random instant in time. When you use the snapshots, you should be
-+able to maintain a local copy of libc that is no more than one day older than
-+the official source tree used by the libc maintainers.
-+
-+The primary purpose of providing snapshots is to widen the group of motivated
-+developers that would like to help test, debug, and enhance glibc, by providing
-+you with access to the "latest and greatest" source. This has several
-+advantages, and several disadvantages.
-+
-+ First the advantages:
-+
-+ o Once we have a large base of motivated testers using the snapshots,
-+ this should provide good coverage across all currently supported
-+ glibc hosts and targets. If a new bug is introduced in glibc due to
-+ fixing another bug or ongoing development, it should become
-+ obvious much more quickly and get fixed before the next general
-+ net release. This should help to reduce the chances of glibc being
-+ released to the general public with a major bug that went unnoticed
-+ during the release cycle testing because they are machine dependent.
-+ We hope to greatly improve glibc's stability and reliability by
-+ involving more people and more execution environments in the
-+ prerelease testing.
-+
-+ o With access to the latest source, any diffs that you send to fix
-+ bugs or add new features should be much easier for the glibc team
-+ to merge into the official source base (after suitable review
-+ of course). This encourages us to merge your changes quicker,
-+ while they are still "fresh".
-+
-+ o Once your diffs are merged, you can obtain a new copy of glibc
-+ containing your changes almost immediately. Thus you do not
-+ have to maintain local copies of your changes for any longer
-+ than it takes to get them merged into the official source base.
-+ This encourages you to send in changes quicker.
-+
-+ And the disadvantages:
-+
-+ o The snapshot you get will be largely untested and of unknown quality.
-+ It may fail to configure or compile. It may have serious bugs.
-+ You should always keep a copy of the last known working version
-+ before updating to the current snapshot, or at least be able to
-+ regenerate a working version if the latest snapshot is unusable
-+ in your environment for some reason.
-+
-+ If a production version of glibc has a bug and a snapshot has the fix,
-+ and you care about stability, you should put only the fix for that
-+ particular problem into your production version. Of course, if you
-+ are eager to test glibc, you can use the snapshot versions in your
-+ daily work, but users who have not been consulted about whether they
-+ feel like testing glibc should generally have something which is at
-+ least as bug free as the last released version.
-+
-+ o Providing timely response to your questions, bug reports, and
-+ submitted patches will require the glibc development team to allocate
-+ time from an already thin time budget. Please try to help us make
-+ this time as productive as possible. See the section below about
-+ how to submit changes.
-+
-+
-+WHO SHOULD TRY THE SNAPSHOTS
-+----------------------------
-+
-+Remember, these are snapshots not tested versions. So if you use
-+these versions you should be able to
-+
-+ o make sure your system stays usable
-+
-+ o locate and hopefully fix problems
-+
-+ o to port glibc to a new target yourself
-+
-+You should not use the snapshots if
-+
-+ o your system is needed in a production environment which needs
-+ stability
-+
-+ o you expect us to fix your problems since you somehow depend on them.
-+ You must be willing to fix the problems yourself, we don't want to
-+ see "I have problems, fix this" messages.
-+
-+
-+HOW TO GET THE SNAPSHOTS
-+------------------------
-+
-+At the moment we provide a full snapshot weekly (every sunday), so
-+that users getting a snapshot for the first time, or updating after
-+a long period of not updating, can get the latest version in a single
-+operation. Along with the full snapshot, we will provide incremental
-+diffs on a nearly daily basis (whenever code changes). Each daily
-+diff will be relative to the source tree after applying all previous
-+daily diffs. The daily diffs are for people who have relatively low
-+bandwidth ftp or uucp connections.
-+
-+The files will be available via anonymous ftp from alpha.gnu.org, in
-+directory /gnu/libc and on linux.kernel.org in /pub/software/libs/glibc. The
-+directories should look something like:
-+
-+ libc-970921.tar.gz
-+ libc-970917-970922.diff.gz
-+ libc-970922-970925.diff.gz
-+ .
-+ .
-+ .
-+
-+Please note that the snapshots on alpha.gnu.org and on
-+linux.kernel.org are not always in sync. Patches to some files might
-+appear a day a diff earlier or later on alpha than on kernel.
-+Use always alpha or always kernel but don't mix them.
-+
-+There are sometimes additionally test releases of the add-ons available in
-+these directories. If a new version of an add-on is available it is normally
-+required for the corresponding snapshot so always pay attention for these.
-+
-+Note that we provide GNU gzip compressed files only. You can ftp gzip
-+from ftp.gnu.org in directory pub/gnu.
-+
-+In some cases the dates for diffs and snapshots do not match like in the
-+example above. The full release is for 970921 but the patch is for
-+970917-970922. This only means that nothing changed between 970917 and 970922
-+and that you have to use this patch on top of the 970921 snapshot since the
-+patch is made on 970922.
-+
-+Also, as the gcc developers did with their gcc snapshot system, even though we
-+will make the snapshots available on a publically accessible ftp area, we ask
-+that recipients not widely publicise their availability. The motivation for
-+this request is not to hoard them, but to avoid the situation where the
-+general glibc user base naively attempts to use the snapshots, has trouble with
-+them, complains publically, and the reputation of glibc declines because of a
-+perception of instability or lack of quality control.
-+
-+
-+GLIBC TEST SUITE
-+----------------
-+
-+A test suite is distributed as an integral part of the snapshots. A simple
-+"make check" in your build directory is sufficient to run the tests. glibc
-+should pass all tests and if any fails, please report it. A failure might not
-+originate from a bug in glibc but also from bugs in the tools, e.g. with gcc
-+2.7.2.x the math tests fail some of the tests because of compiler bugs.
-+
-+Note that the test suite is still in its infancy. The tests themselves only
-+cover a small portion of libc features, and where tests do exist for a feature
-+they are not exhaustive. New tests are welcome.
-+
-+
-+GETTING HELP, GLIBC DISCUSSIONS, etc
-+------------------------------------
-+
-+People who want to help with glibc and who test out snapshots
-+regularly should get on the libc-alpha@sourceware.cygnus.com mailing
-+list by sending an email to libc-alpha-subscribe@sourceware.cygnus.com.
-+This list is meant (as the name suggests) for the discussion of test
-+releases and also reports for them. People who are on this list are
-+welcome to post questions of general interest.
-+
-+People who are not only willing to test the snapshots but instead
-+really want to help developing glibc should contact
-+libc-hacker-subscribe@sourceware.cygnus.com.org to be put on the developers
-+mailing list. This list is really only meant for developers. No
-+questions about installation problems or other simple topics are
-+wanted nor will they be answered.
-+
-+Do *not* send any questions about the snapshots or patches specific to the
-+snapshots to bug-glibc@gnu.org. Nobody there will have any idea what
-+you are talking about and it will just cause confusion.
-+
-+
-+BUG REPORTS
-+-----------
-+
-+Send bug reports directly to Ulrich Drepper <drepper@gnu.org>. Please
-+do *not* use the glibcbug script for reporting bugs in the snapshots.
-+glibcbug should only be used for problems with the official released versions.
-+We don't like bug reports in the bug database because otherwise the impression
-+of instability or lack of quality control of glibc as a whole might manifest
-+in people's mind.
-+
-+Note that since no testing is done on the snapshots, and snapshots may even be
-+made when glibc is in an inconsistent state, it may not be unusual for an
-+occasional snapshot to have a very obvious bug, such as failure to compile on
-+*any* machine. It is likely that such bugs will be fixed by the next
-+snapshot, so it really isn't necessary to report them unless they persist for
-+a couple of days.
-+
-+Missing files should always be reported, since they usually mean there is a
-+problem with the snapshot-generating process and we won't know about them
-+unless someone tells us.
-+
-+Bugs which are non-obvious, such as failure to compile on only a specific
-+machine, a new machine dependent or obscure bug (particularly one not detected
-+by the testsuite), etc should be reported when you discover them, or have a
-+suggested patch to fix them.
-+
-+
-+FORMAT FOR PATCHES
-+------------------
-+
-+If you have a fix for a bug, or an enhancement to submit, send your patch to
-+Ulrich Drepper <drepper@gnu.org>. Here are some simple guidelines for
-+submitting patches:
-+
-+ o Use "unified diffs" for patches. A typical command for generating
-+ context diffs is "diff -ru glibc-old glibc-patched".
-+
-+ o Use the "minimalist approach" for patches. That is, each patch
-+ should address only one particular bug, new feature, etc. Do not
-+ save up many unrelated changes and submit them all in one big
-+ patch, since in general, the larger the patch the more difficult
-+ it is for us to decide if the patch is either correct or
-+ desirable. And if we find something about the patch that needs
-+ to be corrected before it can be installed, we would have to reject
-+ the entire patch, which might contain changes which otherwise would
-+ be accepted if submitted separately.
-+
-+ o Submit a sample ChangeLog entry with your patch. See the existing
-+ glibc ChangeLog for examples of what a ChangeLog entry should look
-+ like. The emacs command ^X4A will create a ChangeLog entry header
-+ for you.
-+
-+
-+BUILDING SNAPSHOTS
-+------------------
-+
-+The `best' way to build glibc is to use an extra directory, e.g.:
-+tar xzf libc-970921.tar.gz
-+mkdir build-glibc
-+cd build-glibc
-+../libc-970921/configure ...
-+
-+In this way you can easily clean up (since `make clean' doesn't work at
-+the moment) and rebuild glibc.
-+
-+
-+NECESSARY TOOLS
-+---------------
-+
-+For the recommended versions of gcc, binutils, make, texinfo, gettext,
-+autoconf and other tools which might be especially needed when using patches,
-+please read the file INSTALL.
-+
-+
-+HOW CAN YOU HELP
-+----------------
-+
-+It helps already a lot if you just install glibc on your system and try to
-+solve any problems. You might want to look at the file `PROJECTS' and help
-+with one of those projects, fix some bugs (see `BUGS' or the bug database),
-+port to an unsupported platform, ...
-+
-+
-+FURTHER DOCUMENTATION
-+---------------------
-+
-+A lot of questions are answered in the FAQ. The files `INSTALL', `README' and
-+`NOTES' contain the most important documentation. Furthermore glibc has its
-+own 700+ pages info documentation, ...
-+
-+
-+
-+And finally a word of caution: The libc is one of the most fundamental parts
-+of your system - and these snapshots are untested and come without any
-+guarantee or warranty. You might be lucky and everything works or you might
-+crash your system. If you install a glibc snapshot as primary library, you
-+should have a backup somewhere.
-+
-+On many systems it is also a problem to replace the libc while the system is
-+running. In the worst case on broken OSes some systems crash. On better
-+systems you can move the old libc aside but removing it will cause problems
-+since there are still processes using this libc image and so you might have to
-+check the filesystem to get rid of the libc data. One good alternative (which
-+is also safer) is to use a chroot'ed environment.
-+
-+Thanks for your help and support.
-+
-+Thanks to Fred Fish from Cygnus for the original version of this text
-+(for GDB).
-+
-+
-+Ulrich Drepper
-diff -Naur ../glibc-2.1.3/README.template glibc-2.1.3/README.template
---- ../glibc-2.1.3/README.template 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/README.template 1999-07-28 15:46:07.000000000 -0700
-@@ -0,0 +1,96 @@
-+This directory contains the version VERSION release of the GNU C Library.
-+Many bugs have been fixed since the last release.
-+Some bugs surely remain.
-+
-+As of this release, the GNU C library is known to run on the following
-+configurations:
-+
-+ *-*-gnu GNU Hurd
-+ i[3456]86-*-linux-gnu Linux-2.x on Intel
-+ m68k-*-linux-gnu Linux-2.x on Motorola 680x0
-+ alpha-*-linux-gnu Linux-2.x on DEC Alpha
-+ powerpc-*-linux-gnu Linux and MkLinux on PowerPC systems
-+ sparc-*-linux-gnu Linux-2.x on SPARC
-+ sparc64-*-linux-gnu Linux-2.x on UltraSPARC
-+ arm-*-none ARM standalone systems
-+ arm-*-linux Linux-2.x on ARM
-+ arm-*-linuxaout Linux-2.x on ARM using a.out binaries
-+
-+
-+Former releases of this library (version 1.09.1 and perhaps earlier
-+versions) used to run on the following configurations:
-+
-+ alpha-dec-osf1
-+ i[3456]86-*-bsd4.3
-+ i[3456]86-*-isc2.2
-+ i[3456]86-*-isc3
-+ i[3456]86-*-sco3.2
-+ i[3456]86-*-sco3.2v4
-+ i[3456]86-*-sysv
-+ i[3456]86-*-sysv4
-+ i[3456]86-force_cpu386-none
-+ i[3456]86-sequent-bsd
-+ i960-nindy960-none
-+ m68k-hp-bsd4.3
-+ m68k-mvme135-none
-+ m68k-mvme136-none
-+ m68k-sony-newsos3
-+ m68k-sony-newsos4
-+ m68k-sun-sunos4
-+ mips-dec-ultrix4
-+ mips-sgi-irix4
-+ sparc-sun-solaris2
-+ sparc-sun-sunos4
-+
-+Since no one has volunteered to test and fix the above configurations,
-+these are not supported at the moment. It's expected that these don't
-+work anymore. Porting the library is not hard. If you are interested
-+in doing a port, please contact the glibc maintainers by sending
-+electronic mail to <bug-glibc@gnu.org>.
-+
-+The GNU C library now includes Michael Glad's Ultra Fast Crypt, which
-+provides the Unix `crypt' function, plus some other entry points.
-+Because of the United States export restriction on DES
-+implementations, we are distributing this code separately from the
-+rest of the C library. There is an extra distribution tar file just
-+for crypt; it is called `glibc-crypt-VERSION.tar.gz'. You can just
-+unpack the crypt distribution along with the rest of the C library and
-+build; you can also build the library without getting crypt. Users
-+outside the USA can get the crypt distribution via anonymous FTP from
-+ftp.gwdg.de [134.76.11.100] in the directory pub/linux/glibc, or
-+another archive site outside the USA. Archive maintainers are
-+encouraged to copy this distribution to their archives outside the
-+USA. Please get it from ftp.gwdg.de; transferring this distribution
-+from ftp.gnu.org (or any other site in the USA) to a site outside the
-+USA is in violation of US export laws.
-+
-+Beside the separate crypt tar file there are some more add-ons which can be
-+used together with GNU libc. They are designed in a way to ease the
-+installation by integrating them in the libc source tree. Simply get the
-+add-ons you need and use the --enable-add-ons option of the `configure'
-+script to tell where the add-ons are found. Please read the FAQ file for
-+more details.
-+
-+See the file INSTALL to find out how to configure, build, install, and port
-+the GNU C library. You might also consider reading the WWW pages for the
-+GNU libc at http://www.gnu.org/software/libc/libc.html.
-+
-+The GNU C Library is completely documented by the Texinfo manual found
-+in the `manual/' subdirectory. The manual is still being updated and
-+contains some known errors and omissions; we regret that we do not
-+have the resources to work on the manual as much as we would like.
-+Please send comments on the manual to <bug-glibc-manual@gnu.org>, and
-+not to the library bug-reporting address.
-+
-+The file NOTES contains a description of the feature-test macros used
-+in the GNU C library, explaining how you can tell the library what
-+facilities you want it to make available.
-+
-+We prefer to get bug reports sent using the `glibcbug' shell script which
-+is installed together with the rest of the GNU libc to <bugs@gnu.org>.
-+Simply run this shell script and fill in the information. Nevertheless
-+you can still send bug reports to <bug-glibc@gnu.org> as normal electronic
-+mails.
-+
-+The GNU C Library is free software. See the file COPYING.LIB for copying
-+conditions.
-diff -Naur ../glibc-2.1.3/Versions.def glibc-2.1.3/Versions.def
---- ../glibc-2.1.3/Versions.def 1999-11-15 16:24:57.000000000 -0800
-+++ glibc-2.1.3/Versions.def 1999-12-27 08:16:06.000000000 -0800
-@@ -31,6 +31,7 @@
- libnsl {
- GLIBC_2.0
- GLIBC_2.1 GLIBC_2.0
-+ GLIBC_2.1.2 GLIBC_2.1
- }
- libnss_compat {
- GLIBC_2.0
-diff -Naur ../glibc-2.1.3/c_stubs/Banner glibc-2.1.3/c_stubs/Banner
---- ../glibc-2.1.3/c_stubs/Banner 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/c_stubs/Banner 2000-02-25 16:35:04.000000000 -0800
-@@ -0,0 +1 @@
-+The C stubs add-on version 2.1.2.
-diff -Naur ../glibc-2.1.3/c_stubs/COPYING.LIB glibc-2.1.3/c_stubs/COPYING.LIB
---- ../glibc-2.1.3/c_stubs/COPYING.LIB 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/c_stubs/COPYING.LIB 2000-02-25 16:35:05.000000000 -0800
-@@ -0,0 +1,482 @@
-+ GNU LIBRARY GENERAL PUBLIC LICENSE
-+ Version 2, June 1991
-+
-+ Copyright (C) 1991 Free Software Foundation, Inc.
-+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-+ Everyone is permitted to copy and distribute verbatim copies
-+ of this license document, but changing it is not allowed.
-+
-+[This is the first released version of the library GPL. It is
-+ numbered 2 because it goes with version 2 of the ordinary GPL.]
-+
-+ Preamble
-+
-+ The licenses for most software are designed to take away your
-+freedom to share and change it. By contrast, the GNU General Public
-+Licenses are intended to guarantee your freedom to share and change
-+free software--to make sure the software is free for all its users.
-+
-+ This license, the Library General Public License, applies to some
-+specially designated Free Software Foundation software, and to any
-+other libraries whose authors decide to use it. You can use it for
-+your libraries, too.
-+
-+ When we speak of free software, we are referring to freedom, not
-+price. Our General Public Licenses are designed to make sure that you
-+have the freedom to distribute copies of free software (and charge for
-+this service if you wish), that you receive source code or can get it
-+if you want it, that you can change the software or use pieces of it
-+in new free programs; and that you know you can do these things.
-+
-+ To protect your rights, we need to make restrictions that forbid
-+anyone to deny you these rights or to ask you to surrender the rights.
-+These restrictions translate to certain responsibilities for you if
-+you distribute copies of the library, or if you modify it.
-+
-+ For example, if you distribute copies of the library, whether gratis
-+or for a fee, you must give the recipients all the rights that we gave
-+you. You must make sure that they, too, receive or can get the source
-+code. If you link a program with the library, you must provide
-+complete object files to the recipients so that they can relink them
-+with the library, after making changes to the library and recompiling
-+it. And you must show them these terms so they know their rights.
-+
-+ Our method of protecting your rights has two steps: (1) copyright
-+the library, and (2) offer you this license which gives you legal
-+permission to copy, distribute and/or modify the library.
-+
-+ Also, for each distributor's protection, we want to make certain
-+that everyone understands that there is no warranty for this free
-+library. If the library is modified by someone else and passed on, we
-+want its recipients to know that what they have is not the original
-+version, so that any problems introduced by others will not reflect on
-+the original authors' reputations.
-+
-+ Finally, any free program is threatened constantly by software
-+patents. We wish to avoid the danger that companies distributing free
-+software will individually obtain patent licenses, thus in effect
-+transforming the program into proprietary software. To prevent this,
-+we have made it clear that any patent must be licensed for everyone's
-+free use or not licensed at all.
-+
-+ Most GNU software, including some libraries, is covered by the ordinary
-+GNU General Public License, which was designed for utility programs. This
-+license, the GNU Library General Public License, applies to certain
-+designated libraries. This license is quite different from the ordinary
-+one; be sure to read it in full, and don't assume that anything in it is
-+the same as in the ordinary license.
-+
-+ The reason we have a separate public license for some libraries is that
-+they blur the distinction we usually make between modifying or adding to a
-+program and simply using it. Linking a program with a library, without
-+changing the library, is in some sense simply using the library, and is
-+analogous to running a utility program or application program. However, in
-+a textual and legal sense, the linked executable is a combined work, a
-+derivative of the original library, and the ordinary General Public License
-+treats it as such.
-+
-+ Because of this blurred distinction, using the ordinary General
-+Public License for libraries did not effectively promote software
-+sharing, because most developers did not use the libraries. We
-+concluded that weaker conditions might promote sharing better.
-+
-+ However, unrestricted linking of non-free programs would deprive the
-+users of those programs of all benefit from the free status of the
-+libraries themselves. This Library General Public License is intended to
-+permit developers of non-free programs to use free libraries, while
-+preserving your freedom as a user of such programs to change the free
-+libraries that are incorporated in them. (We have not seen how to achieve
-+this as regards changes in header files, but we have achieved it as regards
-+changes in the actual functions of the Library.) The hope is that this
-+will lead to faster development of free libraries.
-+
-+ The precise terms and conditions for copying, distribution and
-+modification follow. Pay close attention to the difference between a
-+"work based on the library" and a "work that uses the library". The
-+former contains code derived from the library, while the latter only
-+works together with the library.
-+
-+ Note that it is possible for a library to be covered by the ordinary
-+General Public License rather than by this special one.
-+
-+ GNU LIBRARY GENERAL PUBLIC LICENSE
-+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-+
-+ 0. This License Agreement applies to any software library which
-+contains a notice placed by the copyright holder or other authorized
-+party saying it may be distributed under the terms of this Library
-+General Public License (also called "this License"). Each licensee is
-+addressed as "you".
-+
-+ A "library" means a collection of software functions and/or data
-+prepared so as to be conveniently linked with application programs
-+(which use some of those functions and data) to form executables.
-+
-+ The "Library", below, refers to any such software library or work
-+which has been distributed under these terms. A "work based on the
-+Library" means either the Library or any derivative work under
-+copyright law: that is to say, a work containing the Library or a
-+portion of it, either verbatim or with modifications and/or translated
-+straightforwardly into another language. (Hereinafter, translation is
-+included without limitation in the term "modification".)
-+
-+ "Source code" for a work means the preferred form of the work for
-+making modifications to it. For a library, complete source code means
-+all the source code for all modules it contains, plus any associated
-+interface definition files, plus the scripts used to control compilation
-+and installation of the library.
-+
-+ Activities other than copying, distribution and modification are not
-+covered by this License; they are outside its scope. The act of
-+running a program using the Library is not restricted, and output from
-+such a program is covered only if its contents constitute a work based
-+on the Library (independent of the use of the Library in a tool for
-+writing it). Whether that is true depends on what the Library does
-+and what the program that uses the Library does.
-+
-+ 1. You may copy and distribute verbatim copies of the Library's
-+complete source code as you receive it, in any medium, provided that
-+you conspicuously and appropriately publish on each copy an
-+appropriate copyright notice and disclaimer of warranty; keep intact
-+all the notices that refer to this License and to the absence of any
-+warranty; and distribute a copy of this License along with the
-+Library.
-+
-+ You may charge a fee for the physical act of transferring a copy,
-+and you may at your option offer warranty protection in exchange for a
-+fee.
-+
-+ 2. You may modify your copy or copies of the Library or any portion
-+of it, thus forming a work based on the Library, and copy and
-+distribute such modifications or work under the terms of Section 1
-+above, provided that you also meet all of these conditions:
-+
-+ a) The modified work must itself be a software library.
-+
-+ b) You must cause the files modified to carry prominent notices
-+ stating that you changed the files and the date of any change.
-+
-+ c) You must cause the whole of the work to be licensed at no
-+ charge to all third parties under the terms of this License.
-+
-+ d) If a facility in the modified Library refers to a function or a
-+ table of data to be supplied by an application program that uses
-+ the facility, other than as an argument passed when the facility
-+ is invoked, then you must make a good faith effort to ensure that,
-+ in the event an application does not supply such function or
-+ table, the facility still operates, and performs whatever part of
-+ its purpose remains meaningful.
-+
-+ (For example, a function in a library to compute square roots has
-+ a purpose that is entirely well-defined independent of the
-+ application. Therefore, Subsection 2d requires that any
-+ application-supplied function or table used by this function must
-+ be optional: if the application does not supply it, the square
-+ root function must still compute square roots.)
-+
-+These requirements apply to the modified work as a whole. If
-+identifiable sections of that work are not derived from the Library,
-+and can be reasonably considered independent and separate works in
-+themselves, then this License, and its terms, do not apply to those
-+sections when you distribute them as separate works. But when you
-+distribute the same sections as part of a whole which is a work based
-+on the Library, the distribution of the whole must be on the terms of
-+this License, whose permissions for other licensees extend to the
-+entire whole, and thus to each and every part regardless of who wrote
-+it.
-+
-+Thus, it is not the intent of this section to claim rights or contest
-+your rights to work written entirely by you; rather, the intent is to
-+exercise the right to control the distribution of derivative or
-+collective works based on the Library.
-+
-+In addition, mere aggregation of another work not based on the Library
-+with the Library (or with a work based on the Library) on a volume of
-+a storage or distribution medium does not bring the other work under
-+the scope of this License.
-+
-+ 3. You may opt to apply the terms of the ordinary GNU General Public
-+License instead of this License to a given copy of the Library. To do
-+this, you must alter all the notices that refer to this License, so
-+that they refer to the ordinary GNU General Public License, version 2,
-+instead of to this License. (If a newer version than version 2 of the
-+ordinary GNU General Public License has appeared, then you can specify
-+that version instead if you wish.) Do not make any other change in
-+these notices.
-+
-+ Once this change is made in a given copy, it is irreversible for
-+that copy, so the ordinary GNU General Public License applies to all
-+subsequent copies and derivative works made from that copy.
-+
-+ This option is useful when you wish to copy part of the code of
-+the Library into a program that is not a library.
-+
-+ 4. You may copy and distribute the Library (or a portion or
-+derivative of it, under Section 2) in object code or executable form
-+under the terms of Sections 1 and 2 above provided that you accompany
-+it with the complete corresponding machine-readable source code, which
-+must be distributed under the terms of Sections 1 and 2 above on a
-+medium customarily used for software interchange.
-+
-+ If distribution of object code is made by offering access to copy
-+from a designated place, then offering equivalent access to copy the
-+source code from the same place satisfies the requirement to
-+distribute the source code, even though third parties are not
-+compelled to copy the source along with the object code.
-+
-+ 5. A program that contains no derivative of any portion of the
-+Library, but is designed to work with the Library by being compiled or
-+linked with it, is called a "work that uses the Library". Such a
-+work, in isolation, is not a derivative work of the Library, and
-+therefore falls outside the scope of this License.
-+
-+ However, linking a "work that uses the Library" with the Library
-+creates an executable that is a derivative of the Library (because it
-+contains portions of the Library), rather than a "work that uses the
-+library". The executable is therefore covered by this License.
-+Section 6 states terms for distribution of such executables.
-+
-+ When a "work that uses the Library" uses material from a header file
-+that is part of the Library, the object code for the work may be a
-+derivative work of the Library even though the source code is not.
-+Whether this is true is especially significant if the work can be
-+linked without the Library, or if the work is itself a library. The
-+threshold for this to be true is not precisely defined by law.
-+
-+ If such an object file uses only numerical parameters, data
-+structure layouts and accessors, and small macros and small inline
-+functions (ten lines or less in length), then the use of the object
-+file is unrestricted, regardless of whether it is legally a derivative
-+work. (Executables containing this object code plus portions of the
-+Library will still fall under Section 6.)
-+
-+ Otherwise, if the work is a derivative of the Library, you may
-+distribute the object code for the work under the terms of Section 6.
-+Any executables containing that work also fall under Section 6,
-+whether or not they are linked directly with the Library itself.
-+
-+ 6. As an exception to the Sections above, you may also compile or
-+link a "work that uses the Library" with the Library to produce a
-+work containing portions of the Library, and distribute that work
-+under terms of your choice, provided that the terms permit
-+modification of the work for the customer's own use and reverse
-+engineering for debugging such modifications.
-+
-+ You must give prominent notice with each copy of the work that the
-+Library is used in it and that the Library and its use are covered by
-+this License. You must supply a copy of this License. If the work
-+during execution displays copyright notices, you must include the
-+copyright notice for the Library among them, as well as a reference
-+directing the user to the copy of this License. Also, you must do one
-+of these things:
-+
-+ a) Accompany the work with the complete corresponding
-+ machine-readable source code for the Library including whatever
-+ changes were used in the work (which must be distributed under
-+ Sections 1 and 2 above); and, if the work is an executable linked
-+ with the Library, with the complete machine-readable "work that
-+ uses the Library", as object code and/or source code, so that the
-+ user can modify the Library and then relink to produce a modified
-+ executable containing the modified Library. (It is understood
-+ that the user who changes the contents of definitions files in the
-+ Library will not necessarily be able to recompile the application
-+ to use the modified definitions.)
-+
-+ b) Accompany the work with a written offer, valid for at
-+ least three years, to give the same user the materials
-+ specified in Subsection 6a, above, for a charge no more
-+ than the cost of performing this distribution.
-+
-+ c) If distribution of the work is made by offering access to copy
-+ from a designated place, offer equivalent access to copy the above
-+ specified materials from the same place.
-+
-+ d) Verify that the user has already received a copy of these
-+ materials or that you have already sent this user a copy.
-+
-+ For an executable, the required form of the "work that uses the
-+Library" must include any data and utility programs needed for
-+reproducing the executable from it. However, as a special exception,
-+the source code distributed need not include anything that is normally
-+distributed (in either source or binary form) with the major
-+components (compiler, kernel, and so on) of the operating system on
-+which the executable runs, unless that component itself accompanies
-+the executable.
-+
-+ It may happen that this requirement contradicts the license
-+restrictions of other proprietary libraries that do not normally
-+accompany the operating system. Such a contradiction means you cannot
-+use both them and the Library together in an executable that you
-+distribute.
-+
-+ 7. You may place library facilities that are a work based on the
-+Library side-by-side in a single library together with other library
-+facilities not covered by this License, and distribute such a combined
-+library, provided that the separate distribution of the work based on
-+the Library and of the other library facilities is otherwise
-+permitted, and provided that you do these two things:
-+
-+ a) Accompany the combined library with a copy of the same work
-+ based on the Library, uncombined with any other library
-+ facilities. This must be distributed under the terms of the
-+ Sections above.
-+
-+ b) Give prominent notice with the combined library of the fact
-+ that part of it is a work based on the Library, and explaining
-+ where to find the accompanying uncombined form of the same work.
-+
-+ 8. You may not copy, modify, sublicense, link with, or distribute
-+the Library except as expressly provided under this License. Any
-+attempt otherwise to copy, modify, sublicense, link with, or
-+distribute the Library is void, and will automatically terminate your
-+rights under this License. However, parties who have received copies,
-+or rights, from you under this License will not have their licenses
-+terminated so long as such parties remain in full compliance.
-+
-+ 9. You are not required to accept this License, since you have not
-+signed it. However, nothing else grants you permission to modify or
-+distribute the Library or its derivative works. These actions are
-+prohibited by law if you do not accept this License. Therefore, by
-+modifying or distributing the Library (or any work based on the
-+Library), you indicate your acceptance of this License to do so, and
-+all its terms and conditions for copying, distributing or modifying
-+the Library or works based on it.
-+
-+ 10. Each time you redistribute the Library (or any work based on the
-+Library), the recipient automatically receives a license from the
-+original licensor to copy, distribute, link with or modify the Library
-+subject to these terms and conditions. You may not impose any further
-+restrictions on the recipients' exercise of the rights granted herein.
-+You are not responsible for enforcing compliance by third parties to
-+this License.
-+
-+ 11. If, as a consequence of a court judgment or allegation of patent
-+infringement or for any other reason (not limited to patent issues),
-+conditions are imposed on you (whether by court order, agreement or
-+otherwise) that contradict the conditions of this License, they do not
-+excuse you from the conditions of this License. If you cannot
-+distribute so as to satisfy simultaneously your obligations under this
-+License and any other pertinent obligations, then as a consequence you
-+may not distribute the Library at all. For example, if a patent
-+license would not permit royalty-free redistribution of the Library by
-+all those who receive copies directly or indirectly through you, then
-+the only way you could satisfy both it and this License would be to
-+refrain entirely from distribution of the Library.
-+
-+If any portion of this section is held invalid or unenforceable under any
-+particular circumstance, the balance of the section is intended to apply,
-+and the section as a whole is intended to apply in other circumstances.
-+
-+It is not the purpose of this section to induce you to infringe any
-+patents or other property right claims or to contest validity of any
-+such claims; this section has the sole purpose of protecting the
-+integrity of the free software distribution system which is
-+implemented by public license practices. Many people have made
-+generous contributions to the wide range of software distributed
-+through that system in reliance on consistent application of that
-+system; it is up to the author/donor to decide if he or she is willing
-+to distribute software through any other system and a licensee cannot
-+impose that choice.
-+
-+This section is intended to make thoroughly clear what is believed to
-+be a consequence of the rest of this License.
-+
-+ 12. If the distribution and/or use of the Library is restricted in
-+certain countries either by patents or by copyrighted interfaces, the
-+original copyright holder who places the Library under this License may add
-+an explicit geographical distribution limitation excluding those countries,
-+so that distribution is permitted only in or among countries not thus
-+excluded. In such case, this License incorporates the limitation as if
-+written in the body of this License.
-+
-+ 13. The Free Software Foundation may publish revised and/or new
-+versions of the Library General Public License from time to time.
-+Such new versions will be similar in spirit to the present version,
-+but may differ in detail to address new problems or concerns.
-+
-+Each version is given a distinguishing version number. If the Library
-+specifies a version number of this License which applies to it and
-+"any later version", you have the option of following the terms and
-+conditions either of that version or of any later version published by
-+the Free Software Foundation. If the Library does not specify a
-+license version number, you may choose any version ever published by
-+the Free Software Foundation.
-+
-+ 14. If you wish to incorporate parts of the Library into other free
-+programs whose distribution conditions are incompatible with these,
-+write to the author to ask for permission. For software which is
-+copyrighted by the Free Software Foundation, write to the Free
-+Software Foundation; we sometimes make exceptions for this. Our
-+decision will be guided by the two goals of preserving the free status
-+of all derivatives of our free software and of promoting the sharing
-+and reuse of software generally.
-+
-+ NO WARRANTY
-+
-+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-+
-+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-+DAMAGES.
-+
-+ END OF TERMS AND CONDITIONS
-+
-+ Appendix: How to Apply These Terms to Your New Libraries
-+
-+ If you develop a new library, and you want it to be of the greatest
-+possible use to the public, we recommend making it free software that
-+everyone can redistribute and change. You can do so by permitting
-+redistribution under these terms (or, alternatively, under the terms of the
-+ordinary General Public License).
-+
-+ To apply these terms, attach the following notices to the library. It is
-+safest to attach them to the start of each source file to most effectively
-+convey the exclusion of warranty; and each file should have at least the
-+"copyright" line and a pointer to where the full notice is found.
-+
-+ <one line to give the library's name and a brief idea of what it does.>
-+ Copyright (C) <year> <name of author>
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public
-+ License as published by the Free Software Foundation; either
-+ version 2 of the License, or (at your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with this library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-+ MA 02111-1307, USA
-+
-+Also add information on how to contact you by electronic and paper mail.
-+
-+You should also get your employer (if you work as a programmer) or your
-+school, if any, to sign a "copyright disclaimer" for the library, if
-+necessary. Here is a sample; alter the names:
-+
-+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
-+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-+
-+ <signature of Ty Coon>, 1 April 1990
-+ Ty Coon, President of Vice
-+
-+That's all there is to it!
-diff -Naur ../glibc-2.1.3/c_stubs/ChangeLog glibc-2.1.3/c_stubs/ChangeLog
---- ../glibc-2.1.3/c_stubs/ChangeLog 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/c_stubs/ChangeLog 2000-02-27 11:35:23.000000000 -0800
-@@ -0,0 +1,32 @@
-+2000-02-27 Cristian Gafton <gafton@redhat.com>
-+
-+ * gconv_stubs.c: Return __gconv_OK for:
-+ __gconv_transform_ascii_internal
-+ __gconv_transform_ucs2little_internal
-+ __gconv_transform_utf16_internal
-+ __gconv_transform_utf8_internal
-+ __gconv_transform_ucs2_internal
-+
-+2000-02-25 Cristian Gafton <gafton@redhat.com>
-+
-+ * gconv_stubs.c: add __c_stubs_is_compiled_in so we can detect when
-+ the library is linked in.
-+
-+Wed Dec 8 13:47:25 1999 Ivan Brunello <ivan.brunello@tiscalinet.it>
-+
-+ * Makefile (extra-objs): Changed stubs.o to gconv_stubs.o.
-+
-+Sun Dec 5 11:32:17 1999 H.J. Lu <hjl@gnu.org>
-+
-+ * gconv_stubs.c: Renamed from stubs.c.
-+ Support glibc 2.1.x.
-+
-+Mon Aug 23 16:42:05 1999 H.J. Lu <hjl@gnu.org>
-+
-+ * Banner: New.
-+ * COPYING.LIB: Likewise.
-+ * Makefile: Likewise.
-+ * README: Likewise.
-+ * configure: Likewise.
-+ * stubs.c: Likewise.
-+ * test-stdio.c: Likewise.
-diff -Naur ../glibc-2.1.3/c_stubs/Makefile glibc-2.1.3/c_stubs/Makefile
---- ../glibc-2.1.3/c_stubs/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/c_stubs/Makefile 2000-02-25 16:35:05.000000000 -0800
-@@ -0,0 +1,46 @@
-+# Copyright (C) 1999 Free Software Foundation, Inc.
-+# This file is part of the GNU C Library.
-+
-+# The GNU C Library is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU Library General Public License as
-+# published by the Free Software Foundation; either version 2 of the
-+# License, or (at your option) any later version.
-+
-+# The GNU C Library is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# Library General Public License for more details.
-+
-+# You should have received a copy of the GNU Library General Public
-+# License along with the GNU C Library; see the file COPYING.LIB. If not,
-+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+# Boston, MA 02111-1307, USA.
-+
-+#
-+# Sub-makefile for the C stub add-on library.
-+#
-+subdir := c_stubs
-+
-+tests-static := test-stdio
-+tests := $(tests-static)
-+
-+libc_stubs-objs := gconv_stubs.o
-+
-+install-lib := libc_stubs.a
-+non-lib.a := libc_stubs.a
-+
-+extra-objs := gconv_stubs.o libc_stubs.a
-+
-+include ../Makeconfig
-+
-+CPPFLAGS += -I../iconv
-+
-+include ../Rules
-+
-+$(objpfx)libc_stubs.a: $(addprefix $(objpfx), $(libc_stubs-objs))
-+ -rm -f $@
-+ $(LD) -r -o $@ $^
-+
-+lib: $(objpfx)libc_stubs.a
-+
-+$(objpfx)test-stdio: $(objpfx)libc_stubs.a
-diff -Naur ../glibc-2.1.3/c_stubs/README glibc-2.1.3/c_stubs/README
---- ../glibc-2.1.3/c_stubs/README 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/c_stubs/README 2000-02-25 16:35:05.000000000 -0800
-@@ -0,0 +1,8 @@
-+This is a stub add-on library for the GNU C library version 2.1.2 and
-+above. It is used to create the smaller static binaries by stubbing
-+out the gconv related functions. The resulting binaries may not have
-+all the functionalities.
-+
-+H.J. Lu
-+hjl@gnu.org
-+12/05/1999
-diff -Naur ../glibc-2.1.3/c_stubs/configure glibc-2.1.3/c_stubs/configure
---- ../glibc-2.1.3/c_stubs/configure 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/c_stubs/configure 2000-02-25 16:35:05.000000000 -0800
-@@ -0,0 +1,2 @@
-+# This is only to keep the GNU C library configure mechanism happy.
-+exit 0
-diff -Naur ../glibc-2.1.3/c_stubs/gconv_stubs.c glibc-2.1.3/c_stubs/gconv_stubs.c
---- ../glibc-2.1.3/c_stubs/gconv_stubs.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/c_stubs/gconv_stubs.c 2000-02-27 11:35:23.000000000 -0800
-@@ -0,0 +1,83 @@
-+/* Provide gconv stub functions for the minimum static binaries.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <features.h>
-+#include <gconv_int.h>
-+
-+/* hack for self identification */
-+int __c_stubs_is_compiled_in;
-+
-+/* Don't drag in the dynamic linker. */
-+void *__libc_stack_end;
-+
-+int
-+__gconv_OK ()
-+{
-+#if __GLIBC__ > 2 || __GLIBC_MINOR__ > 1
-+ return __GCONV_OK;
-+#else
-+ return GCONV_OK;
-+#endif
-+}
-+
-+int
-+__gconv_NOCONV ()
-+{
-+#if __GLIBC__ > 2 || __GLIBC_MINOR__ > 1
-+ return __GCONV_NOCONV;
-+#else
-+ return GCONV_NOCONV;
-+#endif
-+}
-+
-+strong_alias (__gconv_OK,
-+ __gconv_close_transform);
-+
-+strong_alias (__gconv_NOCONV,
-+ __gconv);
-+strong_alias (__gconv_NOCONV,
-+ __gconv_find_transform);
-+strong_alias (__gconv_NOCONV,
-+ __gconv_open);
-+
-+/* These transformations should not fail in normal conditions */
-+strong_alias (__gconv_OK,
-+ __gconv_transform_ascii_internal);
-+strong_alias (__gconv_OK,
-+ __gconv_transform_ucs2little_internal);
-+strong_alias (__gconv_OK,
-+ __gconv_transform_utf16_internal);
-+strong_alias (__gconv_OK,
-+ __gconv_transform_utf8_internal);
-+strong_alias (__gconv_OK,
-+ __gconv_transform_ucs2_internal);
-+
-+/* We can assume no conversion for these ones */
-+strong_alias (__gconv_NOCONV,
-+ __gconv_transform_internal_ascii);
-+strong_alias (__gconv_NOCONV,
-+ __gconv_transform_internal_ucs2);
-+strong_alias (__gconv_NOCONV,
-+ __gconv_transform_internal_ucs2little);
-+strong_alias (__gconv_NOCONV,
-+ __gconv_transform_internal_ucs4);
-+strong_alias (__gconv_NOCONV,
-+ __gconv_transform_internal_utf16);
-+strong_alias (__gconv_NOCONV,
-+ __gconv_transform_internal_utf8);
-diff -Naur ../glibc-2.1.3/c_stubs/test-stdio.c glibc-2.1.3/c_stubs/test-stdio.c
---- ../glibc-2.1.3/c_stubs/test-stdio.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/c_stubs/test-stdio.c 2000-02-25 16:35:05.000000000 -0800
-@@ -0,0 +1,8 @@
-+#include <stdio.h>
-+
-+int
-+main ()
-+{
-+ printf ("Hello world\n");
-+ return 0;
-+}
-diff -Naur ../glibc-2.1.3/config-name.in glibc-2.1.3/config-name.in
---- ../glibc-2.1.3/config-name.in 1994-12-08 01:12:33.000000000 -0800
-+++ glibc-2.1.3/config-name.in 1998-02-07 12:00:39.000000000 -0800
-@@ -1,5 +1,5 @@
- /* @configure_input@ -*- C -*-
-- Generated from $Id: config-name.in,v 1.1 1994/12/08 09:12:33 roland Exp $.
-+ Generated from $Id: config-name.in,v 1.1.1.1 1998/02/07 20:00:39 gafton Exp $.
-
- This is used only by the generic `uname' function for systems with no real
- `uname' call. If this data is not correct, it does not matter much. */
-diff -Naur ../glibc-2.1.3/config.make.in glibc-2.1.3/config.make.in
---- ../glibc-2.1.3/config.make.in 2000-02-11 15:49:41.000000000 -0800
-+++ glibc-2.1.3/config.make.in 2000-02-14 12:05:50.000000000 -0800
-@@ -1,5 +1,5 @@
- # @configure_input@
--# From $Id: config.make.in,v 1.61.2.2 2000/02/11 20:45:02 drepper Exp $.
-+# From $Id: config.make.in,v 1.1.1.2 2000/02/14 20:05:50 gafton Exp $.
- # Don't edit this file. Put configuration parameters in configparms instead.
-
- version = @VERSION@
-diff -Naur ../glibc-2.1.3/db2/include/queue.h glibc-2.1.3/db2/include/queue.h
---- ../glibc-2.1.3/db2/include/queue.h 1998-06-09 08:03:53.000000000 -0700
-+++ glibc-2.1.3/db2/include/queue.h 1998-07-09 11:45:13.000000000 -0700
-@@ -1,4 +1,4 @@
--/* BSDI $Id: queue.h,v 1.3 1998/06/09 15:03:53 drepper Exp $ */
-+/* BSDI $Id: queue.h,v 1.1.1.1 1998/07/09 18:45:13 gafton Exp $ */
-
- /*
- * Copyright (c) 1991, 1993
-diff -Naur ../glibc-2.1.3/elf/rtld.c glibc-2.1.3/elf/rtld.c
---- ../glibc-2.1.3/elf/rtld.c 2000-02-22 23:02:47.000000000 -0800
-+++ glibc-2.1.3/elf/rtld.c 2000-02-23 14:48:17.000000000 -0800
-@@ -758,6 +758,60 @@
- __munmap (file, file_size);
- }
-
-+
-+ /*
-+ * Modifications by Red Hat Software
-+ *
-+ * Deal with the broken binaries from the non-versioned ages of glibc.
-+ * If a binary does not have version information enebled, we assume that
-+ * it is a glibc 2.0 binary andwe load a compatibility library to try to
-+ * overcome binary incompatibilities.
-+ * Blame: gafton@redhat.com
-+ */
-+#define LIB_NOVERSION "/lib/libNoVersion.so.1"
-+
-+ if (_dl_loaded->l_info[DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)] == NULL) {
-+ struct link_map *new_map = NULL;
-+ struct stat test_st;
-+ int test_fd;
-+ int can_load;
-+
-+ HP_TIMING_NOW (start);
-+
-+/* _dl_sysdep_message("Loading compatibility library... ", NULL); */
-+
-+ can_load = 1;
-+ test_fd = __open (LIB_NOVERSION, O_RDONLY);
-+ if (test_fd < 0) {
-+ can_load = 0;
-+/* _dl_sysdep_message(" Can't find " LIB_NOVERSION "\n", NULL); */
-+ } else {
-+ if (__fxstat (_STAT_VER, test_fd, &test_st) < 0 || test_st.st_size == 0) {
-+ can_load = 0;
-+/* _dl_sysdep_message(" Can't stat " LIB_NOVERSION "\n", NULL); */
-+ }
-+ }
-+
-+ if (test_fd >= 0) /* open did no fail.. */
-+ __close(test_fd); /* avoid fd leaks */
-+
-+ if (can_load != 0) {
-+ new_map = _dl_map_object (_dl_loaded, LIB_NOVERSION,
-+ 1, lt_library, 0);
-+ if (new_map->l_opencount == 1) {
-+ /* It is no duplicate. */
-+ ++npreloads;
-+/* _dl_sysdep_message(" DONE\n", NULL); */
-+ } else {
-+/* _dl_sysdep_message(" FAILED\n", NULL); */
-+ }
-+ }
-+
-+ HP_TIMING_NOW (stop);
-+ HP_TIMING_DIFF (diff, start, stop);
-+ HP_TIMING_ACCUM_NT (load_time, diff);
-+ }
-+
- if (npreloads != 0)
- {
- /* Set up PRELOADS with a vector of the preloaded libraries. */
-diff -Naur ../glibc-2.1.3/glibc-2.1.spec glibc-2.1.3/glibc-2.1.spec
---- ../glibc-2.1.3/glibc-2.1.spec 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-2.1.spec 2000-02-29 13:27:37.000000000 -0800
-@@ -0,0 +1,305 @@
-+Summary: The GNU libc libraries.
-+Name: glibc
-+Version: 2.1.3
-+Release: 15
-+Copyright: LGPL
-+Group: System Environment/Libraries
-+Source: %{name}-%{version}.tar.gz
-+# Other sources are available at:
-+# http://www.ozemail.com.au/~geoffk/glibc-crypt/glibc-crypt-2.1.tar.gz
-+# In the source tarball the file diff-CYGNUS-to-REDHAT.patch contains all
-+# diffs applied by Red Hat to the current CVS version of glibc
-+Buildroot: /var/tmp/glibc-%{PACKAGE_VERSION}-root
-+Obsoletes: zoneinfo, libc-static, libc-devel, libc-profile, libc-headers,
-+Obsoletes: linuxthreads, gencat, locale
-+Autoreq: false
-+%ifarch alpha
-+Provides: ld.so.2
-+%else
-+%endif
-+%ifarch sparc
-+Obsoletes: libc
-+%endif
-+
-+%description
-+The glibc package contains standard libraries which are used by
-+multiple programs on the system. In order to save disk space and
-+memory, as well as to make upgrading easier, common system code is
-+kept in one place and shared between programs. This particular package
-+contains the most important sets of shared libraries: the standard C
-+library and the standard math library. Without these two libraries, a
-+Linux system will not function. The glibc package also contains
-+national language (locale) support and timezone databases.
-+
-+%package devel
-+Summary: Header and object files for development using standard C libraries.
-+Group: Development/Libraries
-+Conflicts: texinfo < 3.11
-+Prereq: /sbin/install-info
-+Obsoletes: libc-debug, libc-headers, libc-devel, linuxthreads-devel
-+Obsoletes: glibc-debug
-+Prereq: kernel-headers
-+Requires: kernel-headers >= 2.2.1
-+Autoreq: true
-+
-+%description devel
-+The glibc-devel package contains the header and object files necessary
-+for developing programs which use the standard C libraries (which are
-+used by nearly all programs). If you are developing programs which
-+will use the standard C libraries, your system needs to have these
-+standard header and object files available in order to create the
-+executables.
-+
-+Install glibc-devel if you are going to develop programs which will
-+use the standard C libraries.
-+
-+%package profile
-+Summary: The GNU libc libraries, including support for gprof profiling.
-+Group: Development/Libraries
-+Obsoletes: libc-profile
-+Autoreq: true
-+
-+%description profile
-+The glibc-profile package includes the GNU libc libraries and support
-+for profiling using the gprof program. Profiling is analyzing a
-+program's functions to see how much CPU time they use and determining
-+which functions are calling other functions during execution. To use
-+gprof to profile a program, your program needs to use the GNU libc
-+libraries included in glibc-profile (instead of the standard GNU libc
-+libraries included in the glibc package).
-+
-+If you are going to use the gprof program to profile a program, you'll
-+need to install the glibc-profile program.
-+
-+%package -n nscd
-+Summary: A Name Service Caching Daemon (nscd).
-+Group: System Environment/Daemons
-+Conflicts: kernel < 2.2.0
-+Prereq: /sbin/chkconfig
-+Autoreq: true
-+
-+%description -n nscd
-+Nscd caches name service lookups and can dramatically improve
-+performance with NIS+, and may help with DNS as well. Note that you
-+can't use nscd with 2.0 kernels because of bugs in the kernel-side
-+thread support. Unfortunately, nscd happens to hit these bugs
-+particularly hard.
-+
-+Install nscd if you need a name service lookup caching daemon, and
-+you're not using a version 2.0 kernel.
-+
-+%prep
-+%setup -q
-+
-+%ifarch armv4l
-+rm -rf glibc-compat
-+%endif
-+
-+find . -type f -size 0 -o -name "*.orig" -exec rm -f {} \;
-+
-+%build
-+rm -rf build-$RPM_ARCH-linux
-+mkdir build-$RPM_ARCH-linux ; cd build-$RPM_ARCH-linux
-+%ifarch i586 i686
-+BuildFlags="-mpentium -D__USE_STRING_INLINES -fstrict-aliasing -mcpu=%{_target_cpu}"
-+%endif
-+%ifarch sparcv9
-+BuildFlags="-mv8 -mtune=ultrasparc"
-+%endif
-+CC=egcs CFLAGS="$BuildFlags -g -O3" ../configure --prefix=/usr \
-+ --enable-add-ons=yes --without-cvs \
-+ %{_target_cpu}-redhat-linux
-+make -r CFLAGS="$BuildFlags -g -O3" PARALLELMFLAGS=-s
-+
-+%install
-+rm -rf $RPM_BUILD_ROOT
-+mkdir -p $RPM_BUILD_ROOT
-+make install_root=$RPM_BUILD_ROOT install -C build-$RPM_ARCH-linux
-+cd build-$RPM_ARCH-linux && \
-+ make install_root=$RPM_BUILD_ROOT install-locales -C ../localedata objdir=`pwd` && \
-+ cd ..
-+
-+# compatibility hack: this locale has vanished from glibc, but some other
-+# programs are still using it. Normally we would handle it in the %pre
-+# section but with glibc that is simply not an option
-+mkdir -p $RPM_BUILD_ROOT/usr/share/locale/ru_RU/LC_MESSAGES
-+
-+# Remove the files we don't want to distribute
-+rm -f $RPM_BUILD_ROOT/usr/lib/libNoVersion*
-+
-+# the man pages for the linuxthreads require special attention
-+make -C linuxthreads/man
-+mkdir -p $RPM_BUILD_ROOT/usr/man/man3
-+install -m 0644 linuxthreads/man/*.3thr $RPM_BUILD_ROOT/usr/man/man3
-+gzip -9nvf $RPM_BUILD_ROOT/usr/man/man3/*
-+
-+gzip -9nvf $RPM_BUILD_ROOT/usr/info/libc*
-+
-+ln -sf libbsd-compat.a $RPM_BUILD_ROOT/usr/lib/libbsd.a
-+
-+install -m 644 redhat/nsswitch.conf $RPM_BUILD_ROOT/etc/nsswitch.conf
-+
-+# Take care of setuids
-+# -- new security review sez that this shouldn't be needed anymore
-+#chmod 755 $RPM_BUILD_ROOT/usr/libexec/pt_chown
-+
-+# This is for ncsd - in glibc 2.1
-+install -m 644 nscd/nscd.conf $RPM_BUILD_ROOT/etc
-+mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
-+install -m 755 nscd/nscd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/nscd
-+
-+# The database support
-+mkdir -p $RPM_BUILD_ROOT/var/db
-+install -m 644 nss/db-Makefile $RPM_BUILD_ROOT/var/db/Makefile
-+
-+# Strip binaries
-+strip $RPM_BUILD_ROOT/sbin/* || :
-+strip $RPM_BUILD_ROOT/usr/bin/* || :
-+strip $RPM_BUILD_ROOT/usr/sbin/* || :
-+
-+# BUILD THE FILE LIST
-+find $RPM_BUILD_ROOT -type f -or -type l |
-+ sed -e 's|.*/etc|%config &|' > rpm.filelist.in
-+for n in /usr/share /usr/include; do
-+ find ${RPM_BUILD_ROOT}${n} -type d | \
-+ grep -v '^/usr/share$' | \
-+ sed "s/^/%dir /" >> rpm.filelist.in
-+done
-+
-+# primary filelist
-+sed "s|$RPM_BUILD_ROOT||" < rpm.filelist.in |
-+ grep -v '/etc/localtime' | \
-+ grep -v '/etc/nsswitch.conf' | \
-+ sort > rpm.filelist
-+
-+grep '/usr/lib/lib.*_p\.a' < rpm.filelist > profile.filelist
-+egrep "(/usr/include)|(/usr/info)" < rpm.filelist |
-+ grep -v /usr/info/dir > devel.filelist
-+
-+mv rpm.filelist rpm.filelist.full
-+grep -v '/usr/lib/lib.*_p.a' rpm.filelist.full |
-+ egrep -v "(/usr/include)|(/usr/info)" > rpm.filelist
-+
-+grep '/usr/lib/lib.*\.a' < rpm.filelist >> devel.filelist
-+grep '/usr/lib/.*\.o' < rpm.filelist >> devel.filelist
-+grep '/usr/lib/lib.*\.so' < rpm.filelist >> devel.filelist
-+grep '/usr/man/man' < rpm.filelist >> devel.filelist
-+
-+mv rpm.filelist rpm.filelist.full
-+grep -v '/usr/lib/lib.*\.a' < rpm.filelist.full |
-+ grep -v '/usr/lib/.*\.o' |
-+ grep -v '/usr/lib/lib.*\.so'|
-+ grep -v '/usr/man/man' |
-+ grep -v 'nscd' > rpm.filelist
-+
-+# /etc/localtime - we're proud of our timezone
-+rm -f $RPM_BUILD_ROOT/etc/localtime
-+cp -f $RPM_BUILD_ROOT/usr/share/zoneinfo/US/Eastern $RPM_BUILD_ROOT/etc/localtime
-+#ln -sf ../usr/share/zoneinfo/US/Eastern $RPM_BUILD_ROOT/etc/localtime
-+
-+# the last bit: more documentation
-+rm -rf documentation
-+mkdir documentation
-+cp linuxthreads/ChangeLog documentation/ChangeLog.threads
-+cp linuxthreads/Changes documentation/Changes.threads
-+cp linuxthreads/README documentation/README.threads
-+cp linuxthreads/FAQ.html documentation/FAQ-threads.html
-+cp -r linuxthreads/Examples documentation/examples.threads
-+cp crypt/README documentation/README.crypt
-+cp db2/README documentation/README.db2
-+cp db2/mutex/README documentation/README.db2.mutex
-+cp timezone/README documentation/README.timezone
-+cp ChangeLog* documentation
-+gzip -9 documentation/ChangeLog*
-+
-+%post -p /sbin/ldconfig
-+
-+%postun -p /sbin/ldconfig
-+
-+%post devel
-+/sbin/install-info /usr/info/libc.info.gz /usr/info/dir
-+
-+%pre devel
-+# this used to be a link and it is causing nightmares now
-+if [ -L /usr/include/scsi ] ; then
-+ rm -f /usr/include/scsi
-+fi
-+
-+%preun devel
-+if [ "$1" = 0 ]; then
-+ /sbin/install-info --delete /usr/info/libc.info.gz /usr/info/dir
-+fi
-+
-+%post -n nscd
-+/sbin/chkconfig --add nscd
-+
-+%preun -n nscd
-+if [ $1 = 0 ] ; then
-+ /sbin/chkconfig --del nscd
-+fi
-+
-+%clean
-+rm -rf "$RPM_BUILD_ROOT"
-+rm -f *.filelist*
-+
-+%files -f rpm.filelist
-+%defattr(-,root,root)
-+%config(noreplace) /etc/localtime
-+%config(noreplace) /etc/nsswitch.conf
-+%doc README NEWS INSTALL FAQ BUGS NOTES PROJECTS
-+%doc documentation/* README.template README.libm
-+%doc login/README.utmpd hesiod/README.hesiod
-+%dir /var/db
-+
-+%ifnarch sparcv9 i586 i686
-+%files -f devel.filelist devel
-+%defattr(-,root,root)
-+
-+%files -f profile.filelist profile
-+%defattr(-,root,root)
-+
-+%files -n nscd
-+%defattr(-,root,root)
-+%config /etc/nscd.conf
-+/etc/rc.d/init.d/nscd
-+/usr/sbin/nscd
-+%endif
-+
-+%define date %(echo `LC_ALL="C" date +"%a %b %d %Y"`)
-+
-+%changelog
-+* %{date} Cristian Gafton <gafton@redhat.com>
-+- fix c_stubs add-on to work around various assert()s in glibc
-+- add Davem's patch for _NPROCESSORS_ONLN on Sparc
-+
-+* Fri Feb 25 2000 Cristian Gafton <gafton@redhat.com>
-+- add the c_stubs add-on
-+- sparc patch from davem
-+
-+* Thu Feb 24 2000 Cristian Gafton <gafton@redhat.com>
-+- fix locale problems on 64 bit arches
-+
-+* Tue Feb 22 2000 Cristian Gafton <gafton@redhat.com>
-+- cygnus sync up for fixes to nscd
-+
-+* Thu Feb 17 2000 Cristian Gafton <gafton@redhat.com>
-+- updated to include new China timezones
-+- sync up with the locale changes from Cygnus
-+
-+* Tue Feb 01 2000 Cristian Gafton <gafton@redhat.com>
-+- updated from cygnus branch
-+- fix syslog so that it will continuously try to fallback from SOK_DGRAM to
-+ SOCK_STREAM and backwards
-+
-+* Mon Jan 31 2000 Cristian Gafton <gafton@redhat.com>
-+- update from cygnus branch
-+- compress man pages for the linuxthreads stuff
-+
-+* Fri Jan 21 2000 Cristian Gafton <gafton@redhat.com>
-+- add Jakub's patch so we back out even more
-+
-+* Thu Jan 20 2000 Cristian Gafton <gafton@redhat.com>
-+- back out the setrlimit changes (well, sort of)
-+
-+* Mon Jan 03 2000 Cristian Gafton <gafton@redhat.com>
-+- make release from CVS server directly now
-diff -Naur ../glibc-2.1.3/glibc-compat/.cvsignore glibc-2.1.3/glibc-compat/.cvsignore
---- ../glibc-2.1.3/glibc-compat/.cvsignore 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/.cvsignore 2000-01-03 18:17:33.000000000 -0800
-@@ -0,0 +1 @@
-+glibc-compat*.tar.gz
-diff -Naur ../glibc-2.1.3/glibc-compat/Banner glibc-2.1.3/glibc-compat/Banner
---- ../glibc-2.1.3/glibc-compat/Banner 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/Banner 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1 @@
-+Glibc-2.0 compatibility add-on by Cristian Gafton
-diff -Naur ../glibc-2.1.3/glibc-compat/ChangeLog glibc-2.1.3/glibc-compat/ChangeLog
---- ../glibc-2.1.3/glibc-compat/ChangeLog 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/ChangeLog 2000-02-23 17:59:39.000000000 -0800
-@@ -0,0 +1,24 @@
-+2000-02-23 Cristian Gafton <gafton@redhat.com>
-+
-+ * stubs.c (__setfpucw): Avoid using _FPU_SETCW on platform that do not have it
-+
-+1999-07-08 Cristian Gafton <gafton@redhat.com>
-+
-+ * stubs.c (__setfpucw): New function
-+ * Makefile: Use -include, not include
-+ (archive): New target.
-+
-+
-+1999-04-09 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+ * glibc-compat/Makefile: Add rules to link libnss_*.so.1 to libnss1_*.so.2.
-+
-+1998-11-18 Cristian Gafton <gafton@redhat.com>
-+
-+ * shlib-versions: added alpha versions
-+
-+ * Makefile (services): Added libnss_dns
-+
-+1998-11-16 Cristian Gafton <gafton@redhat.com>
-+
-+ * makedist (archive): remove old tar file just in case
-+
-diff -Naur ../glibc-2.1.3/glibc-compat/Depend glibc-2.1.3/glibc-compat/Depend
---- ../glibc-2.1.3/glibc-compat/Depend 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/Depend 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,3 @@
-+resolv
-+nss
-+nis
-diff -Naur ../glibc-2.1.3/glibc-compat/Makefile glibc-2.1.3/glibc-compat/Makefile
---- ../glibc-2.1.3/glibc-compat/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/Makefile 2000-01-06 09:33:12.000000000 -0800
-@@ -0,0 +1,152 @@
-+# Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+
-+# This is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU Library General Public License as
-+# published by the Free Software Foundation; either version 2 of the
-+# License, or (at your option) any later version.
-+
-+# The GNU C Library is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# Library General Public License for more details.
-+
-+# You should have received a copy of the GNU Library General Public
-+# License along with the GNU C Library; see the file COPYING.LIB. If not,
-+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+# Boston, MA 02111-1307, USA.
-+
-+# $Id: Makefile,v 1.2 2000/01/06 17:33:12 gafton Exp $
-+
-+subdir := glibc-compat
-+
-+distribute := nss-nis.h
-+
-+# This is the trivial part which goes into libc itself.
-+routines =
-+
-+# These are the databases that go through nss dispatch.
-+# Caution: if you add a database here, you must add its real name
-+# in databases.def, too.
-+databases = proto service hosts network grp pwd rpc ethers \
-+ spwd netgrp alias
-+
-+# Specify rules for the nss_* modules. We have some services.
-+services := files nis compat dns db
-+
-+extra-libs := $(services:%=libnss1_%) libNoVersion
-+# These libraries will be built in the `others' pass rather than
-+# the `lib' pass, because they depend on libc.so being built already.
-+extra-libs-others = $(extra-libs)
-+
-+# The sources are found in the appropriate subdir.
-+subdir-dirs = $(services:%=nss_%)
-+vpath %.c $(subdir-dirs)
-+
-+libnss1_files-routines := $(addprefix files-,$(databases))
-+libnss1_db-routines := $(addprefix db-,$(filter-out hosts network,$(databases)))
-+libnss1_compat-routines := $(addprefix compat-,grp pwd spwd)
-+libnss1_nis-routines := $(addprefix nis-,$(databases))
-+libnss1_dns-routines := $(addprefix dns-, host network)
-+
-+libcompat-routines := $(addprefix old, fileops iofdopen iopopen stdfiles \
-+ iofclose iofopen pclose tmpfile)
-+libNoVersion-routines := stubs
-+
-+generated += $(filter-out db-alias.c db-netgrp.c, \
-+ $(addsuffix .c,$(libnss1_db-routines)))
-+
-+libnss1_files-inhibit-o = $(filter-out .os,$(object-suffixes))
-+libnss1_db-inhibit-o = $(filter-out .os,$(object-suffixes))
-+libnss1_compat-inhibit-o = $(filter-out .os,$(object-suffixes))
-+libnss1_nis-inhibit-o = $(filter-out .os,$(object-suffixes))
-+libnss1_dns-inhibit-o = $(filter-out .os,$(object-suffixes))
-+
-+-include ../Rules
-+
-+# Force the soname to be libnss_*.so.1 for compatibility.
-+LDFLAGS-nss1_files.so = -Wl,-soname=lib$(libprefix)nss_files.so$($(@F)-version)
-+LDFLAGS-nss1_db.so = -Wl,-soname=lib$(libprefix)nss_db.so$($(@F)-version)
-+LDFLAGS-nss1_nis.so = -Wl,-soname=lib$(libprefix)nss_nis.so$($(@F)-version)
-+LDFLAGS-nss1_compat.so = -Wl,-soname=lib$(libprefix)nss_compat.so$($(@F)-version)
-+LDFLAGS-nss1_dns.so = -Wl,-soname=lib$(libprefix)nss_dns.so$($(@F)-version)
-+
-+-include ../Makeconfig
-+
-+ifeq (yes,$(build-shared))
-+install-others += $(inst_slibdir)/libnss_files.so$(libnss1_files.so-version) \
-+ $(inst_slibdir)/libnss_db.so$(libnss1_db.so-version) \
-+ $(inst_slibdir)/libnss_nis.so$(libnss1_nis.so-version) \
-+ $(inst_slibdir)/libnss_compat.so$(libnss1_compat.so-version) \
-+ $(inst_slibdir)/libnss_dns.so$(libnss1_dns.so-version)
-+endif
-+
-+$(inst_slibdir)/libnss_files.so$(libnss1_files.so-version): $(inst_slibdir)/libnss1_files-$(version).so $(+force)
-+ rm -f $@
-+ $(LN_S) $(<F) $@
-+
-+$(inst_slibdir)/libnss_db.so$(libnss1_db.so-version): $(inst_slibdir)/libnss1_db-$(version).so $(+force)
-+ rm -f $@
-+ $(LN_S) $(<F) $@
-+
-+$(inst_slibdir)/libnss_nis.so$(libnss1_nis.so-version): $(inst_slibdir)/libnss1_nis-$(version).so $(+force)
-+ rm -f $@
-+ $(LN_S) $(<F) $@
-+
-+$(inst_slibdir)/libnss_compat.so$(libnss1_compat.so-version): $(inst_slibdir)/libnss1_compat-$(version).so $(+force)
-+ rm -f $@
-+ $(LN_S) $(<F) $@
-+
-+$(inst_slibdir)/libnss_dns.so$(libnss1_dns.so-version): $(inst_slibdir)/libnss1_dns-$(version).so $(+force)
-+ rm -f $@
-+ $(LN_S) $(<F) $@
-+
-+
-+$(objpfx)libnss1_db.so: $(common-objpfx)db/libdb1.so $(objpfx)libnss1_files.so
-+
-+$(libnss1_db-routines:%=$(objpfx)%.c): $(objpfx)db-%.c: nss_files/files-%.c
-+ @rm -f $@.new
-+ (echo '#define EXTERN_PARSER';\
-+ echo '#define GENERIC "../nss_db/db-XXX.c"';\
-+ echo '#include <$<>') > $@.new
-+ mv -f $@.new $@
-+
-+$(objpfx)libnss1_compat.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
-+ $(objpfx)libnss1_files.so
-+$(objpfx)libnss1_nis.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
-+ $(objpfx)libnss1_files.so
-+
-+# The DNS NSS modules needs the resolver.
-+#$(objpfx)libnss1_dns.so: $(filter-out $(common-objpfx)resolv/stamp.os, \
-+# $(wildcard $(common-objpfx)resolv/*.os)) \
-+# $(common-objpfx)libc.so
-+$(objpfx)libnss1_dns.so: $(common-objpfx)resolv/libresolv.so $(common-objpfx)libc.so
-+
-+# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
-+# This ensures they will load libc.so for needed symbols if loaded by
-+# a statically-linked program that hasn't already loaded it.
-+$(objpfx)libnss1_compat.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
-+ $(objpfx)libnss1_files.so $(common-objpfx)libc.so
-+$(objpfx)libnss1_db.so: $(common-objpfx)db2/libdb.so $(objpfx)libnss1_files.so\
-+ $(common-objpfx)libc.so
-+$(objpfx)libnss1_dns.so: $(common-objpfx)resolv/libresolv.so \
-+ $(common-objpfx)libc.so
-+$(objpfs)libnss1_files.so: $(common-objpfx)libc.so
-+$(objpfx)libnss1_nis.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
-+ $(objpfx)libnss1_files.so $(common-objpfx)libc.so
-+
-+
-+#
-+# This is needed to build the separate tarball
-+#
-+pkgNAME = $(subdir)
-+pkgVERSION = 2.1.2
-+pkgCVSTAG = $(pkgNAME)_$(subst .,-,$(pkgVERSION))
-+
-+archive:
-+ @rm -f *.tar.gz *~
-+ cvs tag -F $(pkgCVSTAG) .
-+ @rm -rf /tmp/$(pkgNAME)-$(pkgVERSION) /tmp/$(pkgNAME) $(pkgNAME)-$(pkgVERSION).tar.gz
-+ @cd /tmp; cvs export -r$(pkgCVSTAG) $(pkgNAME)
-+ @pkgDIR=$$PWD; cd /tmp; tar cvzf $$pkgDIR/$(pkgNAME)-$(pkgVERSION).tar.gz $(pkgNAME)
-+ @rm -rf /tmp/$(pkgNAME)
-+ @echo "The archive is in $(pkgNAME)-$(pkgVERSION).tar.gz"
-diff -Naur ../glibc-2.1.3/glibc-compat/Versions glibc-2.1.3/glibc-compat/Versions
---- ../glibc-2.1.3/glibc-compat/Versions 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/Versions 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,106 @@
-+libnss1_db {
-+ GLIBC_2.0 {
-+ _nss_db_endaliasent; _nss_db_endetherent; _nss_db_endgrent;
-+ _nss_db_endnetgrent; _nss_db_endprotoent; _nss_db_endpwent;
-+ _nss_db_endrpcent; _nss_db_endservent; _nss_db_endspent;
-+ _nss_db_getaliasbyname_r; _nss_db_getaliasent_r; _nss_db_getetherent_r;
-+ _nss_db_getgrent_r; _nss_db_getgrgid_r; _nss_db_getgrnam_r;
-+ _nss_db_gethostton_r; _nss_db_getnetgrent_r; _nss_db_getntohost_r;
-+ _nss_db_getprotobyname_r; _nss_db_getprotobynumber_r;
-+ _nss_db_getprotoent_r; _nss_db_getpwent_r; _nss_db_getpwnam_r;
-+ _nss_db_getpwuid_r; _nss_db_getrpcbyname_r; _nss_db_getrpcbynumber_r;
-+ _nss_db_getrpcent_r; _nss_db_getservbyname_r; _nss_db_getservbyport_r;
-+ _nss_db_getservent_r; _nss_db_getspent_r; _nss_db_getspnam_r;
-+ _nss_db_setaliasent; _nss_db_setetherent; _nss_db_setgrent;
-+ _nss_db_setnetgrent; _nss_db_setprotoent; _nss_db_setpwent;
-+ _nss_db_setrpcent; _nss_db_setservent; _nss_db_setspent;
-+ }
-+}
-+
-+libnss1_dns {
-+ GLIBC_2.0 {
-+ _nss_dns_gethostbyaddr_r; _nss_dns_gethostbyname2_r;
-+ _nss_dns_gethostbyname_r; _nss_dns_getnetbyaddr_r;
-+ _nss_dns_getnetbyname_r;
-+ }
-+}
-+
-+libnss1_files {
-+ GLIBC_2.0 {
-+ _nss_files_setaliasent; _nss_files_endaliasent;
-+ _nss_files_getaliasbyname_r; _nss_files_getaliasent_r;
-+
-+ _nss_files_setetherent; _nss_files_endetherent;
-+ _nss_files_getetherent_r; _nss_files_parse_etherent;
-+
-+ _nss_files_setgrent; _nss_files_endgrent;
-+ _nss_files_getgrent_r; _nss_files_getgrgid_r; _nss_files_getgrnam_r;
-+
-+ _nss_files_sethostent; _nss_files_endhostent;
-+ _nss_files_gethostbyaddr_r; _nss_files_gethostbyname2_r; _nss_files_gethostbyname_r;
-+ _nss_files_gethostent_r; _nss_files_gethostton_r;
-+
-+ _nss_files_setnetent; _nss_files_endnetent;
-+ _nss_files_getnetbyaddr_r; _nss_files_getnetbyname_r;
-+ _nss_files_getnetent_r; _nss_files_getntohost_r;
-+ _nss_files_parse_netent;
-+
-+ _nss_files_setnetgrent; _nss_files_endnetgrent; _nss_files_getnetgrent_r;
-+
-+ _nss_files_setprotoent; _nss_files_endprotoent;
-+ _nss_files_getprotobyname_r; _nss_files_getprotobynumber_r;
-+ _nss_files_getprotoent_r; _nss_files_parse_protoent;
-+
-+ _nss_files_setpwent; _nss_files_endpwent;
-+ _nss_files_getpwent_r; _nss_files_getpwnam_r; _nss_files_getpwuid_r;
-+
-+ _nss_files_setrpcent; _nss_files_endrpcent;
-+ _nss_files_getrpcbyname_r; _nss_files_getrpcbynumber_r;
-+ _nss_files_getrpcent_r;
-+ _nss_files_parse_rpcent;
-+
-+ _nss_files_setservent; _nss_files_endservent;
-+ _nss_files_getservbyname_r; _nss_files_getservbyport_r;
-+ _nss_files_getservent_r;
-+ _nss_files_parse_servent;
-+
-+ _nss_files_setspent; _nss_files_endspent;
-+ _nss_files_getspent_r; _nss_files_getspnam_r;
-+
-+ _nss_netgroup_parseline;
-+ }
-+}
-+
-+libnss1_compat {
-+ GLIBC_2.0 {
-+ _nss_compat_endgrent; _nss_compat_endpwent; _nss_compat_endspent;
-+ _nss_compat_getgrent_r; _nss_compat_getgrgid_r; _nss_compat_getgrnam_r;
-+ _nss_compat_getpwent_r; _nss_compat_getpwnam_r; _nss_compat_getpwuid_r;
-+ _nss_compat_getspent_r; _nss_compat_getspnam_r; _nss_compat_initgroups;
-+ _nss_compat_setgrent; _nss_compat_setpwent; _nss_compat_setspent;
-+ }
-+}
-+
-+libnss1_nis {
-+ GLIBC_2.0 {
-+ _nss_nis_endaliasent; _nss_nis_endetherent; _nss_nis_endgrent;
-+ _nss_nis_endhostent; _nss_nis_endnetent; _nss_nis_endnetgrent;
-+ _nss_nis_endprotoent; _nss_nis_endpwent; _nss_nis_endrpcent;
-+ _nss_nis_endservent; _nss_nis_endspent; _nss_nis_getaliasbyname_r;
-+ _nss_nis_getaliasent_r; _nss_nis_getetherent_r; _nss_nis_getgrent_r;
-+ _nss_nis_getgrgid_r; _nss_nis_getgrnam_r; _nss_nis_gethostbyaddr_r;
-+ _nss_nis_gethostbyname2_r; _nss_nis_gethostbyname_r; _nss_nis_gethostent_r;
-+ _nss_nis_gethostton_r; _nss_nis_getnetbyaddr_r; _nss_nis_getnetbyname_r;
-+ _nss_nis_getnetent_r; _nss_nis_getnetgrent_r; _nss_nis_getntohost_r;
-+ _nss_nis_getprotobyname_r; _nss_nis_getprotobynumber_r;
-+ _nss_nis_getprotoent_r; _nss_nis_getpublickey; _nss_nis_getpwent_r;
-+ _nss_nis_getpwnam_r; _nss_nis_getpwuid_r; _nss_nis_getrpcbyname_r;
-+ _nss_nis_getrpcbynumber_r; _nss_nis_getrpcent_r; _nss_nis_getsecretkey;
-+ _nss_nis_getservbyname_r; _nss_nis_getservbyport_r; _nss_nis_getservent_r;
-+ _nss_nis_getspent_r; _nss_nis_getspnam_r; _nss_nis_initgroups;
-+ _nss_nis_netname2user; _nss_nis_setaliasent; _nss_nis_setetherent;
-+ _nss_nis_setgrent; _nss_nis_sethostent; _nss_nis_setnetent;
-+ _nss_nis_setnetgrent; _nss_nis_setprotoent; _nss_nis_setpwent;
-+ _nss_nis_setrpcent; _nss_nis_setservent; _nss_nis_setspent;
-+ }
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/Versions.def glibc-2.1.3/glibc-compat/Versions.def
---- ../glibc-2.1.3/glibc-compat/Versions.def 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/Versions.def 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,15 @@
-+libnss1_files {
-+ GLIBC_2.0
-+}
-+libnss1_db {
-+ GLIBC_2.0
-+}
-+libnss1_dns {
-+ GLIBC_2.0
-+}
-+libnss1_nis {
-+ GLIBC_2.0
-+}
-+libnss1_compat {
-+ GLIBC_2.0
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/configure glibc-2.1.3/glibc-compat/configure
---- ../glibc-2.1.3/glibc-compat/configure 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/configure 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,28 @@
-+#! /bin/sh
-+#
-+# We need a configure script only when compiling as part of GNU C library.
-+# Here we have to generate one of the files we need while compiling.
-+#
-+# The only problem is that no users of the package might thing they have to
-+# run configure themself and find it irritating when nothing happens.
-+#
-+# So we try here to find out whether we are called from the glibc configure
-+# or by a user. If the later is true show a gentle message.
-+#
-+saw_srcdir=no
-+srcdir=
-+saw_cache_file=no
-+# We use a simple heuristic which might fail: if we see the argument the
-+# glibc configure passes we assume it's glibc who calls us.
-+for opt in $*; do
-+ case $opt in
-+ --srcdir=*) saw_srcdir=yes
-+ srcdir=`echo "$opt" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
-+ --cache-file=*) saw_cache_file=yes ;;
-+ *) ;;
-+ esac
-+done
-+
-+echo "Configure stage for glibc 2.0 add-on"
-+
-+exit 0
-diff -Naur ../glibc-2.1.3/glibc-compat/nss-nis.h glibc-2.1.3/glibc-compat/nss-nis.h
---- ../glibc-2.1.3/glibc-compat/nss-nis.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss-nis.h 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,58 @@
-+/* Copyright (C) 1996 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef _NIS_NSS_NIS_H
-+#define _NIS_NSS_NIS_H 1
-+
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nsswitch.h"
-+
-+
-+/* Convert YP error number to NSS error number. */
-+static enum nss_status yperr2nss_tab[] =
-+{
-+ [YPERR_SUCCESS] = NSS_STATUS_SUCCESS,
-+ [YPERR_BADARGS] = NSS_STATUS_UNAVAIL,
-+ [YPERR_RPC] = NSS_STATUS_UNAVAIL,
-+ [YPERR_DOMAIN] = NSS_STATUS_UNAVAIL,
-+ [YPERR_MAP] = NSS_STATUS_UNAVAIL,
-+ [YPERR_KEY] = NSS_STATUS_NOTFOUND,
-+ [YPERR_YPERR] = NSS_STATUS_UNAVAIL,
-+ [YPERR_RESRC] = NSS_STATUS_TRYAGAIN,
-+ [YPERR_NOMORE] = NSS_STATUS_NOTFOUND,
-+ [YPERR_PMAP] = NSS_STATUS_UNAVAIL,
-+ [YPERR_YPBIND] = NSS_STATUS_UNAVAIL,
-+ [YPERR_YPSERV] = NSS_STATUS_UNAVAIL,
-+ [YPERR_NODOM] = NSS_STATUS_UNAVAIL,
-+ [YPERR_BADDB] = NSS_STATUS_UNAVAIL,
-+ [YPERR_VERS] = NSS_STATUS_UNAVAIL,
-+ [YPERR_ACCESS] = NSS_STATUS_UNAVAIL,
-+ [YPERR_BUSY] = NSS_STATUS_TRYAGAIN
-+};
-+#define YPERR_COUNT (sizeof (yperr2nss_tab) / sizeof (yperr2nss_tab[0]))
-+
-+static inline enum nss_status
-+yperr2nss (int errval)
-+{
-+ if ((unsigned int) errval > YPERR_COUNT)
-+ return NSS_STATUS_UNAVAIL;
-+ return yperr2nss_tab[errval];
-+}
-+
-+#endif /* nis/nss-nis.h */
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_compat/compat-grp.c glibc-2.1.3/glibc-compat/nss_compat/compat-grp.c
---- ../glibc-2.1.3/glibc-compat/nss_compat/compat-grp.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_compat/compat-grp.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,769 @@
-+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <nss.h>
-+#include <grp.h>
-+#include <ctype.h>
-+#include <bits/libc-lock.h>
-+#include <string.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+#include <nsswitch.h>
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME grent
-+#define STRUCTURE group
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+/* Structure for remembering -group members ... */
-+#define BLACKLIST_INITIAL_SIZE 512
-+#define BLACKLIST_INCREMENT 256
-+struct blacklist_t
-+ {
-+ char *data;
-+ int current;
-+ int size;
-+ };
-+
-+struct ent_t
-+ {
-+ bool_t nis;
-+ bool_t nis_first;
-+ char *oldkey;
-+ int oldkeylen;
-+ FILE *stream;
-+ struct blacklist_t blacklist;
-+};
-+typedef struct ent_t ent_t;
-+
-+static ent_t ext_ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
-+
-+/* Protect global state against multiple changers. */
-+__libc_lock_define_initialized (static, lock)
-+
-+/* Prototypes for local functions. */
-+static void blacklist_store_name (const char *, ent_t *);
-+static int in_blacklist (const char *, int, ent_t *);
-+
-+static enum nss_status
-+internal_setgrent (ent_t *ent)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ ent->nis = ent->nis_first = 0;
-+
-+ if (ent->oldkey != NULL)
-+ {
-+ free (ent->oldkey);
-+ ent->oldkey = NULL;
-+ ent->oldkeylen = 0;
-+ }
-+
-+ if (ent->blacklist.data != NULL)
-+ {
-+ ent->blacklist.current = 1;
-+ ent->blacklist.data[0] = '|';
-+ ent->blacklist.data[1] = '\0';
-+ }
-+ else
-+ ent->blacklist.current = 0;
-+
-+ if (ent->stream == NULL)
-+ {
-+ ent->stream = fopen ("/etc/group", "r");
-+
-+ if (ent->stream == NULL)
-+ status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-+ else
-+ {
-+ /* We have to make sure the file is `closed on exec'. */
-+ int result, flags;
-+
-+ result = flags = fcntl (fileno (ent->stream), F_GETFD, 0);
-+ if (result >= 0)
-+ {
-+ flags |= FD_CLOEXEC;
-+ result = fcntl (fileno (ent->stream), F_SETFD, flags);
-+ }
-+ if (result < 0)
-+ {
-+ /* Something went wrong. Close the stream and return a
-+ failure. */
-+ fclose (ent->stream);
-+ ent->stream = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ }
-+ }
-+ else
-+ rewind (ent->stream);
-+
-+ return status;
-+}
-+
-+
-+enum nss_status
-+_nss_compat_setgrent (void)
-+{
-+ enum nss_status result;
-+
-+ __libc_lock_lock (lock);
-+
-+ result = internal_setgrent (&ext_ent);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return result;
-+}
-+
-+
-+static enum nss_status
-+internal_endgrent (ent_t *ent)
-+{
-+ if (ent->stream != NULL)
-+ {
-+ fclose (ent->stream);
-+ ent->stream = NULL;
-+ }
-+
-+ ent->nis = ent->nis_first = 0;
-+
-+ if (ent->oldkey != NULL)
-+ {
-+ free (ent->oldkey);
-+ ent->oldkey = NULL;
-+ ent->oldkeylen = 0;
-+ }
-+
-+ if (ent->blacklist.data != NULL)
-+ {
-+ ent->blacklist.current = 1;
-+ ent->blacklist.data[0] = '|';
-+ ent->blacklist.data[1] = '\0';
-+ }
-+ else
-+ ent->blacklist.current = 0;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_compat_endgrent (void)
-+{
-+ enum nss_status result;
-+
-+ __libc_lock_lock (lock);
-+
-+ result = internal_endgrent (&ext_ent);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return result;
-+}
-+
-+static enum nss_status
-+getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
-+ size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *domain;
-+ char *outkey, *outval;
-+ int outkeylen, outvallen, parse_res;
-+ char *p;
-+
-+ if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-+ {
-+ ent->nis = 0;
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+
-+ do
-+ {
-+ char *save_oldkey;
-+ int save_oldlen;
-+ bool_t save_nis_first;
-+
-+ if (ent->nis_first)
-+ {
-+ if (yp_first (domain, "group.byname", &outkey, &outkeylen,
-+ &outval, &outvallen) != YPERR_SUCCESS)
-+ {
-+ ent->nis = 0;
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+ save_oldkey = ent->oldkey;
-+ save_oldlen = ent->oldkeylen;
-+ save_nis_first = TRUE;
-+ ent->oldkey = outkey;
-+ ent->oldkeylen = outkeylen;
-+ ent->nis_first = FALSE;
-+ }
-+ else
-+ {
-+ if (yp_next (domain, "group.byname", ent->oldkey, ent->oldkeylen,
-+ &outkey, &outkeylen, &outval, &outvallen)
-+ != YPERR_SUCCESS)
-+ {
-+ ent->nis = 0;
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+
-+ save_oldkey = ent->oldkey;
-+ save_oldlen = ent->oldkeylen;
-+ save_nis_first = FALSE;
-+ ent->oldkey = outkey;
-+ ent->oldkeylen = outkeylen;
-+ }
-+
-+ /* Copy the found data to our buffer */
-+ p = strncpy (buffer, outval, buflen);
-+
-+ /* ...and free the data. */
-+ free (outval);
-+
-+ while (isspace (*p))
-+ ++p;
-+
-+ if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
-+ {
-+ free (ent->oldkey);
-+ ent->oldkey = save_oldkey;
-+ ent->oldkeylen = save_oldlen;
-+ ent->nis_first = save_nis_first;
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ else
-+ {
-+ if (!save_nis_first)
-+ free (save_oldkey);
-+ }
-+
-+ if (parse_res &&
-+ in_blacklist (result->gr_name, strlen (result->gr_name), ent))
-+ parse_res = 0; /* if result->gr_name in blacklist,search next entry */
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+/* This function handle the +group entrys in /etc/group */
-+static enum nss_status
-+getgrnam_plusgroup (const char *name, struct group *result, char *buffer,
-+ size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ int parse_res;
-+ char *domain, *outval, *p;
-+ int outvallen;
-+
-+ if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ if (yp_match (domain, "group.byname", name, strlen (name),
-+ &outval, &outvallen) != YPERR_SUCCESS)
-+ return NSS_STATUS_NOTFOUND;
-+ p = strncpy (buffer, outval,
-+ buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
-+ free (outval);
-+ while (isspace (*p))
-+ p++;
-+ if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (parse_res)
-+ /* We found the entry. */
-+ return NSS_STATUS_SUCCESS;
-+ else
-+ return NSS_STATUS_RETURN;
-+}
-+
-+static enum nss_status
-+getgrent_next_file (struct group *result, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ while (1)
-+ {
-+ fpos_t pos;
-+ int parse_res = 0;
-+ char *p;
-+
-+ do
-+ {
-+ fgetpos (ent->stream, &pos);
-+ buffer[buflen - 1] = '\xff';
-+ p = fgets (buffer, buflen, ent->stream);
-+ if (p == NULL && feof (ent->stream))
-+ return NSS_STATUS_NOTFOUND;
-+ if (p == NULL || buffer[buflen - 1] != '\xff')
-+ {
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Terminate the line for any case. */
-+ buffer[buflen - 1] = '\0';
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+ }
-+ while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
-+ /* Parse the line. If it is invalid, loop to
-+ get the next line of the file to parse. */
-+ !(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
-+
-+ if (parse_res == -1)
-+ {
-+ /* The parser ran out of space. */
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
-+ /* This is a real entry. */
-+ break;
-+
-+ /* -group */
-+ if (result->gr_name[0] == '-' && result->gr_name[1] != '\0'
-+ && result->gr_name[1] != '@')
-+ {
-+ blacklist_store_name (&result->gr_name[1], ent);
-+ continue;
-+ }
-+
-+ /* +group */
-+ if (result->gr_name[0] == '+' && result->gr_name[1] != '\0'
-+ && result->gr_name[1] != '@')
-+ {
-+ enum nss_status status;
-+
-+ /* Store the group in the blacklist for the "+" at the end of
-+ /etc/group */
-+ blacklist_store_name (&result->gr_name[1], ent);
-+ status = getgrnam_plusgroup (&result->gr_name[1], result, buffer,
-+ buflen);
-+ if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
-+ break;
-+ else
-+ if (status == NSS_STATUS_RETURN /* We couldn't parse the entry */
-+ || status == NSS_STATUS_NOTFOUND) /* No group in NIS */
-+ continue;
-+ else
-+ {
-+ if (status == NSS_STATUS_TRYAGAIN)
-+ /* The parser ran out of space. */
-+ fsetpos (ent->stream, &pos);
-+ return status;
-+ }
-+ }
-+
-+ /* +:... */
-+ if (result->gr_name[0] == '+' && result->gr_name[1] == '\0')
-+ {
-+ ent->nis = TRUE;
-+ ent->nis_first = TRUE;
-+
-+ return getgrent_next_nis (result, ent, buffer, buflen);
-+ }
-+ }
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+
-+static enum nss_status
-+internal_getgrent_r (struct group *gr, ent_t *ent, char *buffer,
-+ size_t buflen)
-+{
-+ if (ent->nis)
-+ {
-+ return getgrent_next_nis (gr, ent, buffer, buflen);
-+ }
-+ else
-+ return getgrent_next_file (gr, ent, buffer, buflen);
-+}
-+
-+enum nss_status
-+_nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ __libc_lock_lock (lock);
-+
-+ /* Be prepared that the setgrent function was not called before. */
-+ if (ext_ent.stream == NULL)
-+ status = internal_setgrent (&ext_ent);
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ status = internal_getgrent_r (grp, &ext_ent, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+/* Searches in /etc/group and the NIS/NIS+ map for a special group */
-+static enum nss_status
-+internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ while (1)
-+ {
-+ fpos_t pos;
-+ int parse_res = 0;
-+ char *p;
-+
-+ do
-+ {
-+ fgetpos (ent->stream, &pos);
-+ buffer[buflen - 1] = '\xff';
-+ p = fgets (buffer, buflen, ent->stream);
-+ if (p == NULL && feof (ent->stream))
-+ return NSS_STATUS_NOTFOUND;
-+ if (p == NULL || buffer[buflen - 1] != '\xff')
-+ {
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Terminate the line for any case. */
-+ buffer[buflen - 1] = '\0';
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+ }
-+ while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
-+ /* Parse the line. If it is invalid, loop to
-+ get the next line of the file to parse. */
-+ !(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
-+
-+ if (parse_res == -1)
-+ {
-+ /* The parser ran out of space. */
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* This is a real entry. */
-+ if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
-+ {
-+ if (strcmp (result->gr_name, name) == 0)
-+ return NSS_STATUS_SUCCESS;
-+ else
-+ continue;
-+ }
-+
-+ /* -group */
-+ if (result->gr_name[0] == '-' && result->gr_name[1] != '\0')
-+ {
-+ if (strcmp (&result->gr_name[1], name) == 0)
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ continue;
-+ }
-+
-+ /* +group */
-+ if (result->gr_name[0] == '+' && result->gr_name[1] != '\0')
-+ {
-+ if (strcmp (name, &result->gr_name[1]) == 0)
-+ {
-+ enum nss_status status;
-+
-+ status = getgrnam_plusgroup (name, result, buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ /* We couldn't parse the entry */
-+ continue;
-+ else
-+ return status;
-+ }
-+ }
-+ /* +:... */
-+ if (result->gr_name[0] == '+' && result->gr_name[1] == '\0')
-+ {
-+ enum nss_status status;
-+
-+ status = getgrnam_plusgroup (name, result, buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ /* We couldn't parse the entry */
-+ continue;
-+ else
-+ return status;
-+ }
-+ }
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_compat_getgrnam_r (const char *name, struct group *grp,
-+ char *buffer, size_t buflen)
-+{
-+ ent_t ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
-+ enum nss_status status;
-+
-+ if (name[0] == '-' || name[0] == '+')
-+ return NSS_STATUS_NOTFOUND;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_setgrent (&ent);
-+
-+ __libc_lock_unlock (lock);
-+
-+ if (status != NSS_STATUS_SUCCESS)
-+ return status;
-+
-+ status = internal_getgrnam_r (name, grp, &ent, buffer, buflen);
-+
-+ internal_endgrent (&ent);
-+
-+ return status;
-+}
-+
-+/* This function handle the + entry in /etc/group */
-+static enum nss_status
-+getgrgid_plusgroup (gid_t gid, struct group *result, char *buffer,
-+ size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ int parse_res;
-+ char buf[1024];
-+ char *domain, *outval, *p;
-+ int outvallen;
-+
-+ if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-+ return NSS_STATUS_TRYAGAIN;
-+
-+ snprintf (buf, sizeof (buf), "%d", gid);
-+
-+ if (yp_match (domain, "group.bygid", buf, strlen (buf),
-+ &outval, &outvallen) != YPERR_SUCCESS)
-+ return NSS_STATUS_TRYAGAIN;
-+ p = strncpy (buffer, outval,
-+ buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
-+ free (outval);
-+ while (isspace (*p))
-+ p++;
-+ if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (parse_res)
-+ /* We found the entry. */
-+ return NSS_STATUS_SUCCESS;
-+ else
-+ return NSS_STATUS_RETURN;
-+}
-+
-+/* Searches in /etc/group and the NIS/NIS+ map for a special group id */
-+static enum nss_status
-+internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ while (1)
-+ {
-+ fpos_t pos;
-+ int parse_res = 0;
-+ char *p;
-+
-+ do
-+ {
-+ fgetpos (ent->stream, &pos);
-+ buffer[buflen - 1] = '\xff';
-+ p = fgets (buffer, buflen, ent->stream);
-+ if (p == NULL && feof (ent->stream))
-+ return NSS_STATUS_NOTFOUND;
-+ if (p == NULL || buffer[buflen - 1] != '\xff')
-+ {
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Terminate the line for any case. */
-+ buffer[buflen - 1] = '\0';
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+ }
-+ while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
-+ /* Parse the line. If it is invalid, loop to
-+ get the next line of the file to parse. */
-+ !(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
-+
-+ if (parse_res == -1)
-+ {
-+ /* The parser ran out of space. */
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* This is a real entry. */
-+ if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
-+ {
-+ if (result->gr_gid == gid)
-+ return NSS_STATUS_SUCCESS;
-+ else
-+ continue;
-+ }
-+
-+ /* -group */
-+ if (result->gr_name[0] == '-' && result->gr_name[1] != '\0')
-+ {
-+ blacklist_store_name (&result->gr_name[1], ent);
-+ continue;
-+ }
-+
-+ /* +group */
-+ if (result->gr_name[0] == '+' && result->gr_name[1] != '\0')
-+ {
-+ enum nss_status status;
-+
-+ /* Store the group in the blacklist for the "+" at the end of
-+ /etc/group */
-+ blacklist_store_name (&result->gr_name[1], ent);
-+ status = getgrnam_plusgroup (&result->gr_name[1], result, buffer,
-+ buflen);
-+ if (status == NSS_STATUS_SUCCESS && result->gr_gid == gid)
-+ break;
-+ else
-+ continue;
-+ }
-+ /* +:... */
-+ if (result->gr_name[0] == '+' && result->gr_name[1] == '\0')
-+ {
-+ enum nss_status status;
-+
-+ status = getgrgid_plusgroup (gid, result, buffer, buflen);
-+ if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ return status;
-+ }
-+ }
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_compat_getgrgid_r (gid_t gid, struct group *grp,
-+ char *buffer, size_t buflen)
-+{
-+ ent_t ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_setgrent (&ent);
-+
-+ __libc_lock_unlock (lock);
-+
-+ if (status != NSS_STATUS_SUCCESS)
-+ return status;
-+
-+ status = internal_getgrgid_r (gid, grp, &ent, buffer, buflen);
-+
-+ internal_endgrent (&ent);
-+
-+ return status;
-+}
-+
-+
-+/* Support routines for remembering -@netgroup and -user entries.
-+ The names are stored in a single string with `|' as separator. */
-+static void
-+blacklist_store_name (const char *name, ent_t *ent)
-+{
-+ int namelen = strlen (name);
-+ char *tmp;
-+
-+ /* first call, setup cache */
-+ if (ent->blacklist.size == 0)
-+ {
-+ ent->blacklist.size = MAX (BLACKLIST_INITIAL_SIZE, 2 * namelen);
-+ ent->blacklist.data = malloc (ent->blacklist.size);
-+ if (ent->blacklist.data == NULL)
-+ return;
-+ ent->blacklist.data[0] = '|';
-+ ent->blacklist.data[1] = '\0';
-+ ent->blacklist.current = 1;
-+ }
-+ else
-+ {
-+ if (in_blacklist (name, namelen, ent))
-+ return; /* no duplicates */
-+
-+ if (ent->blacklist.current + namelen + 1 >= ent->blacklist.size)
-+ {
-+ ent->blacklist.size += MAX (BLACKLIST_INCREMENT, 2 * namelen);
-+ tmp = realloc (ent->blacklist.data, ent->blacklist.size);
-+ if (tmp == NULL)
-+ {
-+ free (ent->blacklist.data);
-+ ent->blacklist.size = 0;
-+ return;
-+ }
-+ ent->blacklist.data = tmp;
-+ }
-+ }
-+
-+ tmp = stpcpy (ent->blacklist.data + ent->blacklist.current, name);
-+ *tmp++ = '|';
-+ *tmp = '\0';
-+ ent->blacklist.current += namelen + 1;
-+
-+ return;
-+}
-+
-+/* returns TRUE if ent->blacklist contains name, else FALSE */
-+static bool_t
-+in_blacklist (const char *name, int namelen, ent_t *ent)
-+{
-+ char buf[namelen + 3];
-+ char *cp;
-+
-+ if (ent->blacklist.data == NULL)
-+ return FALSE;
-+
-+ buf[0] = '|';
-+ cp = stpcpy (&buf[1], name);
-+ *cp++= '|';
-+ *cp = '\0';
-+ return strstr (ent->blacklist.data, buf) != NULL;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_compat/compat-pwd.c glibc-2.1.3/glibc-compat/nss_compat/compat-pwd.c
---- ../glibc-2.1.3/glibc-compat/nss_compat/compat-pwd.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_compat/compat-pwd.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,1199 @@
-+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <pwd.h>
-+#include <errno.h>
-+#include <ctype.h>
-+#include <fcntl.h>
-+#include <netdb.h>
-+#include <string.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+#include <nsswitch.h>
-+
-+#include "netgroup.h"
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME pwent
-+#define STRUCTURE passwd
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+/* Structure for remembering -@netgroup and -user members ... */
-+#define BLACKLIST_INITIAL_SIZE 512
-+#define BLACKLIST_INCREMENT 256
-+struct blacklist_t
-+ {
-+ char *data;
-+ int current;
-+ int size;
-+ };
-+
-+struct ent_t
-+ {
-+ bool_t netgroup;
-+ bool_t nis;
-+ bool_t first;
-+ char *oldkey;
-+ int oldkeylen;
-+ FILE *stream;
-+ struct blacklist_t blacklist;
-+ struct passwd pwd;
-+ struct __netgrent netgrdata;
-+ };
-+typedef struct ent_t ent_t;
-+
-+static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
-+ {NULL, NULL, 0, 0, NULL, NULL, NULL}};
-+
-+/* Protect global state against multiple changers. */
-+__libc_lock_define_initialized (static, lock)
-+
-+/* Prototypes for local functions. */
-+static void blacklist_store_name (const char *, ent_t *);
-+static int in_blacklist (const char *, int, ent_t *);
-+
-+static void
-+give_pwd_free (struct passwd *pwd)
-+{
-+ if (pwd->pw_name != NULL)
-+ free (pwd->pw_name);
-+ if (pwd->pw_passwd != NULL)
-+ free (pwd->pw_passwd);
-+ if (pwd->pw_gecos != NULL)
-+ free (pwd->pw_gecos);
-+ if (pwd->pw_dir != NULL)
-+ free (pwd->pw_dir);
-+ if (pwd->pw_shell != NULL)
-+ free (pwd->pw_shell);
-+
-+ memset (pwd, '\0', sizeof (struct passwd));
-+}
-+
-+static size_t
-+pwd_need_buflen (struct passwd *pwd)
-+{
-+ size_t len = 0;
-+
-+ if (pwd->pw_passwd != NULL)
-+ len += strlen (pwd->pw_passwd) + 1;
-+
-+ if (pwd->pw_gecos != NULL)
-+ len += strlen (pwd->pw_gecos) + 1;
-+
-+ if (pwd->pw_dir != NULL)
-+ len += strlen (pwd->pw_dir) + 1;
-+
-+ if (pwd->pw_shell != NULL)
-+ len += strlen (pwd->pw_shell) + 1;
-+
-+ return len;
-+}
-+
-+static void
-+copy_pwd_changes (struct passwd *dest, struct passwd *src,
-+ char *buffer, size_t buflen)
-+{
-+ if (src->pw_passwd != NULL && strlen (src->pw_passwd))
-+ {
-+ if (buffer == NULL)
-+ dest->pw_passwd = strdup (src->pw_passwd);
-+ else if (dest->pw_passwd &&
-+ strlen (dest->pw_passwd) >= strlen (src->pw_passwd))
-+ strcpy (dest->pw_passwd, src->pw_passwd);
-+ else
-+ {
-+ dest->pw_passwd = buffer;
-+ strcpy (dest->pw_passwd, src->pw_passwd);
-+ buffer += strlen (dest->pw_passwd) + 1;
-+ buflen = buflen - (strlen (dest->pw_passwd) + 1);
-+ }
-+ }
-+
-+ if (src->pw_gecos != NULL && strlen (src->pw_gecos))
-+ {
-+ if (buffer == NULL)
-+ dest->pw_gecos = strdup (src->pw_gecos);
-+ else if (dest->pw_gecos &&
-+ strlen (dest->pw_gecos) >= strlen (src->pw_gecos))
-+ strcpy (dest->pw_gecos, src->pw_gecos);
-+ else
-+ {
-+ dest->pw_gecos = buffer;
-+ strcpy (dest->pw_gecos, src->pw_gecos);
-+ buffer += strlen (dest->pw_gecos) + 1;
-+ buflen = buflen - (strlen (dest->pw_gecos) + 1);
-+ }
-+ }
-+ if (src->pw_dir != NULL && strlen (src->pw_dir))
-+ {
-+ if (buffer == NULL)
-+ dest->pw_dir = strdup (src->pw_dir);
-+ else if (dest->pw_dir &&
-+ strlen (dest->pw_dir) >= strlen (src->pw_dir))
-+ strcpy (dest->pw_dir, src->pw_dir);
-+ else
-+ {
-+ dest->pw_dir = buffer;
-+ strcpy (dest->pw_dir, src->pw_dir);
-+ buffer += strlen (dest->pw_dir) + 1;
-+ buflen = buflen - (strlen (dest->pw_dir) + 1);
-+ }
-+ }
-+
-+ if (src->pw_shell != NULL && strlen (src->pw_shell))
-+ {
-+ if (buffer == NULL)
-+ dest->pw_shell = strdup (src->pw_shell);
-+ else if (dest->pw_shell &&
-+ strlen (dest->pw_shell) >= strlen (src->pw_shell))
-+ strcpy (dest->pw_shell, src->pw_shell);
-+ else
-+ {
-+ dest->pw_shell = buffer;
-+ strcpy (dest->pw_shell, src->pw_shell);
-+ buffer += strlen (dest->pw_shell) + 1;
-+ buflen = buflen - (strlen (dest->pw_shell) + 1);
-+ }
-+ }
-+}
-+
-+static enum nss_status
-+internal_setpwent (ent_t *ent)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ ent->nis = ent->first = ent->netgroup = 0;
-+
-+ /* If something was left over free it. */
-+ if (ent->netgroup)
-+ __internal_endnetgrent (&ent->netgrdata);
-+
-+ if (ent->oldkey != NULL)
-+ {
-+ free (ent->oldkey);
-+ ent->oldkey = NULL;
-+ ent->oldkeylen = 0;
-+ }
-+
-+ if (ent->blacklist.data != NULL)
-+ {
-+ ent->blacklist.current = 1;
-+ ent->blacklist.data[0] = '|';
-+ ent->blacklist.data[1] = '\0';
-+ }
-+ else
-+ ent->blacklist.current = 0;
-+
-+ if (ent->stream == NULL)
-+ {
-+ ent->stream = fopen ("/etc/passwd", "r");
-+
-+ if (ent->stream == NULL)
-+ status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-+ else
-+ {
-+ /* We have to make sure the file is `closed on exec'. */
-+ int result, flags;
-+
-+ result = flags = fcntl (fileno (ent->stream), F_GETFD, 0);
-+ if (result >= 0)
-+ {
-+ flags |= FD_CLOEXEC;
-+ result = fcntl (fileno (ent->stream), F_SETFD, flags);
-+ }
-+ if (result < 0)
-+ {
-+ /* Something went wrong. Close the stream and return a
-+ failure. */
-+ fclose (ent->stream);
-+ ent->stream = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ }
-+ }
-+ else
-+ rewind (ent->stream);
-+
-+ give_pwd_free (&ent->pwd);
-+
-+ return status;
-+}
-+
-+
-+enum nss_status
-+_nss_compat_setpwent (void)
-+{
-+ enum nss_status result;
-+
-+ __libc_lock_lock (lock);
-+
-+ result = internal_setpwent (&ext_ent);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return result;
-+}
-+
-+
-+static enum nss_status
-+internal_endpwent (ent_t *ent)
-+{
-+ if (ent->stream != NULL)
-+ {
-+ fclose (ent->stream);
-+ ent->stream = NULL;
-+ }
-+
-+ if (ent->netgroup)
-+ __internal_endnetgrent (&ent->netgrdata);
-+
-+ ent->nis = ent->first = ent->netgroup = 0;
-+
-+ if (ent->oldkey != NULL)
-+ {
-+ free (ent->oldkey);
-+ ent->oldkey = NULL;
-+ ent->oldkeylen = 0;
-+ }
-+
-+ if (ent->blacklist.data != NULL)
-+ {
-+ ent->blacklist.current = 1;
-+ ent->blacklist.data[0] = '|';
-+ ent->blacklist.data[1] = '\0';
-+ }
-+ else
-+ ent->blacklist.current = 0;
-+
-+ give_pwd_free (&ent->pwd);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_compat_endpwent (void)
-+{
-+ enum nss_status result;
-+
-+ __libc_lock_lock (lock);
-+
-+ result = internal_endpwent (&ext_ent);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return result;
-+}
-+
-+static enum nss_status
-+getpwent_next_nis_netgr (const char *name, struct passwd *result, ent_t *ent,
-+ char *group, char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *ypdomain, *host, *user, *domain, *outval, *p, *p2;
-+ int status, outvallen;
-+ size_t p2len;
-+
-+ if (yp_get_default_domain (&ypdomain) != YPERR_SUCCESS)
-+ {
-+ ent->netgroup = 0;
-+ ent->first = 0;
-+ give_pwd_free (&ent->pwd);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (ent->first == TRUE)
-+ {
-+ memset (&ent->netgrdata, 0, sizeof (struct __netgrent));
-+ __internal_setnetgrent (group, &ent->netgrdata);
-+ ent->first = FALSE;
-+ }
-+
-+ while (1)
-+ {
-+ char *saved_cursor;
-+ int parse_res;
-+
-+ saved_cursor = ent->netgrdata.cursor;
-+ status = __internal_getnetgrent_r (&host, &user, &domain,
-+ &ent->netgrdata, buffer, buflen,
-+ &errno);
-+ if (status != 1)
-+ {
-+ __internal_endnetgrent (&ent->netgrdata);
-+ ent->netgroup = 0;
-+ give_pwd_free (&ent->pwd);
-+ return NSS_STATUS_RETURN;
-+ }
-+
-+ if (user == NULL || user[0] == '-')
-+ continue;
-+
-+ if (domain != NULL && strcmp (ypdomain, domain) != 0)
-+ continue;
-+
-+ /* If name != NULL, we are called from getpwnam */
-+ if (name != NULL)
-+ if (strcmp (user, name) != 0)
-+ continue;
-+
-+ if (yp_match (ypdomain, "passwd.byname", user,
-+ strlen (user), &outval, &outvallen)
-+ != YPERR_SUCCESS)
-+ continue;
-+
-+ p2len = pwd_need_buflen (&ent->pwd);
-+ if (p2len > buflen)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ p2 = buffer + (buflen - p2len);
-+ buflen -= p2len;
-+ p = strncpy (buffer, outval, buflen);
-+ while (isspace (*p))
-+ p++;
-+ free (outval);
-+ if ((parse_res = _nss_files_parse_pwent (p, result, data, buflen)) == -1)
-+ {
-+ ent->netgrdata.cursor = saved_cursor;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (parse_res)
-+ {
-+ /* Store the User in the blacklist for the "+" at the end of
-+ /etc/passwd */
-+ blacklist_store_name (result->pw_name, ent);
-+ copy_pwd_changes (result, &ent->pwd, p2, p2len);
-+ break;
-+ }
-+ }
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
-+ size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *domain, *outkey, *outval, *p, *p2;
-+ int outkeylen, outvallen, parse_res;
-+ size_t p2len;
-+
-+ if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-+ {
-+ ent->nis = 0;
-+ give_pwd_free (&ent->pwd);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ p2len = pwd_need_buflen (&ent->pwd);
-+ if (p2len > buflen)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ p2 = buffer + (buflen - p2len);
-+ buflen -= p2len;
-+ do
-+ {
-+ bool_t saved_first;
-+ char *saved_oldkey;
-+ int saved_oldlen;
-+
-+ if (ent->first)
-+ {
-+ if (yp_first (domain, "passwd.byname", &outkey, &outkeylen,
-+ &outval, &outvallen) != YPERR_SUCCESS)
-+ {
-+ ent->nis = 0;
-+ give_pwd_free (&ent->pwd);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ saved_first = TRUE;
-+ saved_oldkey = ent->oldkey;
-+ saved_oldlen = ent->oldkeylen;
-+ ent->oldkey = outkey;
-+ ent->oldkeylen = outkeylen;
-+ ent->first = FALSE;
-+ }
-+ else
-+ {
-+ if (yp_next (domain, "passwd.byname", ent->oldkey, ent->oldkeylen,
-+ &outkey, &outkeylen, &outval, &outvallen)
-+ != YPERR_SUCCESS)
-+ {
-+ ent->nis = 0;
-+ give_pwd_free (&ent->pwd);
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+
-+ saved_first = FALSE;
-+ saved_oldkey = ent->oldkey;
-+ saved_oldlen = ent->oldkeylen;
-+ ent->oldkey = outkey;
-+ ent->oldkeylen = outkeylen;
-+ }
-+
-+ /* Copy the found data to our buffer */
-+ p = strncpy (buffer, outval, buflen);
-+
-+ /* ...and free the data. */
-+ free (outval);
-+
-+ while (isspace (*p))
-+ ++p;
-+ if ((parse_res = _nss_files_parse_pwent (p, result, data, buflen)) == -1)
-+ {
-+ free (ent->oldkey);
-+ ent->oldkey = saved_oldkey;
-+ ent->oldkeylen = saved_oldlen;
-+ ent->first = saved_first;
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ else
-+ {
-+ if (!saved_first)
-+ free (saved_oldkey);
-+ }
-+ if (parse_res &&
-+ in_blacklist (result->pw_name, strlen (result->pw_name), ent))
-+ parse_res = 0;
-+ }
-+ while (!parse_res);
-+
-+ copy_pwd_changes (result, &ent->pwd, p2, p2len);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+/* This function handle the +user entrys in /etc/passwd */
-+static enum nss_status
-+getpwnam_plususer (const char *name, struct passwd *result, char *buffer,
-+ size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ struct passwd pwd;
-+ int parse_res;
-+ char *p;
-+ size_t plen;
-+ char *domain, *outval, *ptr;
-+ int outvallen;
-+
-+ memset (&pwd, '\0', sizeof (struct passwd));
-+
-+ copy_pwd_changes (&pwd, result, NULL, 0);
-+
-+ plen = pwd_need_buflen (&pwd);
-+ if (plen > buflen)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ p = buffer + (buflen - plen);
-+ buflen -= plen;
-+
-+
-+ if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ if (yp_match (domain, "passwd.byname", name, strlen (name),
-+ &outval, &outvallen) != YPERR_SUCCESS)
-+ return NSS_STATUS_NOTFOUND;
-+ ptr = strncpy (buffer, outval, buflen < (size_t) outvallen ?
-+ buflen : (size_t) outvallen);
-+ buffer[buflen < (size_t) outvallen ? buflen : (size_t) outvallen] = '\0';
-+ free (outval);
-+ while (isspace (*ptr))
-+ ptr++;
-+ if ((parse_res = _nss_files_parse_pwent (ptr, result, data, buflen))
-+ == -1)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (parse_res > 0)
-+ {
-+ copy_pwd_changes (result, &pwd, p, plen);
-+ give_pwd_free (&pwd);
-+ /* We found the entry. */
-+ return NSS_STATUS_SUCCESS;
-+ }
-+ else
-+ {
-+ /* Give buffer the old len back */
-+ buflen += plen;
-+ give_pwd_free (&pwd);
-+ }
-+ return NSS_STATUS_RETURN;
-+}
-+
-+/* get the next user from NIS+ (+ entry) */
-+static enum nss_status
-+getpwent_next_file (struct passwd *result, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ while (1)
-+ {
-+ fpos_t pos;
-+ char *p;
-+ int parse_res;
-+
-+ do
-+ {
-+ fgetpos (ent->stream, &pos);
-+ buffer[buflen - 1] = '\xff';
-+ p = fgets (buffer, buflen, ent->stream);
-+ if (p == NULL && feof (ent->stream))
-+ return NSS_STATUS_NOTFOUND;
-+ if (p == NULL || buffer[buflen - 1] != '\xff')
-+ {
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Terminate the line for any case. */
-+ buffer[buflen - 1] = '\0';
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+ }
-+ while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
-+ /* Parse the line. If it is invalid, loop to
-+ get the next line of the file to parse. */
-+ !(parse_res = _nss_files_parse_pwent (p, result, data, buflen)));
-+
-+ if (parse_res == -1)
-+ {
-+ /* The parser ran out of space. */
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (result->pw_name[0] != '+' && result->pw_name[0] != '-')
-+ /* This is a real entry. */
-+ break;
-+
-+ /* -@netgroup */
-+ if (result->pw_name[0] == '-' && result->pw_name[1] == '@'
-+ && result->pw_name[2] != '\0')
-+ {
-+ char buf2[1024];
-+ char *user, *host, *domain;
-+ struct __netgrent netgrdata;
-+
-+ bzero (&netgrdata, sizeof (struct __netgrent));
-+ __internal_setnetgrent (&result->pw_name[2], &netgrdata);
-+ while (__internal_getnetgrent_r (&host, &user, &domain,
-+ &netgrdata, buf2, sizeof (buf2),
-+ &errno))
-+ {
-+ if (user != NULL && user[0] != '-')
-+ blacklist_store_name (user, ent);
-+ }
-+ __internal_endnetgrent (&netgrdata);
-+ continue;
-+ }
-+
-+ /* +@netgroup */
-+ if (result->pw_name[0] == '+' && result->pw_name[1] == '@'
-+ && result->pw_name[2] != '\0')
-+ {
-+ int status;
-+
-+ ent->netgroup = TRUE;
-+ ent->first = TRUE;
-+ copy_pwd_changes (&ent->pwd, result, NULL, 0);
-+
-+ status = getpwent_next_nis_netgr (NULL, result, ent,
-+ &result->pw_name[2],
-+ buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ continue;
-+ else
-+ return status;
-+ }
-+
-+ /* -user */
-+ if (result->pw_name[0] == '-' && result->pw_name[1] != '\0'
-+ && result->pw_name[1] != '@')
-+ {
-+ blacklist_store_name (&result->pw_name[1], ent);
-+ continue;
-+ }
-+
-+ /* +user */
-+ if (result->pw_name[0] == '+' && result->pw_name[1] != '\0'
-+ && result->pw_name[1] != '@')
-+ {
-+ enum nss_status status;
-+
-+ /* Store the User in the blacklist for the "+" at the end of
-+ /etc/passwd */
-+ blacklist_store_name (&result->pw_name[1], ent);
-+ status = getpwnam_plususer (&result->pw_name[1], result, buffer,
-+ buflen);
-+ if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
-+ break;
-+ else
-+ if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
-+ continue;
-+ else
-+ return status;
-+ }
-+
-+ /* +:... */
-+ if (result->pw_name[0] == '+' && result->pw_name[1] == '\0')
-+ {
-+ ent->nis = TRUE;
-+ ent->first = TRUE;
-+ copy_pwd_changes (&ent->pwd, result, NULL, 0);
-+
-+ return getpwent_next_nis (result, ent, buffer, buflen);
-+ }
-+ }
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+
-+/* get the next user from NIS (+ entry) */
-+static enum nss_status
-+internal_getpwent_r (struct passwd *pw, ent_t *ent, char *buffer,
-+ size_t buflen)
-+{
-+ if (ent->netgroup)
-+ {
-+ int status;
-+
-+ /* We are searching members in a netgroup */
-+ /* Since this is not the first call, we don't need the group name */
-+ status = getpwent_next_nis_netgr (NULL, pw, ent, NULL, buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ return getpwent_next_file (pw, ent, buffer, buflen);
-+ else
-+ return status;
-+ }
-+ else
-+ if (ent->nis)
-+ {
-+ return getpwent_next_nis (pw, ent, buffer, buflen);
-+ }
-+ else
-+ return getpwent_next_file (pw, ent, buffer, buflen);
-+}
-+
-+enum nss_status
-+_nss_compat_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ __libc_lock_lock (lock);
-+
-+ /* Be prepared that the setpwent function was not called before. */
-+ if (ext_ent.stream == NULL)
-+ status = internal_setpwent (&ext_ent);
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ status = internal_getpwent_r (pwd, &ext_ent, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+/* Searches in /etc/passwd and the NIS/NIS+ map for a special user */
-+static enum nss_status
-+internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+
-+ while (1)
-+ {
-+ fpos_t pos;
-+ char *p;
-+ int parse_res;
-+
-+ do
-+ {
-+ fgetpos (ent->stream, &pos);
-+ buffer[buflen - 1] = '\xff';
-+ p = fgets (buffer, buflen, ent->stream);
-+ if (p == NULL && feof (ent->stream))
-+ return NSS_STATUS_NOTFOUND;
-+ if (p == NULL || buffer[buflen - 1] != '\xff')
-+ {
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Terminate the line for any case. */
-+ buffer[buflen - 1] = '\0';
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+ }
-+ while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
-+ /* Parse the line. If it is invalid, loop to
-+ get the next line of the file to parse. */
-+ !(parse_res = _nss_files_parse_pwent (p, result, data, buflen)));
-+
-+ if (parse_res == -1)
-+ {
-+ /* The parser ran out of space. */
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* This is a real entry. */
-+ if (result->pw_name[0] != '+' && result->pw_name[0] != '-')
-+ {
-+ if (strcmp (result->pw_name, name) == 0)
-+ return NSS_STATUS_SUCCESS;
-+ else
-+ continue;
-+ }
-+
-+ /* -@netgroup */
-+ if (result->pw_name[0] == '-' && result->pw_name[1] == '@'
-+ && result->pw_name[2] != '\0')
-+ {
-+ char buf2[1024];
-+ char *user, *host, *domain;
-+ struct __netgrent netgrdata;
-+
-+ bzero (&netgrdata, sizeof (struct __netgrent));
-+ __internal_setnetgrent (&result->pw_name[2], &netgrdata);
-+ while (__internal_getnetgrent_r (&host, &user, &domain,
-+ &netgrdata, buf2, sizeof (buf2),
-+ &errno))
-+ {
-+ if (user != NULL && user[0] != '-')
-+ if (strcmp (user, name) == 0)
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+ __internal_endnetgrent (&netgrdata);
-+ continue;
-+ }
-+
-+ /* +@netgroup */
-+ if (result->pw_name[0] == '+' && result->pw_name[1] == '@'
-+ && result->pw_name[2] != '\0')
-+ {
-+ char buf[strlen (result->pw_name)];
-+ int status;
-+
-+ strcpy (buf, &result->pw_name[2]);
-+ ent->netgroup = TRUE;
-+ ent->first = TRUE;
-+ copy_pwd_changes (&ent->pwd, result, NULL, 0);
-+
-+ do
-+ {
-+ status = getpwent_next_nis_netgr (name, result, ent, buf,
-+ buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ continue;
-+
-+ if (status == NSS_STATUS_SUCCESS &&
-+ strcmp (result->pw_name, name) == 0)
-+ return NSS_STATUS_SUCCESS;
-+ } while (status == NSS_STATUS_SUCCESS);
-+ continue;
-+ }
-+
-+ /* -user */
-+ if (result->pw_name[0] == '-' && result->pw_name[1] != '\0'
-+ && result->pw_name[1] != '@')
-+ {
-+ if (strcmp (&result->pw_name[1], name) == 0)
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ continue;
-+ }
-+
-+ /* +user */
-+ if (result->pw_name[0] == '+' && result->pw_name[1] != '\0'
-+ && result->pw_name[1] != '@')
-+ {
-+ if (strcmp (name, &result->pw_name[1]) == 0)
-+ {
-+ enum nss_status status;
-+
-+ status = getpwnam_plususer (name, result, buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ /* We couldn't parse the entry */
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ return status;
-+ }
-+ }
-+
-+ /* +:... */
-+ if (result->pw_name[0] == '+' && result->pw_name[1] == '\0')
-+ {
-+ enum nss_status status;
-+
-+ status = getpwnam_plususer (name, result, buffer, buflen);
-+ if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
-+ break;
-+ else
-+ if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ return status;
-+ }
-+ }
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
-+ char *buffer, size_t buflen)
-+{
-+ ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
-+ {NULL, NULL, 0, 0, NULL, NULL, NULL}};
-+ enum nss_status status;
-+
-+ if (name[0] == '-' || name[0] == '+')
-+ return NSS_STATUS_NOTFOUND;
-+
-+ status = internal_setpwent (&ent);
-+ if (status != NSS_STATUS_SUCCESS)
-+ return status;
-+
-+ status = internal_getpwnam_r (name, pwd, &ent, buffer, buflen);
-+
-+ internal_endpwent (&ent);
-+
-+ return status;
-+}
-+
-+/* This function handle the + entry in /etc/passwd for getpwuid */
-+static enum nss_status
-+getpwuid_plususer (uid_t uid, struct passwd *result, char *buffer,
-+ size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ struct passwd pwd;
-+ int parse_res;
-+ char *p;
-+ size_t plen;
-+ char buf[1024];
-+ char *domain, *outval, *ptr;
-+ int outvallen;
-+
-+ memset (&pwd, '\0', sizeof (struct passwd));
-+
-+ copy_pwd_changes (&pwd, result, NULL, 0);
-+
-+ plen = pwd_need_buflen (&pwd);
-+ if (plen > buflen)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ p = buffer + (buflen - plen);
-+ buflen -= plen;
-+
-+
-+ if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-+ return NSS_STATUS_TRYAGAIN;
-+
-+ sprintf (buf, "%d", uid);
-+ if (yp_match (domain, "passwd.byuid", buf, strlen (buf),
-+ &outval, &outvallen)
-+ != YPERR_SUCCESS)
-+ return NSS_STATUS_TRYAGAIN;
-+ ptr = strncpy (buffer, outval, buflen < (size_t) outvallen ?
-+ buflen : (size_t) outvallen);
-+ buffer[buflen < (size_t) outvallen ? buflen : (size_t) outvallen] = '\0';
-+ free (outval);
-+ while (isspace (*ptr))
-+ ptr++;
-+ if ((parse_res = _nss_files_parse_pwent (ptr, result, data, buflen))
-+ == -1)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (parse_res > 0)
-+ {
-+ copy_pwd_changes (result, &pwd, p, plen);
-+ give_pwd_free (&pwd);
-+ /* We found the entry. */
-+ return NSS_STATUS_SUCCESS;
-+ }
-+ else
-+ {
-+ /* Give buffer the old len back */
-+ buflen += plen;
-+ give_pwd_free (&pwd);
-+ }
-+ return NSS_STATUS_RETURN;
-+}
-+
-+/* Searches in /etc/passwd and the NIS/NIS+ map for a special user id */
-+static enum nss_status
-+internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+
-+ while (1)
-+ {
-+ fpos_t pos;
-+ char *p;
-+ int parse_res;
-+
-+ do
-+ {
-+ fgetpos (ent->stream, &pos);
-+ buffer[buflen - 1] = '\xff';
-+ p = fgets (buffer, buflen, ent->stream);
-+ if (p == NULL && feof (ent->stream))
-+ return NSS_STATUS_NOTFOUND;
-+ if (p == NULL || buffer[buflen - 1] != '\xff')
-+ {
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Terminate the line for any case. */
-+ buffer[buflen - 1] = '\0';
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+ }
-+ while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
-+ /* Parse the line. If it is invalid, loop to
-+ get the next line of the file to parse. */
-+ !(parse_res = _nss_files_parse_pwent (p, result, data, buflen)));
-+
-+ if (parse_res == -1)
-+ {
-+ /* The parser ran out of space. */
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* This is a real entry. */
-+ if (result->pw_name[0] != '+' && result->pw_name[0] != '-')
-+ {
-+ if (result->pw_uid == uid)
-+ return NSS_STATUS_SUCCESS;
-+ else
-+ continue;
-+ }
-+
-+ /* -@netgroup */
-+ if (result->pw_name[0] == '-' && result->pw_name[1] == '@'
-+ && result->pw_name[2] != '\0')
-+ {
-+ char buf2[1024];
-+ char *user, *host, *domain;
-+ struct __netgrent netgrdata;
-+
-+ bzero (&netgrdata, sizeof (struct __netgrent));
-+ __internal_setnetgrent (&result->pw_name[2], &netgrdata);
-+ while (__internal_getnetgrent_r (&host, &user, &domain,
-+ &netgrdata, buf2, sizeof (buf2),
-+ &errno))
-+ {
-+ if (user != NULL && user[0] != '-')
-+ blacklist_store_name (user, ent);
-+ }
-+ __internal_endnetgrent (&netgrdata);
-+ continue;
-+ }
-+
-+ /* +@netgroup */
-+ if (result->pw_name[0] == '+' && result->pw_name[1] == '@'
-+ && result->pw_name[2] != '\0')
-+ {
-+ char buf[strlen (result->pw_name)];
-+ int status;
-+
-+ strcpy (buf, &result->pw_name[2]);
-+ ent->netgroup = TRUE;
-+ ent->first = TRUE;
-+ copy_pwd_changes (&ent->pwd, result, NULL, 0);
-+
-+ do
-+ {
-+ status = getpwent_next_nis_netgr (NULL, result, ent, buf,
-+ buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ continue;
-+
-+ if (status == NSS_STATUS_SUCCESS && uid == result->pw_uid)
-+ return NSS_STATUS_SUCCESS;
-+ } while (status == NSS_STATUS_SUCCESS);
-+ continue;
-+ }
-+
-+ /* -user */
-+ if (result->pw_name[0] == '-' && result->pw_name[1] != '\0'
-+ && result->pw_name[1] != '@')
-+ {
-+ blacklist_store_name (&result->pw_name[1], ent);
-+ continue;
-+ }
-+
-+ /* +user */
-+ if (result->pw_name[0] == '+' && result->pw_name[1] != '\0'
-+ && result->pw_name[1] != '@')
-+ {
-+ enum nss_status status;
-+
-+ /* Store the User in the blacklist for the "+" at the end of
-+ /etc/passwd */
-+ blacklist_store_name (&result->pw_name[1], ent);
-+ status = getpwnam_plususer (&result->pw_name[1], result, buffer,
-+ buflen);
-+ if (status == NSS_STATUS_SUCCESS && result->pw_uid == uid)
-+ break;
-+ else
-+ continue;
-+ }
-+
-+ /* +:... */
-+ if (result->pw_name[0] == '+' && result->pw_name[1] == '\0')
-+ {
-+ enum nss_status status;
-+
-+ status = getpwuid_plususer (uid, result, buffer, buflen);
-+ if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
-+ break;
-+ else
-+ if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ {
-+ if (status == NSS_STATUS_TRYAGAIN)
-+ /* The parser ran out of space */
-+ fsetpos (ent->stream, &pos);
-+ return status;
-+ }
-+ }
-+ }
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
-+ char *buffer, size_t buflen)
-+{
-+ ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
-+ {NULL, NULL, 0, 0, NULL, NULL, NULL}};
-+ enum nss_status status;
-+
-+ status = internal_setpwent (&ent);
-+ if (status != NSS_STATUS_SUCCESS)
-+ return status;
-+
-+ status = internal_getpwuid_r (uid, pwd, &ent, buffer, buflen);
-+
-+ internal_endpwent (&ent);
-+
-+ return status;
-+}
-+
-+
-+/* Support routines for remembering -@netgroup and -user entries.
-+ The names are stored in a single string with `|' as separator. */
-+static void
-+blacklist_store_name (const char *name, ent_t *ent)
-+{
-+ int namelen = strlen (name);
-+ char *tmp;
-+
-+ /* first call, setup cache */
-+ if (ent->blacklist.size == 0)
-+ {
-+ ent->blacklist.size = MAX (BLACKLIST_INITIAL_SIZE, 2 * namelen);
-+ ent->blacklist.data = malloc (ent->blacklist.size);
-+ if (ent->blacklist.data == NULL)
-+ return;
-+ ent->blacklist.data[0] = '|';
-+ ent->blacklist.data[1] = '\0';
-+ ent->blacklist.current = 1;
-+ }
-+ else
-+ {
-+ if (in_blacklist (name, namelen, ent))
-+ return; /* no duplicates */
-+
-+ if (ent->blacklist.current + namelen + 1 >= ent->blacklist.size)
-+ {
-+ ent->blacklist.size += MAX (BLACKLIST_INCREMENT, 2 * namelen);
-+ tmp = realloc (ent->blacklist.data, ent->blacklist.size);
-+ if (tmp == NULL)
-+ {
-+ free (ent->blacklist.data);
-+ ent->blacklist.size = 0;
-+ return;
-+ }
-+ ent->blacklist.data = tmp;
-+ }
-+ }
-+
-+ tmp = stpcpy (ent->blacklist.data + ent->blacklist.current, name);
-+ *tmp++ = '|';
-+ *tmp = '\0';
-+ ent->blacklist.current += namelen + 1;
-+
-+ return;
-+}
-+
-+/* returns TRUE if ent->blacklist contains name, else FALSE */
-+static bool_t
-+in_blacklist (const char *name, int namelen, ent_t *ent)
-+{
-+ char buf[namelen + 3];
-+ char *cp;
-+
-+ if (ent->blacklist.data == NULL)
-+ return FALSE;
-+
-+ buf[0] = '|';
-+ cp = stpcpy (&buf[1], name);
-+ *cp++= '|';
-+ *cp = '\0';
-+ return strstr (ent->blacklist.data, buf) != NULL;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_compat/compat-spwd.c glibc-2.1.3/glibc-compat/nss_compat/compat-spwd.c
---- ../glibc-2.1.3/glibc-compat/nss_compat/compat-spwd.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_compat/compat-spwd.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,915 @@
-+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <errno.h>
-+#include <ctype.h>
-+#include <fcntl.h>
-+#include <netdb.h>
-+#include <shadow.h>
-+#include <string.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+#include <nsswitch.h>
-+
-+#include "netgroup.h"
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME spent
-+#define STRUCTURE spwd
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+/* Structure for remembering -@netgroup and -user members ... */
-+#define BLACKLIST_INITIAL_SIZE 512
-+#define BLACKLIST_INCREMENT 256
-+struct blacklist_t
-+ {
-+ char *data;
-+ int current;
-+ int size;
-+ };
-+
-+struct ent_t
-+ {
-+ bool_t netgroup;
-+ bool_t nis;
-+ bool_t first;
-+ char *oldkey;
-+ int oldkeylen;
-+ FILE *stream;
-+ struct blacklist_t blacklist;
-+ struct spwd pwd;
-+ struct __netgrent netgrdata;
-+ };
-+typedef struct ent_t ent_t;
-+
-+static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
-+ {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
-+
-+/* Protect global state against multiple changers. */
-+__libc_lock_define_initialized (static, lock)
-+
-+/* Prototypes for local functions. */
-+static void blacklist_store_name (const char *, ent_t *);
-+static int in_blacklist (const char *, int, ent_t *);
-+
-+static void
-+give_spwd_free (struct spwd *pwd)
-+{
-+ if (pwd->sp_namp != NULL)
-+ free (pwd->sp_namp);
-+ if (pwd->sp_pwdp != NULL)
-+ free (pwd->sp_pwdp);
-+
-+ memset (pwd, '\0', sizeof (struct spwd));
-+}
-+
-+static int
-+spwd_need_buflen (struct spwd *pwd)
-+{
-+ int len = 0;
-+
-+ if (pwd->sp_pwdp != NULL)
-+ len += strlen (pwd->sp_pwdp) + 1;
-+
-+ return len;
-+}
-+
-+static void
-+copy_spwd_changes (struct spwd *dest, struct spwd *src,
-+ char *buffer, size_t buflen)
-+{
-+ if (src->sp_pwdp != NULL && strlen (src->sp_pwdp))
-+ {
-+ if (buffer == NULL)
-+ dest->sp_pwdp = strdup (src->sp_pwdp);
-+ else if (dest->sp_pwdp &&
-+ strlen (dest->sp_pwdp) >= strlen (src->sp_pwdp))
-+ strcpy (dest->sp_pwdp, src->sp_pwdp);
-+ else
-+ {
-+ dest->sp_pwdp = buffer;
-+ strcpy (dest->sp_pwdp, src->sp_pwdp);
-+ buffer += strlen (dest->sp_pwdp) + 1;
-+ buflen = buflen - (strlen (dest->sp_pwdp) + 1);
-+ }
-+ }
-+ if (src->sp_lstchg != 0)
-+ dest->sp_lstchg = src->sp_lstchg;
-+ if (src->sp_min != 0)
-+ dest->sp_min = src->sp_min;
-+ if (src->sp_max != 0)
-+ dest->sp_max = src->sp_max;
-+ if (src->sp_warn != 0)
-+ dest->sp_warn = src->sp_warn;
-+ if (src->sp_inact != 0)
-+ dest->sp_inact = src->sp_inact;
-+ if (src->sp_expire != 0)
-+ dest->sp_expire = src->sp_expire;
-+ if (src->sp_flag != 0)
-+ dest->sp_flag = src->sp_flag;
-+}
-+
-+static enum nss_status
-+internal_setspent (ent_t *ent)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ ent->nis = ent->first = ent->netgroup = 0;
-+
-+ /* If something was left over free it. */
-+ if (ent->netgroup)
-+ __internal_endnetgrent (&ent->netgrdata);
-+
-+ if (ent->oldkey != NULL)
-+ {
-+ free (ent->oldkey);
-+ ent->oldkey = NULL;
-+ ent->oldkeylen = 0;
-+ }
-+
-+ if (ent->blacklist.data != NULL)
-+ {
-+ ent->blacklist.current = 1;
-+ ent->blacklist.data[0] = '|';
-+ ent->blacklist.data[1] = '\0';
-+ }
-+ else
-+ ent->blacklist.current = 0;
-+
-+ if (ent->stream == NULL)
-+ {
-+ ent->stream = fopen ("/etc/shadow", "r");
-+
-+ if (ent->stream == NULL)
-+ status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-+ else
-+ {
-+ /* We have to make sure the file is `closed on exec'. */
-+ int result, flags;
-+
-+ result = flags = fcntl (fileno (ent->stream), F_GETFD, 0);
-+ if (result >= 0)
-+ {
-+ flags |= FD_CLOEXEC;
-+ result = fcntl (fileno (ent->stream), F_SETFD, flags);
-+ }
-+ if (result < 0)
-+ {
-+ /* Something went wrong. Close the stream and return a
-+ failure. */
-+ fclose (ent->stream);
-+ ent->stream = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ }
-+ }
-+ else
-+ rewind (ent->stream);
-+
-+ give_spwd_free (&ent->pwd);
-+
-+ return status;
-+}
-+
-+
-+enum nss_status
-+_nss_compat_setspent (void)
-+{
-+ enum nss_status result;
-+
-+ __libc_lock_lock (lock);
-+
-+ result = internal_setspent (&ext_ent);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return result;
-+}
-+
-+
-+static enum nss_status
-+internal_endspent (ent_t *ent)
-+{
-+ if (ent->stream != NULL)
-+ {
-+ fclose (ent->stream);
-+ ent->stream = NULL;
-+ }
-+
-+ if (ent->netgroup)
-+ __internal_endnetgrent (&ent->netgrdata);
-+
-+ ent->nis = ent->first = ent->netgroup = 0;
-+
-+ if (ent->oldkey != NULL)
-+ {
-+ free (ent->oldkey);
-+ ent->oldkey = NULL;
-+ ent->oldkeylen = 0;
-+ }
-+
-+ if (ent->blacklist.data != NULL)
-+ {
-+ ent->blacklist.current = 1;
-+ ent->blacklist.data[0] = '|';
-+ ent->blacklist.data[1] = '\0';
-+ }
-+ else
-+ ent->blacklist.current = 0;
-+
-+ give_spwd_free (&ent->pwd);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_compat_endspent (void)
-+{
-+ enum nss_status result;
-+
-+ __libc_lock_lock (lock);
-+
-+ result = internal_endspent (&ext_ent);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return result;
-+}
-+
-+
-+static enum nss_status
-+getspent_next_nis_netgr (const char *name, struct spwd *result, ent_t *ent,
-+ char *group, char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *ypdomain, *host, *user, *domain, *outval, *p, *p2;
-+ int status, outvallen;
-+ size_t p2len;
-+
-+ if (yp_get_default_domain (&ypdomain) != YPERR_SUCCESS)
-+ {
-+ ent->netgroup = 0;
-+ ent->first = 0;
-+ give_spwd_free (&ent->pwd);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (ent->first == TRUE)
-+ {
-+ bzero (&ent->netgrdata, sizeof (struct __netgrent));
-+ __internal_setnetgrent (group, &ent->netgrdata);
-+ ent->first = FALSE;
-+ }
-+
-+ while (1)
-+ {
-+ char *saved_cursor;
-+ int parse_res;
-+
-+ saved_cursor = ent->netgrdata.cursor;
-+ status = __internal_getnetgrent_r (&host, &user, &domain,
-+ &ent->netgrdata, buffer, buflen,
-+ &errno);
-+ if (status != 1)
-+ {
-+ __internal_endnetgrent (&ent->netgrdata);
-+ ent->netgroup = 0;
-+ give_spwd_free (&ent->pwd);
-+ return NSS_STATUS_RETURN;
-+ }
-+
-+ if (user == NULL || user[0] == '-')
-+ continue;
-+
-+ if (domain != NULL && strcmp (ypdomain, domain) != 0)
-+ continue;
-+
-+ /* If name != NULL, we are called from getpwnam */
-+ if (name != NULL)
-+ if (strcmp (user, name) != 0)
-+ continue;
-+
-+ if (yp_match (ypdomain, "shadow.byname", user,
-+ strlen (user), &outval, &outvallen)
-+ != YPERR_SUCCESS)
-+ continue;
-+
-+ p2len = spwd_need_buflen (&ent->pwd);
-+ if (p2len > buflen)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ p2 = buffer + (buflen - p2len);
-+ buflen -= p2len;
-+ p = strncpy (buffer, outval, buflen);
-+ while (isspace (*p))
-+ p++;
-+ free (outval);
-+ if ((parse_res = _nss_files_parse_spent (p, result, data, buflen)) == -1)
-+ {
-+ ent->netgrdata.cursor = saved_cursor;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (parse_res)
-+ {
-+ /* Store the User in the blacklist for the "+" at the end of
-+ /etc/passwd */
-+ blacklist_store_name (result->sp_namp, ent);
-+ copy_spwd_changes (result, &ent->pwd, p2, p2len);
-+ break;
-+ }
-+ }
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+getspent_next_nis (struct spwd *result, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *domain, *outkey, *outval, *p, *p2;
-+ int outkeylen, outvallen, parse_res;
-+ size_t p2len;
-+
-+ if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-+ {
-+ ent->nis = 0;
-+ give_spwd_free (&ent->pwd);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ p2len = spwd_need_buflen (&ent->pwd);
-+ if (p2len > buflen)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ p2 = buffer + (buflen - p2len);
-+ buflen -= p2len;
-+ do
-+ {
-+ bool_t saved_first;
-+ char *saved_oldkey;
-+ int saved_oldlen;
-+
-+ if (ent->first)
-+ {
-+ if (yp_first (domain, "shadow.byname", &outkey, &outkeylen,
-+ &outval, &outvallen) != YPERR_SUCCESS)
-+ {
-+ ent->nis = 0;
-+ give_spwd_free (&ent->pwd);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+ saved_first = TRUE;
-+ saved_oldkey = ent->oldkey;
-+ saved_oldlen = ent->oldkeylen;
-+ ent->oldkey = outkey;
-+ ent->oldkeylen = outkeylen;
-+ ent->first = FALSE;
-+ }
-+ else
-+ {
-+ if (yp_next (domain, "shadow.byname", ent->oldkey, ent->oldkeylen,
-+ &outkey, &outkeylen, &outval, &outvallen)
-+ != YPERR_SUCCESS)
-+ {
-+ ent->nis = 0;
-+ give_spwd_free (&ent->pwd);
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+
-+ saved_first = FALSE;
-+ saved_oldkey = ent->oldkey;
-+ saved_oldlen = ent->oldkeylen;
-+ ent->oldkey = outkey;
-+ ent->oldkeylen = outkeylen;
-+ }
-+
-+ /* Copy the found data to our buffer */
-+ p = strncpy (buffer, outval, buflen);
-+
-+ /* ...and free the data. */
-+ free (outval);
-+
-+ while (isspace (*p))
-+ ++p;
-+ if ((parse_res = _nss_files_parse_spent (p, result, data, buflen)) == -1)
-+ {
-+ free (ent->oldkey);
-+ ent->oldkey = saved_oldkey;
-+ ent->oldkeylen = saved_oldlen;
-+ ent->first = saved_first;
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ else
-+ {
-+ if (!saved_first)
-+ free (saved_oldkey);
-+ }
-+ if (parse_res &&
-+ in_blacklist (result->sp_namp, strlen (result->sp_namp), ent))
-+ parse_res = 0;
-+ }
-+ while (!parse_res);
-+
-+ copy_spwd_changes (result, &ent->pwd, p2, p2len);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+/* This function handle the +user entrys in /etc/shadow */
-+static enum nss_status
-+getspnam_plususer (const char *name, struct spwd *result, char *buffer,
-+ size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ struct spwd pwd;
-+ int parse_res;
-+ char *p;
-+ size_t plen;
-+ char *domain, *outval, *ptr;
-+ int outvallen;
-+
-+
-+ memset (&pwd, '\0', sizeof (struct spwd));
-+
-+ copy_spwd_changes (&pwd, result, NULL, 0);
-+
-+ plen = spwd_need_buflen (&pwd);
-+ if (plen > buflen)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ p = buffer + (buflen - plen);
-+ buflen -= plen;
-+
-+ if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ if (yp_match (domain, "shadow.byname", name, strlen (name),
-+ &outval, &outvallen) != YPERR_SUCCESS)
-+ return NSS_STATUS_NOTFOUND;
-+ ptr = strncpy (buffer, outval, buflen < (size_t) outvallen ?
-+ buflen : (size_t) outvallen);
-+ buffer[buflen < (size_t) outvallen ? buflen : (size_t) outvallen] = '\0';
-+ free (outval);
-+ while (isspace (*ptr))
-+ ptr++;
-+ if ((parse_res = _nss_files_parse_spent (ptr, result, data, buflen)) == -1)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (parse_res)
-+ {
-+ copy_spwd_changes (result, &pwd, p, plen);
-+ give_spwd_free (&pwd);
-+ /* We found the entry. */
-+ return NSS_STATUS_SUCCESS;
-+ }
-+ else
-+ {
-+ /* Give buffer the old len back */
-+ buflen += plen;
-+ give_spwd_free (&pwd);
-+ }
-+ return NSS_STATUS_RETURN;
-+}
-+
-+static enum nss_status
-+getspent_next_file (struct spwd *result, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ while (1)
-+ {
-+ fpos_t pos;
-+ int parse_res = 0;
-+ char *p;
-+
-+ do
-+ {
-+ fgetpos (ent->stream, &pos);
-+ buffer[buflen - 1] = '\xff';
-+ p = fgets (buffer, buflen, ent->stream);
-+ if (p == NULL && feof (ent->stream))
-+ return NSS_STATUS_NOTFOUND;
-+ if (p == NULL || buffer[buflen - 1] != '\xff')
-+ {
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Terminate the line for any case. */
-+ buffer[buflen - 1] = '\0';
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+ }
-+ while (*p == '\0' || *p == '#' /* Ignore empty and comment lines. */
-+ /* Parse the line. If it is invalid, loop to
-+ get the next line of the file to parse. */
-+ || !(parse_res = _nss_files_parse_spent (p, result, data,
-+ buflen)));
-+
-+ if (parse_res == -1)
-+ {
-+ /* The parser ran out of space. */
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (result->sp_namp[0] != '+' && result->sp_namp[0] != '-')
-+ /* This is a real entry. */
-+ break;
-+
-+ /* -@netgroup */
-+ if (result->sp_namp[0] == '-' && result->sp_namp[1] == '@'
-+ && result->sp_namp[2] != '\0')
-+ {
-+ char buf2[1024];
-+ char *user, *host, *domain;
-+ struct __netgrent netgrdata;
-+
-+ bzero (&netgrdata, sizeof (struct __netgrent));
-+ __internal_setnetgrent (&result->sp_namp[2], &netgrdata);
-+ while (__internal_getnetgrent_r (&host, &user, &domain,
-+ &netgrdata, buf2, sizeof (buf2),
-+ &errno))
-+ {
-+ if (user != NULL && user[0] != '-')
-+ blacklist_store_name (user, ent);
-+ }
-+ __internal_endnetgrent (&netgrdata);
-+ continue;
-+ }
-+
-+ /* +@netgroup */
-+ if (result->sp_namp[0] == '+' && result->sp_namp[1] == '@'
-+ && result->sp_namp[2] != '\0')
-+ {
-+ int status;
-+
-+ ent->netgroup = TRUE;
-+ ent->first = TRUE;
-+ copy_spwd_changes (&ent->pwd, result, NULL, 0);
-+
-+ status = getspent_next_nis_netgr (NULL, result, ent,
-+ &result->sp_namp[2],
-+ buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ continue;
-+ else
-+ return status;
-+ }
-+
-+ /* -user */
-+ if (result->sp_namp[0] == '-' && result->sp_namp[1] != '\0'
-+ && result->sp_namp[1] != '@')
-+ {
-+ blacklist_store_name (&result->sp_namp[1], ent);
-+ continue;
-+ }
-+
-+ /* +user */
-+ if (result->sp_namp[0] == '+' && result->sp_namp[1] != '\0'
-+ && result->sp_namp[1] != '@')
-+ {
-+ enum nss_status status;
-+
-+ /* Store the User in the blacklist for the "+" at the end of
-+ /etc/passwd */
-+ blacklist_store_name (&result->sp_namp[1], ent);
-+ status = getspnam_plususer (&result->sp_namp[1], result, buffer,
-+ buflen);
-+ if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
-+ break;
-+ else
-+ if (status == NSS_STATUS_RETURN /* We couldn't parse the entry */
-+ || status == NSS_STATUS_NOTFOUND) /* entry doesn't exist */
-+ continue;
-+ else
-+ {
-+ if (status == NSS_STATUS_TRYAGAIN)
-+ fsetpos (ent->stream, &pos);
-+ return status;
-+ }
-+ }
-+
-+ /* +:... */
-+ if (result->sp_namp[0] == '+' && result->sp_namp[1] == '\0')
-+ {
-+ ent->nis = TRUE;
-+ ent->first = TRUE;
-+ copy_spwd_changes (&ent->pwd, result, NULL, 0);
-+
-+ return getspent_next_nis (result, ent, buffer, buflen);
-+ }
-+ }
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+
-+static enum nss_status
-+internal_getspent_r (struct spwd *pw, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ if (ent->netgroup)
-+ {
-+ int status;
-+
-+ /* We are searching members in a netgroup */
-+ /* Since this is not the first call, we don't need the group name */
-+ status = getspent_next_nis_netgr (NULL, pw, ent, NULL, buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ return getspent_next_file (pw, ent, buffer, buflen);
-+ else
-+ return status;
-+ }
-+ else
-+ if (ent->nis)
-+ {
-+ return getspent_next_nis (pw, ent, buffer, buflen);
-+ }
-+ else
-+ return getspent_next_file (pw, ent, buffer, buflen);
-+}
-+
-+enum nss_status
-+_nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ __libc_lock_lock (lock);
-+
-+ if (ext_ent.stream == NULL)
-+ status = internal_setspent (&ext_ent);
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ status = internal_getspent_r (pwd, &ext_ent, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+/* Searches in /etc/passwd and the NIS/NIS+ map for a special user */
-+static enum nss_status
-+internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+
-+ while (1)
-+ {
-+ fpos_t pos;
-+ char *p;
-+ int parse_res;
-+
-+ do
-+ {
-+ fgetpos (ent->stream, &pos);
-+ buffer[buflen - 1] = '\xff';
-+ p = fgets (buffer, buflen, ent->stream);
-+ if (p == NULL && feof (ent->stream))
-+ return NSS_STATUS_NOTFOUND;
-+ if (p == NULL || buffer[buflen - 1] != '\xff')
-+ {
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Terminate the line for any case. */
-+ buffer[buflen - 1] = '\0';
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+ }
-+ while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
-+ /* Parse the line. If it is invalid, loop to
-+ get the next line of the file to parse. */
-+ !(parse_res = _nss_files_parse_spent (p, result, data, buflen)));
-+
-+ if (parse_res == -1)
-+ {
-+ /* The parser ran out of space. */
-+ fsetpos (ent->stream, &pos);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* This is a real entry. */
-+ if (result->sp_namp[0] != '+' && result->sp_namp[0] != '-')
-+ {
-+ if (strcmp (result->sp_namp, name) == 0)
-+ return NSS_STATUS_SUCCESS;
-+ else
-+ continue;
-+ }
-+
-+ /* -@netgroup */
-+ if (result->sp_namp[0] == '-' && result->sp_namp[1] == '@'
-+ && result->sp_namp[2] != '\0')
-+ {
-+ char buf2[1024];
-+ char *user, *host, *domain;
-+ struct __netgrent netgrdata;
-+
-+ bzero (&netgrdata, sizeof (struct __netgrent));
-+ __internal_setnetgrent (&result->sp_namp[2], &netgrdata);
-+ while (__internal_getnetgrent_r (&host, &user, &domain,
-+ &netgrdata, buf2, sizeof (buf2),
-+ &errno))
-+ {
-+ if (user != NULL && user[0] != '-')
-+ if (strcmp (user, name) == 0)
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+ __internal_endnetgrent (&netgrdata);
-+ continue;
-+ }
-+
-+ /* +@netgroup */
-+ if (result->sp_namp[0] == '+' && result->sp_namp[1] == '@'
-+ && result->sp_namp[2] != '\0')
-+ {
-+ char buf[strlen (result->sp_namp)];
-+ int status;
-+
-+ strcpy (buf, &result->sp_namp[2]);
-+ ent->netgroup = TRUE;
-+ ent->first = TRUE;
-+ copy_spwd_changes (&ent->pwd, result, NULL, 0);
-+
-+ do
-+ {
-+ status = getspent_next_nis_netgr (name, result, ent, buf,
-+ buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ continue;
-+
-+ if (status == NSS_STATUS_SUCCESS &&
-+ strcmp (result->sp_namp, name) == 0)
-+ return NSS_STATUS_SUCCESS;
-+ } while (status == NSS_STATUS_SUCCESS);
-+ continue;
-+ }
-+
-+ /* -user */
-+ if (result->sp_namp[0] == '-' && result->sp_namp[1] != '\0'
-+ && result->sp_namp[1] != '@')
-+ {
-+ if (strcmp (&result->sp_namp[1], name) == 0)
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ continue;
-+ }
-+
-+ /* +user */
-+ if (result->sp_namp[0] == '+' && result->sp_namp[1] != '\0'
-+ && result->sp_namp[1] != '@')
-+ {
-+ if (strcmp (name, &result->sp_namp[1]) == 0)
-+ {
-+ enum nss_status status;
-+
-+ status = getspnam_plususer (name, result, buffer, buflen);
-+ if (status == NSS_STATUS_RETURN)
-+ /* We couldn't parse the entry */
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ return status;
-+ }
-+ }
-+
-+ /* +:... */
-+ if (result->sp_namp[0] == '+' && result->sp_namp[1] == '\0')
-+ {
-+ enum nss_status status;
-+
-+ status = getspnam_plususer (name, result, buffer, buflen);
-+ if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ return status;
-+ }
-+ }
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_compat_getspnam_r (const char *name, struct spwd *pwd,
-+ char *buffer, size_t buflen)
-+{
-+ ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
-+ {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
-+ enum nss_status status;
-+
-+ if (name[0] == '-' || name[0] == '+')
-+ return NSS_STATUS_NOTFOUND;
-+
-+ status = internal_setspent (&ent);
-+ if (status != NSS_STATUS_SUCCESS)
-+ return status;
-+
-+ status = internal_getspnam_r (name, pwd, &ent, buffer, buflen);
-+
-+ internal_endspent (&ent);
-+
-+ return status;
-+}
-+
-+/* Support routines for remembering -@netgroup and -user entries.
-+ The names are stored in a single string with `|' as separator. */
-+static void
-+blacklist_store_name (const char *name, ent_t *ent)
-+{
-+ int namelen = strlen (name);
-+ char *tmp;
-+
-+ /* first call, setup cache */
-+ if (ent->blacklist.size == 0)
-+ {
-+ ent->blacklist.size = MAX (BLACKLIST_INITIAL_SIZE, 2 * namelen);
-+ ent->blacklist.data = malloc (ent->blacklist.size);
-+ if (ent->blacklist.data == NULL)
-+ return;
-+ ent->blacklist.data[0] = '|';
-+ ent->blacklist.data[1] = '\0';
-+ ent->blacklist.current = 1;
-+ }
-+ else
-+ {
-+ if (in_blacklist (name, namelen, ent))
-+ return; /* no duplicates */
-+
-+ if (ent->blacklist.current + namelen + 1 >= ent->blacklist.size)
-+ {
-+ ent->blacklist.size += MAX (BLACKLIST_INCREMENT, 2 * namelen);
-+ tmp = realloc (ent->blacklist.data, ent->blacklist.size);
-+ if (tmp == NULL)
-+ {
-+ free (ent->blacklist.data);
-+ ent->blacklist.size = 0;
-+ return;
-+ }
-+ ent->blacklist.data = tmp;
-+ }
-+ }
-+
-+ tmp = stpcpy (ent->blacklist.data + ent->blacklist.current, name);
-+ *tmp++ = '|';
-+ *tmp = '\0';
-+ ent->blacklist.current += namelen + 1;
-+
-+ return;
-+}
-+
-+/* Returns TRUE if ent->blacklist contains name, else FALSE. */
-+static bool_t
-+in_blacklist (const char *name, int namelen, ent_t *ent)
-+{
-+ char buf[namelen + 3];
-+ char *cp;
-+
-+ if (ent->blacklist.data == NULL)
-+ return FALSE;
-+
-+ buf[0] = '|';
-+ cp = stpcpy (&buf[1], name);
-+ *cp++= '|';
-+ *cp = '\0';
-+ return strstr (ent->blacklist.data, buf) != NULL;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_db/db-XXX.c glibc-2.1.3/glibc-compat/nss_db/db-XXX.c
---- ../glibc-2.1.3/glibc-compat/nss_db/db-XXX.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_db/db-XXX.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,288 @@
-+/* Common code for DB-based databases in nss_db module.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <db_185.h>
-+#include <fcntl.h>
-+#include <bits/libc-lock.h>
-+#include "nsswitch.h"
-+
-+/* These symbols are defined by the including source file:
-+
-+ ENTNAME -- database name of the structure and functions (hostent, pwent).
-+ STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
-+ DATABASE -- database file name, ("hosts", "passwd")
-+
-+ NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
-+*/
-+
-+#define ENTNAME_r CONCAT(ENTNAME,_r)
-+
-+#include <paths.h>
-+#define DBFILE _PATH_VARDB DATABASE ".db"
-+
-+#ifdef NEED_H_ERRNO
-+#define H_ERRNO_PROTO , int *herrnop
-+#define H_ERRNO_ARG , herrnop
-+#define H_ERRNO_SET(val) (*herrnop = (val))
-+#else
-+#define H_ERRNO_PROTO
-+#define H_ERRNO_ARG
-+#define H_ERRNO_SET(val) ((void) 0)
-+#endif
-+
-+/* Locks the static variables in this file. */
-+__libc_lock_define_initialized (static, lock)
-+
-+/* Maintenance of the shared handle open on the database. */
-+
-+static DB *db;
-+static int keep_db;
-+static unsigned int entidx; /* Index for `getENTNAME'. */
-+
-+/* Open database file if not already opened. */
-+static enum nss_status
-+internal_setent (int stayopen)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ if (db == NULL)
-+ {
-+ db = dbopen (DBFILE, O_RDONLY, 0, DB_BTREE, NULL);
-+
-+ if (db == NULL)
-+ status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-+ else
-+ {
-+ /* We have to make sure the file is `closed on exec'. */
-+ int result, flags;
-+
-+ result = flags = fcntl ((*db->fd) (db), F_GETFD, 0);
-+ if (result >= 0)
-+ {
-+ flags |= FD_CLOEXEC;
-+ result = fcntl ((*db->fd) (db), F_SETFD, flags);
-+ }
-+ if (result < 0)
-+ {
-+ /* Something went wrong. Close the stream and return a
-+ failure. */
-+ (*db->close) (db);
-+ db = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ }
-+ }
-+
-+ /* Remember STAYOPEN flag. */
-+ if (db != NULL)
-+ keep_db |= stayopen;
-+
-+ return status;
-+}
-+
-+
-+/* Thread-safe, exported version of that. */
-+enum nss_status
-+CONCAT(_nss_db_set,ENTNAME) (int stayopen)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_setent (stayopen);
-+
-+ /* Reset the sequential index. */
-+ entidx = 0;
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+
-+/* Close the database file. */
-+static void
-+internal_endent (void)
-+{
-+ if (db != NULL)
-+ {
-+ (*db->close) (db);
-+ db = NULL;
-+ }
-+}
-+
-+
-+/* Thread-safe, exported version of that. */
-+enum nss_status
-+CONCAT(_nss_db_end,ENTNAME) (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ internal_endent ();
-+
-+ /* Reset STAYOPEN flag. */
-+ keep_db = 0;
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+/* Do a database lookup for KEY. */
-+static enum nss_status
-+lookup (const DBT *key, struct STRUCTURE *result,
-+ void *buffer, int buflen H_ERRNO_PROTO)
-+{
-+ char *p;
-+ enum nss_status status;
-+ int err;
-+ DBT value;
-+
-+ /* Open the database. */
-+ status = internal_setent (keep_db);
-+ if (status != NSS_STATUS_SUCCESS)
-+ {
-+ H_ERRNO_SET (NETDB_INTERNAL);
-+ return status;
-+ }
-+
-+ /* Succeed iff it matches a value that parses correctly. */
-+ err = (*db->get) (db, key, &value, 0);
-+ if (err < 0)
-+ {
-+ H_ERRNO_SET (NETDB_INTERNAL);
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ else if (err != 0)
-+ {
-+ H_ERRNO_SET (HOST_NOT_FOUND);
-+ status = NSS_STATUS_NOTFOUND;
-+ }
-+ else
-+ {
-+ /* Copy the result to a safe place. */
-+ p = (char *) memcpy (buffer, value.data, value.size);
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+
-+ err = parse_line (p, result, buffer, buflen);
-+
-+ if (err == 0)
-+ {
-+ /* If the key begins with '0' we are trying to get the next
-+ entry. We want to ignore unparsable lines in this case. */
-+ if (((char *) key->data)[0] == '0')
-+ {
-+ /* Super magical return value. We need to tell our caller
-+ that it should continue looping. This value cannot
-+ happen in other cases. */
-+ status = NSS_STATUS_RETURN;
-+ }
-+ else
-+ {
-+ H_ERRNO_SET (HOST_NOT_FOUND);
-+ status = NSS_STATUS_NOTFOUND;
-+ }
-+ }
-+ else if (err < 0)
-+ {
-+ H_ERRNO_SET (NETDB_INTERNAL);
-+ status = NSS_STATUS_TRYAGAIN;
-+ }
-+ else
-+ status = NSS_STATUS_SUCCESS;
-+ }
-+
-+ if (! keep_db)
-+ internal_endent ();
-+
-+ return status;
-+}
-+
-+
-+/* Macro for defining lookup functions for this DB-based database.
-+
-+ NAME is the name of the lookup; e.g. `pwnam'.
-+
-+ KEYPATTERN gives `printf' args to construct a key string;
-+ e.g. `(".%s", name)'.
-+
-+ KEYSIZE gives the allocation size of a buffer to construct it in;
-+ e.g. `1 + strlen (name)'.
-+
-+ PROTO describes the arguments for the lookup key;
-+ e.g. `const char *name'.
-+
-+ BREAK_IF_MATCH is ignored, but used by ../nss_files/files-XXX.c. */
-+
-+#define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...) \
-+enum nss_status \
-+_nss_db_get##name##_r (proto, \
-+ struct STRUCTURE *result, \
-+ char *buffer, size_t buflen H_ERRNO_PROTO) \
-+{ \
-+ DBT key; \
-+ enum nss_status status; \
-+ const size_t size = (keysize) + 1; \
-+ key.data = __alloca (size); \
-+ key.size = KEYPRINTF keypattern; \
-+ __libc_lock_lock (lock); \
-+ status = lookup (&key, result, buffer, buflen H_ERRNO_ARG); \
-+ __libc_lock_unlock (lock); \
-+ return status; \
-+}
-+
-+#define KEYPRINTF(pattern, args...) snprintf (key.data, size, pattern ,##args)
-+
-+
-+
-+
-+/* Return the next entry from the database file, doing locking. */
-+enum nss_status
-+CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result,
-+ char *buffer, size_t buflen H_ERRNO_PROTO)
-+{
-+ /* Return next entry in host file. */
-+ enum nss_status status;
-+ char buf[20];
-+ DBT key;
-+
-+ __libc_lock_lock (lock);
-+ /* Loop until we find a valid entry or hit EOF. See above for the
-+ special meaning of the status value. */
-+ do
-+ {
-+ key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
-+ status = lookup (&key, result, buffer, buflen H_ERRNO_ARG);
-+ if (status == NSS_STATUS_TRYAGAIN
-+#ifdef NEED_H_ERRNO
-+ && *herrnop == NETDB_INTERNAL
-+#endif
-+ && errno == ERANGE)
-+ /* Give the user a chance to get the same entry with a larger
-+ buffer. */
-+ --entidx;
-+ }
-+ while (status == NSS_STATUS_RETURN);
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_db/db-alias.c glibc-2.1.3/glibc-compat/nss_db/db-alias.c
---- ../glibc-2.1.3/glibc-compat/nss_db/db-alias.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_db/db-alias.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,255 @@
-+/* Mail alias file parser in nss_db module.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <aliases.h>
-+#include <alloca.h>
-+#include <ctype.h>
-+#include <db_185.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <bits/libc-lock.h>
-+#include <paths.h>
-+#include <string.h>
-+
-+#include "nsswitch.h"
-+
-+/* Locks the static variables in this file. */
-+__libc_lock_define_initialized (static, lock)
-+
-+/* Maintenance of the shared handle open on the database. */
-+
-+static DB *db;
-+static int keep_db;
-+static unsigned int entidx; /* Index for `getaliasent_r'. */
-+
-+/* Open database file if not already opened. */
-+static enum nss_status
-+internal_setent (int stayopen)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ if (db == NULL)
-+ {
-+ db = dbopen (_PATH_VARDB "aliases.db", O_RDONLY, 0, DB_BTREE, NULL);
-+
-+ if (db == NULL)
-+ status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-+ else
-+ {
-+ /* We have to make sure the file is `closed on exec'. */
-+ int result, flags;
-+
-+ result = flags = fcntl ((*db->fd) (db), F_GETFD, 0);
-+ if (result >= 0)
-+ {
-+ flags |= FD_CLOEXEC;
-+ result = fcntl ((*db->fd) (db), F_SETFD, flags);
-+ }
-+ if (result < 0)
-+ {
-+ /* Something went wrong. Close the stream and return a
-+ failure. */
-+ (*db->close) (db);
-+ db = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ }
-+ }
-+
-+ /* Remember STAYOPEN flag. */
-+ if (db != NULL)
-+ keep_db |= stayopen;
-+
-+ return status;
-+}
-+
-+
-+/* Thread-safe, exported version of that. */
-+enum nss_status
-+_nss_db_setaliasent (int stayopen)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_setent (stayopen);
-+
-+ /* Reset the sequential index. */
-+ entidx = 0;
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+
-+/* Close the database file. */
-+static void
-+internal_endent (void)
-+{
-+ if (db != NULL)
-+ {
-+ (*db->close) (db);
-+ db = NULL;
-+ }
-+}
-+
-+
-+/* Thread-safe, exported version of that. */
-+enum nss_status
-+_nss_db_endaliasent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ internal_endent ();
-+
-+ /* Reset STAYOPEN flag. */
-+ keep_db = 0;
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+/* We provide the parse function here. The parser in libnss_files
-+ cannot be used. The generation of the db file already resolved all
-+ :include: statements so we simply have to parse the list and store
-+ the result. */
-+static enum nss_status
-+lookup (const DBT *key, struct aliasent *result, char *buffer,
-+ size_t buflen)
-+{
-+ enum nss_status status;
-+ DBT value;
-+
-+ /* Open the database. */
-+ status = internal_setent (keep_db);
-+ if (status != NSS_STATUS_SUCCESS)
-+ return status;
-+
-+ if ((*db->get) (db, key, &value, 0) == 0)
-+ {
-+ const char *src = value.data;
-+
-+ result->alias_members_len = 0;
-+
-+ /* We now have to fill the BUFFER with all the information. */
-+ if (buflen < key->size + 1)
-+ {
-+ no_more_room:
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ {
-+ char *cp;
-+ size_t cnt;
-+
-+ buffer = stpncpy (buffer, key->data, key->size) + 1;
-+ buflen -= key->size + 1;
-+
-+ while (*src != '\0')
-+ {
-+ const char *end, *upto;
-+ while (isspace (*src))
-+ ++src;
-+
-+ end = strchr (src, ',');
-+ if (end == NULL)
-+ end = strchr (src, '\0');
-+ for (upto = end; upto > src && isspace (upto[-1]); --upto);
-+
-+ if (upto != src)
-+ {
-+ if ((upto - src) + __alignof__ (char *) > buflen)
-+ goto no_more_room;
-+ buffer = stpncpy (buffer, src, upto - src) + 1;
-+ buflen -= (upto - src) + __alignof (char *);
-+ ++result->alias_members_len;
-+ }
-+ src = end + (*end != '\0');
-+ }
-+
-+ /* Now prepare the return. Provide string pointers for the
-+ currently selected aliases. */
-+
-+ /* Adjust the pointer so it is aligned for storing pointers. */
-+ buffer += __alignof__ (char *) - 1;
-+ buffer -= ((buffer - (char *) 0) % __alignof__ (char *));
-+ result->alias_members = (char **) buffer;
-+
-+ /* Compute addresses of alias entry strings. */
-+ cp = result->alias_name;
-+ for (cnt = 0; cnt < result->alias_members_len; ++cnt)
-+ {
-+ cp = strchr (cp, '\0') + 1;
-+ result->alias_members[cnt] = cp;
-+ }
-+
-+ status = (result->alias_members_len == 0
-+ ? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS);
-+ }
-+ }
-+ else
-+ status = NSS_STATUS_NOTFOUND;
-+
-+ if (! keep_db)
-+ internal_endent ();
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
-+{
-+ /* Return next entry in alias file. */
-+ enum nss_status status;
-+ char buf[20];
-+ DBT key;
-+
-+ __libc_lock_lock (lock);
-+ key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
-+ status = lookup (&key, result, buffer, buflen);
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+
-+enum nss_status
-+_nss_db_getaliasbyname_r (const char *name, struct aliasent *result,
-+ char *buffer, size_t buflen)
-+{
-+ DBT key;
-+ enum nss_status status;
-+
-+ key.size = 1 + strlen (name);
-+
-+ key.data = __alloca (key.size);
-+ ((char *) key.data)[0] = '.';
-+ memcpy (&((char *) key.data)[1], name, key.size - 1);
-+
-+ __libc_lock_lock (lock);
-+ status = lookup (&key, result, buffer, buflen);
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_db/db-netgrp.c glibc-2.1.3/glibc-compat/nss_db/db-netgrp.c
---- ../glibc-2.1.3/glibc-compat/nss_db/db-netgrp.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_db/db-netgrp.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,129 @@
-+/* Netgroup file parser in nss_db modules.
-+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <db_185.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <string.h>
-+#include <bits/libc-lock.h>
-+#include <paths.h>
-+#include "nsswitch.h"
-+#include "netgroup.h"
-+
-+
-+#define DBFILE _PATH_VARDB "netgroup.db"
-+
-+
-+/* Locks the static variables in this file. */
-+__libc_lock_define_initialized (static, lock)
-+
-+/* Maintenance of the shared handle open on the database. */
-+static DB *db;
-+static char *entry;
-+static char *cursor;
-+
-+enum nss_status
-+_nss_db_setnetgrent (const char *group)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ __libc_lock_lock (lock);
-+
-+ /* Make sure the data base file is open. */
-+ if (db == NULL)
-+ {
-+ db = dbopen (DBFILE, O_RDONLY, 0, DB_BTREE, NULL);
-+
-+ if (db == NULL)
-+ status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-+ else
-+ {
-+ /* We have to make sure the file is `closed on exec'. */
-+ int result, flags;
-+
-+ result = flags = fcntl ((*db->fd) (db), F_GETFD, 0);
-+ if (result >= 0)
-+ {
-+ flags |= FD_CLOEXEC;
-+ result = fcntl ((*db->fd) (db), F_SETFD, flags);
-+ }
-+ if (result < 0)
-+ {
-+ /* Something went wrong. Close the stream and return a
-+ failure. */
-+ (*db->close) (db);
-+ db = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ }
-+ }
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ {
-+ DBT key = { data: (void *) group, size: strlen (group) };
-+ DBT value;
-+
-+ if ((*db->get) (db, &key, &value, 0) != 0)
-+ status = NSS_STATUS_NOTFOUND;
-+ else
-+ cursor = entry = value.data;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+
-+}
-+
-+
-+enum nss_status
-+_nss_db_endnetgrent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ if (db != NULL)
-+ {
-+ (*db->close) (db);
-+ db = NULL;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+
-+extern enum nss_status _nss_netgroup_parseline (char **cursor,
-+ struct __netgrent *result,
-+ char *buffer, int buflen);
-+
-+enum nss_status
-+_nss_db_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen)
-+{
-+ int status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_dns/dns-host.c glibc-2.1.3/glibc-compat/nss_dns/dns-host.c
---- ../glibc-2.1.3/glibc-compat/nss_dns/dns-host.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_dns/dns-host.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,602 @@
-+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+/* Parts of this file are plain copies of the file `gethtnamadr.c' from
-+ the bind package and it has the following copyright. */
-+
-+/*
-+ * ++Copyright++ 1985, 1988, 1993
-+ * -
-+ * Copyright (c) 1985, 1988, 1993
-+ * The Regents of the University of California. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * This product includes software developed by the University of
-+ * California, Berkeley and its contributors.
-+ * 4. Neither the name of the University nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ * -
-+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies, and that
-+ * the name of Digital Equipment Corporation not be used in advertising or
-+ * publicity pertaining to distribution of the document or software without
-+ * specific, written prior permission.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
-+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
-+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-+ * SOFTWARE.
-+ * -
-+ * --Copyright--
-+ */
-+
-+#include <ctype.h>
-+#include <errno.h>
-+#include <netdb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stddef.h>
-+#include <string.h>
-+#include <sys/syslog.h>
-+
-+#include "nsswitch.h"
-+
-+/* Get implementation for some internal functions. */
-+#include "../resolv/mapv4v6addr.h"
-+#include "../resolv/mapv4v6hostent.h"
-+
-+/* Maximum number of aliases we allow. */
-+#define MAX_NR_ALIASES 48
-+#define MAX_NR_ADDRS 48
-+
-+#if PACKETSZ > 1024
-+# define MAXPACKET PACKETSZ
-+#else
-+# define MAXPACKET 1024
-+#endif
-+/* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length. */
-+#ifdef MAXHOSTNAMELEN
-+# undef MAXHOSTNAMELEN
-+#endif
-+#define MAXHOSTNAMELEN 256
-+
-+static const char AskedForGot[] = "\
-+gethostby*.getanswer: asked for \"%s\", got \"%s\"";
-+
-+
-+/* We need this time later. */
-+typedef union querybuf
-+{
-+ HEADER hdr;
-+ u_char buf[MAXPACKET];
-+} querybuf;
-+
-+
-+static enum nss_status getanswer_r (const querybuf *answer, int anslen,
-+ const char *qname, int qtype,
-+ struct hostent *result, char *buffer,
-+ size_t buflen, int *h_errnop);
-+
-+enum nss_status
-+_nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
-+ char *buffer, size_t buflen, int *h_errnop)
-+{
-+ querybuf host_buffer;
-+ int size, type, n;
-+ const char *cp;
-+
-+ switch (af) {
-+ case AF_INET:
-+ size = INADDRSZ;
-+ type = T_A;
-+ break;
-+ case AF_INET6:
-+ size = IN6ADDRSZ;
-+ type = T_AAAA;
-+ break;
-+ default:
-+ *h_errnop = NETDB_INTERNAL;
-+ __set_errno (EAFNOSUPPORT);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ result->h_addrtype = af;
-+ result->h_length = size;
-+
-+ /*
-+ * if there aren't any dots, it could be a user-level alias.
-+ * this is also done in res_query() since we are not the only
-+ * function that looks up host names.
-+ */
-+ if (strchr (name, '.') == NULL && (cp = __hostalias (name)) != NULL)
-+ name = cp;
-+
-+ n = res_search (name, C_IN, type, host_buffer.buf, sizeof (host_buffer.buf));
-+ if (n < 0)
-+ {
-+ *h_errnop = h_errno;
-+ return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
-+ }
-+
-+ return getanswer_r (&host_buffer, n, name, type, result, buffer, buflen,
-+ h_errnop);
-+}
-+
-+
-+enum nss_status
-+_nss_dns_gethostbyname_r (const char *name, struct hostent *result,
-+ char *buffer, size_t buflen, int *h_errnop)
-+{
-+ enum nss_status status = NSS_STATUS_NOTFOUND;
-+
-+ if (_res.options & RES_USE_INET6)
-+ status = _nss_dns_gethostbyname2_r (name, AF_INET6, result, buffer,
-+ buflen, h_errnop);
-+ if (status == NSS_STATUS_NOTFOUND)
-+ status = _nss_dns_gethostbyname2_r (name, AF_INET, result, buffer,
-+ buflen, h_errnop);
-+
-+ return status;
-+}
-+
-+
-+enum nss_status
-+_nss_dns_gethostbyaddr_r (const char *addr, int len, int af,
-+ struct hostent *result, char *buffer, size_t buflen,
-+ int *h_errnop)
-+{
-+ static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
-+ static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
-+ const u_char *uaddr = (const u_char *)addr;
-+ struct host_data
-+ {
-+ char *aliases[MAX_NR_ALIASES];
-+ unsigned char host_addr[16]; /* IPv4 or IPv6 */
-+ char *h_addr_ptrs[MAX_NR_ADDRS + 1];
-+ char linebuffer[0];
-+ } *host_data = (struct host_data *) buffer;
-+ querybuf host_buffer;
-+ char qbuf[MAXDNAME+1], *qp;
-+ int size, n, status;
-+
-+ if (af == AF_INET6 && len == IN6ADDRSZ &&
-+ (memcmp (uaddr, mapped, sizeof mapped) == 0
-+ || memcmp (uaddr, tunnelled, sizeof tunnelled) == 0))
-+ {
-+ /* Unmap. */
-+ addr += sizeof mapped;
-+ uaddr += sizeof mapped;
-+ af = AF_INET;
-+ len = INADDRSZ;
-+ }
-+
-+ switch (af)
-+ {
-+ case AF_INET:
-+ size = INADDRSZ;
-+ break;
-+ case AF_INET6:
-+ size = IN6ADDRSZ;
-+ break;
-+ default:
-+ __set_errno (EAFNOSUPPORT);
-+ *h_errnop = NETDB_INTERNAL;
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+ if (size != len)
-+ {
-+ __set_errno (EAFNOSUPPORT);
-+ *h_errnop = NETDB_INTERNAL;
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ switch (af)
-+ {
-+ case AF_INET:
-+ sprintf (qbuf, "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff),
-+ (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff));
-+ break;
-+ case AF_INET6:
-+ qp = qbuf;
-+ for (n = IN6ADDRSZ - 1; n >= 0; n--)
-+ qp += sprintf (qp, "%x.%x.", uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf);
-+ strcpy(qp, "ip6.int");
-+ break;
-+ default:
-+ /* Cannot happen. */
-+ }
-+
-+ n = res_query (qbuf, C_IN, T_PTR, (u_char *)host_buffer.buf,
-+ sizeof host_buffer);
-+ if (n < 0)
-+ {
-+ *h_errnop = h_errno;
-+ return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
-+ }
-+
-+ status = getanswer_r (&host_buffer, n, qbuf, T_PTR, result, buffer, buflen,
-+ h_errnop);
-+ if (status != NSS_STATUS_SUCCESS)
-+ {
-+ *h_errnop = h_errno;
-+ return status;
-+ }
-+
-+#ifdef SUNSECURITY
-+ This is not implemented because it is not possible to use the current
-+ source from bind in a multi-threaded program.
-+#endif
-+
-+ result->h_addrtype = af;
-+ result->h_length = len;
-+ memcpy (host_data->host_addr, addr, len);
-+ host_data->h_addr_ptrs[0] = (char *) host_data->host_addr;
-+ host_data->h_addr_ptrs[1] = NULL;
-+ if (af == AF_INET && (_res.options & RES_USE_INET6))
-+ {
-+ map_v4v6_address ((char *) host_data->host_addr,
-+ (char *) host_data->host_addr);
-+ result->h_addrtype = AF_INET6;
-+ result->h_length = IN6ADDRSZ;
-+ }
-+ *h_errnop = NETDB_SUCCESS;
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+
-+static enum nss_status
-+getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
-+ struct hostent *result, char *buffer, size_t buflen,
-+ int *h_errnop)
-+{
-+ struct host_data
-+ {
-+ char *aliases[MAX_NR_ALIASES];
-+ unsigned char host_addr[16]; /* IPv4 or IPv6 */
-+ char *h_addr_ptrs[MAX_NR_ADDRS + 1];
-+ char linebuffer[0];
-+ } *host_data = (struct host_data *) buffer;
-+ int linebuflen = buflen - offsetof (struct host_data, linebuffer);
-+ register const HEADER *hp;
-+ const u_char *end_of_message, *cp;
-+ int n, ancount, qdcount;
-+ int haveanswer, had_error;
-+ char *bp, **ap, **hap;
-+ char tbuf[MAXDNAME];
-+ const char *tname;
-+ int (*name_ok) __P ((const char *));
-+
-+ tname = qname;
-+ result->h_name = NULL;
-+ end_of_message = answer->buf + anslen;
-+ switch (qtype)
-+ {
-+ case T_A:
-+ case T_AAAA:
-+ name_ok = res_hnok;
-+ break;
-+ case T_PTR:
-+ name_ok = res_dnok;
-+ break;
-+ default:
-+ return NSS_STATUS_UNAVAIL; /* XXX should be abort(); */
-+ }
-+
-+ /*
-+ * find first satisfactory answer
-+ */
-+ hp = &answer->hdr;
-+ bp = host_data->linebuffer;
-+ ancount = ntohs (hp->ancount);
-+ qdcount = ntohs (hp->qdcount);
-+ cp = answer->buf + HFIXEDSZ;
-+ if (qdcount != 1)
-+ {
-+ *h_errnop = NO_RECOVERY;
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
-+ if (n < 0 || (*name_ok) (bp) == 0)
-+ {
-+ *h_errnop = NO_RECOVERY;
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+ cp += n + QFIXEDSZ;
-+
-+ if (qtype == T_A || qtype == T_AAAA)
-+ {
-+ /* res_send() has already verified that the query name is the
-+ * same as the one we sent; this just gets the expanded name
-+ * (i.e., with the succeeding search-domain tacked on).
-+ */
-+ n = strlen (bp) + 1; /* for the \0 */
-+ if (n >= MAXHOSTNAMELEN)
-+ {
-+ __set_h_errno (NO_RECOVERY);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ result->h_name = bp;
-+ bp += n;
-+ linebuflen -= n;
-+ /* The qname can be abbreviated, but h_name is now absolute. */
-+ qname = result->h_name;
-+ }
-+
-+ ap = host_data->aliases;
-+ *ap = NULL;
-+ result->h_aliases = host_data->aliases;
-+ hap = host_data->h_addr_ptrs;
-+ *hap = NULL;
-+ result->h_addr_list = host_data->h_addr_ptrs;
-+ haveanswer = 0;
-+ had_error = 0;
-+
-+ while (ancount-- > 0 && cp < end_of_message && had_error == 0)
-+ {
-+ int type, class;
-+
-+ n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
-+ if (n < 0 || (*name_ok) (bp) == 0)
-+ {
-+ ++had_error;
-+ continue;
-+ }
-+ cp += n; /* name */
-+ type = _getshort (cp);
-+ cp += INT16SZ; /* type */
-+ class = _getshort(cp);
-+ cp += INT16SZ + INT32SZ; /* class, TTL */
-+ n = _getshort(cp);
-+ cp += INT16SZ; /* len */
-+ if (class != C_IN)
-+ {
-+ /* XXX - debug? syslog? */
-+ cp += n;
-+ continue; /* XXX - had_error++ ? */
-+ }
-+
-+ if ((qtype ==T_A || qtype == T_AAAA) && type == T_CNAME)
-+ {
-+ if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1])
-+ continue;
-+ n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
-+ if (n < 0 || (*name_ok) (tbuf) == 0)
-+ {
-+ ++had_error;
-+ continue;
-+ }
-+ cp += n;
-+ /* Store alias. */
-+ *ap++ = bp;
-+ n = strlen (bp) + 1; /* For the \0. */
-+ if (n >= MAXHOSTNAMELEN)
-+ {
-+ ++had_error;
-+ continue;
-+ }
-+ bp += n;
-+ linebuflen -= n;
-+ /* Get canonical name. */
-+ n = strlen (tbuf) + 1; /* For the \0. */
-+ if ((size_t) n > buflen || n >= MAXHOSTNAMELEN)
-+ {
-+ ++had_error;
-+ continue;
-+ }
-+ strcpy (bp, tbuf); /* Cannot overflow. */
-+ result->h_name = bp;
-+ bp += n;
-+ linebuflen -= n;
-+ continue;
-+ }
-+
-+ if (qtype == T_PTR && type == T_CNAME)
-+ {
-+ n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
-+ if (n < 0 || res_dnok (tbuf) == 0)
-+ {
-+ ++had_error;
-+ continue;
-+ }
-+ cp += n;
-+ /* Get canonical name. */
-+ n = strlen (tbuf) + 1; /* For the \0. */
-+ if ((size_t) n > buflen || n >= MAXHOSTNAMELEN)
-+ {
-+ ++had_error;
-+ continue;
-+ }
-+ strcpy (bp, tbuf); /* Cannot overflow. */
-+ tname = bp;
-+ bp += n;
-+ linebuflen -= n;
-+ continue;
-+ }
-+ if (type != qtype)
-+ {
-+ syslog (LOG_NOTICE | LOG_AUTH,
-+ "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
-+ qname, p_class (C_IN), p_type (qtype), p_type (type));
-+ cp += n;
-+ continue; /* XXX - had_error++ ? */
-+ }
-+
-+ switch (type)
-+ {
-+ case T_PTR:
-+ if (strcasecmp (tname, bp) != 0)
-+ {
-+ syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp);
-+ cp += n;
-+ continue; /* XXX - had_error++ ? */
-+ }
-+ n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
-+ if (n < 0 || res_hnok (bp) == 0)
-+ {
-+ ++had_error;
-+ break;
-+ }
-+#if MULTI_PTRS_ARE_ALIASES
-+ cp += n;
-+ if (haveanswer == 0)
-+ result->h_name = bp;
-+ else if (ap < &host_data->aliases[MAXALIASES-1])
-+ *ap++ = bp;
-+ else
-+ n = -1;
-+ if (n != -1)
-+ {
-+ n = strlen (bp) + 1; /* for the \0 */
-+ if (n >= MAXHOSTNAMELEN)
-+ {
-+ ++had_error;
-+ break;
-+ }
-+ bp += n;
-+ linebuflen -= n;
-+ }
-+ break;
-+#else
-+ result->h_name = bp;
-+ if (_res.options & RES_USE_INET6)
-+ {
-+ n = strlen (bp) + 1; /* for the \0 */
-+ if (n >= MAXHOSTNAMELEN)
-+ {
-+ ++had_error;
-+ break;
-+ }
-+ bp += n;
-+ linebuflen -= n;
-+ map_v4v6_hostent (result, &bp, &linebuflen);
-+ }
-+ *h_errnop = NETDB_SUCCESS;
-+ return NSS_STATUS_SUCCESS;
-+#endif
-+ case T_A:
-+ case T_AAAA:
-+ if (strcasecmp (result->h_name, bp) != 0)
-+ {
-+ syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, result->h_name, bp);
-+ cp += n;
-+ continue; /* XXX - had_error++ ? */
-+ }
-+ if (n != result->h_length)
-+ {
-+ cp += n;
-+ continue;
-+ }
-+ if (!haveanswer)
-+ {
-+ register int nn;
-+
-+ result->h_name = bp;
-+ nn = strlen (bp) + 1; /* for the \0 */
-+ bp += nn;
-+ linebuflen -= nn;
-+ }
-+
-+ bp += sizeof (align) - ((u_long) bp % sizeof (align));
-+
-+ if (n >= linebuflen)
-+ {
-+ ++had_error;
-+ continue;
-+ }
-+ if (hap >= &host_data->h_addr_ptrs[MAX_NR_ADDRS-1])
-+ {
-+ cp += n;
-+ continue;
-+ }
-+ memcpy (*hap++ = bp, cp, n);
-+ bp += n;
-+ cp += n;
-+ linebuflen -= n;
-+ break;
-+ default:
-+ abort ();
-+ }
-+ if (had_error == 0)
-+ ++haveanswer;
-+ }
-+
-+ if (haveanswer > 0)
-+ {
-+ *ap = NULL;
-+ *hap = NULL;
-+#if defined(RESOLVSORT)
-+ /*
-+ * Note: we sort even if host can take only one address
-+ * in its return structures - should give it the "best"
-+ * address in that case, not some random one
-+ */
-+ if (_res.nsort && haveanswer > 1 && qtype == T_A)
-+ addrsort (host_data->h_addr_ptrs, haveanswer);
-+#endif /*RESOLVSORT*/
-+
-+ if (result->h_name == NULL)
-+ {
-+ n = strlen (qname) + 1; /* For the \0. */
-+ if (n > linebuflen || n >= MAXHOSTNAMELEN)
-+ goto no_recovery;
-+ strcpy (bp, qname); /* Cannot overflow. */
-+ result->h_name = bp;
-+ bp += n;
-+ linebuflen -= n;
-+ }
-+
-+ if (_res.options & RES_USE_INET6)
-+ map_v4v6_hostent (result, &bp, &linebuflen);
-+ *h_errnop = NETDB_SUCCESS;
-+ return NSS_STATUS_SUCCESS;
-+ }
-+ no_recovery:
-+ *h_errnop = NO_RECOVERY;
-+ return NSS_STATUS_TRYAGAIN;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_dns/dns-network.c glibc-2.1.3/glibc-compat/nss_dns/dns-network.c
---- ../glibc-2.1.3/glibc-compat/nss_dns/dns-network.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_dns/dns-network.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,345 @@
-+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+/* Parts of this file are plain copies of the file `getnetnamadr.c' from
-+ the bind package and it has the following copyright. */
-+
-+/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
-+ * Dep. Matematica Universidade de Coimbra, Portugal, Europe
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ */
-+/*
-+ * Copyright (c) 1983, 1993
-+ * The Regents of the University of California. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * This product includes software developed by the University of
-+ * California, Berkeley and its contributors.
-+ * 4. Neither the name of the University nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#include <ctype.h>
-+#include <errno.h>
-+#include <netdb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include "nsswitch.h"
-+#include <arpa/inet.h>
-+
-+/* Maximum number of aliases we allow. */
-+#define MAX_NR_ALIASES 48
-+
-+
-+#if PACKETSZ > 1024
-+#define MAXPACKET PACKETSZ
-+#else
-+#define MAXPACKET 1024
-+#endif
-+
-+
-+typedef enum
-+{
-+ BYADDR,
-+ BYNAME
-+} lookup_method;
-+
-+
-+/* We need this time later. */
-+typedef union querybuf
-+{
-+ HEADER hdr;
-+ u_char buf[MAXPACKET];
-+} querybuf;
-+
-+
-+/* Prototypes for local functions. */
-+static enum nss_status getanswer_r (const querybuf *answer, int anslen,
-+ struct netent *result, char *buffer,
-+ size_t buflen, lookup_method net_i);
-+
-+
-+enum nss_status
-+_nss_dns_getnetbyname_r (const char *name, struct netent *result,
-+ char *buffer, size_t buflen)
-+{
-+ /* Return entry for network with NAME. */
-+ querybuf net_buffer;
-+ int anslen;
-+ char *qbuf;
-+
-+ qbuf = strdupa (name);
-+ anslen = res_search (qbuf, C_IN, T_PTR, (u_char *) &net_buffer,
-+ sizeof (querybuf));
-+ if (anslen < 0)
-+ /* Nothing found. */
-+ return (errno == ECONNREFUSED
-+ || errno == EPFNOSUPPORT
-+ || errno == EAFNOSUPPORT)
-+ ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
-+
-+ return getanswer_r (&net_buffer, anslen, result, buffer, buflen, BYNAME);
-+}
-+
-+
-+enum nss_status
-+_nss_dns_getnetbyaddr_r (long net, int type, struct netent *result,
-+ char *buffer, size_t buflen)
-+{
-+ /* Return entry for network with NAME. */
-+ enum nss_status status;
-+ querybuf net_buffer;
-+ unsigned int net_bytes[4];
-+ char qbuf[MAXDNAME];
-+ int cnt, anslen;
-+ u_int32_t net2;
-+
-+ /* No net address lookup for IPv6 yet. */
-+ if (type != AF_INET)
-+ return NSS_STATUS_UNAVAIL;
-+
-+ net2 = (u_int32_t) net;
-+ for (cnt = 4; net2 != 0; net2 >>= 8)
-+ net_bytes[--cnt] = net2 & 0xff;
-+
-+ switch (cnt)
-+ {
-+ case 3:
-+ /* Class A network. */
-+ sprintf (qbuf, "0.0.0.%u.in-addr.arpa", net_bytes[3]);
-+ break;
-+ case 2:
-+ /* Class B network. */
-+ sprintf (qbuf, "0.0.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2]);
-+ break;
-+ case 1:
-+ /* Class C network. */
-+ sprintf (qbuf, "0.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
-+ net_bytes[1]);
-+ break;
-+ case 0:
-+ /* Class D - E network. */
-+ sprintf (qbuf, "%u.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
-+ net_bytes[1], net_bytes[0]);
-+ break;
-+ }
-+
-+ anslen = res_query (qbuf, C_IN, T_PTR, (u_char *) &net_buffer,
-+ sizeof (querybuf));
-+ if (anslen < 0)
-+ /* Nothing found. */
-+ return (errno == ECONNREFUSED
-+ || errno == EPFNOSUPPORT
-+ || errno == EAFNOSUPPORT)
-+ ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
-+
-+ status = getanswer_r (&net_buffer, anslen, result, buffer, buflen, BYADDR);
-+ if (status == NSS_STATUS_SUCCESS)
-+ {
-+ /* Strip trailing zeros. */
-+ unsigned int u_net = net; /* Maybe net should be unsigned? */
-+
-+ while ((u_net & 0xff) == 0 && u_net != 0)
-+ u_net >>= 8;
-+ result->n_net = u_net;
-+ }
-+
-+ return status;
-+}
-+
-+
-+#undef offsetof
-+#define offsetof(Type, Member) ((size_t) &((Type *) NULL)->Member)
-+
-+static enum nss_status
-+getanswer_r (const querybuf *answer, int anslen, struct netent *result,
-+ char *buffer, size_t buflen, lookup_method net_i)
-+{
-+ /*
-+ * Find first satisfactory answer
-+ *
-+ * answer --> +------------+ ( MESSAGE )
-+ * | Header |
-+ * +------------+
-+ * | Question | the question for the name server
-+ * +------------+
-+ * | Answer | RRs answering the question
-+ * +------------+
-+ * | Authority | RRs pointing toward an authority
-+ * | Additional | RRs holding additional information
-+ * +------------+
-+ */
-+ struct net_data
-+ {
-+ char *aliases[MAX_NR_ALIASES];
-+ char linebuffer[0];
-+ } *net_data = (struct net_data *) buffer;
-+ int linebuflen = buflen - offsetof (struct net_data, linebuffer);
-+ const char *end_of_message = &answer->buf[anslen];
-+ const HEADER *header_pointer = &answer->hdr;
-+ /* #/records in the answer section. */
-+ int answer_count = ntohs (header_pointer->ancount);
-+ /* #/entries in the question section. */
-+ int question_count = ntohs (header_pointer->qdcount);
-+ char *bp = net_data->linebuffer;
-+ const char *cp = &answer->buf[HFIXEDSZ];
-+ char **alias_pointer;
-+ int have_answer;
-+ char *ans;
-+
-+ if (question_count == 0)
-+ {
-+ /* FIXME: the Sun version uses for host name lookup an additional
-+ parameter for pointing to h_errno. this is missing here.
-+ OSF/1 has a per-thread h_errno variable. */
-+ if (header_pointer->aa != 0)
-+ {
-+ __set_h_errno (HOST_NOT_FOUND);
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+ else
-+ {
-+ __set_h_errno (TRY_AGAIN);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ }
-+
-+ /* Skip the question part. */
-+ while (question_count-- > 0)
-+ cp += __dn_skipname (cp, end_of_message) + QFIXEDSZ;
-+
-+ alias_pointer = result->n_aliases = &net_data->aliases[0];
-+ *alias_pointer = NULL;
-+ have_answer = 0;
-+ ans = NULL;
-+
-+ while (--answer_count >= 0 && cp < end_of_message)
-+ {
-+ int n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
-+ int type, class;
-+
-+ if (n < 0 || res_dnok (bp) == 0)
-+ break;
-+ cp += n;
-+ ans = strdupa (bp);
-+ GETSHORT (type, cp);
-+ GETSHORT (class, cp);
-+ cp += INT32SZ; /* TTL */
-+ GETSHORT (n, cp);
-+
-+ if (class == C_IN && type == T_PTR)
-+ {
-+ n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
-+ if (n < 0 || !res_hnok (bp))
-+ {
-+ /* XXX What does this mean? The original form from bind
-+ returns NULL. Incrementing cp has no effect in any case.
-+ What should I return here. ??? */
-+ cp += n;
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+ cp += n;
-+ *alias_pointer++ = bp;
-+ bp += strlen (bp) + 1;
-+ result->n_addrtype = class == C_IN ? AF_INET : AF_UNSPEC;
-+ ++have_answer;
-+ }
-+ }
-+
-+ if (have_answer)
-+ {
-+ char *tmp;
-+ int len;
-+ char *in, *cp, *rp, *wp;
-+ int cnt, first_flag;
-+
-+ *alias_pointer = NULL;
-+ switch (net_i)
-+ {
-+ case BYADDR:
-+ result->n_name = result->n_aliases[0];
-+ result->n_net = 0L;
-+ break;
-+ case BYNAME:
-+ len = strlen (result->n_aliases[0]);
-+ tmp = (char *) alloca (len + 1);
-+ tmp[len] = 0;
-+ wp = &tmp[len - 1];
-+
-+ rp = in = result->n_aliases[0];
-+ result->n_name = ans;
-+
-+ first_flag = 1;
-+ for (cnt = 0; cnt < 4; ++cnt)
-+ {
-+ char *startp;
-+
-+ startp = rp;
-+ while (*rp != '.')
-+ ++rp;
-+ if (rp - startp > 1 || *startp != '0' || !first_flag)
-+ {
-+ first_flag = 0;
-+ if (cnt > 0)
-+ *wp-- = '.';
-+ cp = rp;
-+ while (cp > startp)
-+ *wp-- = *--cp;
-+ }
-+ in = rp + 1;
-+ }
-+
-+ result->n_net = inet_network (wp);
-+ break;
-+ }
-+
-+ ++result->n_aliases;
-+ return NSS_STATUS_SUCCESS;
-+ }
-+
-+ __set_h_errno (TRY_AGAIN);
-+ return NSS_STATUS_TRYAGAIN;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-XXX.c glibc-2.1.3/glibc-compat/nss_files/files-XXX.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-XXX.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-XXX.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,311 @@
-+/* Common code for file-based databases in nss_files module.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stdio.h>
-+#include <ctype.h>
-+#include <fcntl.h>
-+#include <assert.h>
-+#include <errno.h>
-+#include <bits/libc-lock.h>
-+#include "nsswitch.h"
-+
-+/* These symbols are defined by the including source file:
-+
-+ ENTNAME -- database name of the structure and functions (hostent, pwent).
-+ STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
-+ DATABASE -- string of the database file's name ("hosts", "passwd").
-+
-+ NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
-+
-+ Also see files-parse.c.
-+*/
-+
-+#define ENTNAME_r CONCAT(ENTNAME,_r)
-+
-+#define DATAFILE "/etc/" DATABASE
-+
-+#ifdef NEED_H_ERRNO
-+# include <netdb.h>
-+# define H_ERRNO_PROTO , int *herrnop
-+# define H_ERRNO_ARG , herrnop
-+# define H_ERRNO_SET(val) (*herrnop = (val))
-+#else
-+# define H_ERRNO_PROTO
-+# define H_ERRNO_ARG
-+# define H_ERRNO_SET(val) ((void) 0)
-+#endif
-+
-+/* Locks the static variables in this file. */
-+__libc_lock_define_initialized (static, lock)
-+
-+/* Maintenance of the shared stream open on the database file. */
-+
-+static FILE *stream;
-+static fpos_t position;
-+static enum { none, getent, getby } last_use;
-+static int keep_stream;
-+
-+/* Open database file if not already opened. */
-+static enum nss_status
-+internal_setent (int stayopen)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ if (stream == NULL)
-+ {
-+ stream = fopen (DATAFILE, "r");
-+
-+ if (stream == NULL)
-+ status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-+ else
-+ {
-+ /* We have to make sure the file is `closed on exec'. */
-+ int result, flags;
-+
-+ result = flags = fcntl (fileno (stream), F_GETFD, 0);
-+ if (result >= 0)
-+ {
-+ flags |= FD_CLOEXEC;
-+ result = fcntl (fileno (stream), F_SETFD, flags);
-+ }
-+ if (result < 0)
-+ {
-+ /* Something went wrong. Close the stream and return a
-+ failure. */
-+ fclose (stream);
-+ stream = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ }
-+ }
-+ else
-+ rewind (stream);
-+
-+ /* Remember STAYOPEN flag. */
-+ if (stream != NULL)
-+ keep_stream |= stayopen;
-+
-+ return status;
-+}
-+
-+
-+/* Thread-safe, exported version of that. */
-+enum nss_status
-+CONCAT(_nss_files_set,ENTNAME) (int stayopen)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_setent (stayopen);
-+
-+ if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
-+ {
-+ fclose (stream);
-+ stream = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+
-+ last_use = getent;
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+
-+/* Close the database file. */
-+static void
-+internal_endent (void)
-+{
-+ if (stream != NULL)
-+ {
-+ fclose (stream);
-+ stream = NULL;
-+ }
-+}
-+
-+
-+/* Thread-safe, exported version of that. */
-+enum nss_status
-+CONCAT(_nss_files_end,ENTNAME) (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ internal_endent ();
-+
-+ /* Reset STAYOPEN flag. */
-+ keep_stream = 0;
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+/* Parsing the database file into `struct STRUCTURE' data structures. */
-+
-+static enum nss_status
-+internal_getent (struct STRUCTURE *result,
-+ char *buffer, int buflen H_ERRNO_PROTO)
-+{
-+ char *p;
-+ struct parser_data *data = (void *) buffer;
-+ int linebuflen = buffer + buflen - data->linebuffer;
-+ int parse_result;
-+
-+ if (buflen < (int) sizeof *data + 1)
-+ {
-+ __set_errno (ERANGE);
-+ H_ERRNO_SET (NETDB_INTERNAL);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ do
-+ {
-+ /* Terminate the line so that we can test for overflow. */
-+ data->linebuffer[linebuflen - 1] = '\xff';
-+
-+ p = fgets (data->linebuffer, linebuflen, stream);
-+ if (p == NULL && feof (stream))
-+ {
-+ /* End of file or read error. */
-+ __set_errno (ENOENT);
-+ H_ERRNO_SET (HOST_NOT_FOUND);
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+ else if (p == NULL || data->linebuffer[linebuflen - 1] != '\xff')
-+ {
-+ /* The line is too long. Give the user the opportunity to
-+ enlarge the buffer. */
-+ __set_errno (ERANGE);
-+ H_ERRNO_SET (NETDB_INTERNAL);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*p))
-+ ++p;
-+ }
-+ while (*p == '\0' || *p == '#' /* Ignore empty and comment lines. */
-+ /* Parse the line. If it is invalid, loop to get the next
-+ line of the file to parse. */
-+ || ! (parse_result = parse_line (p, result, data, buflen)));
-+
-+ /* Filled in RESULT with the next entry from the database file. */
-+ return parse_result == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_SUCCESS;
-+}
-+
-+
-+/* Return the next entry from the database file, doing locking. */
-+enum nss_status
-+CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result,
-+ char *buffer, size_t buflen H_ERRNO_PROTO)
-+{
-+ /* Return next entry in host file. */
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ __libc_lock_lock (lock);
-+
-+ /* Be prepared that the set*ent function was not called before. */
-+ if (stream == NULL)
-+ {
-+ status = internal_setent (0);
-+
-+ if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
-+ {
-+ fclose (stream);
-+ stream = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ }
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ {
-+ /* If the last use was not by the getent function we need the
-+ position the stream. */
-+ if (last_use != getent)
-+ {
-+ if (fsetpos (stream, &position) < 0)
-+ status = NSS_STATUS_UNAVAIL;
-+ else
-+ last_use = getent;
-+ }
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ {
-+ status = internal_getent (result, buffer, buflen H_ERRNO_ARG);
-+
-+ /* Remember this position if we were successful. If the
-+ operation failed we give the user a chance to repeat the
-+ operation (perhaps the buffer was too small). */
-+ if (status == NSS_STATUS_SUCCESS)
-+ fgetpos (stream, &position);
-+ else
-+ /* We must make sure we reposition the stream the next call. */
-+ last_use = none;
-+ }
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+/* Macro for defining lookup functions for this file-based database.
-+
-+ NAME is the name of the lookup; e.g. `hostbyname'.
-+
-+ KEYSIZE and KEYPATTERN are ignored here but used by ../nss_db/db-XXX.c.
-+
-+ PROTO describes the arguments for the lookup key;
-+ e.g. `const char *hostname'.
-+
-+ BREAK_IF_MATCH is a block of code which compares `struct STRUCTURE *result'
-+ to the lookup key arguments and does `break;' if they match. */
-+
-+#define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...) \
-+enum nss_status \
-+_nss_files_get##name##_r (proto, \
-+ struct STRUCTURE *result, \
-+ char *buffer, size_t buflen H_ERRNO_PROTO) \
-+{ \
-+ enum nss_status status; \
-+ \
-+ __libc_lock_lock (lock); \
-+ \
-+ /* Reset file pointer to beginning or open file. */ \
-+ status = internal_setent (keep_stream); \
-+ \
-+ if (status == NSS_STATUS_SUCCESS) \
-+ { \
-+ /* Tell getent function that we have repositioned the file pointer. */ \
-+ last_use = getby; \
-+ \
-+ while ((status = internal_getent (result, buffer, buflen H_ERRNO_ARG)) \
-+ == NSS_STATUS_SUCCESS) \
-+ { break_if_match } \
-+ \
-+ if (! keep_stream) \
-+ internal_endent (); \
-+ } \
-+ \
-+ __libc_lock_unlock (lock); \
-+ \
-+ return status; \
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-alias.c glibc-2.1.3/glibc-compat/nss_files/files-alias.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-alias.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-alias.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,451 @@
-+/* Mail alias file parser in nss_files module.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <aliases.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <bits/libc-lock.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <string.h>
-+
-+#include "nsswitch.h"
-+
-+/* Locks the static variables in this file. */
-+__libc_lock_define_initialized (static, lock)
-+
-+/* Maintenance of the shared stream open on the database file. */
-+
-+static FILE *stream;
-+static fpos_t position;
-+static enum { none, getent, getby } last_use;
-+
-+
-+static enum nss_status
-+internal_setent (void)
-+{
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ if (stream == NULL)
-+ {
-+ stream = fopen ("/etc/aliases", "r");
-+
-+ if (stream == NULL)
-+ status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-+ else
-+ {
-+ /* We have to make sure the file is `closed on exec'. */
-+ int result, flags;
-+
-+ result = flags = fcntl (fileno (stream), F_GETFD, 0);
-+ if (result >= 0)
-+ {
-+ flags |= FD_CLOEXEC;
-+ result = fcntl (fileno (stream), F_SETFD, flags);
-+ }
-+ if (result < 0)
-+ {
-+ /* Something went wrong. Close the stream and return a
-+ failure. */
-+ fclose (stream);
-+ stream = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ }
-+ }
-+ else
-+ rewind (stream);
-+
-+ return status;
-+}
-+
-+
-+/* Thread-safe, exported version of that. */
-+enum nss_status
-+_nss_files_setaliasent (void)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_setent ();
-+
-+ if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
-+ {
-+ fclose (stream);
-+ stream = NULL;
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+
-+ last_use = getent;
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+
-+/* Close the database file. */
-+static void
-+internal_endent (void)
-+{
-+ if (stream != NULL)
-+ {
-+ fclose (stream);
-+ stream = NULL;
-+ }
-+}
-+
-+
-+/* Thread-safe, exported version of that. */
-+enum nss_status
-+_nss_files_endaliasent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ internal_endent ();
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+/* Parsing the database file into `struct aliasent' data structures. */
-+static enum nss_status
-+get_next_alias (const char *match, struct aliasent *result,
-+ char *buffer, size_t buflen)
-+{
-+ enum nss_status status = NSS_STATUS_NOTFOUND;
-+ int ignore = 0;
-+
-+ result->alias_members_len = 0;
-+
-+ while (1)
-+ {
-+ /* Now we are ready to process the input. We have to read a
-+ line and all its continuations and construct the array of
-+ string pointers. This pointers and the names itself have to
-+ be placed in BUFFER. */
-+ char *first_unused = buffer;
-+ size_t room_left = buflen - (buflen % __alignof__ (char *));
-+ char *line;
-+
-+ /* Read the first line. It must contain the alias name and
-+ possibly some alias names. */
-+ first_unused[room_left - 1] = '\xff';
-+ line = fgets (first_unused, room_left, stream);
-+ if (line == NULL && feof (stream))
-+ /* Nothing to read. */
-+ break;
-+ else if (line == NULL || first_unused[room_left - 1] != '\xff')
-+ {
-+ /* The line is too long for our buffer. */
-+ no_more_room:
-+ __set_errno (ERANGE);
-+ status = NSS_STATUS_TRYAGAIN;
-+ break;
-+ }
-+ else
-+ {
-+ char *cp;
-+
-+ /* If we are in IGNORE mode and the first character in the
-+ line is a white space we ignore the line and start
-+ reading the next. */
-+ if (ignore && isspace (*first_unused))
-+ continue;
-+
-+ /* Terminate the line for any case. */
-+ cp = strpbrk (first_unused, "#\n");
-+ if (cp != NULL)
-+ *cp = '\0';
-+
-+ /* Skip leading blanks. */
-+ while (isspace (*line))
-+ ++line;
-+
-+ result->alias_name = first_unused;
-+ while (*line != '\0' && *line != ':')
-+ *first_unused++ = *line++;
-+ if (*line == '\0' || result->alias_name == first_unused)
-+ /* No valid name. Ignore the line. */
-+ continue;
-+
-+ *first_unused++ = '\0';
-+ if (room_left < (size_t) (first_unused - result->alias_name))
-+ goto no_more_room;
-+ room_left -= first_unused - result->alias_name;
-+ ++line;
-+
-+ /* When we search for a specific alias we can avoid all the
-+ difficult parts and compare now with the name we are
-+ looking for. If it does not match we simply ignore all
-+ lines until the next line containing the start of a new
-+ alias is found. */
-+ ignore = (match != NULL
-+ && __strcasecmp (result->alias_name, match) != 0);
-+
-+ while (! ignore)
-+ {
-+ while (isspace (*line))
-+ ++line;
-+
-+ cp = first_unused;
-+ while (*line != '\0' && *line != ',')
-+ *first_unused++ = *line++;
-+
-+ if (first_unused != cp)
-+ {
-+ /* OK, we can have a regular entry or an include
-+ request. */
-+ if (*line != '\0')
-+ ++line;
-+ *first_unused++ = '\0';
-+
-+ if (strncmp (cp, ":include:", 9) != 0)
-+ {
-+ if (room_left < (first_unused - cp) + sizeof (char *))
-+ goto no_more_room;
-+ room_left -= (first_unused - cp) + sizeof (char *);
-+
-+ ++result->alias_members_len;
-+ }
-+ else
-+ {
-+ /* Oh well, we have to read the addressed file. */
-+ FILE *listfile;
-+ char *old_line = NULL;
-+
-+ first_unused = cp;
-+
-+ listfile = fopen (&cp[9], "r");
-+ /* If the file does not exist we simply ignore
-+ the statement. */
-+ if (listfile != NULL
-+ && (old_line = strdup (line)) != NULL)
-+ {
-+ while (! feof (listfile))
-+ {
-+ first_unused[room_left - 1] = '\xff';
-+ line = fgets (first_unused, room_left, listfile);
-+ if (line == NULL && feof (listfile))
-+ break;
-+ if (line == NULL
-+ || first_unused[room_left - 1] != '\xff')
-+ {
-+ free (old_line);
-+ goto no_more_room;
-+ }
-+
-+ /* Parse the line. */
-+ cp = strpbrk (line, "#\n");
-+ if (cp != NULL)
-+ *cp = '\0';
-+
-+ do
-+ {
-+ while (isspace (*line))
-+ ++line;
-+
-+ cp = first_unused;
-+ while (*line != '\0' && *line != ',')
-+ *first_unused++ = *line++;
-+
-+ if (*line != '\0')
-+ ++line;
-+
-+ if (first_unused != cp)
-+ {
-+ *first_unused++ = '\0';
-+ if (room_left < ((first_unused - cp)
-+ + __alignof__ (char *)))
-+ {
-+ free (old_line);
-+ goto no_more_room;
-+ }
-+ room_left -= ((first_unused - cp)
-+ + __alignof__ (char *));
-+ ++result->alias_members_len;
-+ }
-+ }
-+ while (*line != '\0');
-+ }
-+ fclose (listfile);
-+
-+ first_unused[room_left - 1] = '\0';
-+ strncpy (first_unused, old_line, room_left);
-+
-+ if (old_line != NULL)
-+ free (old_line);
-+
-+ if (first_unused[room_left - 1] != '\0')
-+ goto no_more_room;
-+ }
-+ }
-+ }
-+
-+ if (*line == '\0')
-+ {
-+ /* Get the next line. But we must be careful. We
-+ must not read the whole line at once since it
-+ might belong to the current alias. Simply read
-+ the first character. If it is a white space we
-+ have a continuation line. Otherwise it is the
-+ beginning of a new alias and we can push back the
-+ just read character. */
-+ int ch;
-+
-+ ch = fgetc (stream);
-+ if (ch == EOF || ch == '\n' || !isspace (ch))
-+ {
-+ size_t cnt;
-+
-+ /* Now prepare the return. Provide string
-+ pointers for the currently selected aliases. */
-+ if (ch != EOF)
-+ ungetc (ch, stream);
-+
-+ /* Adjust the pointer so it is aligned for
-+ storing pointers. */
-+ first_unused += __alignof__ (char *) - 1;
-+ first_unused -= ((first_unused - (char *) 0)
-+ % __alignof__ (char *));
-+ result->alias_members = (char **) first_unused;
-+
-+ /* Compute addresses of alias entry strings. */
-+ cp = result->alias_name;
-+ for (cnt = 0; cnt < result->alias_members_len; ++cnt)
-+ {
-+ cp = strchr (cp, '\0') + 1;
-+ result->alias_members[cnt] = cp;
-+ }
-+
-+ status = (result->alias_members_len == 0
-+ ? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS);
-+ break;
-+ }
-+
-+ /* The just read character is a white space and so
-+ can be ignored. */
-+ first_unused[room_left - 1] = '\xff';
-+ line = fgets (first_unused, room_left, stream);
-+ if (line == NULL && feof (stream))
-+ break;
-+ if (line == NULL || first_unused[room_left - 1] != '\xff')
-+ goto no_more_room;
-+ cp = strpbrk (line, "#\n");
-+ if (cp != NULL)
-+ *cp = '\0';
-+ }
-+ }
-+ }
-+
-+ if (status != NSS_STATUS_NOTFOUND)
-+ /* We read something. In any case break here. */
-+ break;
-+ }
-+
-+ return status;
-+}
-+
-+
-+enum nss_status
-+_nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
-+{
-+ /* Return next entry in host file. */
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ __libc_lock_lock (lock);
-+
-+ /* Be prepared that the set*ent function was not called before. */
-+ if (stream == NULL)
-+ status = internal_setent ();
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ {
-+ /* If the last use was not by the getent function we need the
-+ position the stream. */
-+ if (last_use != getent)
-+ {
-+ if (fsetpos (stream, &position) < 0)
-+ status = NSS_STATUS_UNAVAIL;
-+ else
-+ last_use = getent;
-+ }
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ {
-+ result->alias_local = 1;
-+
-+ /* Read lines until we get a definite result. */
-+ do
-+ status = get_next_alias (NULL, result, buffer, buflen);
-+ while (status == NSS_STATUS_RETURN);
-+
-+ /* If we successfully read an entry remember this position. */
-+ if (status == NSS_STATUS_SUCCESS)
-+ fgetpos (stream, &position);
-+ else
-+ last_use = none;
-+ }
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+
-+enum nss_status
-+_nss_files_getaliasbyname_r (const char *name, struct aliasent *result,
-+ char *buffer, size_t buflen)
-+{
-+ /* Return next entry in host file. */
-+ enum nss_status status = NSS_STATUS_SUCCESS;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ __libc_lock_lock (lock);
-+
-+ /* Open the stream or rest it. */
-+ status = internal_setent ();
-+ last_use = getby;
-+
-+ if (status == NSS_STATUS_SUCCESS)
-+ {
-+ result->alias_local = 1;
-+
-+ /* Read lines until we get a definite result. */
-+ do
-+ status = get_next_alias (name, result, buffer, buflen);
-+ while (status == NSS_STATUS_RETURN);
-+ }
-+
-+ internal_endent ();
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-ethers.c glibc-2.1.3/glibc-compat/nss_files/files-ethers.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-ethers.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-ethers.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,75 @@
-+/* Copyright (C) 1996 Free Software Foundation, Inc.
-+This file is part of the GNU C Library.
-+
-+The GNU C Library is free software; you can redistribute it and/or
-+modify it under the terms of the GNU Library General Public License as
-+published by the Free Software Foundation; either version 2 of the
-+License, or (at your option) any later version.
-+
-+The GNU C Library is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+Library General Public License for more details.
-+
-+You should have received a copy of the GNU Library General Public
-+License along with the GNU C Library; see the file COPYING.LIB. If
-+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+#include <string.h>
-+#include <netinet/if_ether.h>
-+
-+/* Because the `ethers' lookup does not fit so well in the scheme so
-+ we define a dummy struct here which helps us to use the available
-+ functions. */
-+struct etherent
-+{
-+ const char *e_name;
-+ struct ether_addr e_addr;
-+};
-+struct etherent_data {};
-+
-+#define ENTNAME etherent
-+#define DATABASE "ethers"
-+#include "files-parse.c"
-+LINE_PARSER
-+("#",
-+ /* Read the ethernet address: 6 x 8bit hexadecimal number. */
-+ {
-+ size_t cnt;
-+
-+ for (cnt = 0; cnt < 6; ++cnt)
-+ {
-+ unsigned int number;
-+
-+ if (cnt < 5)
-+ INT_FIELD (number, ISCOLON , 0, 16, (unsigned int))
-+ else
-+ INT_FIELD (number, isspace, 0, 16, (unsigned int))
-+
-+ if (number > 0xff)
-+ return 0;
-+ result->e_addr.ether_addr_octet[cnt] = number;
-+ }
-+ };
-+ STRING_FIELD (result->e_name, isspace, 1);
-+ )
-+
-+
-+#include GENERIC
-+
-+DB_LOOKUP (hostton, 1 + strlen (name), (".%s", name),
-+ {
-+ if (strcmp (result->e_name, name) == 0)
-+ break;
-+ }, const char *name)
-+
-+DB_LOOKUP (ntohost, 18, ("=%x:%x:%x:%x:%x:%x",
-+ addr->ether_addr_octet[0], addr->ether_addr_octet[1],
-+ addr->ether_addr_octet[2], addr->ether_addr_octet[3],
-+ addr->ether_addr_octet[4], addr->ether_addr_octet[5]),
-+ {
-+ if (memcmp (&result->e_addr, addr,
-+ sizeof (struct ether_addr)) == 0)
-+ break;
-+ }, struct ether_addr *addr)
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-grp.c glibc-2.1.3/glibc-compat/nss_files/files-grp.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-grp.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-grp.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,45 @@
-+/* Group file parser in nss_files module.
-+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <grp.h>
-+
-+#define STRUCTURE group
-+#define ENTNAME grent
-+#define DATABASE "group"
-+struct grent_data {};
-+
-+/* Our parser function is already defined in fgetgrent.c, so use that.
-+ to parse lines from the database file. */
-+#define EXTERN_PARSER
-+#include "files-parse.c"
-+#include GENERIC
-+
-+DB_LOOKUP (grnam, 1 + strlen (name), (".%s", name),
-+ {
-+ if (name[0] != '-' && name[0] != '+'
-+ && ! strcmp (name, result->gr_name))
-+ break;
-+ }, const char *name)
-+
-+DB_LOOKUP (grgid, 20, ("=%lu", (unsigned long int) gid),
-+ {
-+ if (result->gr_gid == gid && result->gr_name[0] != '+'
-+ && result->gr_name[0] != '-')
-+ break;
-+ }, gid_t gid)
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-hosts.c glibc-2.1.3/glibc-compat/nss_files/files-hosts.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-hosts.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-hosts.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,107 @@
-+/* Hosts file parser in nss_files module.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <arpa/nameser.h>
-+#include <netdb.h>
-+#include <resolv.h>
-+
-+
-+/* Get implementation for some internal functions. */
-+#include "../resolv/mapv4v6addr.h"
-+
-+
-+#define ENTNAME hostent
-+#define DATABASE "hosts"
-+#define NEED_H_ERRNO
-+
-+#define ENTDATA hostent_data
-+struct hostent_data
-+ {
-+ unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
-+ char *h_addr_ptrs[2]; /* Points to that and null terminator. */
-+ };
-+
-+#define TRAILING_LIST_MEMBER h_aliases
-+#define TRAILING_LIST_SEPARATOR_P isspace
-+#include "files-parse.c"
-+LINE_PARSER
-+("#",
-+ {
-+ char *addr;
-+
-+ STRING_FIELD (addr, isspace, 1);
-+
-+ /* Parse address. */
-+ if (inet_pton (AF_INET, addr, entdata->host_addr) > 0)
-+ {
-+ if (_res.options & RES_USE_INET6)
-+ {
-+ map_v4v6_address ((char *) entdata->host_addr,
-+ (char *) entdata->host_addr);
-+ result->h_addrtype = AF_INET6;
-+ result->h_length = IN6ADDRSZ;
-+ }
-+ else
-+ {
-+ result->h_addrtype = AF_INET;
-+ result->h_length = INADDRSZ;
-+ }
-+ }
-+ else if (inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
-+ {
-+ result->h_addrtype = AF_INET6;
-+ result->h_length = IN6ADDRSZ;
-+ }
-+ else
-+ /* Illegal address: ignore line. */
-+ return 0;
-+
-+ /* Store a pointer to the address in the expected form. */
-+ entdata->h_addr_ptrs[0] = entdata->host_addr;
-+ entdata->h_addr_ptrs[1] = NULL;
-+ result->h_addr_list = entdata->h_addr_ptrs;
-+
-+ STRING_FIELD (result->h_name, isspace, 1);
-+ })
-+
-+#include "files-XXX.c"
-+
-+DB_LOOKUP (hostbyname, ,,
-+ {
-+ if (result->h_addrtype != ((_res.options & RES_USE_INET6)
-+ ? AF_INET6 : AF_INET))
-+ continue;
-+ LOOKUP_NAME_CASE (h_name, h_aliases)
-+ }, const char *name)
-+
-+DB_LOOKUP (hostbyname2, ,,
-+ {
-+ if (result->h_addrtype != af)
-+ continue;
-+ LOOKUP_NAME_CASE (h_name, h_aliases)
-+ }, const char *name, int af)
-+
-+DB_LOOKUP (hostbyaddr, ,,
-+ {
-+ if (result->h_addrtype == type && result->h_length == len &&
-+ ! memcmp (addr, result->h_addr_list[0], len))
-+ break;
-+ }, const char *addr, int len, int type)
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-netgrp.c glibc-2.1.3/glibc-compat/nss_files/files-netgrp.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-netgrp.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-netgrp.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,268 @@
-+/* Netgroup file parser in nss_files modules.
-+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <ctype.h>
-+#include <errno.h>
-+#include <netdb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include "nsswitch.h"
-+#include "netgroup.h"
-+
-+#define DATAFILE "/etc/netgroup"
-+
-+
-+#define EXPAND(needed) \
-+ do \
-+ { \
-+ size_t old_cursor = result->cursor - result->data; \
-+ \
-+ result->data_size += 512 > 2 * needed ? 512 : 2 * needed; \
-+ result->data = realloc (result->data, result->data_size); \
-+ \
-+ if (result->data == NULL) \
-+ { \
-+ status = NSS_STATUS_UNAVAIL; \
-+ goto the_end; \
-+ } \
-+ \
-+ result->cursor = result->data + old_cursor; \
-+ } \
-+ while (0)
-+
-+
-+enum nss_status
-+_nss_files_setnetgrent (const char *group, struct __netgrent *result)
-+{
-+ FILE *fp;
-+ enum nss_status status;
-+
-+ if (group[0] == '\0')
-+ return NSS_STATUS_UNAVAIL;
-+
-+ /* Find the netgroups file and open it. */
-+ fp = fopen (DATAFILE, "r");
-+ if (fp == NULL)
-+ status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-+ else
-+ {
-+ /* Read the file line by line and try to find the description
-+ GROUP. We must take care for long lines. */
-+ char *line = NULL;
-+ size_t line_len = 0;
-+ const ssize_t group_len = strlen (group);
-+
-+ status = NSS_STATUS_NOTFOUND;
-+ result->cursor = result->data;
-+
-+ while (!feof (fp))
-+ {
-+ ssize_t curlen = getline (&line, &line_len, fp);
-+ int found;
-+
-+ if (curlen < 0)
-+ {
-+ status = NSS_STATUS_NOTFOUND;
-+ break;
-+ }
-+
-+ found = (curlen > group_len && strncmp (line, group, group_len) == 0
-+ && isspace (line[group_len]));
-+
-+ /* Read the whole line (including continuation) and store it
-+ if FOUND in nonzero. Otherwise we don't need it. */
-+ if (found)
-+ {
-+ /* Store the data from the first line. */
-+ EXPAND (curlen - group_len);
-+ memcpy (result->cursor, &line[group_len + 1],
-+ curlen - group_len);
-+ result->cursor += (curlen - group_len) - 1;
-+ }
-+
-+ while (line[curlen - 1] == '\n' && line[curlen - 2] == '\\')
-+ {
-+ /* Yes, we have a continuation line. */
-+ if (found)
-+ /* Remove these characters from the stored line. */
-+ result->cursor -= 2;
-+
-+ /* Get next line. */
-+ curlen = getline (&line, &line_len, fp);
-+ if (curlen <= 0)
-+ break;
-+
-+ if (found)
-+ {
-+ /* Make sure we have enough room. */
-+ EXPAND (1 + curlen + 1);
-+
-+ /* Add separator in case next line starts immediately. */
-+ *result->cursor++ = ' ';
-+
-+ /* Copy new line. */
-+ memcpy (result->cursor, line, curlen + 1);
-+ result->cursor += curlen;
-+ }
-+ }
-+
-+ if (found)
-+ {
-+ /* Now we have read the line. */
-+ status = NSS_STATUS_SUCCESS;
-+ result->cursor = result->data;
-+ result->first = 1;
-+ break;
-+ }
-+ }
-+
-+ the_end:
-+ /* We don't need the file and the line buffer anymore. */
-+ free (line);
-+ fclose (fp);
-+ }
-+
-+ return status;
-+}
-+
-+
-+int
-+_nss_files_endnetgrent (struct __netgrent *result)
-+{
-+ /* Free allocated memory for data if some is present. */
-+ if (result->data != NULL)
-+ {
-+ free (result->data);
-+ result->data = NULL;
-+ result->data_size = 0;
-+ result->cursor = NULL;
-+ }
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+
-+enum nss_status
-+_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
-+ char *buffer, int buflen)
-+{
-+ enum nss_status status;
-+ const char *host, *user, *domain;
-+ char *cp = *cursor;
-+
-+ /* Some sanity checks. */
-+ if (cp == NULL)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ /* First skip leading spaces. */
-+ while (isspace (*cp))
-+ ++cp;
-+
-+ if (*cp != '(')
-+ {
-+ /* We have a list of other netgroups. */
-+ char *name = cp;
-+
-+ while (*cp != '\0' && ! isspace (*cp))
-+ ++cp;
-+
-+ if (name != cp)
-+ {
-+ /* It is another netgroup name. */
-+ int last = *cp == '\0';
-+
-+ result->type = group_val;
-+ result->val.group = name;
-+ *cp = '\0';
-+ if (! last)
-+ ++cp;
-+ *cursor = cp;
-+ result->first = 0;
-+
-+ return NSS_STATUS_SUCCESS;
-+ }
-+
-+ return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
-+ }
-+
-+ /* Match host name. */
-+ host = ++cp;
-+ while (*cp != ',')
-+ if (*cp++ == '\0')
-+ return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
-+
-+ /* Match user name. */
-+ user = ++cp;
-+ while (*cp != ',')
-+ if (*cp++ == '\0')
-+ return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
-+
-+ /* Match domain name. */
-+ domain = ++cp;
-+ while (*cp != ')')
-+ if (*cp++ == '\0')
-+ return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
-+ ++cp;
-+
-+
-+ /* When we got here we have found an entry. Before we can copy it
-+ to the private buffer we have to make sure it is big enough. */
-+ if (cp - host > buflen)
-+ {
-+ __set_errno (ERANGE);
-+ status = NSS_STATUS_UNAVAIL;
-+ }
-+ else
-+ {
-+ memcpy (buffer, host, cp - host);
-+ result->type = triple_val;
-+
-+ buffer[(user - host) - 1] = '\0';
-+ result->val.triple.host = *host == ',' ? NULL : buffer;
-+
-+ buffer[(domain - host) - 1] = '\0';
-+ result->val.triple.user = *user == ',' ? NULL : buffer + (user - host);
-+
-+ buffer[(cp - host) - 1] = '\0';
-+ result->val.triple.domain =
-+ *domain == ')' ? NULL : buffer + (domain - host);
-+
-+ status = NSS_STATUS_SUCCESS;
-+
-+ /* Remember where we stopped reading. */
-+ *cursor = cp;
-+
-+ result->first = 0;
-+ }
-+
-+ return status;
-+}
-+
-+
-+enum nss_status
-+_nss_files_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen)
-+{
-+ enum nss_status status;
-+
-+ status = _nss_netgroup_parseline (&result->cursor, result, buffer, buflen);
-+
-+ return status;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-network.c glibc-2.1.3/glibc-compat/nss_files/files-network.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-network.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-network.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,56 @@
-+/* Networks file parser in nss_files module.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <netdb.h>
-+
-+#define ENTNAME netent
-+#define DATABASE "networks"
-+
-+struct netent_data {};
-+
-+#define TRAILING_LIST_MEMBER n_aliases
-+#define TRAILING_LIST_SEPARATOR_P isspace
-+#include "files-parse.c"
-+LINE_PARSER
-+("#",
-+ {
-+ char *addr;
-+
-+ STRING_FIELD (result->n_name, isspace, 1);
-+
-+ STRING_FIELD (addr, isspace, 1);
-+ result->n_net = inet_network (addr);
-+ result->n_addrtype = AF_INET;
-+
-+ })
-+
-+#include "files-XXX.c"
-+
-+DB_LOOKUP (netbyname, ,,
-+ LOOKUP_NAME_CASE (n_name, n_aliases),
-+ const char *name)
-+
-+DB_LOOKUP (netbyaddr, ,,
-+ {
-+ if (result->n_addrtype == type && result->n_net == net)
-+ /* Bingo! */
-+ break;
-+ }, unsigned long int net, int type)
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-parse.c glibc-2.1.3/glibc-compat/nss_files/files-parse.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-parse.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-parse.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,251 @@
-+/* Common code for file-based database parsers in nss_files module.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <stdlib.h>
-+
-+/* These symbols are defined by the including source file:
-+
-+ ENTNAME -- database name of the structure and functions (hostent, pwent).
-+ STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
-+ DATABASE -- string of the database file's name ("hosts", "passwd").
-+
-+ ENTDATA -- if defined, `struct ENTDATA' is used by the parser to store
-+ things pointed to by the resultant `struct STRUCTURE'.
-+
-+ NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
-+
-+ Also see files-XXX.c. */
-+
-+#define CONCAT(a,b) CONCAT1(a,b)
-+#define CONCAT1(a,b) a##b
-+
-+#ifndef STRUCTURE
-+# define STRUCTURE ENTNAME
-+#endif
-+
-+
-+struct parser_data
-+ {
-+#ifdef ENTDATA
-+ struct ENTDATA entdata;
-+# define ENTDATA_DECL(data) struct ENTDATA *const entdata = &data->entdata;
-+#else
-+# define ENTDATA_DECL(data)
-+#endif
-+ char linebuffer[0];
-+ };
-+
-+#ifdef ENTDATA
-+/* The function can't be exported, because the entdata structure
-+ is defined only in files-foo.c. */
-+# define parser_stclass static inline
-+#else
-+/* Export the line parser function so it can be used in nss_db. */
-+# define parser_stclass /* Global */
-+# define parse_line CONCAT(_nss_files_parse_,ENTNAME)
-+#endif
-+
-+
-+#ifdef EXTERN_PARSER
-+
-+/* The parser is defined in a different module. */
-+extern int parse_line (char *line, struct STRUCTURE *result,
-+ struct parser_data *data, size_t datalen);
-+
-+# define LINE_PARSER(EOLSET, BODY) /* Do nothing */
-+
-+#else
-+
-+/* Define a line parsing function. */
-+
-+# define LINE_PARSER(EOLSET, BODY) \
-+parser_stclass int \
-+parse_line (char *line, struct STRUCTURE *result, \
-+ struct parser_data *data, size_t datalen) \
-+{ \
-+ ENTDATA_DECL (data) \
-+ char *p = strpbrk (line, EOLSET "\n"); \
-+ if (p != NULL) \
-+ *p = '\0'; \
-+ BODY; \
-+ TRAILING_LIST_PARSER; \
-+ return 1; \
-+}
-+
-+
-+# define STRING_FIELD(variable, terminator_p, swallow) \
-+ { \
-+ variable = line; \
-+ while (*line != '\0' && !terminator_p (*line)) \
-+ ++line; \
-+ if (*line != '\0') \
-+ { \
-+ *line = '\0'; \
-+ do \
-+ ++line; \
-+ while (swallow && terminator_p (*line)); \
-+ } \
-+ }
-+
-+# define INT_FIELD(variable, terminator_p, swallow, base, convert) \
-+ { \
-+ char *endp; \
-+ variable = convert (strtoul (line, &endp, base)); \
-+ if (endp == line) \
-+ return 0; \
-+ else if (terminator_p (*endp)) \
-+ do \
-+ ++endp; \
-+ while (swallow && terminator_p (*endp)); \
-+ else if (*endp != '\0') \
-+ return 0; \
-+ line = endp; \
-+ }
-+
-+# define INT_FIELD_MAYBE_NULL(variable, terminator_p, swallow, base, convert, default) \
-+ { \
-+ char *endp; \
-+ if (*line == '\0') \
-+ /* We expect some more input, so don't allow the string to end here. */ \
-+ return 0; \
-+ variable = convert (strtoul (line, &endp, base)); \
-+ if (endp == line) \
-+ variable = default; \
-+ if (terminator_p (*endp)) \
-+ do \
-+ ++endp; \
-+ while (swallow && terminator_p (*endp)); \
-+ else if (*endp != '\0') \
-+ return 0; \
-+ line = endp; \
-+ }
-+
-+# define ISCOLON(c) ((c) == ':')
-+
-+
-+# ifndef TRAILING_LIST_MEMBER
-+# define TRAILING_LIST_PARSER /* Nothing to do. */
-+# else
-+
-+# define TRAILING_LIST_PARSER \
-+{ \
-+ char **list = parse_list (line, data, datalen); \
-+ if (list) \
-+ result->TRAILING_LIST_MEMBER = list; \
-+ else \
-+ return -1; /* -1 indicates we ran out of space. */ \
-+}
-+
-+static inline char **
-+parse_list (char *line, struct parser_data *data, size_t datalen)
-+{
-+ char *eol, **list, **p;
-+
-+ if (line >= data->linebuffer && line < (char *) data + datalen)
-+ /* Find the end of the line buffer, we will use the space in DATA after
-+ it for storing the vector of pointers. */
-+ eol = strchr (line, '\0') + 1;
-+ else
-+ /* LINE does not point within DATA->linebuffer, so that space is
-+ not being used for scratch space right now. We can use all of
-+ it for the pointer vector storage. */
-+ eol = data->linebuffer;
-+ /* Adjust the pointer so it is aligned for storing pointers. */
-+ eol += __alignof__ (char *) - 1;
-+ eol -= (eol - (char *) 0) % __alignof__ (char *);
-+ /* We will start the storage here for the vector of pointers. */
-+ list = (char **) eol;
-+
-+ p = list;
-+ while (1)
-+ {
-+ char *elt;
-+
-+ if ((size_t) ((char *) &p[1] - (char *) data) > datalen)
-+ {
-+ /* We cannot fit another pointer in the buffer. */
-+ __set_errno (ERANGE);
-+ return NULL;
-+ }
-+ if (*line == '\0')
-+ break;
-+
-+ /* Skip leading white space. This might not be portable but useful. */
-+ while (isspace (*line))
-+ ++line;
-+
-+ elt = line;
-+ while (1)
-+ {
-+ if (*line == '\0' || TRAILING_LIST_SEPARATOR_P (*line))
-+ {
-+ /* End of the next entry. */
-+ if (line > elt)
-+ /* We really found some data. */
-+ *p++ = elt;
-+
-+ /* Terminate string if necessary. */
-+ if (*line != '\0')
-+ *line++ = '\0';
-+ break;
-+ }
-+ ++line;
-+ }
-+ }
-+ *p = NULL;
-+
-+ return list;
-+}
-+
-+# endif /* TRAILING_LIST_MEMBER */
-+#endif /* EXTERN_PARSER */
-+
-+
-+#define LOOKUP_NAME(nameelt, aliaselt) \
-+{ \
-+ char **ap; \
-+ if (! strcmp (name, result->nameelt)) \
-+ break; \
-+ for (ap = result->aliaselt; *ap; ++ap) \
-+ if (! strcmp (name, *ap)) \
-+ break; \
-+ if (*ap) \
-+ break; \
-+}
-+
-+#define LOOKUP_NAME_CASE(nameelt, aliaselt) \
-+{ \
-+ char **ap; \
-+ if (! __strcasecmp (name, result->nameelt)) \
-+ break; \
-+ for (ap = result->aliaselt; *ap; ++ap) \
-+ if (! __strcasecmp (name, *ap)) \
-+ break; \
-+ if (*ap) \
-+ break; \
-+}
-+
-+
-+/* This is defined by db-*.c to include "../nss_db/db-XXX.c" instead. */
-+#ifndef GENERIC
-+# define GENERIC "files-XXX.c"
-+#endif
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-proto.c glibc-2.1.3/glibc-compat/nss_files/files-proto.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-proto.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-proto.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,47 @@
-+/* Protocols file parser in nss_files module.
-+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <netdb.h>
-+
-+
-+#define ENTNAME protoent
-+#define DATABASE "protocols"
-+
-+struct protoent_data {};
-+
-+#define TRAILING_LIST_MEMBER p_aliases
-+#define TRAILING_LIST_SEPARATOR_P isspace
-+#include "files-parse.c"
-+LINE_PARSER
-+("#",
-+ STRING_FIELD (result->p_name, isspace, 1);
-+ INT_FIELD (result->p_proto, isspace, 1, 10,);
-+ )
-+
-+#include GENERIC
-+
-+DB_LOOKUP (protobyname, 1 + strlen (name), (".%s", name),
-+ LOOKUP_NAME (p_name, p_aliases),
-+ const char *name)
-+
-+DB_LOOKUP (protobynumber, 20, ("=%d", proto),
-+ {
-+ if (result->p_proto == proto)
-+ break;
-+ }, int proto)
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-pwd.c glibc-2.1.3/glibc-compat/nss_files/files-pwd.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-pwd.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-pwd.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,45 @@
-+/* User file parser in nss_files module.
-+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <pwd.h>
-+
-+#define STRUCTURE passwd
-+#define ENTNAME pwent
-+#define DATABASE "passwd"
-+struct pwent_data {};
-+
-+/* Our parser function is already defined in fgetpwent_r.c, so use that
-+ to parse lines from the database file. */
-+#define EXTERN_PARSER
-+#include "files-parse.c"
-+#include GENERIC
-+
-+DB_LOOKUP (pwnam, 1 + strlen (name), (".%s", name),
-+ {
-+ if (name[0] != '+' && name[0] != '-'
-+ && ! strcmp (name, result->pw_name))
-+ break;
-+ }, const char *name)
-+
-+DB_LOOKUP (pwuid, 20, ("=%lu", (unsigned long int) uid),
-+ {
-+ if (result->pw_uid == uid && result->pw_name[0] != '+'
-+ && result->pw_name[0] != '-')
-+ break;
-+ }, uid_t uid)
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-rpc.c glibc-2.1.3/glibc-compat/nss_files/files-rpc.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-rpc.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-rpc.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,47 @@
-+/* SunRPC program number file parser in nss_files module.
-+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <rpc/netdb.h>
-+
-+
-+#define ENTNAME rpcent
-+#define DATABASE "rpc"
-+
-+struct rpcent_data {};
-+
-+#define TRAILING_LIST_MEMBER r_aliases
-+#define TRAILING_LIST_SEPARATOR_P isspace
-+#include "files-parse.c"
-+LINE_PARSER
-+("#",
-+ STRING_FIELD (result->r_name, isspace, 1);
-+ INT_FIELD (result->r_number, isspace, 1, 10,);
-+ )
-+
-+#include GENERIC
-+
-+DB_LOOKUP (rpcbyname, 1 + strlen (name), (".%s", name),
-+ LOOKUP_NAME (r_name, r_aliases),
-+ const char *name)
-+
-+DB_LOOKUP (rpcbynumber, 20, ("=%d", number),
-+ {
-+ if (result->r_number == number)
-+ break;
-+ }, int number)
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-service.c glibc-2.1.3/glibc-compat/nss_files/files-service.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-service.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-service.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,60 @@
-+/* Services file parser in nss_files module.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <netinet/in.h>
-+#include <netdb.h>
-+
-+
-+#define ENTNAME servent
-+#define DATABASE "services"
-+
-+struct servent_data {};
-+
-+#define TRAILING_LIST_MEMBER s_aliases
-+#define TRAILING_LIST_SEPARATOR_P isspace
-+#include "files-parse.c"
-+#define ISSLASH(c) ((c) == '/')
-+LINE_PARSER
-+("#",
-+ STRING_FIELD (result->s_name, isspace, 1);
-+ INT_FIELD (result->s_port, ISSLASH, 10, 0, htons);
-+ STRING_FIELD (result->s_proto, isspace, 1);
-+ )
-+
-+#include GENERIC
-+
-+DB_LOOKUP (servbyname, 2 + strlen (name) + (proto ? strlen (proto) : 0),
-+ (".%s/%s", name, proto ?: ""),
-+ {
-+ /* Must match both protocol (if specified) and name. */
-+ if (proto != NULL && strcmp (result->s_proto, proto))
-+ continue;
-+ LOOKUP_NAME (s_name, s_aliases)
-+ },
-+ const char *name, const char *proto)
-+
-+DB_LOOKUP (servbyport, 21 + (proto ? strlen (proto) : 0),
-+ ("=%d/%s", ntohs (port), proto ?: ""),
-+ {
-+ /* Must match both port and protocol. */
-+ if (result->s_port == port
-+ && (proto == NULL
-+ || strcmp (result->s_proto, proto) == 0))
-+ break;
-+ }, int port, const char *proto)
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_files/files-spwd.c glibc-2.1.3/glibc-compat/nss_files/files-spwd.c
---- ../glibc-2.1.3/glibc-compat/nss_files/files-spwd.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_files/files-spwd.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,38 @@
-+/* User file parser in nss_files module.
-+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <shadow.h>
-+
-+#define STRUCTURE spwd
-+#define ENTNAME spent
-+#define DATABASE "shadow"
-+struct spent_data {};
-+
-+/* Our parser function is already defined in sgetspent_r.c, so use that
-+ to parse lines from the database file. */
-+#define EXTERN_PARSER
-+#include "files-parse.c"
-+#include GENERIC
-+
-+DB_LOOKUP (spnam, 1 + strlen (name), (".%s", name),
-+ {
-+ if (name[0] != '+' && name[0] != '-'
-+ && ! strcmp (name, result->sp_namp))
-+ break;
-+ }, const char *name)
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-alias.c glibc-2.1.3/glibc-compat/nss_nis/nis-alias.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-alias.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-alias.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,278 @@
-+/* Copyright (C) 1996, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <aliases.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+__libc_lock_define_initialized (static, lock)
-+
-+static bool_t new_start = 1;
-+static char *oldkey = NULL;
-+static int oldkeylen = 0;
-+
-+static int
-+_nss_nis_parse_aliasent (const char *key, char *alias, struct aliasent *result,
-+ char *buffer, size_t buflen)
-+{
-+ char *first_unused = buffer + strlen (alias) + 1;
-+ size_t room_left =
-+ buflen - (buflen % __alignof__ (char *)) - strlen (alias) - 2;
-+ char *line;
-+ char *cp;
-+
-+ result->alias_members_len = 0;
-+ *first_unused = '\0';
-+ first_unused++;
-+ strcpy (first_unused, key);
-+
-+ if (first_unused[room_left - 1] != '\0')
-+ {
-+ /* The line is too long for our buffer. */
-+ no_more_room:
-+ __set_errno (ERANGE);
-+ return -1;
-+ }
-+
-+ result->alias_name = first_unused;
-+
-+ /* Terminate the line for any case. */
-+ cp = strpbrk (alias, "#\n");
-+ if (cp != NULL)
-+ *cp = '\0';
-+
-+ first_unused += strlen (result->alias_name) + 1;
-+ /* Adjust the pointer so it is aligned for
-+ storing pointers. */
-+ first_unused += __alignof__ (char *) - 1;
-+ first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
-+ result->alias_members = (char **) first_unused;
-+
-+ line = alias;
-+
-+ while (*line != '\0')
-+ {
-+ /* Skip leading blanks. */
-+ while (isspace (*line))
-+ line++;
-+
-+ if (*line == '\0')
-+ break;
-+
-+ if (room_left < sizeof (char *))
-+ goto no_more_room;
-+ room_left -= sizeof (char *);
-+ result->alias_members[result->alias_members_len] = line;
-+
-+ while (*line != '\0' && *line != ',')
-+ line++;
-+
-+ if (line != result->alias_members[result->alias_members_len])
-+ {
-+ *line = '\0';
-+ line++;
-+ result->alias_members_len++;
-+ }
-+ }
-+ return result->alias_members_len == 0 ? 0 : 1;
-+}
-+
-+enum nss_status
-+_nss_nis_setaliasent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_endaliasent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+internal_nis_getaliasent_r (struct aliasent *alias, char *buffer,
-+ size_t buflen)
-+{
-+ char *domain;
-+ char *result;
-+ int len;
-+ char *outkey;
-+ int keylen;
-+ char *p;
-+ int parse_res;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ alias->alias_local = 0;
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ enum nss_status retval;
-+
-+ if (new_start)
-+ retval = yperr2nss (yp_first (domain, "mail.aliases",
-+ &outkey, &keylen, &result, &len));
-+ else
-+ retval = yperr2nss ( yp_next (domain, "mail.aliases", oldkey,
-+ oldkeylen, &outkey, &keylen,
-+ &result, &len));
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_nis_parse_aliasent (outkey, p, alias, buffer, buflen);
-+ if (parse_res == -1)
-+ {
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ free (oldkey);
-+ oldkey = outkey;
-+ oldkeylen = keylen;
-+ new_start = 0;
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getaliasent_r (struct aliasent *alias, char *buffer, size_t buflen)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_getaliasent_r (alias, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
-+ char *buffer, size_t buflen)
-+{
-+ enum nss_status retval;
-+ int parse_res;
-+ char *domain;
-+ char *result;
-+ int len;
-+ char *p;
-+ size_t namlen = strlen (name);
-+ char name2[namlen + 1];
-+ int i;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ /* Convert name to lowercase. */
-+ for (i = 0; i < namlen; ++i)
-+ name2[i] = tolower (name[i]);
-+ name2[i] = '\0';
-+
-+ retval = yperr2nss (yp_match (domain, "mail.aliases", name, namlen,
-+ &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ alias->alias_local = 0;
-+ parse_res = _nss_nis_parse_aliasent (name, p, alias, buffer, buflen);
-+ if (parse_res == -1)
-+ return NSS_STATUS_TRYAGAIN;
-+ else
-+ if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ return NSS_STATUS_SUCCESS;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-ethers.c glibc-2.1.3/glibc-compat/nss_nis/nis-ethers.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-ethers.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-ethers.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,299 @@
-+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+#include <netinet/if_ether.h>
-+
-+#include "nss-nis.h"
-+
-+/* Protect global state against multiple changers */
-+__libc_lock_define_initialized (static, lock)
-+
-+struct ether
-+{
-+ const char *e_name;
-+ struct ether_addr e_addr;
-+};
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME etherent
-+#define STRUCTURE ether
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+struct response
-+{
-+ char *val;
-+ struct response *next;
-+};
-+
-+static struct response *start = NULL;
-+static struct response *next = NULL;
-+
-+static int
-+saveit (int instatus, char *inkey, int inkeylen, char *inval,
-+ int invallen, char *indata)
-+{
-+ if (instatus != YP_TRUE)
-+ return instatus;
-+
-+ if (inkey && inkeylen > 0 && inval && invallen > 0)
-+ {
-+ if (start == NULL)
-+ {
-+ start = malloc (sizeof (struct response));
-+ next = start;
-+ }
-+ else
-+ {
-+ next->next = malloc (sizeof (struct response));
-+ next = next->next;
-+ }
-+ next->next = NULL;
-+ next->val = malloc (invallen + 1);
-+ strncpy (next->val, inval, invallen);
-+ next->val[invallen] = '\0';
-+ }
-+
-+ return 0;
-+}
-+
-+enum nss_status
-+internal_nis_setetherent (void)
-+{
-+ char *domainname;
-+ struct ypall_callback ypcb;
-+ enum nss_status status;
-+
-+ yp_get_default_domain (&domainname);
-+
-+ while (start != NULL)
-+ {
-+ if (start->val != NULL)
-+ free (start->val);
-+ next = start;
-+ start = start->next;
-+ free (next);
-+ }
-+ start = NULL;
-+
-+ ypcb.foreach = saveit;
-+ ypcb.data = NULL;
-+ status = yperr2nss (yp_all (domainname, "ethers.byname", &ypcb));
-+ next = start;
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_setetherent (void)
-+{
-+ enum nss_status result;
-+
-+ __libc_lock_lock (lock);
-+
-+ result = internal_nis_setetherent ();
-+
-+ __libc_lock_unlock (lock);
-+
-+ return result;
-+}
-+
-+enum nss_status
-+_nss_nis_endetherent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ while (start != NULL)
-+ {
-+ if (start->val != NULL)
-+ free (start->val);
-+ next = start;
-+ start = start->next;
-+ free (next);
-+ }
-+ start = NULL;
-+ next = NULL;
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+internal_nis_getetherent_r (struct ether *eth, char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ int parse_res;
-+
-+ if (start == NULL)
-+ internal_nis_setetherent ();
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ char *p;
-+
-+ if (next == NULL)
-+ return NSS_STATUS_NOTFOUND;
-+ p = strncpy (buffer, next->val, buflen);
-+ next = next->next;
-+
-+ while (isspace (*p))
-+ ++p;
-+
-+ parse_res = _nss_files_parse_etherent (p, eth, data, buflen);
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getetherent_r (struct ether *result, char *buffer, size_t buflen)
-+{
-+ int status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_getetherent_r (result, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_gethostton_r (const char *name, struct ether *eth,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, parse_res;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ retval = yperr2nss (yp_match (domain, "ethers.byname", name,
-+ strlen (name), &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_etherent (p, eth, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getntohost_r (struct ether_addr *addr, struct ether *eth,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, nlen, parse_res;
-+ char buf[33];
-+
-+ if (addr == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ nlen = sprintf (buf, "%x:%x:%x:%x:%x:%x",
-+ (int) addr->ether_addr_octet[0],
-+ (int) addr->ether_addr_octet[1],
-+ (int) addr->ether_addr_octet[2],
-+ (int) addr->ether_addr_octet[3],
-+ (int) addr->ether_addr_octet[4],
-+ (int) addr->ether_addr_octet[5]);
-+
-+ retval = yperr2nss (yp_match (domain, "ethers.byaddr", buf,
-+ nlen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_etherent (p, eth, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-grp.c glibc-2.1.3/glibc-compat/nss_nis/nis-grp.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-grp.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-grp.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,249 @@
-+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <grp.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME grent
-+#define STRUCTURE group
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+/* Protect global state against multiple changers */
-+__libc_lock_define_initialized (static, lock)
-+
-+static bool_t new_start = 1;
-+static char *oldkey = NULL;
-+static int oldkeylen = 0;
-+
-+enum nss_status
-+_nss_nis_setgrent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_endgrent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *domain, *result, *outkey;
-+ int len, keylen, parse_res;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ enum nss_status retval;
-+ char *p;
-+
-+ if (new_start)
-+ retval = yperr2nss (yp_first (domain, "group.byname",
-+ &outkey, &keylen, &result, &len));
-+ else
-+ retval = yperr2nss ( yp_next (domain, "group.byname",
-+ oldkey, oldkeylen,
-+ &outkey, &keylen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_grent (p, grp, data, buflen);
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+
-+ free (oldkey);
-+ oldkey = outkey;
-+ oldkeylen = keylen;
-+ new_start = 0;
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getgrent_r (struct group *result, char *buffer, size_t buflen)
-+{
-+ int status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_getgrent_r (result, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getgrnam_r (const char *name, struct group *grp,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, parse_res;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ retval = yperr2nss (yp_match (domain, "group.byname", name,
-+ strlen (name), &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_grent (p, grp, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getgrgid_r (gid_t gid, struct group *grp,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, nlen, parse_res;
-+ char buf[32];
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ nlen = sprintf (buf, "%d", gid);
-+
-+ retval = yperr2nss (yp_match (domain, "group.bygid", buf,
-+ nlen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_grent (p, grp, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-hosts.c glibc-2.1.3/glibc-compat/nss_nis/nis-hosts.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-hosts.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-hosts.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,417 @@
-+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <ctype.h>
-+#include <netdb.h>
-+#include <string.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <resolv.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+/* Get implementation for some internal functions. */
-+#include "../../resolv/mapv4v6addr.h"
-+#include "../../resolv/mapv4v6hostent.h"
-+
-+#define ENTNAME hostent
-+#define DATABASE "hosts"
-+#define NEED_H_ERRNO
-+
-+#define ENTDATA hostent_data
-+struct hostent_data
-+ {
-+ unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
-+ char *h_addr_ptrs[2]; /* Points to that and null terminator. */
-+ };
-+
-+#define TRAILING_LIST_MEMBER h_aliases
-+#define TRAILING_LIST_SEPARATOR_P isspace
-+#include "../nss_files/files-parse.c"
-+LINE_PARSER
-+("#",
-+ {
-+ char *addr;
-+
-+ STRING_FIELD (addr, isspace, 1);
-+
-+ /* Parse address. */
-+ if ((_res.options & RES_USE_INET6)
-+ && inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
-+ {
-+ result->h_addrtype = AF_INET6;
-+ result->h_length = IN6ADDRSZ;
-+ }
-+ else
-+ if (inet_pton (AF_INET, addr, entdata->host_addr) > 0)
-+ {
-+ if (_res.options & RES_USE_INET6)
-+ {
-+ map_v4v6_address ((char *) entdata->host_addr,
-+ (char *) entdata->host_addr);
-+ result->h_addrtype = AF_INET6;
-+ result->h_length = IN6ADDRSZ;
-+ }
-+ else
-+ {
-+ result->h_addrtype = AF_INET;
-+ result->h_length = INADDRSZ;
-+ }
-+ }
-+ else
-+ /* Illegal address: ignore line. */
-+ return 0;
-+
-+ /* Store a pointer to the address in the expected form. */
-+ entdata->h_addr_ptrs[0] = entdata->host_addr;
-+ entdata->h_addr_ptrs[1] = NULL;
-+ result->h_addr_list = entdata->h_addr_ptrs;
-+
-+ /* If we need the host entry in IPv6 form change it now. */
-+ if (_res.options & RES_USE_INET6)
-+ {
-+ char *bufptr = data->linebuffer;
-+ size_t buflen = (char *) data + datalen - bufptr;
-+ int ibuflen = buflen; /* Use this for machines with size_t > int. */
-+ map_v4v6_hostent (result, &bufptr, &ibuflen);
-+ buflen = ibuflen;
-+ }
-+
-+ STRING_FIELD (result->h_name, isspace, 1);
-+ }
-+)
-+
-+__libc_lock_define_initialized (static, lock)
-+
-+static bool_t new_start = 1;
-+static char *oldkey = NULL;
-+static int oldkeylen = 0;
-+
-+enum nss_status
-+_nss_nis_sethostent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_endhostent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+internal_nis_gethostent_r (struct hostent *host, char *buffer,
-+ size_t buflen, int *h_errnop)
-+{
-+ char *domain;
-+ char *result;
-+ int len, parse_res;
-+ char *outkey;
-+ int keylen;
-+ struct parser_data *data = (void *) buffer;
-+ size_t linebuflen = buffer + buflen - data->linebuffer;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ if (buflen < sizeof *data + 1)
-+ {
-+ __set_errno (ERANGE);
-+ *h_errnop = NETDB_INTERNAL;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ enum nss_status retval;
-+ char *p;
-+
-+ if (new_start)
-+ retval = yperr2nss (yp_first (domain, "hosts.byname",
-+ &outkey, &keylen, &result, &len));
-+ else
-+ retval = yperr2nss ( yp_next (domain, "hosts.byname",
-+ oldkey, oldkeylen,
-+ &outkey, &keylen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ switch (retval)
-+ {
-+ case NSS_STATUS_TRYAGAIN:
-+ __set_errno (EAGAIN);
-+ *h_errnop = TRY_AGAIN;
-+ break;
-+ case NSS_STATUS_NOTFOUND:
-+ *h_errnop = HOST_NOT_FOUND;
-+ break;
-+ default:
-+ *h_errnop = NO_RECOVERY;
-+ break;
-+ }
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > linebuflen)
-+ {
-+ free (result);
-+ *h_errnop = NETDB_INTERNAL;
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (data->linebuffer, result, len);
-+ data->linebuffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = parse_line (p, host, data, buflen);
-+ if (parse_res == -1 && errno == ERANGE)
-+ {
-+ *h_errnop = NETDB_INTERNAL;;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ free (oldkey);
-+ oldkey = outkey;
-+ oldkeylen = keylen;
-+ new_start = 0;
-+ }
-+ while (!parse_res);
-+
-+ *h_errnop = NETDB_SUCCESS;
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+int
-+_nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen,
-+ int *h_errnop)
-+{
-+ int status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_gethostent_r (host, buffer, buflen, h_errnop);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
-+ char *buffer, size_t buflen, int *h_errnop)
-+{
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, parse_res;
-+ struct parser_data *data = (void *) buffer;
-+ size_t linebuflen = buffer + buflen - data->linebuffer;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ if (buflen < sizeof *data + 1)
-+ {
-+ *h_errnop = NETDB_INTERNAL;
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ else
-+ {
-+ /* Convert name to lowercase. */
-+ size_t namelen = strlen (name);
-+ char name2[namelen + 1];
-+ int i;
-+
-+ for (i = 0; i < namelen; ++i)
-+ name2[i] = tolower (name[i]);
-+ name2[i] = '\0';
-+
-+ retval = yperr2nss (yp_match (domain, "hosts.byname", name2,
-+ namelen, &result, &len));
-+
-+ }
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ {
-+ *h_errnop = TRY_AGAIN;
-+ __set_errno (EAGAIN);
-+ }
-+ if (retval == NSS_STATUS_NOTFOUND)
-+ *h_errnop = HOST_NOT_FOUND;
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > linebuflen)
-+ {
-+ free (result);
-+ *h_errnop = NETDB_INTERNAL;
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (data->linebuffer, result, len);
-+ data->linebuffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = parse_line (p, host, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ {
-+ *h_errnop = NETDB_INTERNAL;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ if (parse_res == 0 || host->h_addrtype != af)
-+ {
-+ *h_errnop = HOST_NOT_FOUND;
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+
-+ *h_errnop = NETDB_SUCCESS;
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_gethostbyname_r (const char *name, struct hostent *host,
-+ char *buffer, size_t buflen, int *h_errnop)
-+{
-+ if (_res.options & RES_USE_INET6)
-+ {
-+ enum nss_status status;
-+
-+ status = _nss_nis_gethostbyname2_r (name, AF_INET6, host, buffer, buflen,
-+ h_errnop);
-+ if (status == NSS_STATUS_SUCCESS)
-+ return status;
-+ }
-+
-+ return _nss_nis_gethostbyname2_r (name, AF_INET, host, buffer, buflen,
-+ h_errnop);
-+}
-+
-+enum nss_status
-+_nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
-+ struct hostent *host, char *buffer, size_t buflen,
-+ int *h_errnop)
-+{
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, parse_res;
-+ char *buf;
-+ struct parser_data *data = (void *) buffer;
-+ size_t linebuflen = buffer + buflen - data->linebuffer;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ if (buflen < sizeof *data + 1)
-+ {
-+ __set_errno (ERANGE);
-+ *h_errnop = NETDB_INTERNAL;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ buf = inet_ntoa (*(struct in_addr *) addr);
-+
-+ retval = yperr2nss (yp_match (domain, "hosts.byaddr", buf,
-+ strlen (buf), &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ {
-+ *h_errnop = TRY_AGAIN;
-+ __set_errno (EAGAIN);
-+ }
-+ if (retval == NSS_STATUS_NOTFOUND)
-+ *h_errnop = HOST_NOT_FOUND;
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > linebuflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ *h_errnop = NETDB_INTERNAL;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (data->linebuffer, result, len);
-+ data->linebuffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = parse_line (p, host, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ {
-+ *h_errnop = NETDB_INTERNAL;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ else if (parse_res == 0)
-+ {
-+ *h_errnop = HOST_NOT_FOUND;
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+
-+ *h_errnop = NETDB_SUCCESS;
-+ return NSS_STATUS_SUCCESS;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-netgrp.c glibc-2.1.3/glibc-compat/nss_nis/nis-netgrp.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-netgrp.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-netgrp.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,128 @@
-+/* Copyright (C) 1996 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <bits/libc-lock.h>
-+#include <netdb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <netgroup.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+/* Locks the static variables in this file. */
-+__libc_lock_define_initialized (static, lock)
-+
-+static char *data = NULL;
-+static size_t data_size = 0;
-+static char *cursor = NULL;;
-+
-+extern enum nss_status
-+_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
-+ char *buffer, size_t buflen);
-+
-+enum nss_status
-+_nss_nis_setnetgrent (char *group)
-+{
-+ char *domain;
-+ char *result;
-+ int len, group_len;
-+ enum nss_status status;
-+
-+ status = NSS_STATUS_SUCCESS;
-+
-+ if (group[0] == '\0')
-+ return NSS_STATUS_UNAVAIL;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ __libc_lock_lock (lock);
-+
-+ if (data != NULL)
-+ {
-+ free (data);
-+ data = NULL;
-+ data_size = 0;
-+ cursor = NULL;
-+ }
-+
-+ group_len = strlen (group);
-+
-+ status = yperr2nss (yp_match (domain, "netgroup", group, group_len,
-+ &result, &len));
-+ if (status == NSS_STATUS_SUCCESS)
-+ {
-+ if (len > 0)
-+ {
-+ data = malloc (len + 1);
-+ data_size = len;
-+ cursor = strncpy (data, result, len + 1);
-+ data[len] = '\0';
-+ free (result);
-+ }
-+ else
-+ status = NSS_STATUS_NOTFOUND;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+
-+enum nss_status
-+_nss_nis_endnetgrent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ if (data != NULL)
-+ {
-+ free (data);
-+ data = NULL;
-+ data_size = 0;
-+ cursor = NULL;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen)
-+{
-+ enum nss_status status;
-+
-+ if (cursor == NULL)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-network.c glibc-2.1.3/glibc-compat/nss_nis/nis-network.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-network.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-network.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,318 @@
-+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <netdb.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME netent
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+__libc_lock_define_initialized (static, lock)
-+
-+static bool_t new_start = 1;
-+static char *oldkey = NULL;
-+static int oldkeylen = 0;
-+
-+enum nss_status
-+_nss_nis_setnetent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_endnetent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+internal_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
-+ int *herrnop)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *domain, *result, *outkey;
-+ int len, keylen, parse_res;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ enum nss_status retval;
-+ char *p;
-+
-+ if (new_start)
-+ retval = yperr2nss (yp_first (domain, "networks.byname",
-+ &outkey, &keylen, &result, &len));
-+ else
-+ retval = yperr2nss ( yp_next (domain, "networks.byname",
-+ oldkey, oldkeylen,
-+ &outkey, &keylen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ {
-+ *herrnop = NETDB_INTERNAL;
-+ __set_errno (EAGAIN);
-+ }
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ *herrnop = NETDB_INTERNAL;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_netent (p, net, data, buflen);
-+ if (parse_res == -1 && errno == ERANGE)
-+ {
-+ *herrnop = NETDB_INTERNAL;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ free (oldkey);
-+ oldkey = outkey;
-+ oldkeylen = keylen;
-+ new_start = 0;
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
-+ int *herrnop)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_getnetent_r (net, buffer, buflen, herrnop);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getnetbyname_r (const char *name, struct netent *net,
-+ char *buffer, size_t buflen, int *herrnop)
-+{
-+ enum nss_status retval;
-+ struct parser_data *data = (void *) buffer;
-+ char *domain, *result, *p;
-+ int len, parse_res;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ *herrnop = NETDB_INTERNAL;
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ if (buflen < sizeof *data + 1)
-+ {
-+ *herrnop = NETDB_INTERNAL;
-+ __set_errno(ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ else
-+ {
-+ /* Convert name to lowercase. */
-+ size_t namlen = strlen (name);
-+ char name2[namlen + 1];
-+ int i;
-+
-+ for (i = 0; i < namlen; ++i)
-+ name2[i] = tolower (name[i]);
-+ name2[i] = '\0';
-+
-+ retval = yperr2nss (yp_match (domain, "networks.byname", name2,
-+ namlen, &result, &len));
-+ }
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ {
-+ __set_errno (EAGAIN);
-+ *herrnop = NETDB_INTERNAL;
-+ }
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ *herrnop = NETDB_INTERNAL;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_netent (p, net, data, buflen);
-+
-+ if (parse_res <= 0)
-+ {
-+ *herrnop = NETDB_INTERNAL;
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+ else
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getnetbyaddr_r (unsigned long addr, int type, struct netent *net,
-+ char *buffer, size_t buflen, int *herrnop)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *domain;
-+ char *result;
-+ int len;
-+ char buf[256];
-+ int blen;
-+ struct in_addr in;
-+ char *p;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ in = inet_makeaddr (addr, 0);
-+ strcpy (buf, inet_ntoa (in));
-+ blen = strlen (buf);
-+
-+ while (1)
-+ {
-+ enum nss_status retval;
-+ int parse_res;
-+
-+ retval = yperr2nss (yp_match (domain, "networks.byaddr", buf,
-+ strlen (buf), &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_NOTFOUND)
-+ {
-+ if (buf[blen - 2] == '.' && buf[blen - 1] == '0')
-+ {
-+ /* Try again, but with trailing dot(s)
-+ removed (one by one) */
-+ buf[blen - 2] = '\0';
-+ blen -= 2;
-+ continue;
-+ }
-+ else
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+ else
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ *herrnop = NETDB_INTERNAL;
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_netent (p, net, data, buflen);
-+
-+
-+ if (parse_res <= 0)
-+ {
-+ *herrnop = NETDB_INTERNAL;
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else
-+ return NSS_STATUS_NOTFOUND;
-+ }
-+ else
-+ return NSS_STATUS_SUCCESS;
-+ }
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-proto.c glibc-2.1.3/glibc-compat/nss_nis/nis-proto.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-proto.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-proto.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,280 @@
-+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <netdb.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME protoent
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+__libc_lock_define_initialized (static, lock)
-+
-+struct response
-+{
-+ char *val;
-+ struct response *next;
-+};
-+
-+static struct response *start = NULL;
-+static struct response *next = NULL;
-+
-+static int
-+saveit (int instatus, char *inkey, int inkeylen, char *inval,
-+ int invallen, char *indata)
-+{
-+ if (instatus != YP_TRUE)
-+ return instatus;
-+
-+ if (inkey && inkeylen > 0 && inval && invallen > 0)
-+ {
-+ if (start == NULL)
-+ {
-+ start = malloc (sizeof (struct response));
-+ next = start;
-+ }
-+ else
-+ {
-+ next->next = malloc (sizeof (struct response));
-+ next = next->next;
-+ }
-+ next->next = NULL;
-+ next->val = malloc (invallen + 1);
-+ strncpy (next->val, inval, invallen);
-+ next->val[invallen] = '\0';
-+ }
-+
-+ return 0;
-+}
-+
-+enum nss_status
-+internal_nis_setprotoent (void)
-+{
-+ char *domainname;
-+ struct ypall_callback ypcb;
-+ enum nss_status status;
-+
-+ yp_get_default_domain (&domainname);
-+
-+ while (start != NULL)
-+ {
-+ if (start->val != NULL)
-+ free (start->val);
-+ next = start;
-+ start = start->next;
-+ free (next);
-+ }
-+ start = NULL;
-+
-+ ypcb.foreach = saveit;
-+ ypcb.data = NULL;
-+ status = yperr2nss (yp_all (domainname, "protocols.bynumber", &ypcb));
-+ next = start;
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_setprotoent (void)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_setprotoent ();
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_endprotoent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ while (start != NULL)
-+ {
-+ if (start->val != NULL)
-+ free (start->val);
-+ next = start;
-+ start = start->next;
-+ free (next);
-+ }
-+ start = NULL;
-+ next = NULL;
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+internal_nis_getprotoent_r (struct protoent *proto,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ int parse_res;
-+
-+ if (start == NULL)
-+ internal_nis_setprotoent ();
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ char *p;
-+
-+ if (next == NULL)
-+ return NSS_STATUS_NOTFOUND;
-+ p = strncpy (buffer, next->val, buflen);
-+ next = next->next;
-+
-+ while (isspace (*p))
-+ ++p;
-+
-+ parse_res = _nss_files_parse_protoent (p, proto, data, buflen);
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getprotoent_r (struct protoent *proto, char *buffer, size_t buflen)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_getprotoent_r (proto, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getprotobyname_r (const char *name, struct protoent *proto,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, parse_res;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ retval = yperr2nss (yp_match (domain, "protocols.byname", name,
-+ strlen (name), &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_protoent (p, proto, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getprotobynumber_r (int number, struct protoent *proto,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, nlen, parse_res;
-+ char buf[32];
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ nlen = sprintf (buf, "%d", number);
-+
-+ retval = yperr2nss (yp_match (domain, "protocols.bynumber", buf,
-+ nlen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_protoent (p, proto, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-pwd.c glibc-2.1.3/glibc-compat/nss_nis/nis-pwd.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-pwd.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-pwd.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,407 @@
-+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <pwd.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME pwent
-+#define STRUCTURE passwd
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+/* Protect global state against multiple changers */
-+__libc_lock_define_initialized (static, lock)
-+
-+static bool_t new_start = 1;
-+static char *oldkey = NULL;
-+static int oldkeylen = 0;
-+
-+enum nss_status
-+_nss_nis_setpwent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_endpwent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *domain;
-+ int parse_res;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ enum nss_status retval;
-+ char *result, *outkey, *result2, *p;
-+ int len, keylen, len2;
-+ size_t namelen;
-+
-+ if (new_start)
-+ retval = yperr2nss (yp_first (domain, "passwd.byname",
-+ &outkey, &keylen, &result, &len));
-+ else
-+ retval = yperr2nss ( yp_next (domain, "passwd.byname",
-+ oldkey, oldkeylen,
-+ &outkey, &keylen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ /* Check for adjunct style secret passwords. They can be
-+ recognized by a password starting with "##". */
-+ p = strchr (result, ':');
-+ if (p != NULL /* This better should be true in all cases. */
-+ && p[1] == '#' && p[2] == '#'
-+ && (namelen = p - result,
-+ yp_match (domain, "passwd.adjunct.byname", result, namelen,
-+ &result2, &len2)) == YPERR_SUCCESS)
-+ {
-+ /* We found a passwd.adjunct entry. Merge encrypted
-+ password therein into original result. */
-+ char *encrypted = strchr (result2, ':');
-+ char *endp, *tmp;
-+ size_t restlen;
-+
-+ if (encrypted == NULL
-+ || (endp = strchr (++encrypted, ':')) == NULL
-+ || (p = strchr (p + 1, ':')) == NULL)
-+ {
-+ /* Invalid format of the entry. This never should happen
-+ unless the data from which the NIS table is generated is
-+ wrong. We simply ignore it. */
-+ free (result2);
-+ goto non_adjunct;
-+ }
-+
-+ restlen = len - (p - result);
-+ if ((size_t) (namelen + (endp - encrypted) + restlen + 2) > buflen)
-+ {
-+ free (result2);
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ memcpy (buffer, result, namelen);
-+ tmp = buffer + namelen;
-+ *tmp++ = ':';
-+ memcpy (tmp, encrypted, endp - encrypted);
-+ tmp += endp - encrypted;
-+ memcpy (tmp, p, restlen + 1);
-+ p = buffer;
-+
-+ free (result2);
-+ }
-+ else
-+ {
-+ non_adjunct:
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_pwent (p, pwd, data, buflen);
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+
-+ free (oldkey);
-+ oldkey = outkey;
-+ oldkeylen = keylen;
-+ new_start = 0;
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getpwent_r (struct passwd *result, char *buffer, size_t buflen)
-+{
-+ int status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_getpwent_r (result, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getpwnam_r (const char *name, struct passwd *pwd,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *result2, *p;
-+ int len, len2, parse_res;
-+ size_t namelen;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ namelen = strlen (name);
-+
-+ retval = yperr2nss (yp_match (domain, "passwd.byname", name,
-+ namelen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ /* Check for adjunct style secret passwords. They can be recognized
-+ by a password starting with "##". */
-+ p = strchr (result, ':');
-+ if (p != NULL /* This better should be true in all cases. */
-+ && p[1] == '#' && p[2] == '#'
-+ && (namelen = p - result,
-+ yp_match (domain, "passwd.adjunct.byname", name, namelen,
-+ &result2, &len2)) == YPERR_SUCCESS)
-+ {
-+ /* We found a passwd.adjunct entry. Merge encrypted password
-+ therein into original result. */
-+ char *encrypted = strchr (result2, ':');
-+ char *endp, *tmp;
-+ size_t restlen;
-+
-+ if (encrypted == NULL
-+ || (endp = strchr (++encrypted, ':')) == NULL
-+ || (p = strchr (p + 1, ':')) == NULL)
-+ {
-+ /* Invalid format of the entry. This never should happen
-+ unless the data from which the NIS table is generated is
-+ wrong. We simply ignore it. */
-+ free (result2);
-+ goto non_adjunct;
-+ }
-+
-+ restlen = len - (p - result);
-+ if ((size_t) (namelen + (endp - encrypted) + restlen + 2) > buflen)
-+ {
-+ free (result2);
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ memcpy (buffer, name, namelen);
-+ tmp = buffer + namelen;
-+ *tmp++ = ':';
-+ memcpy (tmp, encrypted, endp - encrypted);
-+ tmp += endp - encrypted;
-+ memcpy (tmp, p, restlen + 1);
-+ p = buffer;
-+
-+ free (result2);
-+ }
-+ else
-+ {
-+ non_adjunct:
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ }
-+
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_pwent (p, pwd, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *p, *result2;
-+ int len, nlen, parse_res, len2;
-+ char buf[32];
-+ size_t namelen;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ nlen = sprintf (buf, "%d", uid);
-+
-+ retval = yperr2nss (yp_match (domain, "passwd.byuid", buf,
-+ nlen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ /* Check for adjunct style secret passwords. They can be recognized
-+ by a password starting with "##". */
-+ p = strchr (result, ':');
-+ if (p != NULL /* This better should be true in all cases. */
-+ && p[1] == '#' && p[2] == '#'
-+ && (namelen = p - result,
-+ yp_match (domain, "passwd.adjunct.byname", result, namelen,
-+ &result2, &len2)) == YPERR_SUCCESS)
-+ {
-+ /* We found a passwd.adjunct entry. Merge encrypted password
-+ therein into original result. */
-+ char *encrypted = strchr (result2, ':');
-+ char *endp, *tmp;
-+ size_t restlen;
-+
-+ if (encrypted == NULL
-+ || (endp = strchr (++encrypted, ':')) == NULL
-+ || (p = strchr (p + 1, ':')) == NULL)
-+ {
-+ /* Invalid format of the entry. This never should happen
-+ unless the data from which the NIS table is generated is
-+ wrong. We simply ignore it. */
-+ free (result2);
-+ goto non_adjunct;
-+ }
-+
-+ restlen = len - (p - result);
-+ if ((size_t) (namelen + (endp - encrypted) + restlen + 2) > buflen)
-+ {
-+ free (result2);
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ memcpy (buffer, result, namelen);
-+ tmp = buffer + namelen;
-+ *tmp++ = ':';
-+ memcpy (tmp, encrypted, endp - encrypted);
-+ tmp += endp - encrypted;
-+ memcpy (tmp, p, restlen + 1);
-+ p = buffer;
-+
-+ free (result2);
-+ }
-+ else
-+ {
-+ non_adjunct:
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ }
-+
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_pwent (p, pwd, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-rpc.c glibc-2.1.3/glibc-compat/nss_nis/nis-rpc.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-rpc.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-rpc.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,295 @@
-+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <netdb.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME rpcent
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+__libc_lock_define_initialized (static, lock)
-+
-+struct response_t
-+{
-+ char *val;
-+ struct response_t *next;
-+};
-+
-+struct intern_t
-+{
-+ struct response_t *start;
-+ struct response_t *next;
-+};
-+typedef struct intern_t intern_t;
-+
-+static intern_t intern = {NULL, NULL};
-+
-+static int
-+saveit (int instatus, char *inkey, int inkeylen, char *inval,
-+ int invallen, char *indata)
-+{
-+ intern_t *intern = (intern_t *)indata;
-+
-+ if (instatus != YP_TRUE)
-+ return instatus;
-+
-+ if (inkey && inkeylen > 0 && inval && invallen > 0)
-+ {
-+ if (intern->start == NULL)
-+ {
-+ intern->start = malloc (sizeof (struct response_t));
-+ intern->next = intern->start;
-+ }
-+ else
-+ {
-+ intern->next->next = malloc (sizeof (struct response_t));
-+ intern->next = intern->next->next;
-+ }
-+ intern->next->next = NULL;
-+ intern->next->val = malloc (invallen + 1);
-+ strncpy (intern->next->val, inval, invallen);
-+ intern->next->val[invallen] = '\0';
-+ }
-+
-+ return 0;
-+}
-+
-+static enum nss_status
-+internal_nis_setrpcent (intern_t *intern)
-+{
-+ char *domainname;
-+ struct ypall_callback ypcb;
-+ enum nss_status status;
-+
-+ if (yp_get_default_domain (&domainname))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ while (intern->start != NULL)
-+ {
-+ if (intern->start->val != NULL)
-+ free (intern->start->val);
-+ intern->next = intern->start;
-+ intern->start = intern->start->next;
-+ free (intern->next);
-+ }
-+ intern->start = NULL;
-+
-+ ypcb.foreach = saveit;
-+ ypcb.data = (char *)intern;
-+ status = yperr2nss (yp_all(domainname, "rpc.bynumber", &ypcb));
-+ intern->next = intern->start;
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_setrpcent (void)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_setrpcent (&intern);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+static enum nss_status
-+internal_nis_endrpcent (intern_t *intern)
-+{
-+ while (intern->start != NULL)
-+ {
-+ if (intern->start->val != NULL)
-+ free (intern->start->val);
-+ intern->next = intern->start;
-+ intern->start = intern->start->next;
-+ free (intern->next);
-+ }
-+ intern->start = NULL;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_endrpcent (void)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_endrpcent (&intern);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+static enum nss_status
-+internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
-+ intern_t *data)
-+{
-+ struct parser_data *pdata = (void *) buffer;
-+ int parse_res;
-+ char *p;
-+
-+ if (data->start == NULL)
-+ internal_nis_setrpcent (data);
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ if (data->next == NULL)
-+ return NSS_STATUS_NOTFOUND;
-+ p = strncpy (buffer, data->next->val, buflen);
-+ data->next = data->next->next;
-+ while (isspace (*p))
-+ ++p;
-+
-+ parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen);
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_getrpcent_r (rpc, buffer, buflen, &intern);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
-+ char *buffer, size_t buflen)
-+{
-+ intern_t data = {NULL, NULL};
-+ enum nss_status status;
-+ int found;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ status = internal_nis_setrpcent (&data);
-+ if (status != NSS_STATUS_SUCCESS)
-+ return status;
-+
-+ found = 0;
-+ while (!found &&
-+ ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, &data))
-+ == NSS_STATUS_SUCCESS))
-+ {
-+ if (strcmp (rpc->r_name, name) == 0)
-+ found = 1;
-+ else
-+ {
-+ int i = 0;
-+
-+ while (rpc->r_aliases[i] != NULL)
-+ {
-+ if (strcmp (rpc->r_aliases[i], name) == 0)
-+ {
-+ found = 1;
-+ break;
-+ }
-+ else
-+ ++i;
-+ }
-+ }
-+ }
-+
-+ internal_nis_endrpcent (&data);
-+
-+ if (!found && status == NSS_STATUS_SUCCESS)
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, nlen, parse_res;
-+ char buf[32];
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ nlen = sprintf (buf, "%d", number);
-+
-+ retval = yperr2nss (yp_match (domain, "rpc.bynumber", buf,
-+ nlen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_rpcent (p, rpc, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-service.c glibc-2.1.3/glibc-compat/nss_nis/nis-service.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-service.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-service.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,280 @@
-+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <netdb.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME servent
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+__libc_lock_define_initialized (static, lock)
-+
-+struct response_t
-+{
-+ char *val;
-+ struct response_t *next;
-+};
-+
-+struct intern_t
-+{
-+ struct response_t *start;
-+ struct response_t *next;
-+};
-+typedef struct intern_t intern_t;
-+
-+static intern_t intern = { NULL, NULL };
-+
-+static int
-+saveit (int instatus, char *inkey, int inkeylen, char *inval,
-+ int invallen, char *indata)
-+{
-+ intern_t *intern = (intern_t *) indata;
-+
-+ if (instatus != YP_TRUE)
-+ return instatus;
-+
-+ if (inkey && inkeylen > 0 && inval && invallen > 0)
-+ {
-+ if (intern->start == NULL)
-+ {
-+ intern->start = malloc (sizeof (struct response_t));
-+ intern->next = intern->start;
-+ }
-+ else
-+ {
-+ intern->next->next = malloc (sizeof (struct response_t));
-+ intern->next = intern->next->next;
-+ }
-+ intern->next->next = NULL;
-+ intern->next->val = malloc (invallen + 1);
-+ strncpy (intern->next->val, inval, invallen);
-+ intern->next->val[invallen] = '\0';
-+ }
-+
-+ return 0;
-+}
-+
-+static enum nss_status
-+internal_nis_setservent (intern_t *intern)
-+{
-+ char *domainname;
-+ struct ypall_callback ypcb;
-+ enum nss_status status;
-+
-+ if (yp_get_default_domain (&domainname))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ while (intern->start != NULL)
-+ {
-+ if (intern->start->val != NULL)
-+ free (intern->start->val);
-+ intern->next = intern->start;
-+ intern->start = intern->start->next;
-+ free (intern->next);
-+ }
-+ intern->start = NULL;
-+
-+ ypcb.foreach = saveit;
-+ ypcb.data = (char *) intern;
-+ status = yperr2nss (yp_all (domainname, "services.byname", &ypcb));
-+ intern->next = intern->start;
-+
-+ return status;
-+}
-+enum nss_status
-+_nss_nis_setservent (void)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_setservent (&intern);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+static enum nss_status
-+internal_nis_endservent (intern_t * intern)
-+{
-+ while (intern->start != NULL)
-+ {
-+ if (intern->start->val != NULL)
-+ free (intern->start->val);
-+ intern->next = intern->start;
-+ intern->start = intern->start->next;
-+ free (intern->next);
-+ }
-+ intern->start = NULL;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_endservent (void)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_endservent (&intern);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+static enum nss_status
-+internal_nis_getservent_r (struct servent *serv, char *buffer,
-+ size_t buflen, intern_t *data)
-+{
-+ struct parser_data *pdata = (void *) buffer;
-+ int parse_res;
-+ char *p;
-+
-+ if (data->start == NULL)
-+ internal_nis_setservent (data);
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ if (data->next == NULL)
-+ return NSS_STATUS_NOTFOUND;
-+ p = strncpy (buffer, data->next->val, buflen);
-+ data->next = data->next->next;
-+ while (isspace (*p))
-+ ++p;
-+
-+ parse_res = _nss_files_parse_servent (p, serv, pdata, buflen);
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getservent_r (struct servent *serv, char *buffer, size_t buflen)
-+{
-+ enum nss_status status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_getservent_r (serv, buffer, buflen, &intern);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getservbyname_r (const char *name, char *protocol,
-+ struct servent *serv, char *buffer, size_t buflen)
-+{
-+ intern_t data = { NULL, NULL };
-+ enum nss_status status;
-+ int found;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ status = internal_nis_setservent (&data);
-+ if (status != NSS_STATUS_SUCCESS)
-+ return status;
-+
-+ found = 0;
-+ while (!found &&
-+ ((status = internal_nis_getservent_r (serv, buffer, buflen, &data))
-+ == NSS_STATUS_SUCCESS))
-+ {
-+ if (protocol == NULL || strcmp (serv->s_proto, protocol) == 0)
-+ {
-+ char **cp;
-+
-+ if (strcmp (serv->s_name, name) == 0)
-+ found = 1;
-+ else
-+ for (cp = serv->s_aliases; *cp; cp++)
-+ if (strcmp (name, *cp) == 0)
-+ found = 1;
-+ }
-+ }
-+
-+ internal_nis_endservent (&data);
-+
-+ if (!found && status == NSS_STATUS_SUCCESS)
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getservbyport_r (int port, char *protocol, struct servent *serv,
-+ char *buffer, size_t buflen)
-+{
-+ intern_t data = { NULL, NULL };
-+ enum nss_status status;
-+ int found;
-+
-+ if (protocol == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ status = internal_nis_setservent (&data);
-+ if (status != NSS_STATUS_SUCCESS)
-+ return status;
-+
-+ found = 0;
-+ while (!found &&
-+ ((status = internal_nis_getservent_r (serv, buffer, buflen, &data))
-+ == NSS_STATUS_SUCCESS))
-+ {
-+ if (htons (serv->s_port) == port)
-+ {
-+ if (strcmp (serv->s_proto, protocol) == 0)
-+ {
-+ found = 1;
-+ }
-+ }
-+ }
-+
-+ internal_nis_endservent (&data);
-+
-+ if (!found && status == NSS_STATUS_SUCCESS)
-+ return NSS_STATUS_NOTFOUND;
-+ else
-+ return status;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/nss_nis/nis-spwd.c glibc-2.1.3/glibc-compat/nss_nis/nis-spwd.c
---- ../glibc-2.1.3/glibc-compat/nss_nis/nis-spwd.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/nss_nis/nis-spwd.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,201 @@
-+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <nss.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <shadow.h>
-+#include <bits/libc-lock.h>
-+#include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-+
-+#include "nss-nis.h"
-+
-+/* Get the declaration of the parser function. */
-+#define ENTNAME spent
-+#define STRUCTURE spwd
-+#define EXTERN_PARSER
-+#include "../nss_files/files-parse.c"
-+
-+/* Protect global state against multiple changers */
-+__libc_lock_define_initialized (static, lock)
-+
-+static bool_t new_start = 1;
-+static char *oldkey = NULL;
-+static int oldkeylen = 0;
-+
-+enum nss_status
-+_nss_nis_setspent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_endspent (void)
-+{
-+ __libc_lock_lock (lock);
-+
-+ new_start = 1;
-+ if (oldkey != NULL)
-+ {
-+ free (oldkey);
-+ oldkey = NULL;
-+ oldkeylen = 0;
-+ }
-+
-+ __libc_lock_unlock (lock);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+static enum nss_status
-+internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ char *domain, *result, *outkey;
-+ int len, keylen, parse_res;
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ /* Get the next entry until we found a correct one. */
-+ do
-+ {
-+ enum nss_status retval;
-+ char *p;
-+
-+ if (new_start)
-+ retval = yperr2nss (yp_first (domain, "shadow.byname",
-+ &outkey, &keylen, &result, &len));
-+ else
-+ retval = yperr2nss ( yp_next (domain, "shadow.byname",
-+ oldkey, oldkeylen,
-+ &outkey, &keylen, &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_spent (p, sp, data, buflen);
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+
-+ free (oldkey);
-+ oldkey = outkey;
-+ oldkeylen = keylen;
-+ new_start = 0;
-+ }
-+ while (!parse_res);
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-+
-+enum nss_status
-+_nss_nis_getspent_r (struct spwd *result, char *buffer, size_t buflen)
-+{
-+ int status;
-+
-+ __libc_lock_lock (lock);
-+
-+ status = internal_nis_getspent_r (result, buffer, buflen);
-+
-+ __libc_lock_unlock (lock);
-+
-+ return status;
-+}
-+
-+enum nss_status
-+_nss_nis_getspnam_r (const char *name, struct spwd *sp,
-+ char *buffer, size_t buflen)
-+{
-+ struct parser_data *data = (void *) buffer;
-+ enum nss_status retval;
-+ char *domain, *result, *p;
-+ int len, parse_res;
-+
-+ if (name == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return NSS_STATUS_UNAVAIL;
-+ }
-+
-+ if (yp_get_default_domain (&domain))
-+ return NSS_STATUS_UNAVAIL;
-+
-+ retval = yperr2nss (yp_match (domain, "shadow.byname", name,
-+ strlen (name), &result, &len));
-+
-+ if (retval != NSS_STATUS_SUCCESS)
-+ {
-+ if (retval == NSS_STATUS_TRYAGAIN)
-+ __set_errno (EAGAIN);
-+ return retval;
-+ }
-+
-+ if ((size_t) (len + 1) > buflen)
-+ {
-+ free (result);
-+ __set_errno (ERANGE);
-+ return NSS_STATUS_TRYAGAIN;
-+ }
-+
-+ p = strncpy (buffer, result, len);
-+ buffer[len] = '\0';
-+ while (isspace (*p))
-+ ++p;
-+ free (result);
-+
-+ parse_res = _nss_files_parse_spent (p, sp, data, buflen);
-+
-+ if (parse_res == -1 && errno == ERANGE)
-+ return NSS_STATUS_TRYAGAIN;
-+ else if (parse_res == 0)
-+ return NSS_STATUS_NOTFOUND;
-+
-+ return NSS_STATUS_SUCCESS;
-+}
-diff -Naur ../glibc-2.1.3/glibc-compat/oldfileops.c glibc-2.1.3/glibc-compat/oldfileops.c
---- ../glibc-2.1.3/glibc-compat/oldfileops.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/oldfileops.c 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,774 @@
-+/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU IO Library.
-+ Written by Per Bothner <bothner@cygnus.com>.
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this library; see the file COPYING. If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-+ MA 02111-1307, USA.
-+
-+ As a special exception, if you link this library with files
-+ compiled with a GNU compiler to produce an executable, this does
-+ not cause the resulting executable to be covered by the GNU General
-+ Public License. This exception does not however invalidate any
-+ other reasons why the executable file might be covered by the GNU
-+ General Public License. */
-+
-+/* This is a compatibility file. If we don't build the libc with
-+ versioning don't compile this file. */
-+
-+#ifndef _POSIX_SOURCE
-+# define _POSIX_SOURCE
-+#endif
-+#define _IO_USE_OLD_IO_FILE
-+#include "libioP.h"
-+#include <fcntl.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <string.h>
-+#include <errno.h>
-+#ifndef errno
-+extern int errno;
-+#endif
-+#ifndef __set_errno
-+# define __set_errno(Val) errno = (Val)
-+#endif
-+
-+
-+#ifdef _LIBC
-+# define open(Name, Flags, Prot) __open (Name, Flags, Prot)
-+# define close(FD) __close (FD)
-+# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
-+# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
-+# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
-+#endif
-+
-+/* An fstream can be in at most one of put mode, get mode, or putback mode.
-+ Putback mode is a variant of get mode.
-+
-+ In a filebuf, there is only one current position, instead of two
-+ separate get and put pointers. In get mode, the current position
-+ is that of gptr(); in put mode that of pptr().
-+
-+ The position in the buffer that corresponds to the position
-+ in external file system is normally _IO_read_end, except in putback
-+ mode, when it is _IO_save_end.
-+ If the field _fb._offset is >= 0, it gives the offset in
-+ the file as a whole corresponding to eGptr(). (?)
-+
-+ PUT MODE:
-+ If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
-+ and _IO_read_base are equal to each other. These are usually equal
-+ to _IO_buf_base, though not necessarily if we have switched from
-+ get mode to put mode. (The reason is to maintain the invariant
-+ that _IO_read_end corresponds to the external file position.)
-+ _IO_write_base is non-NULL and usually equal to _IO_base_base.
-+ We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
-+ The un-flushed character are those between _IO_write_base and _IO_write_ptr.
-+
-+ GET MODE:
-+ If a filebuf is in get or putback mode, eback() != egptr().
-+ In get mode, the unread characters are between gptr() and egptr().
-+ The OS file position corresponds to that of egptr().
-+
-+ PUTBACK MODE:
-+ Putback mode is used to remember "excess" characters that have
-+ been sputbackc'd in a separate putback buffer.
-+ In putback mode, the get buffer points to the special putback buffer.
-+ The unread characters are the characters between gptr() and egptr()
-+ in the putback buffer, as well as the area between save_gptr()
-+ and save_egptr(), which point into the original reserve buffer.
-+ (The pointers save_gptr() and save_egptr() are the values
-+ of gptr() and egptr() at the time putback mode was entered.)
-+ The OS position corresponds to that of save_egptr().
-+
-+ LINE BUFFERED OUTPUT:
-+ During line buffered output, _IO_write_base==base() && epptr()==base().
-+ However, ptr() may be anywhere between base() and ebuf().
-+ This forces a call to filebuf::overflow(int C) on every put.
-+ If there is more space in the buffer, and C is not a '\n',
-+ then C is inserted, and pptr() incremented.
-+
-+ UNBUFFERED STREAMS:
-+ If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
-+*/
-+
-+#define CLOSED_FILEBUF_FLAGS \
-+ (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
-+
-+
-+void
-+_IO_old_file_init (fp)
-+ _IO_FILE *fp;
-+{
-+ /* POSIX.1 allows another file handle to be used to change the position
-+ of our file descriptor. Hence we actually don't know the actual
-+ position before we do the first fseek (and until a following fflush). */
-+ fp->_old_offset = _IO_pos_BAD;
-+ fp->_IO_file_flags |= CLOSED_FILEBUF_FLAGS;
-+
-+ _IO_link_in(fp);
-+ fp->_vtable_offset = ((int) sizeof (struct _IO_FILE)
-+ - (int) sizeof (struct _IO_FILE_complete));
-+ fp->_fileno = -1;
-+}
-+
-+int
-+_IO_old_file_close_it (fp)
-+ _IO_FILE *fp;
-+{
-+ int write_status, close_status;
-+ if (!_IO_file_is_open (fp))
-+ return EOF;
-+
-+ write_status = _IO_old_do_flush (fp);
-+
-+ _IO_unsave_markers(fp);
-+
-+ close_status = _IO_SYSCLOSE (fp);
-+
-+ /* Free buffer. */
-+ _IO_setb (fp, NULL, NULL, 0);
-+ _IO_setg (fp, NULL, NULL, NULL);
-+ _IO_setp (fp, NULL, NULL);
-+
-+ _IO_un_link (fp);
-+ fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
-+ fp->_fileno = EOF;
-+ fp->_old_offset = _IO_pos_BAD;
-+
-+ return close_status ? close_status : write_status;
-+}
-+
-+void
-+_IO_old_file_finish (fp, dummy)
-+ _IO_FILE *fp;
-+ int dummy;
-+{
-+ if (_IO_file_is_open (fp))
-+ {
-+ _IO_old_do_flush (fp);
-+ if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
-+ _IO_SYSCLOSE (fp);
-+ }
-+ _IO_default_finish (fp, 0);
-+}
-+
-+_IO_FILE *
-+_IO_old_file_fopen (fp, filename, mode)
-+ _IO_FILE *fp;
-+ const char *filename;
-+ const char *mode;
-+{
-+ int oflags = 0, omode;
-+ int read_write, fdesc;
-+ int oprot = 0666;
-+ if (_IO_file_is_open (fp))
-+ return 0;
-+ switch (*mode++)
-+ {
-+ case 'r':
-+ omode = O_RDONLY;
-+ read_write = _IO_NO_WRITES;
-+ break;
-+ case 'w':
-+ omode = O_WRONLY;
-+ oflags = O_CREAT|O_TRUNC;
-+ read_write = _IO_NO_READS;
-+ break;
-+ case 'a':
-+ omode = O_WRONLY;
-+ oflags = O_CREAT|O_APPEND;
-+ read_write = _IO_NO_READS|_IO_IS_APPENDING;
-+ break;
-+ default:
-+ __set_errno (EINVAL);
-+ return NULL;
-+ }
-+ if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
-+ {
-+ omode = O_RDWR;
-+ read_write &= _IO_IS_APPENDING;
-+ }
-+ fdesc = open (filename, omode|oflags, oprot);
-+ if (fdesc < 0)
-+ return NULL;
-+ fp->_fileno = fdesc;
-+ _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
-+ if (read_write & _IO_IS_APPENDING)
-+ if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
-+ == _IO_pos_BAD && errno != ESPIPE)
-+ return NULL;
-+ _IO_link_in (fp);
-+ return fp;
-+}
-+
-+_IO_FILE *
-+_IO_old_file_attach (fp, fd)
-+ _IO_FILE *fp;
-+ int fd;
-+{
-+ if (_IO_file_is_open (fp))
-+ return NULL;
-+ fp->_fileno = fd;
-+ fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
-+ fp->_flags |= _IO_DELETE_DONT_CLOSE;
-+ /* Get the current position of the file. */
-+ /* We have to do that since that may be junk. */
-+ fp->_old_offset = _IO_pos_BAD;
-+ if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
-+ == _IO_pos_BAD && errno != ESPIPE)
-+ return NULL;
-+ return fp;
-+}
-+
-+_IO_FILE *
-+_IO_old_file_setbuf (fp, p, len)
-+ _IO_FILE *fp;
-+ char *p;
-+ _IO_ssize_t len;
-+{
-+ if (_IO_default_setbuf (fp, p, len) == NULL)
-+ return NULL;
-+
-+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
-+ = fp->_IO_buf_base;
-+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
-+
-+ return fp;
-+}
-+
-+static int old_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
-+
-+/* Write TO_DO bytes from DATA to FP.
-+ Then mark FP as having empty buffers. */
-+
-+int
-+_IO_old_do_write (fp, data, to_do)
-+ _IO_FILE *fp;
-+ const char *data;
-+ _IO_size_t to_do;
-+{
-+ return (to_do == 0 || old_do_write (fp, data, to_do) == to_do)
-+ ? 0 : EOF;
-+}
-+
-+static
-+int
-+old_do_write (fp, data, to_do)
-+ _IO_FILE *fp;
-+ const char *data;
-+ _IO_size_t to_do;
-+{
-+ _IO_size_t count;
-+ if (fp->_flags & _IO_IS_APPENDING)
-+ /* On a system without a proper O_APPEND implementation,
-+ you would need to sys_seek(0, SEEK_END) here, but is
-+ is not needed nor desirable for Unix- or Posix-like systems.
-+ Instead, just indicate that offset (before and after) is
-+ unpredictable. */
-+ fp->_old_offset = _IO_pos_BAD;
-+ else if (fp->_IO_read_end != fp->_IO_write_base)
-+ {
-+ _IO_pos_t new_pos
-+ = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
-+ if (new_pos == _IO_pos_BAD)
-+ return 0;
-+ fp->_old_offset = new_pos;
-+ }
-+ count = _IO_SYSWRITE (fp, data, to_do);
-+ if (fp->_cur_column && count)
-+ fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1;
-+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
-+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
-+ fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
-+ ? fp->_IO_buf_base : fp->_IO_buf_end);
-+ return count;
-+}
-+
-+int
-+_IO_old_file_underflow (fp)
-+ _IO_FILE *fp;
-+{
-+ _IO_ssize_t count;
-+#if 0
-+ /* SysV does not make this test; take it out for compatibility */
-+ if (fp->_flags & _IO_EOF_SEEN)
-+ return (EOF);
-+#endif
-+
-+ if (fp->_flags & _IO_NO_READS)
-+ {
-+ __set_errno (EBADF);
-+ return EOF;
-+ }
-+ if (fp->_IO_read_ptr < fp->_IO_read_end)
-+ return *(unsigned char *) fp->_IO_read_ptr;
-+
-+ if (fp->_IO_buf_base == NULL)
-+ _IO_doallocbuf (fp);
-+
-+ /* Flush all line buffered files before reading. */
-+ /* FIXME This can/should be moved to genops ?? */
-+ if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
-+ _IO_flush_all_linebuffered ();
-+
-+ _IO_switch_to_get_mode (fp);
-+
-+ /* This is very tricky. We have to adjust those
-+ pointers before we call _IO_SYSREAD () since
-+ we may longjump () out while waiting for
-+ input. Those pointers may be screwed up. H.J. */
-+ fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
-+ fp->_IO_read_end = fp->_IO_buf_base;
-+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
-+ = fp->_IO_buf_base;
-+
-+ count = _IO_SYSREAD (fp, fp->_IO_buf_base,
-+ fp->_IO_buf_end - fp->_IO_buf_base);
-+ if (count <= 0)
-+ {
-+ if (count == 0)
-+ fp->_flags |= _IO_EOF_SEEN;
-+ else
-+ fp->_flags |= _IO_ERR_SEEN, count = 0;
-+ }
-+ fp->_IO_read_end += count;
-+ if (count == 0)
-+ return EOF;
-+ if (fp->_old_offset != _IO_pos_BAD)
-+ _IO_pos_adjust (fp->_old_offset, count);
-+ return *(unsigned char *) fp->_IO_read_ptr;
-+}
-+
-+int
-+_IO_old_file_overflow (f, ch)
-+ _IO_FILE *f;
-+ int ch;
-+{
-+ if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
-+ {
-+ f->_flags |= _IO_ERR_SEEN;
-+ __set_errno (EBADF);
-+ return EOF;
-+ }
-+ /* If currently reading or no buffer allocated. */
-+ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
-+ {
-+ /* Allocate a buffer if needed. */
-+ if (f->_IO_write_base == 0)
-+ {
-+ _IO_doallocbuf (f);
-+ _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
-+ }
-+ /* Otherwise must be currently reading.
-+ If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
-+ logically slide the buffer forwards one block (by setting the
-+ read pointers to all point at the beginning of the block). This
-+ makes room for subsequent output.
-+ Otherwise, set the read pointers to _IO_read_end (leaving that
-+ alone, so it can continue to correspond to the external position). */
-+ if (f->_IO_read_ptr == f->_IO_buf_end)
-+ f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
-+ f->_IO_write_ptr = f->_IO_read_ptr;
-+ f->_IO_write_base = f->_IO_write_ptr;
-+ f->_IO_write_end = f->_IO_buf_end;
-+ f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
-+
-+ if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
-+ f->_IO_write_end = f->_IO_write_ptr;
-+ f->_flags |= _IO_CURRENTLY_PUTTING;
-+ }
-+ if (ch == EOF)
-+ return _IO_old_do_flush (f);
-+ if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
-+ if (_IO_old_do_flush (f) == EOF)
-+ return EOF;
-+ *f->_IO_write_ptr++ = ch;
-+ if ((f->_flags & _IO_UNBUFFERED)
-+ || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
-+ if (_IO_old_do_flush (f) == EOF)
-+ return EOF;
-+ return (unsigned char) ch;
-+}
-+
-+int
-+_IO_old_file_sync (fp)
-+ _IO_FILE *fp;
-+{
-+ _IO_size_t delta;
-+ int retval = 0;
-+
-+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
-+ _IO_flockfile (fp);
-+ /* char* ptr = cur_ptr(); */
-+ if (fp->_IO_write_ptr > fp->_IO_write_base)
-+ if (_IO_old_do_flush(fp)) return EOF;
-+ delta = fp->_IO_read_ptr - fp->_IO_read_end;
-+ if (delta != 0)
-+ {
-+#ifdef TODO
-+ if (_IO_in_backup (fp))
-+ delta -= eGptr () - Gbase ();
-+#endif
-+ _IO_off_t new_pos = _IO_SYSSEEK (fp, delta, 1);
-+ if (new_pos != (_IO_off_t) EOF)
-+ fp->_IO_read_end = fp->_IO_read_ptr;
-+#ifdef ESPIPE
-+ else if (errno == ESPIPE)
-+ ; /* Ignore error from unseekable devices. */
-+#endif
-+ else
-+ retval = EOF;
-+ }
-+ if (retval != EOF)
-+ fp->_old_offset = _IO_pos_BAD;
-+ /* FIXME: Cleanup - can this be shared? */
-+ /* setg(base(), ptr, ptr); */
-+ _IO_funlockfile (fp);
-+ _IO_cleanup_region_end (0);
-+ return retval;
-+}
-+
-+_IO_fpos64_t
-+_IO_old_file_seekoff (fp, offset, dir, mode)
-+ _IO_FILE *fp;
-+ _IO_off64_t offset;
-+ int dir;
-+ int mode;
-+{
-+ _IO_pos_t result;
-+ _IO_off64_t delta, new_offset;
-+ long count;
-+ /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
-+ offset of the underlying file must be exact. */
-+ int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
-+ && fp->_IO_write_base == fp->_IO_write_ptr);
-+
-+ if (mode == 0)
-+ dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
-+
-+ /* Flush unwritten characters.
-+ (This may do an unneeded write if we seek within the buffer.
-+ But to be able to switch to reading, we would need to set
-+ egptr to ptr. That can't be done in the current design,
-+ which assumes file_ptr() is eGptr. Anyway, since we probably
-+ end up flushing when we close(), it doesn't make much difference.)
-+ FIXME: simulate mem-papped files. */
-+
-+ if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
-+ if (_IO_switch_to_get_mode (fp))
-+ return EOF;
-+
-+ if (fp->_IO_buf_base == NULL)
-+ {
-+ _IO_doallocbuf (fp);
-+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
-+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
-+ }
-+
-+ switch (dir)
-+ {
-+ case _IO_seek_cur:
-+ /* Adjust for read-ahead (bytes is buffer). */
-+ offset -= fp->_IO_read_end - fp->_IO_read_ptr;
-+ if (fp->_old_offset == _IO_pos_BAD)
-+ goto dumb;
-+ /* Make offset absolute, assuming current pointer is file_ptr(). */
-+ offset += _IO_pos_as_off (fp->_old_offset);
-+
-+ dir = _IO_seek_set;
-+ break;
-+ case _IO_seek_set:
-+ break;
-+ case _IO_seek_end:
-+ {
-+ struct _G_stat64 st;
-+ if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
-+ {
-+ offset += st.st_size;
-+ dir = _IO_seek_set;
-+ }
-+ else
-+ goto dumb;
-+ }
-+ }
-+ /* At this point, dir==_IO_seek_set. */
-+
-+ /* If destination is within current buffer, optimize: */
-+ if (fp->_old_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
-+ && !_IO_in_backup (fp))
-+ {
-+ /* Offset relative to start of main get area. */
-+ _IO_pos_t rel_offset = (offset - fp->_old_offset
-+ + (fp->_IO_read_end - fp->_IO_read_base));
-+ if (rel_offset >= 0)
-+ {
-+#if 0
-+ if (_IO_in_backup (fp))
-+ _IO_switch_to_main_get_area (fp);
-+#endif
-+ if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
-+ {
-+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
-+ fp->_IO_read_end);
-+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
-+ goto resync;
-+ }
-+#ifdef TODO
-+ /* If we have streammarkers, seek forward by reading ahead. */
-+ if (_IO_have_markers (fp))
-+ {
-+ int to_skip = rel_offset
-+ - (fp->_IO_read_ptr - fp->_IO_read_base);
-+ if (ignore (to_skip) != to_skip)
-+ goto dumb;
-+ goto resync;
-+ }
-+#endif
-+ }
-+#ifdef TODO
-+ if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
-+ {
-+ if (!_IO_in_backup (fp))
-+ _IO_switch_to_backup_area (fp);
-+ gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
-+ goto resync;
-+ }
-+#endif
-+ }
-+
-+#ifdef TODO
-+ _IO_unsave_markers (fp);
-+#endif
-+
-+ if (fp->_flags & _IO_NO_READS)
-+ goto dumb;
-+
-+ /* Try to seek to a block boundary, to improve kernel page management. */
-+ new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
-+ delta = offset - new_offset;
-+ if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
-+ {
-+ new_offset = offset;
-+ delta = 0;
-+ }
-+ result = _IO_SYSSEEK (fp, new_offset, 0);
-+ if (result < 0)
-+ return EOF;
-+ if (delta == 0)
-+ count = 0;
-+ else
-+ {
-+ count = _IO_SYSREAD (fp, fp->_IO_buf_base,
-+ (must_be_exact
-+ ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
-+ if (count < delta)
-+ {
-+ /* We weren't allowed to read, but try to seek the remainder. */
-+ offset = count == EOF ? delta : delta-count;
-+ dir = _IO_seek_cur;
-+ goto dumb;
-+ }
-+ }
-+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
-+ fp->_IO_buf_base + count);
-+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
-+ fp->_old_offset = result + count;
-+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
-+ return offset;
-+ dumb:
-+
-+ _IO_unsave_markers (fp);
-+ result = _IO_SYSSEEK (fp, offset, dir);
-+ if (result != EOF)
-+ {
-+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
-+ fp->_old_offset = result;
-+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
-+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
-+ }
-+ return result;
-+
-+resync:
-+ /* We need to do it since it is possible that the file offset in
-+ the kernel may be changed behind our back. It may happen when
-+ we fopen a file and then do a fork. One process may access the
-+ the file and the kernel file offset will be changed. */
-+ if (fp->_old_offset >= 0)
-+ _IO_SYSSEEK (fp, fp->_old_offset, 0);
-+
-+ return offset;
-+}
-+
-+_IO_ssize_t
-+_IO_old_file_write (f, data, n)
-+ _IO_FILE *f;
-+ const void *data;
-+ _IO_ssize_t n;
-+{
-+ _IO_ssize_t to_do = n;
-+ while (to_do > 0)
-+ {
-+ _IO_ssize_t count = write (f->_fileno, data, to_do);
-+ if (count == EOF)
-+ {
-+ f->_flags |= _IO_ERR_SEEN;
-+ break;
-+ }
-+ to_do -= count;
-+ data = (void *) ((char *) data + count);
-+ }
-+ n -= to_do;
-+ if (f->_old_offset >= 0)
-+ f->_old_offset += n;
-+ return n;
-+}
-+
-+_IO_size_t
-+_IO_old_file_xsputn (f, data, n)
-+ _IO_FILE *f;
-+ const void *data;
-+ _IO_size_t n;
-+{
-+ register const char *s = (char *) data;
-+ _IO_size_t to_do = n;
-+ int must_flush = 0;
-+ _IO_size_t count;
-+
-+ if (n <= 0)
-+ return 0;
-+ /* This is an optimized implementation.
-+ If the amount to be written straddles a block boundary
-+ (or the filebuf is unbuffered), use sys_write directly. */
-+
-+ /* First figure out how much space is available in the buffer. */
-+ count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
-+ if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
-+ {
-+ count = f->_IO_buf_end - f->_IO_write_ptr;
-+ if (count >= n)
-+ {
-+ register const char *p;
-+ for (p = s + n; p > s; )
-+ {
-+ if (*--p == '\n')
-+ {
-+ count = p - s + 1;
-+ must_flush = 1;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ /* Then fill the buffer. */
-+ if (count > 0)
-+ {
-+ if (count > to_do)
-+ count = to_do;
-+ if (count > 20)
-+ {
-+ memcpy (f->_IO_write_ptr, s, count);
-+ s += count;
-+ }
-+ else
-+ {
-+ register char *p = f->_IO_write_ptr;
-+ register int i = (int) count;
-+ while (--i >= 0)
-+ *p++ = *s++;
-+ }
-+ f->_IO_write_ptr += count;
-+ to_do -= count;
-+ }
-+ if (to_do + must_flush > 0)
-+ {
-+ _IO_size_t block_size, do_write;
-+ /* Next flush the (full) buffer. */
-+ if (__overflow (f, EOF) == EOF)
-+ return n - to_do;
-+
-+ /* Try to maintain alignment: write a whole number of blocks.
-+ dont_write is what gets left over. */
-+ block_size = f->_IO_buf_end - f->_IO_buf_base;
-+ do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
-+
-+ if (do_write)
-+ {
-+ count = old_do_write (f, s, do_write);
-+ to_do -= count;
-+ if (count < do_write)
-+ return n - to_do;
-+ }
-+
-+ /* Now write out the remainder. Normally, this will fit in the
-+ buffer, but it's somewhat messier for line-buffered files,
-+ so we let _IO_default_xsputn handle the general case. */
-+ if (to_do)
-+ to_do -= _IO_default_xsputn (f, s+do_write, to_do);
-+ }
-+ return n - to_do;
-+}
-+
-+
-+struct _IO_jump_t _IO_old_file_jumps =
-+{
-+ JUMP_INIT_DUMMY,
-+ JUMP_INIT(finish, _IO_old_file_finish),
-+ JUMP_INIT(overflow, _IO_old_file_overflow),
-+ JUMP_INIT(underflow, _IO_old_file_underflow),
-+ JUMP_INIT(uflow, _IO_default_uflow),
-+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
-+ JUMP_INIT(xsputn, _IO_old_file_xsputn),
-+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
-+ JUMP_INIT(seekoff, _IO_old_file_seekoff),
-+ JUMP_INIT(seekpos, _IO_default_seekpos),
-+ JUMP_INIT(setbuf, _IO_old_file_setbuf),
-+ JUMP_INIT(sync, _IO_old_file_sync),
-+ JUMP_INIT(doallocate, _IO_file_doallocate),
-+ JUMP_INIT(read, _IO_file_read),
-+ JUMP_INIT(write, _IO_old_file_write),
-+ JUMP_INIT(seek, _IO_file_seek),
-+ JUMP_INIT(close, _IO_file_close),
-+ JUMP_INIT(stat, _IO_file_stat)
-+};
-+
-+#ifdef SHARED
-+symbol_version (_IO_old_do_write, _IO_do_write, GLIBC_2.0);
-+symbol_version (_IO_old_file_attach, _IO_file_attach, GLIBC_2.0);
-+symbol_version (_IO_old_file_close_it, _IO_file_close_it, GLIBC_2.0);
-+symbol_version (_IO_old_file_finish, _IO_file_finish, GLIBC_2.0);
-+symbol_version (_IO_old_file_fopen, _IO_file_fopen, GLIBC_2.0);
-+symbol_version (_IO_old_file_init, _IO_file_init, GLIBC_2.0);
-+symbol_version (_IO_old_file_setbuf, _IO_file_setbuf, GLIBC_2.0);
-+symbol_version (_IO_old_file_sync, _IO_file_sync, GLIBC_2.0);
-+symbol_version (_IO_old_file_overflow, _IO_file_overflow, GLIBC_2.0);
-+symbol_version (_IO_old_file_seekoff, _IO_file_seekoff, GLIBC_2.0);
-+symbol_version (_IO_old_file_underflow, _IO_file_underflow, GLIBC_2.0);
-+symbol_version (_IO_old_file_write, _IO_file_write, GLIBC_2.0);
-+symbol_version (_IO_old_file_xsputn, _IO_file_xsputn, GLIBC_2.0);
-+#else
-+strong_alias (_IO_old_do_write, _IO_do_write);
-+strong_alias (_IO_old_file_attach, _IO_file_attach);
-+strong_alias (_IO_old_file_close_it, _IO_file_close_it);
-+strong_alias (_IO_old_file_finish, _IO_file_finish);
-+strong_alias (_IO_old_file_fopen, _IO_file_fopen);
-+strong_alias (_IO_old_file_init, _IO_file_init);
-+strong_alias (_IO_old_file_setbuf, _IO_file_setbuf);
-+strong_alias (_IO_old_file_sync, _IO_file_sync);
-+strong_alias (_IO_old_file_overflow, _IO_file_overflow);
-+strong_alias (_IO_old_file_seekoff, _IO_file_seekoff);
-+strong_alias (_IO_old_file_underflow, _IO_file_underflow);
-+strong_alias (_IO_old_file_write, _IO_file_write);
-+strong_alias (_IO_old_file_xsputn, _IO_file_xsputn);
-+#endif
-diff -Naur ../glibc-2.1.3/glibc-compat/oldiofclose.c glibc-2.1.3/glibc-compat/oldiofclose.c
---- ../glibc-2.1.3/glibc-compat/oldiofclose.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/oldiofclose.c 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,60 @@
-+/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU IO Library.
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this library; see the file COPYING. If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-+ MA 02111-1307, USA.
-+
-+ As a special exception, if you link this library with files
-+ compiled with a GNU compiler to produce an executable, this does
-+ not cause the resulting executable to be covered by the GNU General
-+ Public License. This exception does not however invalidate any
-+ other reasons why the executable file might be covered by the GNU
-+ General Public License. */
-+
-+#define _IO_USE_OLD_IO_FILE
-+#include "libioP.h"
-+#ifdef __STDC__
-+#include <stdlib.h>
-+#endif
-+
-+int
-+_IO_old_fclose (fp)
-+ _IO_FILE *fp;
-+{
-+ int status;
-+
-+ CHECK_FILE(fp, EOF);
-+
-+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
-+ _IO_flockfile (fp);
-+ if (fp->_IO_file_flags & _IO_IS_FILEBUF)
-+ status = _IO_old_file_close_it (fp);
-+ else
-+ status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
-+ _IO_FINISH (fp);
-+ _IO_funlockfile (fp);
-+ _IO_cleanup_region_end (0);
-+ if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
-+ {
-+ fp->_IO_file_flags = 0;
-+ free(fp);
-+ }
-+
-+ return status;
-+}
-+
-+strong_alias (_IO_old_fclose, __old_fclose)
-+symbol_version (_IO_old_fclose, _IO_fclose, GLIBC_2.0);
-+symbol_version (__old_fclose, fclose, GLIBC_2.0);
-diff -Naur ../glibc-2.1.3/glibc-compat/oldiofdopen.c glibc-2.1.3/glibc-compat/oldiofdopen.c
---- ../glibc-2.1.3/glibc-compat/oldiofdopen.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/oldiofdopen.c 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,140 @@
-+/* Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU IO Library.
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this library; see the file COPYING. If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-+ MA 02111-1307, USA.
-+
-+ As a special exception, if you link this library with files
-+ compiled with a GNU compiler to produce an executable, this does
-+ not cause the resulting executable to be covered by the GNU General
-+ Public License. This exception does not however invalidate any
-+ other reasons why the executable file might be covered by the GNU
-+ General Public License. */
-+
-+#define _IO_USE_OLD_IO_FILE
-+#ifdef __STDC__
-+# include <stdlib.h>
-+#endif
-+#include "libioP.h"
-+#include <fcntl.h>
-+
-+#ifndef _IO_fcntl
-+# define _IO_fcntl __fcntl
-+#endif
-+
-+_IO_FILE *
-+_IO_old_fdopen (fd, mode)
-+ int fd;
-+ const char *mode;
-+{
-+ int read_write;
-+ int posix_mode = 0;
-+ struct locked_FILE
-+ {
-+ struct _IO_FILE_plus fp;
-+#ifdef _IO_MTSAFE_IO
-+ _IO_lock_t lock;
-+#endif
-+ } *new_f;
-+ int fd_flags;
-+
-+ switch (*mode++)
-+ {
-+ case 'r':
-+ read_write = _IO_NO_WRITES;
-+ break;
-+ case 'w':
-+ read_write = _IO_NO_READS;
-+ break;
-+ case 'a':
-+ posix_mode = O_APPEND;
-+ read_write = _IO_NO_READS|_IO_IS_APPENDING;
-+ break;
-+ default:
-+ MAYBE_SET_EINVAL;
-+ return NULL;
-+ }
-+ if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
-+ read_write &= _IO_IS_APPENDING;
-+#ifdef F_GETFL
-+ fd_flags = _IO_fcntl (fd, F_GETFL);
-+#ifndef O_ACCMODE
-+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
-+#endif
-+ if (fd_flags == -1
-+ || ((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
-+ || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
-+ return NULL;
-+
-+ /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
-+ [System Application Program Interface (API) Amendment 1:
-+ Realtime Extensions], Rationale B.8.3.3
-+ Open a Stream on a File Descriptor says:
-+
-+ Although not explicitly required by POSIX.1, a good
-+ implementation of append ("a") mode would cause the
-+ O_APPEND flag to be set.
-+
-+ (Historical implementations [such as Solaris2] do a one-time
-+ seek in fdopen.)
-+
-+ However, we do not turn O_APPEND off if the mode is "w" (even
-+ though that would seem consistent) because that would be more
-+ likely to break historical programs.
-+ */
-+ if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
-+ {
-+#ifdef F_SETFL
-+ if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1)
-+#endif
-+ return NULL;
-+ }
-+#endif
-+
-+ new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
-+ if (new_f == NULL)
-+ return NULL;
-+#ifdef _IO_MTSAFE_IO
-+ new_f->fp.file._lock = &new_f->lock;
-+#endif
-+ _IO_init (&new_f->fp.file, 0);
-+ _IO_JUMPS (&new_f->fp) = &_IO_old_file_jumps;
-+ _IO_old_file_init (&new_f->fp.file);
-+#if !_IO_UNIFIED_JUMPTABLES
-+ new_f->fp.vtable = NULL;
-+#endif
-+ if (_IO_old_file_attach (&new_f->fp.file, fd) == NULL)
-+ {
-+ _IO_un_link (&new_f->fp.file);
-+ free (new_f);
-+ return NULL;
-+ }
-+ new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE;
-+
-+ new_f->fp.file._IO_file_flags =
-+ _IO_mask_flags (&new_f->fp.file, read_write,
-+ _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
-+
-+ return (_IO_FILE *) &new_f->fp;
-+}
-+
-+#ifdef SHARED
-+strong_alias (_IO_old_fdopen, __old_fdopen)
-+symbol_version (_IO_old_fdopen, _IO_fdopen, GLIBC_2.0);
-+symbol_version (__old_fdopen, fdopen, GLIBC_2.0);
-+#else
-+strong_alias (_IO_old_fdopen, _IO_fdopen);
-+strong_alias (__old_fdopen, fdopen);
-+#endif
-diff -Naur ../glibc-2.1.3/glibc-compat/oldiofopen.c glibc-2.1.3/glibc-compat/oldiofopen.c
---- ../glibc-2.1.3/glibc-compat/oldiofopen.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/oldiofopen.c 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,71 @@
-+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU IO Library.
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this library; see the file COPYING. If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-+ MA 02111-1307, USA.
-+
-+ As a special exception, if you link this library with files
-+ compiled with a GNU compiler to produce an executable, this does
-+ not cause the resulting executable to be covered by the GNU General
-+ Public License. This exception does not however invalidate any
-+ other reasons why the executable file might be covered by the GNU
-+ General Public License. */
-+
-+#define _IO_USE_OLD_IO_FILE
-+#include "libioP.h"
-+#ifdef __STDC__
-+#include <stdlib.h>
-+#endif
-+
-+
-+_IO_FILE *
-+_IO_old_fopen (filename, mode)
-+ const char *filename;
-+ const char *mode;
-+{
-+ struct locked_FILE
-+ {
-+ struct _IO_FILE_plus fp;
-+#ifdef _IO_MTSAFE_IO
-+ _IO_lock_t lock;
-+#endif
-+ } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
-+
-+ if (new_f == NULL)
-+ return NULL;
-+#ifdef _IO_MTSAFE_IO
-+ new_f->fp.file._lock = &new_f->lock;
-+#endif
-+ _IO_init (&new_f->fp.file, 0);
-+ _IO_JUMPS (&new_f->fp.file) = &_IO_old_file_jumps;
-+ _IO_old_file_init (&new_f->fp.file);
-+#if !_IO_UNIFIED_JUMPTABLES
-+ new_f->fp.vtable = NULL;
-+#endif
-+ if (_IO_old_file_fopen (&new_f->fp.file, filename, mode) != NULL)
-+ return (_IO_FILE *) &new_f->fp;
-+ _IO_un_link (&new_f->fp.file);
-+ free (new_f);
-+ return NULL;
-+}
-+
-+#ifdef SHARED
-+strong_alias (_IO_old_fopen, __old_fopen)
-+symbol_version (_IO_old_fopen, _IO_fopen, GLIBC_2.0);
-+symbol_version (__old_fopen, fopen, GLIBC_2.0);
-+#else
-+strong_alias (_IO_old_fopen, _IO_fopen);
-+strong_alias (__old_fopen, fopen);
-+#endif
-diff -Naur ../glibc-2.1.3/glibc-compat/oldiopopen.c glibc-2.1.3/glibc-compat/oldiopopen.c
---- ../glibc-2.1.3/glibc-compat/oldiopopen.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/oldiopopen.c 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,289 @@
-+/* Copyright (C) 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU IO Library.
-+ Written by Per Bothner <bothner@cygnus.com>.
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this library; see the file COPYING. If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-+ MA 02111-1307, USA.
-+
-+ As a special exception, if you link this library with files
-+ compiled with a GNU compiler to produce an executable, this does
-+ not cause the resulting executable to be covered by the GNU General
-+ Public License. This exception does not however invalidate any
-+ other reasons why the executable file might be covered by the GNU
-+ General Public License. */
-+
-+#define _IO_USE_OLD_IO_FILE
-+#ifndef _POSIX_SOURCE
-+# define _POSIX_SOURCE
-+#endif
-+#include "libioP.h"
-+#if _IO_HAVE_SYS_WAIT
-+#include <signal.h>
-+#include <unistd.h>
-+#ifdef __STDC__
-+#include <stdlib.h>
-+#endif
-+#ifdef _LIBC
-+# include <unistd.h>
-+#endif
-+#include <sys/types.h>
-+#include <sys/wait.h>
-+
-+#ifndef _IO_fork
-+#ifdef _LIBC
-+#define _IO_fork __vfork
-+#else
-+#define _IO_fork vfork /* defined in libiberty, if needed */
-+#endif
-+extern _IO_pid_t _IO_fork __P ((void));
-+#endif
-+
-+#endif /* _IO_HAVE_SYS_WAIT */
-+
-+#ifndef _IO_pipe
-+#ifdef _LIBC
-+#define _IO_pipe __pipe
-+#else
-+#define _IO_pipe pipe
-+#endif
-+extern int _IO_pipe __P ((int des[2]));
-+#endif
-+
-+#ifndef _IO_dup2
-+#ifdef _LIBC
-+#define _IO_dup2 __dup2
-+#else
-+#define _IO_dup2 dup2
-+#endif
-+extern int _IO_dup2 __P ((int fd, int fd2));
-+#endif
-+
-+#ifndef _IO_waitpid
-+#ifdef _LIBC
-+#define _IO_waitpid __waitpid
-+#else
-+#define _IO_waitpid waitpid
-+#endif
-+#endif
-+
-+#ifndef _IO_execl
-+#define _IO_execl execl
-+#endif
-+#ifndef _IO__exit
-+#define _IO__exit _exit
-+#endif
-+
-+#ifndef _IO_close
-+#ifdef _LIBC
-+#define _IO_close __close
-+#else
-+#define _IO_close close
-+#endif
-+#endif
-+
-+struct _IO_proc_file
-+{
-+ struct _IO_FILE_plus file;
-+ /* Following fields must match those in class procbuf (procbuf.h) */
-+ _IO_pid_t pid;
-+ struct _IO_proc_file *next;
-+};
-+typedef struct _IO_proc_file _IO_proc_file;
-+
-+static struct _IO_proc_file *old_proc_file_chain = NULL;
-+
-+_IO_FILE *
-+_IO_old_proc_open (fp, command, mode)
-+ _IO_FILE *fp;
-+ const char *command;
-+ const char *mode;
-+{
-+#if _IO_HAVE_SYS_WAIT
-+ volatile int read_or_write;
-+ volatile int parent_end, child_end;
-+ int pipe_fds[2];
-+ _IO_pid_t child_pid;
-+ if (_IO_file_is_open (fp))
-+ return NULL;
-+ if (_IO_pipe (pipe_fds) < 0)
-+ return NULL;
-+ if (mode[0] == 'r' && mode[1] == '\0')
-+ {
-+ parent_end = pipe_fds[0];
-+ child_end = pipe_fds[1];
-+ read_or_write = _IO_NO_WRITES;
-+ }
-+ else if (mode[0] == 'w' && mode[1] == '\0')
-+ {
-+ parent_end = pipe_fds[1];
-+ child_end = pipe_fds[0];
-+ read_or_write = _IO_NO_READS;
-+ }
-+ else
-+ {
-+ __set_errno (EINVAL);
-+ return NULL;
-+ }
-+ ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork ();
-+ if (child_pid == 0)
-+ {
-+ int child_std_end = mode[0] == 'r' ? 1 : 0;
-+ _IO_close (parent_end);
-+ if (child_end != child_std_end)
-+ {
-+ _IO_dup2 (child_end, child_std_end);
-+ _IO_close (child_end);
-+ }
-+ /* POSIX.2: "popen() shall ensure that any streams from previous
-+ popen() calls that remain open in the parent process are closed
-+ in the new child process." */
-+ while (old_proc_file_chain)
-+ {
-+ _IO_close (_IO_fileno ((_IO_FILE *) old_proc_file_chain));
-+ old_proc_file_chain = old_proc_file_chain->next;
-+ }
-+
-+ _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0);
-+ _IO__exit (127);
-+ }
-+ _IO_close (child_end);
-+ if (child_pid < 0)
-+ {
-+ _IO_close (parent_end);
-+ return NULL;
-+ }
-+ _IO_fileno (fp) = parent_end;
-+
-+ /* Link into old_proc_file_chain. */
-+ ((_IO_proc_file *) fp)->next = old_proc_file_chain;
-+ old_proc_file_chain = (_IO_proc_file *) fp;
-+
-+ _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
-+ return fp;
-+#else /* !_IO_HAVE_SYS_WAIT */
-+ return NULL;
-+#endif
-+}
-+
-+_IO_FILE *
-+_IO_old_popen (command, mode)
-+ const char *command;
-+ const char *mode;
-+{
-+ struct locked_FILE
-+ {
-+ struct _IO_proc_file fpx;
-+#ifdef _IO_MTSAFE_IO
-+ _IO_lock_t lock;
-+#endif
-+ } *new_f;
-+ _IO_FILE *fp;
-+
-+ new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
-+ if (new_f == NULL)
-+ return NULL;
-+#ifdef _IO_MTSAFE_IO
-+ new_f->fpx.file.file._lock = &new_f->lock;
-+#endif
-+ fp = &new_f->fpx.file.file;
-+ _IO_init (fp, 0);
-+ _IO_JUMPS (fp) = &_IO_old_proc_jumps;
-+ _IO_old_file_init (fp);
-+#if !_IO_UNIFIED_JUMPTABLES
-+ new_f->fpx.file.vtable = NULL;
-+#endif
-+ if (_IO_old_proc_open (fp, command, mode) != NULL)
-+ return fp;
-+ _IO_un_link (fp);
-+ free (new_f);
-+ return NULL;
-+}
-+
-+int
-+_IO_old_proc_close (fp)
-+ _IO_FILE *fp;
-+{
-+ /* This is not name-space clean. FIXME! */
-+#if _IO_HAVE_SYS_WAIT
-+ int wstatus;
-+ _IO_proc_file **ptr = &old_proc_file_chain;
-+ _IO_pid_t wait_pid;
-+ int status = -1;
-+
-+ /* Unlink from old_proc_file_chain. */
-+ for ( ; *ptr != NULL; ptr = &(*ptr)->next)
-+ {
-+ if (*ptr == (_IO_proc_file *) fp)
-+ {
-+ *ptr = (*ptr)->next;
-+ status = 0;
-+ break;
-+ }
-+ }
-+
-+ if (status < 0 || _IO_close (_IO_fileno(fp)) < 0)
-+ return -1;
-+ /* POSIX.2 Rationale: "Some historical implementations either block
-+ or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
-+ for the child process to terminate. Since this behavior is not
-+ described in POSIX.2, such implementations are not conforming." */
-+ do
-+ {
-+ wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
-+ }
-+ while (wait_pid == -1 && errno == EINTR);
-+ if (wait_pid == -1)
-+ return -1;
-+ return wstatus;
-+#else /* !_IO_HAVE_SYS_WAIT */
-+ return -1;
-+#endif
-+}
-+
-+struct _IO_jump_t _IO_old_proc_jumps = {
-+ JUMP_INIT_DUMMY,
-+ JUMP_INIT(finish, _IO_old_file_finish),
-+ JUMP_INIT(overflow, _IO_old_file_overflow),
-+ JUMP_INIT(underflow, _IO_old_file_underflow),
-+ JUMP_INIT(uflow, _IO_default_uflow),
-+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
-+ JUMP_INIT(xsputn, _IO_old_file_xsputn),
-+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
-+ JUMP_INIT(seekoff, _IO_old_file_seekoff),
-+ JUMP_INIT(seekpos, _IO_default_seekpos),
-+ JUMP_INIT(setbuf, _IO_old_file_setbuf),
-+ JUMP_INIT(sync, _IO_old_file_sync),
-+ JUMP_INIT(doallocate, _IO_file_doallocate),
-+ JUMP_INIT(read, _IO_file_read),
-+ JUMP_INIT(write, _IO_old_file_write),
-+ JUMP_INIT(seek, _IO_file_seek),
-+ JUMP_INIT(close, _IO_old_proc_close),
-+ JUMP_INIT(stat, _IO_file_stat),
-+ JUMP_INIT(showmanyc, _IO_default_showmanyc),
-+ JUMP_INIT(imbue, _IO_default_imbue)
-+};
-+
-+#ifdef SHARED
-+strong_alias (_IO_old_popen, __old_popen)
-+symbol_version (_IO_old_popen, _IO_popen, GLIBC_2.0);
-+symbol_version (__old_popen, popen, GLIBC_2.0);
-+symbol_version (_IO_old_proc_open, _IO_proc_open, GLIBC_2.0);
-+symbol_version (_IO_old_proc_close, _IO_proc_close, GLIBC_2.0);
-+#else
-+strong_alias (_IO_old_popen, _IO_popen);
-+strong_alias (__old_popen, popen);
-+strong_alias (_IO_old_proc_open, _IO_proc_open);
-+strong_alias (_IO_old_proc_close, _IO_proc_close);
-+#endif
-diff -Naur ../glibc-2.1.3/glibc-compat/oldpclose.c glibc-2.1.3/glibc-compat/oldpclose.c
---- ../glibc-2.1.3/glibc-compat/oldpclose.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/oldpclose.c 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,48 @@
-+/* Copyright (C) 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU IO Library.
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this library; see the file COPYING. If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-+ MA 02111-1307, USA.
-+
-+ As a special exception, if you link this library with files
-+ compiled with a GNU compiler to produce an executable, this does
-+ not cause the resulting executable to be covered by the GNU General
-+ Public License. This exception does not however invalidate any
-+ other reasons why the executable file might be covered by the GNU
-+ General Public License. */
-+
-+#define _IO_USE_OLD_IO_FILE
-+#include "libioP.h"
-+#include "stdio.h"
-+#include <errno.h>
-+
-+int
-+__old_pclose (fp)
-+ FILE *fp;
-+{
-+#if 0
-+ /* Does not actually test that stream was created by popen(). Instead,
-+ it depends on the filebuf::sys_close() virtual to Do The Right Thing. */
-+ if (fp is not a proc_file)
-+ return -1;
-+#endif
-+ return _IO_old_fclose (fp);
-+}
-+
-+#ifdef SHARED
-+symbol_version (__old_pclose, pclose, GLIBC_2.0);
-+#else
-+strong_alias (__old_pclose, pclose);
-+#endif
-diff -Naur ../glibc-2.1.3/glibc-compat/oldstdfiles.c glibc-2.1.3/glibc-compat/oldstdfiles.c
---- ../glibc-2.1.3/glibc-compat/oldstdfiles.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/oldstdfiles.c 2000-01-03 17:07:07.000000000 -0800
-@@ -0,0 +1,97 @@
-+/* Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU IO Library.
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this library; see the file COPYING. If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-+ MA 02111-1307, USA.
-+
-+ As a special exception, if you link this library with files
-+ compiled with a GNU compiler to produce an executable, this does
-+ not cause the resulting executable to be covered by the GNU General
-+ Public License. This exception does not however invalidate any
-+ other reasons why the executable file might be covered by the GNU
-+ General Public License. */
-+
-+
-+/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr
-+ for C code. Compare stdstreams.cc.
-+ (The difference is that here the vtable field is set to 0,
-+ so the objects defined are not valid C++ objects. On the other
-+ hand, we don't need a C++ compiler to build this file.) */
-+
-+#define _IO_USE_OLD_IO_FILE
-+#include "libioP.h"
-+
-+#ifdef _IO_MTSAFE_IO
-+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
-+ static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
-+ struct _IO_FILE_plus NAME \
-+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps};
-+#else
-+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
-+ struct _IO_FILE_plus NAME \
-+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps};
-+#endif
-+
-+DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES);
-+DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_.file, _IO_NO_READS);
-+DEF_STDFILE(_IO_stderr_, 2, &_IO_stdout_.file,
-+ _IO_NO_READS+_IO_UNBUFFERED);
-+
-+#if defined __GNUC__ && __GNUC__ >= 2
-+
-+#include <stdio.h>
-+
-+extern const int _IO_stdin_used;
-+weak_extern (_IO_stdin_used);
-+
-+#undef stdin
-+#undef stdout
-+#undef stderr
-+
-+extern FILE *stdin;
-+extern FILE *stdout;
-+extern FILE *stderr;
-+
-+#ifdef SHARED
-+extern
-+#endif
-+FILE *_IO_list_all;
-+
-+static void _IO_check_libio __P ((void)) __attribute__ ((constructor));
-+
-+/* This function determines which shared C library the application
-+ was linked against. We then set up the stdin/stdout/stderr and
-+ _IO_list_all accordingly. */
-+
-+static void
-+_IO_check_libio ()
-+{
-+#ifdef SHARED
-+ if (&_IO_stdin_used == NULL)
-+#endif
-+ {
-+ /* We are using the old one. */
-+ _IO_stdin = stdin = &_IO_stdin_.file;
-+ _IO_stdout = stdout = &_IO_stdout_.file;
-+ _IO_stderr = stderr = _IO_list_all = &_IO_stderr_.file;
-+ _IO_stdin->_vtable_offset = _IO_stdout->_vtable_offset =
-+ _IO_stderr->_vtable_offset = stdin->_vtable_offset =
-+ stdout->_vtable_offset = stderr->_vtable_offset =
-+ ((int) sizeof (struct _IO_FILE)
-+ - (int) sizeof (struct _IO_FILE_complete));
-+ }
-+}
-+
-+#endif
-diff -Naur ../glibc-2.1.3/glibc-compat/oldtmpfile.c glibc-2.1.3/glibc-compat/oldtmpfile.c
---- ../glibc-2.1.3/glibc-compat/oldtmpfile.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/oldtmpfile.c 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,55 @@
-+/* Copyright (C) 1991, 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#define _IO_USE_OLD_IO_FILE
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <iolibio.h>
-+
-+/* This returns a new stream opened on a temporary file (generated
-+ by tmpnam). The file is opened with mode "w+b" (binary read/write).
-+ If we couldn't generate a unique filename or the file couldn't
-+ be opened, NULL is returned. */
-+FILE *
-+__old_tmpfile (void)
-+{
-+ char buf[FILENAME_MAX];
-+ int fd;
-+ FILE *f;
-+
-+ if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
-+ return NULL;
-+ fd = __gen_tempname (buf, 1, 0);
-+ if (fd < 0)
-+ return NULL;
-+
-+ /* Note that this relies on the Unix semantics that
-+ a file is not really removed until it is closed. */
-+ (void) remove (buf);
-+
-+ if ((f = _IO_old_fdopen (fd, "w+b")) == NULL)
-+ __close (fd);
-+
-+ return f;
-+}
-+
-+#ifdef SHARED
-+symbol_version (__old_tmpfile, tmpfile, GLIBC_2.0);
-+#else
-+strong_alias (__old_tmpfile, tmpfile);
-+#endif
-diff -Naur ../glibc-2.1.3/glibc-compat/rpcsvc/yp.h glibc-2.1.3/glibc-compat/rpcsvc/yp.h
---- ../glibc-2.1.3/glibc-compat/rpcsvc/yp.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/rpcsvc/yp.h 2000-01-03 18:17:33.000000000 -0800
-@@ -0,0 +1,621 @@
-+/*
-+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
-+ * unrestricted use provided that this legend is included on all tape
-+ * media and as a part of the software program in whole or part. Users
-+ * may copy or modify Sun RPC without charge, but are not authorized
-+ * to license or distribute it to anyone else except as part of a product or
-+ * program developed by the user.
-+ *
-+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
-+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
-+ *
-+ * Sun RPC is provided with no support and without any obligation on the
-+ * part of Sun Microsystems, Inc. to assist in its use, correction,
-+ * modification or enhancement.
-+ *
-+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
-+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
-+ * OR ANY PART THEREOF.
-+ *
-+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
-+ * or profits or other special, indirect and consequential damages, even if
-+ * Sun has been advised of the possibility of such damages.
-+ *
-+ * Sun Microsystems, Inc.
-+ * 2550 Garcia Avenue
-+ * Mountain View, California 94043
-+ */
-+
-+#ifndef __RPCSVC_YP_H__
-+#define __RPCSVC_YP_H__
-+
-+#include <rpc/rpc.h>
-+
-+#define YPMAXRECORD 1024
-+#define YPMAXDOMAIN 64
-+#define YPMAXMAP 64
-+#define YPMAXPEER 64
-+
-+enum ypstat {
-+ YP_TRUE = 1,
-+ YP_NOMORE = 2,
-+ YP_FALSE = 0,
-+ YP_NOMAP = -1,
-+ YP_NODOM = -2,
-+ YP_NOKEY = -3,
-+ YP_BADOP = -4,
-+ YP_BADDB = -5,
-+ YP_YPERR = -6,
-+ YP_BADARGS = -7,
-+ YP_VERS = -8,
-+};
-+typedef enum ypstat ypstat;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypstat(XDR *, ypstat*);
-+#elif __STDC__
-+extern bool_t xdr_ypstat(XDR *, ypstat*);
-+#else /* Old Style C */
-+bool_t xdr_ypstat();
-+#endif /* Old Style C */
-+
-+
-+enum ypxfrstat {
-+ YPXFR_SUCC = 1,
-+ YPXFR_AGE = 2,
-+ YPXFR_NOMAP = -1,
-+ YPXFR_NODOM = -2,
-+ YPXFR_RSRC = -3,
-+ YPXFR_RPC = -4,
-+ YPXFR_MADDR = -5,
-+ YPXFR_YPERR = -6,
-+ YPXFR_BADARGS = -7,
-+ YPXFR_DBM = -8,
-+ YPXFR_FILE = -9,
-+ YPXFR_SKEW = -10,
-+ YPXFR_CLEAR = -11,
-+ YPXFR_FORCE = -12,
-+ YPXFR_XFRERR = -13,
-+ YPXFR_REFUSED = -14,
-+};
-+typedef enum ypxfrstat ypxfrstat;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypxfrstat(XDR *, ypxfrstat*);
-+#elif __STDC__
-+extern bool_t xdr_ypxfrstat(XDR *, ypxfrstat*);
-+#else /* Old Style C */
-+bool_t xdr_ypxfrstat();
-+#endif /* Old Style C */
-+
-+
-+typedef char *domainname;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_domainname(XDR *, domainname*);
-+#elif __STDC__
-+extern bool_t xdr_domainname(XDR *, domainname*);
-+#else /* Old Style C */
-+bool_t xdr_domainname();
-+#endif /* Old Style C */
-+
-+
-+typedef char *mapname;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_mapname(XDR *, mapname*);
-+#elif __STDC__
-+extern bool_t xdr_mapname(XDR *, mapname*);
-+#else /* Old Style C */
-+bool_t xdr_mapname();
-+#endif /* Old Style C */
-+
-+
-+typedef char *peername;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_peername(XDR *, peername*);
-+#elif __STDC__
-+extern bool_t xdr_peername(XDR *, peername*);
-+#else /* Old Style C */
-+bool_t xdr_peername();
-+#endif /* Old Style C */
-+
-+
-+typedef struct {
-+ u_int keydat_len;
-+ char *keydat_val;
-+} keydat;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_keydat(XDR *, keydat*);
-+#elif __STDC__
-+extern bool_t xdr_keydat(XDR *, keydat*);
-+#else /* Old Style C */
-+bool_t xdr_keydat();
-+#endif /* Old Style C */
-+
-+
-+typedef struct {
-+ u_int valdat_len;
-+ char *valdat_val;
-+} valdat;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_valdat(XDR *, valdat*);
-+#elif __STDC__
-+extern bool_t xdr_valdat(XDR *, valdat*);
-+#else /* Old Style C */
-+bool_t xdr_valdat();
-+#endif /* Old Style C */
-+
-+
-+struct ypmap_parms {
-+ domainname domain;
-+ mapname map;
-+ u_int ordernum;
-+ peername peer;
-+};
-+typedef struct ypmap_parms ypmap_parms;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypmap_parms(XDR *, ypmap_parms*);
-+#elif __STDC__
-+extern bool_t xdr_ypmap_parms(XDR *, ypmap_parms*);
-+#else /* Old Style C */
-+bool_t xdr_ypmap_parms();
-+#endif /* Old Style C */
-+
-+
-+struct ypreq_key {
-+ domainname domain;
-+ mapname map;
-+ keydat key;
-+};
-+typedef struct ypreq_key ypreq_key;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypreq_key(XDR *, ypreq_key*);
-+#elif __STDC__
-+extern bool_t xdr_ypreq_key(XDR *, ypreq_key*);
-+#else /* Old Style C */
-+bool_t xdr_ypreq_key();
-+#endif /* Old Style C */
-+
-+
-+struct ypreq_nokey {
-+ domainname domain;
-+ mapname map;
-+};
-+typedef struct ypreq_nokey ypreq_nokey;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypreq_nokey(XDR *, ypreq_nokey*);
-+#elif __STDC__
-+extern bool_t xdr_ypreq_nokey(XDR *, ypreq_nokey*);
-+#else /* Old Style C */
-+bool_t xdr_ypreq_nokey();
-+#endif /* Old Style C */
-+
-+
-+struct ypreq_xfr {
-+ ypmap_parms map_parms;
-+ u_int transid;
-+ u_int prog;
-+ u_int port;
-+};
-+typedef struct ypreq_xfr ypreq_xfr;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypreq_xfr(XDR *, ypreq_xfr*);
-+#elif __STDC__
-+extern bool_t xdr_ypreq_xfr(XDR *, ypreq_xfr*);
-+#else /* Old Style C */
-+bool_t xdr_ypreq_xfr();
-+#endif /* Old Style C */
-+
-+
-+struct ypresp_val {
-+ ypstat stat;
-+ valdat val;
-+};
-+typedef struct ypresp_val ypresp_val;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypresp_val(XDR *, ypresp_val*);
-+#elif __STDC__
-+extern bool_t xdr_ypresp_val(XDR *, ypresp_val*);
-+#else /* Old Style C */
-+bool_t xdr_ypresp_val();
-+#endif /* Old Style C */
-+
-+
-+struct ypresp_key_val {
-+ ypstat stat;
-+#ifdef STUPID_SUN_BUG
-+ /* This is the form as distributed by Sun. But even the Sun NIS
-+ servers expect the values in the other order. So their
-+ implementation somehow must change the order internally. We
-+ don't want to follow this bad example since the user should be
-+ able to use rpcgen on this file. */
-+ keydat key;
-+ valdat val;
-+#else
-+ valdat val;
-+ keydat key;
-+#endif
-+};
-+typedef struct ypresp_key_val ypresp_key_val;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypresp_key_val(XDR *, ypresp_key_val*);
-+#elif __STDC__
-+extern bool_t xdr_ypresp_key_val(XDR *, ypresp_key_val*);
-+#else /* Old Style C */
-+bool_t xdr_ypresp_key_val();
-+#endif /* Old Style C */
-+
-+
-+struct ypresp_master {
-+ ypstat stat;
-+ peername peer;
-+};
-+typedef struct ypresp_master ypresp_master;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypresp_master(XDR *, ypresp_master*);
-+#elif __STDC__
-+extern bool_t xdr_ypresp_master(XDR *, ypresp_master*);
-+#else /* Old Style C */
-+bool_t xdr_ypresp_master();
-+#endif /* Old Style C */
-+
-+
-+struct ypresp_order {
-+ ypstat stat;
-+ u_int ordernum;
-+};
-+typedef struct ypresp_order ypresp_order;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypresp_order(XDR *, ypresp_order*);
-+#elif __STDC__
-+extern bool_t xdr_ypresp_order(XDR *, ypresp_order*);
-+#else /* Old Style C */
-+bool_t xdr_ypresp_order();
-+#endif /* Old Style C */
-+
-+
-+struct ypresp_all {
-+ bool_t more;
-+ union {
-+ ypresp_key_val val;
-+ } ypresp_all_u;
-+};
-+typedef struct ypresp_all ypresp_all;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypresp_all(XDR *, ypresp_all*);
-+#elif __STDC__
-+extern bool_t xdr_ypresp_all(XDR *, ypresp_all*);
-+#else /* Old Style C */
-+bool_t xdr_ypresp_all();
-+#endif /* Old Style C */
-+
-+
-+struct ypresp_xfr {
-+ u_int transid;
-+ ypxfrstat xfrstat;
-+};
-+typedef struct ypresp_xfr ypresp_xfr;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypresp_xfr(XDR *, ypresp_xfr*);
-+#elif __STDC__
-+extern bool_t xdr_ypresp_xfr(XDR *, ypresp_xfr*);
-+#else /* Old Style C */
-+bool_t xdr_ypresp_xfr();
-+#endif /* Old Style C */
-+
-+
-+struct ypmaplist {
-+ mapname map;
-+ struct ypmaplist *next;
-+};
-+typedef struct ypmaplist ypmaplist;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypmaplist(XDR *, ypmaplist*);
-+#elif __STDC__
-+extern bool_t xdr_ypmaplist(XDR *, ypmaplist*);
-+#else /* Old Style C */
-+bool_t xdr_ypmaplist();
-+#endif /* Old Style C */
-+
-+
-+struct ypresp_maplist {
-+ ypstat stat;
-+ ypmaplist *maps;
-+};
-+typedef struct ypresp_maplist ypresp_maplist;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypresp_maplist(XDR *, ypresp_maplist*);
-+#elif __STDC__
-+extern bool_t xdr_ypresp_maplist(XDR *, ypresp_maplist*);
-+#else /* Old Style C */
-+bool_t xdr_ypresp_maplist();
-+#endif /* Old Style C */
-+
-+
-+enum yppush_status {
-+ YPPUSH_SUCC = 1,
-+ YPPUSH_AGE = 2,
-+ YPPUSH_NOMAP = -1,
-+ YPPUSH_NODOM = -2,
-+ YPPUSH_RSRC = -3,
-+ YPPUSH_RPC = -4,
-+ YPPUSH_MADDR = -5,
-+ YPPUSH_YPERR = -6,
-+ YPPUSH_BADARGS = -7,
-+ YPPUSH_DBM = -8,
-+ YPPUSH_FILE = -9,
-+ YPPUSH_SKEW = -10,
-+ YPPUSH_CLEAR = -11,
-+ YPPUSH_FORCE = -12,
-+ YPPUSH_XFRERR = -13,
-+ YPPUSH_REFUSED = -14,
-+};
-+typedef enum yppush_status yppush_status;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_yppush_status(XDR *, yppush_status*);
-+#elif __STDC__
-+extern bool_t xdr_yppush_status(XDR *, yppush_status*);
-+#else /* Old Style C */
-+bool_t xdr_yppush_status();
-+#endif /* Old Style C */
-+
-+
-+struct yppushresp_xfr {
-+ u_int transid;
-+ yppush_status status;
-+};
-+typedef struct yppushresp_xfr yppushresp_xfr;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_yppushresp_xfr(XDR *, yppushresp_xfr*);
-+#elif __STDC__
-+extern bool_t xdr_yppushresp_xfr(XDR *, yppushresp_xfr*);
-+#else /* Old Style C */
-+bool_t xdr_yppushresp_xfr();
-+#endif /* Old Style C */
-+
-+
-+enum ypbind_resptype {
-+ YPBIND_SUCC_VAL = 1,
-+ YPBIND_FAIL_VAL = 2,
-+};
-+typedef enum ypbind_resptype ypbind_resptype;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypbind_resptype(XDR *, ypbind_resptype*);
-+#elif __STDC__
-+extern bool_t xdr_ypbind_resptype(XDR *, ypbind_resptype*);
-+#else /* Old Style C */
-+bool_t xdr_ypbind_resptype();
-+#endif /* Old Style C */
-+
-+
-+struct ypbind_binding {
-+ char ypbind_binding_addr[4];
-+ char ypbind_binding_port[2];
-+};
-+typedef struct ypbind_binding ypbind_binding;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypbind_binding(XDR *, ypbind_binding*);
-+#elif __STDC__
-+extern bool_t xdr_ypbind_binding(XDR *, ypbind_binding*);
-+#else /* Old Style C */
-+bool_t xdr_ypbind_binding();
-+#endif /* Old Style C */
-+
-+
-+struct ypbind_resp {
-+ ypbind_resptype ypbind_status;
-+ union {
-+ u_int ypbind_error;
-+ ypbind_binding ypbind_bindinfo;
-+ } ypbind_resp_u;
-+};
-+typedef struct ypbind_resp ypbind_resp;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypbind_resp(XDR *, ypbind_resp*);
-+#elif __STDC__
-+extern bool_t xdr_ypbind_resp(XDR *, ypbind_resp*);
-+#else /* Old Style C */
-+bool_t xdr_ypbind_resp();
-+#endif /* Old Style C */
-+
-+#define YPBIND_ERR_ERR 1
-+#define YPBIND_ERR_NOSERV 2
-+#define YPBIND_ERR_RESC 3
-+
-+struct ypbind_setdom {
-+ domainname ypsetdom_domain;
-+ ypbind_binding ypsetdom_binding;
-+ u_int ypsetdom_vers;
-+};
-+typedef struct ypbind_setdom ypbind_setdom;
-+#ifdef __cplusplus
-+extern "C" bool_t xdr_ypbind_setdom(XDR *, ypbind_setdom*);
-+#elif __STDC__
-+extern bool_t xdr_ypbind_setdom(XDR *, ypbind_setdom*);
-+#else /* Old Style C */
-+bool_t xdr_ypbind_setdom();
-+#endif /* Old Style C */
-+
-+
-+#define YPPROG ((u_long)100004)
-+#define YPVERS ((u_long)2)
-+
-+#ifdef __cplusplus
-+#define YPPROC_NULL ((u_long)0)
-+extern "C" void * ypproc_null_2(void *, CLIENT *);
-+extern "C" void * ypproc_null_2_svc(void *, struct svc_req *);
-+#define YPPROC_DOMAIN ((u_long)1)
-+extern "C" bool_t * ypproc_domain_2(domainname *, CLIENT *);
-+extern "C" bool_t * ypproc_domain_2_svc(domainname *, struct svc_req *);
-+#define YPPROC_DOMAIN_NONACK ((u_long)2)
-+extern "C" bool_t * ypproc_domain_nonack_2(domainname *, CLIENT *);
-+extern "C" bool_t * ypproc_domain_nonack_2_svc(domainname *, struct svc_req *);
-+#define YPPROC_MATCH ((u_long)3)
-+extern "C" ypresp_val * ypproc_match_2(ypreq_key *, CLIENT *);
-+extern "C" ypresp_val * ypproc_match_2_svc(ypreq_key *, struct svc_req *);
-+#define YPPROC_FIRST ((u_long)4)
-+extern "C" ypresp_key_val * ypproc_first_2(ypreq_key *, CLIENT *);
-+extern "C" ypresp_key_val * ypproc_first_2_svc(ypreq_key *, struct svc_req *);
-+#define YPPROC_NEXT ((u_long)5)
-+extern "C" ypresp_key_val * ypproc_next_2(ypreq_key *, CLIENT *);
-+extern "C" ypresp_key_val * ypproc_next_2_svc(ypreq_key *, struct svc_req *);
-+#define YPPROC_XFR ((u_long)6)
-+extern "C" ypresp_xfr * ypproc_xfr_2(ypreq_xfr *, CLIENT *);
-+extern "C" ypresp_xfr * ypproc_xfr_2_svc(ypreq_xfr *, struct svc_req *);
-+#define YPPROC_CLEAR ((u_long)7)
-+extern "C" void * ypproc_clear_2(void *, CLIENT *);
-+extern "C" void * ypproc_clear_2_svc(void *, struct svc_req *);
-+#define YPPROC_ALL ((u_long)8)
-+extern "C" ypresp_all * ypproc_all_2(ypreq_nokey *, CLIENT *);
-+extern "C" ypresp_all * ypproc_all_2_svc(ypreq_nokey *, struct svc_req *);
-+#define YPPROC_MASTER ((u_long)9)
-+extern "C" ypresp_master * ypproc_master_2(ypreq_nokey *, CLIENT *);
-+extern "C" ypresp_master * ypproc_master_2_svc(ypreq_nokey *, struct svc_req *);
-+#define YPPROC_ORDER ((u_long)10)
-+extern "C" ypresp_order * ypproc_order_2(ypreq_nokey *, CLIENT *);
-+extern "C" ypresp_order * ypproc_order_2_svc(ypreq_nokey *, struct svc_req *);
-+#define YPPROC_MAPLIST ((u_long)11)
-+extern "C" ypresp_maplist * ypproc_maplist_2(domainname *, CLIENT *);
-+extern "C" ypresp_maplist * ypproc_maplist_2_svc(domainname *, struct svc_req *);
-+
-+#elif __STDC__
-+#define YPPROC_NULL ((u_long)0)
-+extern void * ypproc_null_2(void *, CLIENT *);
-+extern void * ypproc_null_2_svc(void *, struct svc_req *);
-+#define YPPROC_DOMAIN ((u_long)1)
-+extern bool_t * ypproc_domain_2(domainname *, CLIENT *);
-+extern bool_t * ypproc_domain_2_svc(domainname *, struct svc_req *);
-+#define YPPROC_DOMAIN_NONACK ((u_long)2)
-+extern bool_t * ypproc_domain_nonack_2(domainname *, CLIENT *);
-+extern bool_t * ypproc_domain_nonack_2_svc(domainname *, struct svc_req *);
-+#define YPPROC_MATCH ((u_long)3)
-+extern ypresp_val * ypproc_match_2(ypreq_key *, CLIENT *);
-+extern ypresp_val * ypproc_match_2_svc(ypreq_key *, struct svc_req *);
-+#define YPPROC_FIRST ((u_long)4)
-+extern ypresp_key_val * ypproc_first_2(ypreq_key *, CLIENT *);
-+extern ypresp_key_val * ypproc_first_2_svc(ypreq_key *, struct svc_req *);
-+#define YPPROC_NEXT ((u_long)5)
-+extern ypresp_key_val * ypproc_next_2(ypreq_key *, CLIENT *);
-+extern ypresp_key_val * ypproc_next_2_svc(ypreq_key *, struct svc_req *);
-+#define YPPROC_XFR ((u_long)6)
-+extern ypresp_xfr * ypproc_xfr_2(ypreq_xfr *, CLIENT *);
-+extern ypresp_xfr * ypproc_xfr_2_svc(ypreq_xfr *, struct svc_req *);
-+#define YPPROC_CLEAR ((u_long)7)
-+extern void * ypproc_clear_2(void *, CLIENT *);
-+extern void * ypproc_clear_2_svc(void *, struct svc_req *);
-+#define YPPROC_ALL ((u_long)8)
-+extern ypresp_all * ypproc_all_2(ypreq_nokey *, CLIENT *);
-+extern ypresp_all * ypproc_all_2_svc(ypreq_nokey *, struct svc_req *);
-+#define YPPROC_MASTER ((u_long)9)
-+extern ypresp_master * ypproc_master_2(ypreq_nokey *, CLIENT *);
-+extern ypresp_master * ypproc_master_2_svc(ypreq_nokey *, struct svc_req *);
-+#define YPPROC_ORDER ((u_long)10)
-+extern ypresp_order * ypproc_order_2(ypreq_nokey *, CLIENT *);
-+extern ypresp_order * ypproc_order_2_svc(ypreq_nokey *, struct svc_req *);
-+#define YPPROC_MAPLIST ((u_long)11)
-+extern ypresp_maplist * ypproc_maplist_2(domainname *, CLIENT *);
-+extern ypresp_maplist * ypproc_maplist_2_svc(domainname *, struct svc_req *);
-+
-+#else /* Old Style C */
-+#define YPPROC_NULL ((u_long)0)
-+extern void * ypproc_null_2();
-+extern void * ypproc_null_2_svc();
-+#define YPPROC_DOMAIN ((u_long)1)
-+extern bool_t * ypproc_domain_2();
-+extern bool_t * ypproc_domain_2_svc();
-+#define YPPROC_DOMAIN_NONACK ((u_long)2)
-+extern bool_t * ypproc_domain_nonack_2();
-+extern bool_t * ypproc_domain_nonack_2_svc();
-+#define YPPROC_MATCH ((u_long)3)
-+extern ypresp_val * ypproc_match_2();
-+extern ypresp_val * ypproc_match_2_svc();
-+#define YPPROC_FIRST ((u_long)4)
-+extern ypresp_key_val * ypproc_first_2();
-+extern ypresp_key_val * ypproc_first_2_svc();
-+#define YPPROC_NEXT ((u_long)5)
-+extern ypresp_key_val * ypproc_next_2();
-+extern ypresp_key_val * ypproc_next_2_svc();
-+#define YPPROC_XFR ((u_long)6)
-+extern ypresp_xfr * ypproc_xfr_2();
-+extern ypresp_xfr * ypproc_xfr_2_svc();
-+#define YPPROC_CLEAR ((u_long)7)
-+extern void * ypproc_clear_2();
-+extern void * ypproc_clear_2_svc();
-+#define YPPROC_ALL ((u_long)8)
-+extern ypresp_all * ypproc_all_2();
-+extern ypresp_all * ypproc_all_2_svc();
-+#define YPPROC_MASTER ((u_long)9)
-+extern ypresp_master * ypproc_master_2();
-+extern ypresp_master * ypproc_master_2_svc();
-+#define YPPROC_ORDER ((u_long)10)
-+extern ypresp_order * ypproc_order_2();
-+extern ypresp_order * ypproc_order_2_svc();
-+#define YPPROC_MAPLIST ((u_long)11)
-+extern ypresp_maplist * ypproc_maplist_2();
-+extern ypresp_maplist * ypproc_maplist_2_svc();
-+#endif /* Old Style C */
-+
-+#define YPPUSH_XFRRESPPROG ((u_long)0x40000000)
-+#define YPPUSH_XFRRESPVERS ((u_long)1)
-+
-+#ifdef __cplusplus
-+#define YPPUSHPROC_NULL ((u_long)0)
-+extern "C" void * yppushproc_null_1(void *, CLIENT *);
-+extern "C" void * yppushproc_null_1_svc(void *, struct svc_req *);
-+#define YPPUSHPROC_XFRRESP ((u_long)1)
-+extern "C" void * yppushproc_xfrresp_1(yppushresp_xfr *, CLIENT *);
-+extern "C" void * yppushproc_xfrresp_1_svc(yppushresp_xfr *, struct svc_req *);
-+
-+#elif __STDC__
-+#define YPPUSHPROC_NULL ((u_long)0)
-+extern void * yppushproc_null_1(void *, CLIENT *);
-+extern void * yppushproc_null_1_svc(void *, struct svc_req *);
-+#define YPPUSHPROC_XFRRESP ((u_long)1)
-+extern void * yppushproc_xfrresp_1(yppushresp_xfr *, CLIENT *);
-+extern void * yppushproc_xfrresp_1_svc(yppushresp_xfr *, struct svc_req *);
-+
-+#else /* Old Style C */
-+#define YPPUSHPROC_NULL ((u_long)0)
-+extern void * yppushproc_null_1();
-+extern void * yppushproc_null_1_svc();
-+#define YPPUSHPROC_XFRRESP ((u_long)1)
-+extern void * yppushproc_xfrresp_1();
-+extern void * yppushproc_xfrresp_1_svc();
-+#endif /* Old Style C */
-+
-+#define YPBINDPROG ((u_long)100007)
-+#define YPBINDVERS ((u_long)2)
-+
-+#ifdef __cplusplus
-+#define YPBINDPROC_NULL ((u_long)0)
-+extern "C" void * ypbindproc_null_2(void *, CLIENT *);
-+extern "C" void * ypbindproc_null_2_svc(void *, struct svc_req *);
-+#define YPBINDPROC_DOMAIN ((u_long)1)
-+extern "C" ypbind_resp * ypbindproc_domain_2(domainname *, CLIENT *);
-+extern "C" ypbind_resp * ypbindproc_domain_2_svc(domainname *, struct svc_req *);
-+#define YPBINDPROC_SETDOM ((u_long)2)
-+extern "C" void * ypbindproc_setdom_2(ypbind_setdom *, CLIENT *);
-+extern "C" void * ypbindproc_setdom_2_svc(ypbind_setdom *, struct svc_req *);
-+
-+#elif __STDC__
-+#define YPBINDPROC_NULL ((u_long)0)
-+extern void * ypbindproc_null_2(void *, CLIENT *);
-+extern void * ypbindproc_null_2_svc(void *, struct svc_req *);
-+#define YPBINDPROC_DOMAIN ((u_long)1)
-+extern ypbind_resp * ypbindproc_domain_2(domainname *, CLIENT *);
-+extern ypbind_resp * ypbindproc_domain_2_svc(domainname *, struct svc_req *);
-+#define YPBINDPROC_SETDOM ((u_long)2)
-+extern void * ypbindproc_setdom_2(ypbind_setdom *, CLIENT *);
-+extern void * ypbindproc_setdom_2_svc(ypbind_setdom *, struct svc_req *);
-+
-+#else /* Old Style C */
-+#define YPBINDPROC_NULL ((u_long)0)
-+extern void * ypbindproc_null_2();
-+extern void * ypbindproc_null_2_svc();
-+#define YPBINDPROC_DOMAIN ((u_long)1)
-+extern ypbind_resp * ypbindproc_domain_2();
-+extern ypbind_resp * ypbindproc_domain_2_svc();
-+#define YPBINDPROC_SETDOM ((u_long)2)
-+extern void * ypbindproc_setdom_2();
-+extern void * ypbindproc_setdom_2_svc();
-+#endif /* Old Style C */
-+
-+#endif /* !__RPCSVC_YP_H__ */
-diff -Naur ../glibc-2.1.3/glibc-compat/rpcsvc/ypclnt.h glibc-2.1.3/glibc-compat/rpcsvc/ypclnt.h
---- ../glibc-2.1.3/glibc-compat/rpcsvc/ypclnt.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/rpcsvc/ypclnt.h 2000-01-03 18:17:33.000000000 -0800
-@@ -0,0 +1,90 @@
-+/*
-+** Copyright (c) 1996 Thorsten Kukuk, Germany
-+**
-+** This library is free software; you can redistribute it and/or
-+** modify it under the terms of the GNU Library General Public
-+** License as published by the Free Software Foundation; either
-+** version 2 of the License, or (at your option) any later version.
-+**
-+** This library is distributed in the hope that it will be useful,
-+** but WITHOUT ANY WARRANTY; without even the implied warranty of
-+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+** Library General Public License for more details.
-+**
-+** You should have received a copy of the GNU Library General Public
-+** License along with this library; if not, write to the Free
-+** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+**
-+** Author: Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
-+**
-+*/
-+
-+#ifndef __RPCSVC_YPCLNT_H__
-+#define __RPCSVC_YPCLNT_H__
-+
-+#include <features.h>
-+
-+/* some defines */
-+#define YPERR_SUCCESS 0 /* There is no error */
-+#define YPERR_BADARGS 1 /* Args to function are bad */
-+#define YPERR_RPC 2 /* RPC failure */
-+#define YPERR_DOMAIN 3 /* Can't bind to a server with this domain */
-+#define YPERR_MAP 4 /* No such map in server's domain */
-+#define YPERR_KEY 5 /* No such key in map */
-+#define YPERR_YPERR 6 /* Internal yp server or client error */
-+#define YPERR_RESRC 7 /* Local resource allocation failure */
-+#define YPERR_NOMORE 8 /* No more records in map database */
-+#define YPERR_PMAP 9 /* Can't communicate with portmapper */
-+#define YPERR_YPBIND 10 /* Can't communicate with ypbind */
-+#define YPERR_YPSERV 11 /* Can't communicate with ypserv */
-+#define YPERR_NODOM 12 /* Local domain name not set */
-+#define YPERR_BADDB 13 /* yp data base is bad */
-+#define YPERR_VERS 14 /* YP version mismatch */
-+#define YPERR_ACCESS 15 /* Access violation */
-+#define YPERR_BUSY 16 /* Database is busy */
-+
-+/* Types of update operations */
-+#define YPOP_CHANGE 1 /* change, do not add */
-+#define YPOP_INSERT 2 /* add, do not change */
-+#define YPOP_DELETE 3 /* delete this entry */
-+#define YPOP_STORE 4 /* add, or change */
-+
-+__BEGIN_DECLS
-+
-+/* struct ypall_callback * is the arg which must be passed to yp_all */
-+struct ypall_callback
-+ {
-+ int (*foreach) __P ((int __status, char *__key, int __keylen,
-+ char *__val, int __vallen, char *__data));
-+ char *data;
-+ };
-+
-+/* External NIS client function references. */
-+extern int yp_bind __P ((__const char *));
-+extern void yp_unbind __P ((__const char *));
-+extern int yp_get_default_domain __P ((char **));
-+extern int yp_match __P ((__const char *, __const char *, __const char *,
-+ __const int, char **, int *));
-+extern int yp_first __P ((__const char *, __const char *, char **,
-+ int *, char **, int *));
-+extern int yp_next __P ((__const char *, __const char *, __const char *,
-+ __const int, char **, int *, char **, int *));
-+extern int yp_master __P ((__const char *, __const char *, char **));
-+extern int yp_order __P ((__const char *, __const char *, unsigned int *));
-+extern int yp_all __P ((__const char *, __const char *,
-+ __const struct ypall_callback *));
-+extern __const char *yperr_string __P ((__const int));
-+extern __const char *ypbinderr_string __P ((__const int));
-+extern int ypprot_err __P ((__const int));
-+extern int yp_update __P ((char *, char *, unsigned, char *,
-+ int, char *, int));
-+#if 0
-+extern int yp_maplist __P ((__const char *, struct ypmaplist **));
-+#endif
-+
-+/* Exist only under BSD and Linux systems */
-+extern int __yp_check __P ((char **));
-+
-+__END_DECLS
-+
-+#endif /* __RPCSVC_YPCLNT_H__ */
-diff -Naur ../glibc-2.1.3/glibc-compat/shlib-versions glibc-2.1.3/glibc-compat/shlib-versions
---- ../glibc-2.1.3/glibc-compat/shlib-versions 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/shlib-versions 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,19 @@
-+# Interface revision of the compat nss_* modules.
-+#
-+# This must match NSS_SHLIB_REVISION in nss/nsswitch.h,
-+# which determines the library names used for service
-+# names given in /etc/nsswitch.conf.
-+alpha-.*-linux.* libnss1_files=1.1
-+alpha-.*-linux.* libnss1_dns=1.1
-+alpha-.*-linux.* libnss1_db=1.1
-+alpha-.*-linux.* libnss1_compat=1.1
-+alpha-.*-linux.* libnss1_nis=1.1
-+.*-.*-.* libnss1_files=1
-+.*-.*-.* libnss1_db=1
-+.*-.*-.* libnss1_dns=1
-+.*-.*-.* libnss1_compat=1
-+.*-.*-.* libnss1_nis=1
-+
-+# The libNoVersion revision number
-+.*-.*-.* libNoVersion=1
-+
-diff -Naur ../glibc-2.1.3/glibc-compat/stubs.c glibc-2.1.3/glibc-compat/stubs.c
---- ../glibc-2.1.3/glibc-compat/stubs.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/glibc-compat/stubs.c 2000-02-23 17:59:39.000000000 -0800
-@@ -0,0 +1,54 @@
-+/*
-+ * STAT stuff that breaks Applix
-+ */
-+
-+#include <sys/stat.h>
-+
-+/* 1 of 3: _xstat */
-+int
-+_xstat (int vers, const char *name, struct stat *buf)
-+{
-+ return __xstat (vers, name, buf);
-+}
-+
-+/* 2 of 3: _fxstat */
-+int
-+_fxstat (int vers, int fd, struct stat *buf)
-+{
-+ return __fxstat (vers, fd, buf);
-+}
-+
-+/* 3 of 3: _lxstat */
-+int
-+_lxstat (int vers, const char *name, struct stat *buf)
-+{
-+ return __lxstat (vers, name, buf);
-+}
-+
-+
-+/*
-+ * __setjmp stuff that breaks again Applix
-+ */
-+#include <setjmp.h>
-+
-+int __setjmp(jmp_buf env)
-+{
-+ return _setjmp(env);
-+}
-+
-+
-+/*
-+ * __setfpucw break several math packages that ahve not heard of
-+ * the standard _FPU_SETCW() way of setting the control word for the FPU
-+ */
-+#include <fpu_control.h>
-+void __setfpucw(fpu_control_t cw)
-+{
-+
-+#if defined(_FPU_SETCW)
-+ _FPU_SETCW(cw);
-+#endif /* _FPU_SETCW */
-+
-+ /* others are a no-op. Why doesn't alpha has something like this? */
-+}
-+
-diff -Naur ../glibc-2.1.3/hesiod/hesiod.c glibc-2.1.3/hesiod/hesiod.c
---- ../glibc-2.1.3/hesiod/hesiod.c 1998-05-25 01:40:13.000000000 -0700
-+++ glibc-2.1.3/hesiod/hesiod.c 1998-07-09 11:46:28.000000000 -0700
-@@ -41,7 +41,7 @@
- * it uses res_send() and accesses _res.
- */
-
--static const char rcsid[] = "$Id: hesiod.c,v 1.5 1998/05/25 08:40:13 drepper Exp $";
-+static const char rcsid[] = "$Id: hesiod.c,v 1.1.1.1 1998/07/09 18:46:28 gafton Exp $";
-
- #include <sys/types.h>
- #include <netinet/in.h>
-diff -Naur ../glibc-2.1.3/hesiod/hesiod.h glibc-2.1.3/hesiod/hesiod.h
---- ../glibc-2.1.3/hesiod/hesiod.h 1997-09-15 17:16:33.000000000 -0700
-+++ glibc-2.1.3/hesiod/hesiod.h 1998-02-07 12:04:52.000000000 -0800
-@@ -1,4 +1,4 @@
--/* $Id: hesiod.h,v 1.1 1997/09/16 00:16:33 drepper Exp $ */
-+/* $Id: hesiod.h,v 1.1.1.1 1998/02/07 20:04:52 gafton Exp $ */
-
- /*
- * Copyright (c) 1996 by Internet Software Consortium.
-diff -Naur ../glibc-2.1.3/hesiod/hesiod_p.h glibc-2.1.3/hesiod/hesiod_p.h
---- ../glibc-2.1.3/hesiod/hesiod_p.h 1997-09-15 17:16:33.000000000 -0700
-+++ glibc-2.1.3/hesiod/hesiod_p.h 1998-02-07 12:04:52.000000000 -0800
-@@ -16,7 +16,7 @@
- */
-
- /*
-- * $Id: hesiod_p.h,v 1.1 1997/09/16 00:16:33 drepper Exp $
-+ * $Id: hesiod_p.h,v 1.1.1.1 1998/02/07 20:04:52 gafton Exp $
- */
-
- /*
-diff -Naur ../glibc-2.1.3/hurd/hurdmalloc.c glibc-2.1.3/hurd/hurdmalloc.c
---- ../glibc-2.1.3/hurd/hurdmalloc.c 1996-12-19 17:32:01.000000000 -0800
-+++ glibc-2.1.3/hurd/hurdmalloc.c 1998-02-07 12:05:05.000000000 -0800
-@@ -37,6 +37,9 @@
- /*
- * HISTORY
- * $Log: hurdmalloc.c,v $
-+ * Revision 1.1.1.1 1998/02/07 20:05:05 gafton
-+ * import from sourceware
-+ *
- * Revision 1.13 1996/12/20 01:32:01 drepper
- * Update from main archive 961219
- *
-diff -Naur ../glibc-2.1.3/include/nlist.h glibc-2.1.3/include/nlist.h
---- ../glibc-2.1.3/include/nlist.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/include/nlist.h 1998-02-07 12:07:02.000000000 -0800
-@@ -0,0 +1 @@
-+#include <misc/nlist.h>
-diff -Naur ../glibc-2.1.3/linuxthreads/Banner glibc-2.1.3/linuxthreads/Banner
---- ../glibc-2.1.3/linuxthreads/Banner 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Banner 1998-08-28 03:07:16.000000000 -0700
-@@ -0,0 +1 @@
-+linuxthreads-0.8 by Xavier Leroy
-diff -Naur ../glibc-2.1.3/linuxthreads/ChangeLog glibc-2.1.3/linuxthreads/ChangeLog
---- ../glibc-2.1.3/linuxthreads/ChangeLog 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/ChangeLog 2000-02-23 13:17:31.000000000 -0800
-@@ -0,0 +1,1257 @@
-+2000-02-22 Ulrich Drepper <drepper@redhat.com>
-+
-+ * semaphore.h (SEM_FAILED): Use 0 not NULL.
-+
-+2000-02-14 Ulrich Drepper <drepper@redhat.com>
-+
-+ * condvar.c (pthread_cond_timedwait_relative_old): Tight loop with
-+ nanosleep does not work either. Get absolute time inside the
-+ loop.
-+ (pthread_cond_timedwait_relative_new): Likewise.
-+ Patch by Kaz Kylheku <kaz@ashi.footprints.net>.
-+
-+2000-02-13 Ulrich Drepper <drepper@redhat.com>
-+
-+ * condvar.c (pthread_cond_timedwait_relative_old): Undo last patch
-+ but keep the code around. A bug in the kernel prevent us from
-+ using the code.
-+ (pthread_cond_timedwait_relative_new): Likewise.
-+ (PR libc/1597 and libc/1598).
-+
-+2000-02-01 Kaz Kylheku <kaz@ashi.footprints.net>
-+
-+ * condvar.c (pthread_cond_timedwait_relative_old): Do tight
-+ loop around nanosleep calls instead of around most of the function
-+ (pthread_cond_timedwait_relative_new): Likewise.
-+ body. Got rid of backwards goto and one local.
-+
-+2000-01-31 Ulrich Drepper <drepper@redhat.com>
-+
-+ * condvar.c (pthread_cond_timedwait_relative_old): Recompute time
-+ before every nanosleep call to account for time spent in the rest
-+ of the function.
-+ (pthread_cond_timedwait_relative_new): Likewise.
-+ Patch by khendricks@ivey.uwo.ca (PR libc/1564).
-+
-+2000-01-29 Ulrich Drepper <drepper@redhat.com>
-+
-+ * condvar.c (pthread_cond_timedwait_relative_old): Get remaining time
-+ from nanosleep call so that in case we restart we only wait for the
-+ remaining time.
-+ (pthread_cond_timedwait_relative_new): Likewise.
-+ Patch by khendricks@ivey.uwo.ca (PR libc/1561).
-+
-+2000-01-18 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_allocate_stack): Compute guard page address
-+ correctly. Patch by HJ Lu.
-+
-+2000-01-12 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * internals.h (pthread_readlock_info): New structure.
-+ (_pthread_descr_struct): Add p_readlock_list, p_readlock_free, and
-+ p_untracked_readlock_count.
-+ * pthread.c (__pthread_initial_thread, pthread_manager_thread):
-+ Add initializers for new fields.
-+ * manager.c (pthread_free): Free read/write lock lists.
-+ * queue.h (queue_is_empty): New function.
-+ * rwlock.c: Implement requirements about when readers should get
-+ locks assigned.
-+ * sysdeps/pthread/pthread.h
-+ (PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP): New definition.
-+ * sysdeps/pthread/bits/pthreadtypes.h (struct _pthread_rwlock_t):
-+ Define this name as well.
-+ Patches by Kaz Kylheku <kaz@ashi.footprints.net>.
-+
-+2000-01-06 Andreas Jaeger <aj@suse.de>
-+
-+ * pthread.c: Remove extra initializer.
-+
-+2000-01-05 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * pthread.c (__pthread_initial_thread, pthread_manager_thread):
-+ Adjust initializers for struct _pthread_descr_struct change.
-+ * internals.h (struct _pthread_descr_struct): Move new elements to
-+ the end.
-+
-+2000-01-03 Kaz Kylheku <kaz@ashi.footprints.net>
-+
-+ Redesigned how cancellation unblocks a thread from internal
-+ cancellation points (sem_wait, pthread_join,
-+ pthread_cond_{wait,timedwait}).
-+ Cancellation won't eat a signal in any of these functions
-+ (*required* by POSIX and Single Unix Spec!).
-+ * condvar.c: Spontaneous wakeup on pthread_cond_timedwait won't eat a
-+ simultaneous condition variable signal (not required by POSIX
-+ or Single Unix Spec, but nice).
-+ * spinlock.c: __pthread_lock queues back any received restarts
-+ that don't belong to it instead of assuming ownership of lock
-+ upon any restart; fastlock can no longer be acquired by two threads
-+ simultaneously.
-+ * restart.h: Restarts queue even on kernels that don't have
-+ queued real time signals (2.0, early 2.1), thanks to atomic counter,
-+ avoiding a rare race condition in pthread_cond_timedwait.
-+
-+1999-12-28 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/alpha/pt-machine.h: Move stack_pointer definition to the
-+ beginning.
-+
-+ * manager.c (__pthread_start): Add one more cast to assignment of
-+ arg to prevent warning on 64bit machines.
-+
-+1999-12-21 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_handle_create): Set p_pid of new thread
-+ before calling the callback function to report a new thread.
-+
-+1999-12-20 Andreas Jaeger <aj@suse.de>
-+
-+ * pthread.c (pthread_initialize): Move getrlimit call after
-+ setting of errno.
-+
-+1999-12-01 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/i386/pt-machine.h: Move stack_pointer definition to the
-+ beginning.
-+ * sysdeps/i386/i686/pt-machine.h: Likewise.
-+ Patches by Alan Modra <alan@SPRI.Levels.UniSA.Edu.Au>.
-+
-+1999-11-23 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_start_thread_event): Initialize p_pid already
-+ here.
-+
-+1999-11-22 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * internals.h: Add prototype for __pthread_manager_event.
-+ * manager.c (__pthread_manager_event): New function.
-+ (pthread_start_thread_event): Correct computation of self.
-+ Use INIT_THREAD_SELF.
-+ * pthread.c (__pthread_manager_thread): Initialize p_lock.
-+ (__pthread_initialize_manager): Respect event flags also for creation
-+ of the manager thread.
-+
-+1999-11-08 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * pthread.c (__pthread_initialize_manager): Initialize
-+ __pthread_manager_thread.p_tid.
-+
-+1999-11-02 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * internals.h: Declare __pthread_last_event.
-+ * manager.c: Define __pthread_last_event.
-+ (pthread_handle_create): Set __pthread_last_event.
-+ (pthread_exited): Likewise.
-+ * join.c (pthread_exit): Likewise.
-+
-+ * Makefile (libpthread-routines): Add events.
-+ * events.c: New file.
-+ * internals.h: Protect against multiple inclusion.
-+ Include thread_dbP.h header.
-+ (struct _pthread_descr_struct): Add new fields p_report_events and
-+ p_eventbuf.
-+ Declare event reporting functions.
-+ * join.c (pthread_exit): Signal event if this is wanted.
-+ * manager.c (__pthread_threads_events): New variable.
-+ (pthread_handle_create): Take new parameters with event information.
-+ Signal TD_CREATE event if wanted.
-+ (__pthread_manager): Adjust pthread_handle_create call.
-+ (pthread_start_thread_event): New function. Block until manager is
-+ finished and then call pthread_start_thread.
-+ (pthread_exited): Signal TD_REAP event if wanted.
-+
-+1999-10-26 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * restart.h (suspend_with_cancellation): Rewrite as a macro.
-+
-+ * condvar.c (pthread_cond_timedwait_relative): Don't mark as inline.
-+
-+1999-10-21 Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+ * linuxthreads/pthread.c: For i386, wrap pthread_handle_sigrestart
-+ and pthread_handle_sigcancel with functions that restore
-+ %gs from the signal context. For each signal handling function,
-+ two wrappers are required, one for a non-RT signal and one for
-+ a RT signal.
-+ * linuxthreads/signal.c: For i386, add code to restore %gs
-+ from the signal context in pthread_sighandler and
-+ pthread_sighandler_rt.
-+
-+1999-10-09 Andreas Jaeger <aj@suse.de>
-+
-+ * internals.h: Add __new_sem_post to get prototype in
-+ manager.c; include semaphore.h for needed types.
-+
-+1999-10-08 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (__pthread_manager) [REQ_POST]: Use __new_sem_post
-+ directly instead of calling sem_post which should not be necessary
-+ but is faster and might help in some case to work around problems.
-+
-+1999-09-25 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * condvar.c (pthread_cond_timedwait_relative): Never return with
-+ EINTR. Patch by Andreas Schwab.
-+
-+1999-09-19 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * signals.c (sigaction): Correct last patch. Don't select
-+ pthread_sighandler_rt based on the signal number but instead of
-+ the SA_SIGINFO flag.
-+
-+1999-09-23 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * specific.c: Move definitions of struct pthread_key_struct and
-+ destr_function to ...
-+ * internals.h: ...here.
-+
-+1999-09-03 Andreas Schwab <schwab@suse.de>
-+
-+ * ptfork.c (__fork): Renamed from fork and use __libc_fork. Add
-+ fork as weak alias.
-+ (__vfork): New function, alias vfork.
-+ * Versions: Export __fork, vfork, and __vfork in libpthread.
-+
-+1999-08-23 Andreas Schwab <schwab@suse.de>
-+
-+ * signals.c (pthread_sighandler): Add SIGCONTEXT_EXTRA_ARGS to
-+ call to signal handler.
-+
-+1999-08-20 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * pthread.c (__pthread_reset_main_thread): Undo last change.
-+ (__pthread_kill_other_threads_np): Reset signal handlers for the
-+ signals we used in the thread implementation here.
-+
-+1999-08-19 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * pthread.c (__pthread_reset_main_thread): Reset signal handlers
-+ for the signals we used in the thread implementation [PR libc/1234].
-+
-+ * Versions: Export __pthread_kill_other_threads_np from libpthread
-+ for GLIBC_2.1.2.
-+
-+ * signals.c: Pass sigcontext through wrapper to the user function.
-+
-+1999-08-01 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Versions [ld.so] (GLIBC_2.0): Export __libc_internal_tsd_get and
-+ __libc_internal_tsd_set.
-+
-+1999-07-29 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * manager.c: Remove inclusion of <linux/tasks.h> since it's not
-+ needed anymore.
-+
-+1999-07-16 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * internals.h: Align _pthread_descr_struct to 32 bytes.
-+ Reported by Tim Hockin <thockin@cobaltnet.com>, close PR libc/1206.
-+
-+1999-07-09 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_handle_create): Free mmap region after stack
-+ if clone failed. Patch by Kaz Kylheku <kaz@ashi.FootPrints.net>.
-+
-+1999-07-09 Cristian Gafton <gafton@redhat.com>
-+
-+ * Makefile (libpthread-routines): Add oldsemaphore routine.
-+ * Versions: Add sem_destroy, sem_getvalue, sem_init, sem_post,
-+ sem_trywait, and sem_wait to GLIBC_2.1.
-+ * oldsemaphore.c: New file.
-+ * semaphore.c: Add default_symbol_versions for the changed functions.
-+ (__new_sem_init): Rename from sem_init.
-+ (__new_sem_post): Rename from sem_post.
-+ (__new_sem_wait): Rename from sem_wait.
-+ (__new_sem_trywait): Rename from sem_trywait.
-+ (__new_sem_getvalue): Rename from sem_getvalue.
-+ (__new_sem_destroy): Rename from sem_destroy.
-+
-+1999-06-23 Robey Pointer <robey@netscape.com>
-+
-+ * internals.h: Added p_nextlock entry to separate queueing for a
-+ lock from queueing for a CV (sometimes a thread queues on a lock
-+ to serialize removing itself from a CV queue).
-+ * pthread.c: Added p_nextlock to initializers.
-+ * spinlock.c: Changed to use p_nextlock instead of p_nextwaiting.
-+
-+1999-05-23 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * man/pthread_cond_init.man: Correct example.
-+ Reported by Tomas Berndtsson <tomas@nocrew.org>.
-+
-+ * linuxthreads.texi (Condition Variables): Likewise.
-+
-+1999-05-18 Jakub Jelinek <jj@ultra.linux.cz>
-+
-+ * sysdeps/sparc/sparc64/pt-machine.h (__compare_and_swap): Use
-+ casx not cas, also successful casx returns the old value in rd
-+ and not the new value.
-+
-+1999-05-16 Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+ * manager.c: If pthread_create() is given a NULL attribute
-+ and the thread manager runs with a realtime policy, set the
-+ scheduling policy of the newly created thread back to SCHED_OTHER.
-+ * manager.c: If the PTHREAD_INHERIT_SCHED attribute is given,
-+ initialize the schedpolicy field of new_thread->p_start_args
-+ to that of the calling thread.
-+
-+1999-04-29 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/sparc/sparc64/pt-machine.h (__compare_and_swap): cas
-+ instruction does not allow memory element to use offset.
-+
-+1999-04-28 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_allocate_stack): Optimize initialization of new
-+ thread descriptor.
-+
-+ * sysdeps/pthread/bits/libc-lock.h (__libc_lock_define_initialized):
-+ Don't use initializer since it is all zeroes.
-+ (__libc_once_define): Likewise.
-+
-+1999-04-16 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * sysdeps/arm/Implies: Removed since cmpxchg/no-cmpxchg
-+ doesn't exist anymore.
-+ * sysdeps/i386/Implies: Likewise.
-+ * sysdeps/m68k/Implies: Likewise.
-+ * sysdeps/mips/Implies: Likewise.
-+ * sysdeps/powerpc/Implies: Likewise.
-+ * sysdeps/sparc/sparc32/Implies: Likewise.
-+ * sysdeps/sparc/sparc64/Implies: Likewise.
-+
-+1999-04-15 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/alpha/bits/semaphore.h: Removed.
-+ * sysdeps/powerpc/bits/semaphore.h: Removed.
-+ * sysdeps/pthread/cmpxchg/bits/semaphore.h: Removed.
-+ * sysdeps/pthread/no-cmpxchg/bits/semaphore.h: Removed.
-+ * Makefile (headers): Remove bits/semaphore.h.
-+
-+ * semaphore.h: Define _pthread_descr if necessary.
-+ Don't include limits.h. Define SEM_VALUE_MAX directly.
-+ Define SEM_FAILED.
-+ (sem_t): Protect element names with leading __.
-+ Add declarations for sem_close, sem_open, and sem_unlink.
-+ * semaphore.c: Adjust all functions for new element names.
-+ Define sem_close, sem_open, and sem_unlink.
-+ * Versions (libthread): Add sem_close, sem_open, and sem_unlink for
-+ GLIBC_2.1.1.
-+ * sysdeps/pthread/bits/pthreadtypes.h: Define _pthread_descr only if
-+ necessary.
-+
-+1999-03-16 H.J. Lu <hjl@gnu.org>
-+
-+ * specific.c (pthread_key_delete): Check th->p_terminated to see
-+ if the thread is running.
-+
-+ * Versions (__libc_internal_tsd_get, __libc_internal_tsd_set):
-+ Added to GLIBC_2.0 for libc.so.
-+
-+1999-02-12 H.J. Lu <hjl@gnu.org>
-+
-+ * Versions (__libc_current_sigrtmin, __libc_current_sigrtmax,
-+ __libc_allocate_rtsig): Added to GLIBC_2.1.
-+
-+ * internals.h (DEFAULT_SIG_RESTART): Removed.
-+ (DEFAULT_SIG_CANCEL): Removed.
-+
-+ * pthread.c (init_rtsigs, __libc_current_sigrtmin,
-+ __libc_current_sigrtmax, __libc_allocate_rtsig): New functions.
-+ (__pthread_sig_restart, __pthread_sig_cancel,
-+ __pthread_sig_debug): Initialized.
-+ (pthread_initialize): Call init_rtsigs () to initialize
-+ real-time signals.
-+
-+1999-02-03 H.J. Lu <hjl@gnu.org>
-+
-+ * manager.c (__pthread_manager): Do block __pthread_sig_debug.
-+ Don't restart the thread which sent REQ_DEBUG.
-+ (pthread_start_thread): Check if __pthread_sig_debug > 0
-+ before debugging.
-+
-+ * pthread.c (__pthread_initialize_manager): Suspend ourself
-+ after sending __pthread_sig_debug to gdb instead of
-+ __pthread_sig_cancel.
-+
-+1999-01-24 H.J. Lu <hjl@gnu.org>
-+
-+ * manager.c (__pthread_manager): Delete __pthread_sig_debug
-+ from mask if __pthread_sig_debug > 0.
-+ (pthread_handle_create): Increment __pthread_handles_num.
-+
-+ * manager.c (pthread_handle_create): Don't pass CLONE_PTRACE to clone.
-+ * pthread.c (__pthread_initialize_manager): Likewise.
-+
-+ * pthread.c (pthread_initialize): Use __libc_allocate_rtsig (1)
-+ instead of __libc_allocate_rtsig (2).
-+ (__pthread_initialize_manager): Send __pthread_sig_debug to gdb
-+ instead of __pthread_sig_cancel.
-+ (pthread_handle_sigdebug): Fix comments.
-+
-+1999-01-21 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_allocate_stack): Set
-+ __pthread_nonstandard_stacks if user-specified stack is used.
-+
-+1999-01-16 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/unix/sysv/linux/bits/posix_opt.h: Add _LFS_ASYNCHRONOUS_IO,
-+ _LFS_LARGEFILE, _LFS64_LARGEFILE, and _LFS64_STDIO from Unix98.
-+
-+1999-01-07 Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+ * pthread.c: Use a third signal __pthread_sig_debug distinct
-+ from __pthread_sig_cancel to notify gdb when a thread is
-+ created
-+ * manager.c: Likewise.
-+ * internals.h: Likewise.
-+ * signals.c: The implementation of sigwait(s) assumed that
-+ all signals in s have signal handlers already attached.
-+ This is not required by the standard, so make it work
-+ also if some of the signals have no handlers.
-+
-+1999-01-05 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
-+
-+ * linuxthreads.texi: Remove pointers from first @node. Move old
-+ @node spec inside comment.
-+
-+1998-12-31 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/pthread/bits/stdio-lock.h: Define _IO_lock_lock and
-+ _IO_lock_unlock.
-+
-+1998-12-29 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * semaphore.c (sem_trywait): Don't forget to unlock the semaphore
-+ lock. Patch by Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>.
-+
-+1998-12-21 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c: Threads now send __pthread_sig_cancel on termination.
-+ Change clone call and signal masks.
-+ * thread.c (pthread_handle_sigrestart): Remove special code for
-+ manager.
-+ (pthread_handle_sigcancel): In manager thread call
-+ __pthread_manager_sighandler.
-+ * sysdeps/i386/pt-machine.h (__compare_and_swap): Add memory clobber.
-+ * sysdeps/i386/i686/pt-machine.h: Likewise.
-+ Patches by Xavier Leroy.
-+
-+1998-12-14 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * spinlock.c (__pthread_unlock): Don't crash if called for an
-+ untaken mutex. Reported by Ruslan V. Brushkoff <rus@Snif.Te.Net.UA>.
-+
-+ * Examples/ex6.c: Unbuffer stdout and reduce sleep time to reduce
-+ overall runtime.
-+
-+1998-12-13 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Examples/ex3.c: Wait until all threads are started before
-+ searching for the number to avoid race condition on very fast
-+ systems.
-+
-+1998-12-08 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * sysdeps/pthread/pthread.h: Remove __pthread_setcanceltype
-+ declaration since it's not needed.
-+
-+ * sysdeps/pthread/pthread.h: Move internal functions to ...
-+ * internals.h: ...here.
-+
-+1998-12-02 H.J. Lu <hjl@gnu.org>
-+
-+ * pthread.c (__pthread_sig_restart): Initiliaze to 0 if
-+ SIGRTMIN is defined.
-+ (__pthread_sig_cancel): Likewise.
-+
-+1998-12-01 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * wrapsyscall.c: Include <sys/mman.h> for msync,
-+ <stdlib.h> for system and <termios.h> for tcdrain prototype.
-+ Correct msync declaration.
-+
-+1998-11-29 Roland McGrath <roland@baalperazim.frob.com>
-+
-+ * sysdeps/pthread/bits/libc-tsd.h (__libc_tsd_define, __libc_tsd_get,
-+ __libc_tsd_set): New macros for new interface.
-+ * no-tsd.c: New file, provide uninitialized defns of
-+ __libc_internal_tsd_get and __libc_internal_tsd_set.
-+ * Makefile (routines): Add no-tsd.
-+
-+1998-10-12 Roland McGrath <roland@baalperazim.frob.com>
-+
-+ * internals.h: Include <bits/libc-tsd.h>, not <bits/libc-lock.h>.
-+ * sysdeps/pthread/bits/libc-lock.h (__libc_internal_tsd_get,
-+ __libc_internal_tsd_set): Move decls to ...
-+ * sysdeps/pthread/bits/libc-tsd.h: New file for __libc_internal_tsd_*
-+ declarations.
-+
-+ * sysdeps/pthread/bits/libc-lock.h (__libc_internal_tsd_get,
-+ __libc_internal_tsd_set): Make these pointers to functions, not
-+ functions; remove #pragma weak decls for them.
-+ * specific.c (__libc_internal_tsd_get, __libc_internal_tsd_set):
-+ Define static functions and initialized pointers to them.
-+
-+1998-11-18 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Makefile (CFLAGS-mutex.c): Define as -D__NO_WEAK_PTHREAD_ALIASES.
-+ (CFLAGS-specific.c): Likewise.
-+ (CFLAGS-pthread.c): Likewise.
-+ (CFLAGS-ptfork.c): Likewise.
-+ (CFLAGS-cancel.c): Likewise.
-+ * sysdeps/pthread/bits/libc-lock.h: Don't mark __pthread_* functions
-+ as weak references if __NO_WEAK_PTHREAD_ALIASES is defined.
-+
-+ * mutex.c (pthread_mutex_init): Define as strong symbol.
-+ (pthread_mutex_destroy): Likewise.
-+ (pthread_mutex_trylock): Likewise.
-+ (pthread_mutex_lock): Likewise.
-+ (pthread_mutex_unlock): Likewise.
-+ (pthread_mutexattr_init): Likewise.
-+ (pthread_mutexattr_destroy): Likewise.
-+ (pthread_once): Likewise.
-+ * ptfork.c (pthread_atfork): Likewise.
-+ * specific.c (pthread_key_create): Likewise.
-+ (pthread_setspecific): Likewise.
-+ (pthread_getspecific): Likewise.
-+
-+1998-11-15 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
-+
-+ * linuxthreads.texi: Fix punctuation after xref.
-+
-+1998-11-10 H.J. Lu <hjl@gnu.org>
-+
-+ * sysdeps/unix/sysv/linux/bits/local_lim.h: Undefine NR_OPEN
-+ if it is defined in <linux/limits.h>.
-+
-+1998-10-29 14:28 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * spinlock.h (__pthread_trylock): Define inline.
-+ (__pthread_lock): Add extra parameter to declaration. Declare
-+ using internal_function.
-+ (__pthread_unlock): Declare using internal_function.
-+ * spinlock.c (__pthread_lock): Add new parameter. Use it instead
-+ of local variable self. Avoid recomputing self. Define using
-+ internal_function.
-+ (__pthread_trylock): Remove.
-+ (__pthread_unlock): Define using internal_function.
-+ * cancel.c: Adjust for __pthread_lock interface change. Use already
-+ computed self value is possible.
-+ * condvar.c: Likewise.
-+ * join.c: Likewise.
-+ * manager.c: Likewise.
-+ * mutex.c: Likewise.
-+ * pthread.c: Likewise.
-+ * rwlock.c: Likewise.
-+ * semaphore.c: Likewise.
-+ * signals.c: Likewise.
-+
-+1998-10-27 13:46 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/pthread/pthread.h (struct _pthread_cleanup_buffer): Prepend
-+ __ to field names of the struct.
-+ * sysdeps/pthread/bits/pthreadtypes.h (struct _pthread_fastlock):
-+ Likewise.
-+ (pthread_attr_t): Likewise.
-+ (pthread_cond_t): Likewise.
-+ (pthread_condattr_t): Likewise.
-+ (pthread_mutex_t): Likewise.
-+ (pthread_mutexattr_t): Likewise.
-+ (pthread_rwlock_t): Likewise.
-+ (pthread_rwlockattr_t): Likewise.
-+ * attr.c: Adjust for pthread.h and pthreadtypes.h change.
-+ * cancel.c: Likewise.
-+ * condvar.c: Likewise.
-+ * manager.c: Likewise.
-+ * mutex.c: Likewise.
-+ * pthread.c: Likewise.
-+ * ptlongjmp.c: Likewise.
-+ * rwlock.c: Likewise.
-+ * spinlock.c: Likewise.
-+
-+1998-10-09 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/i386/pt-machine.h (get_eflags, set_eflags): Mark these
-+ also with PT_EI.
-+
-+ * sysdeps/i386/i686/pt-machine.h: Remove unused inline
-+ definitions.
-+
-+ * Makefile (libpthread-routines): Add pt-machine.
-+ * pt-machine.c: New file.
-+ * sysdeps/alpha/pt-machine.h: Define PT_EI as extern inline is not
-+ yet defined. Use PT_EI in extern inline definitions.
-+ * sysdeps/arm/pt-machine.h: Likewise.
-+ * sysdeps/i386/pt-machine.h: Likewise.
-+ * sysdeps/i386/i686/pt-machine.h: Likewise.
-+ * sysdeps/m68k/pt-machine.h: Likewise.
-+ * sysdeps/mips/pt-machine.h: Likewise.
-+ * sysdeps/powerpc/pt-machine.h: Likewise.
-+ * sysdeps/sparc/sparc32/pt-machine.h: Likewise.
-+ * sysdeps/sparc/sparc64/pt-machine.h: Likewise.
-+
-+1998-10-02 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * semaphore.h: Include <sys/types.h> so that _pthread_descr
-+ is declared.
-+
-+1998-09-15 David S. Miller <davem@pierdol.cobaltmicro.com>
-+
-+ * sysdeps/sparc/sparc32/pt-machine.h (INIT_THREAD_SELF): Add nr
-+ argument.
-+ * sysdeps/sparc/sparc64/pt-machine.h (INIT_THREAD_SELF): Likewise.
-+
-+1998-09-12 14:24 -0400 Zack Weinberg <zack@rabi.phys.columbia.edu>
-+
-+ * linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h: Add
-+ multiple inclusion guard.
-+
-+1998-09-02 11:08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * signals.c (sigaction): Check that sig is less than NSIG to avoid
-+ array index overflow.
-+
-+1998-09-06 10:56 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/pthread/semaphore.h: New file.
-+
-+1998-09-06 09:08 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/pthread/bits/libc-lock.h (enum __libc_tsd_key_t): Add
-+ _LIBC_TSD_KEY_DL_ERROR.
-+
-+1998-08-31 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/i386/i686/pt-machine.h (testandset): Add memory clobber.
-+ * sysdeps/i386/pt-machine.h: Likewise.
-+ Suggested by Roland McGrath.
-+
-+1998-08-28 13:58 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * internals.h: Also define THREAD_GETMEM_NC and THREAD_SETMEM_NC to
-+ access thread data with non-constant offsets.
-+ * specific.c: Use THREAD_GETMEM_NC and THREAD_SETMEM_NC where
-+ necessary.
-+
-+ * sysdeps/i386/useldt.h: Fix typo. Add THREAD_GETMEM_NC and
-+ THREAD_SETMEM_NC definitions.
-+
-+ * sysdeps/sparc/sparc32/pt-machine.h: Define THREAD_GETMEM_NC and
-+ THREAD_SETMEM_NC.
-+ * sysdeps/sparc/sparc64/pt-machine.h: Likewise.
-+
-+1998-08-26 15:46 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * internals.h: Define THREAD_GETMEM and THREAD_SETMEM to default if
-+ not already defined.
-+ (struct _pthread_descr_struct): Add p_self and p_nr field.
-+ * manager.c (__pthread_handles): Define second element to point
-+ to manager thread.
-+ (__pthread_handles_num): Initialize to 2.
-+ (__pthread_manager): Use INIT_THREAD_SELF with two arguments.
-+ (pthread_start_thread): Likewise.
-+ (pthread_handle_create): Start search for free slot at entry 2.
-+ Initialize new fields p_self and p_nr.
-+ Call __clone with CLONE_PTRACE if available.
-+ (pthread_free): Call FREE_THREAD_SELF if available.
-+ * pthread.c (__pthread_initial_thread): Initialize new fields.
-+ (__pthread_manager_thread): Likewise.
-+ (__pthread_initialize_manager): Call __clone with CLONE_PTRACE.
-+
-+ * cancel.c: Use THREAD_GETMEM and THREAD_SETMEM to access the
-+ elements of the thread descriptor.
-+ * condvar.c: Likewise.
-+ * errno.c: Likewise.
-+ * join.c: Likewise.
-+ * manager.c: Likewise.
-+ * pthread.c: Likewise.
-+ * ptlongjmp.c: Likewise.
-+ * semaphore.c: Likewise.
-+ * signals.c: Likewise.
-+ * specific.c: Likewise.
-+ * spinlock.c: Likewise.
-+
-+ * sysdeps/alpha/pt-machine.h (INIT_THREAD_SELF): Add extra parameter.
-+
-+ * sysdeps/i386/useldt.h: New file.
-+ * sysdeps/i386/i686/pt-machine.h: Show how to use this file.
-+
-+ * sysdeps/sparc/sparc32/pt-machine.h: Define THREAD_GETMEM and
-+ THREAD_SETMEM using __thread_self.
-+ * sysdeps/sparc/sparc64/pt-machine.h: Likewise.
-+
-+1998-08-24 Geoff Keating <geoffk@ozemail.com.au>
-+
-+ * spinlock.c (__pthread_lock): Reset p_nextwaiting to NULL if it
-+ turned out that we didn't need to queue after all.
-+
-+1998-08-22 Geoff Keating <geoffk@ozemail.com.au>
-+
-+ * sysdeps/powerpc/pt-machine.h: Remove testandset, it's not used
-+ and wastes space; correct types.
-+
-+1998-08-08 11:18 H.J. Lu <hjl@gnu.org>
-+
-+ * signals.c (sigaction): Handle NULL argument.
-+
-+1998-08-04 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/unix/sysv/linux/bits/sigthread.h: Use __sigset_t instead
-+ of sigset_t.
-+
-+1998-08-02 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * Makefile (linuxthreads-version): Extract correct number from
-+ Banner.
-+
-+1998-07-29 Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+ * Banner: Bump version number to 0.8
-+ * FAQ.html: Many updates, in particular w.r.t. debugging.
-+ * manager.c: Support for non-default stacksize for
-+ LinuxThreads-allocated stacks;
-+ don't use guard pages for stacks with default size, rely on
-+ rlimit(RLIMIT_STACK) instead (it's cheaper).
-+ * attr.c: Likewise.
-+ * cancel.c: Use __pthread_sig_cancel and __pthread_sig_restart
-+ everywhere instead of PTHREAD_SIG_CANCEL and PTHREAD_SIG_RESTART.
-+ * condvar.c: Likewise.
-+ * internals.h: Likewise.
-+ * restart.h: Likewise.
-+ * signals.c: Likewise.
-+ * pthread.c: Likewise; set rlimit(RLIMIT_STACK) as we need it.
-+
-+1998-07-23 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * weaks.c: Define pthread_mutexattr_[sg]ettype instead of
-+ __pthread_mutexattr_[sg]ettype. Add more weak aliases.
-+ * Versions: Put __pthread_mutexattr_settype under version
-+ GLIBC_2.0. Don't export __pthread_mutexattr_setkind_np and
-+ __pthread_mutexattr_gettype.
-+
-+1998-07-23 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * sysdeps/pthread/bits/libc-lock.h: Make
-+ __pthread_mutexattr_settype weak. Don't make
-+ __pthread_mutexattr_setkind_np weak.
-+
-+1998-07-16 10:52 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_handle_create): Check whether sched_setscheduler
-+ call can succeed here.
-+
-+ * mutex.c: Define __pthread_mutexattr_settype and make
-+ __pthread_mutexattr_setkind_np an alias.
-+ Likewise for __pthread_mutexattr_gettype.
-+
-+1998-07-15 11:00 -0400 Zack Weinberg <zack@rabi.phys.columbia.edu>
-+
-+ * attr.c (pthread_attr_setschedpolicy): Don't check whether caller
-+ is root.
-+
-+1998-07-14 19:38 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/pthread/bits/libc-lock.h: Define __libc_cleanup_end.
-+
-+1998-07-11 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * Examples/ex6.c: Include <unistd.h> for usleep.
-+
-+1998-06-13 11:04 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * Examples/ex4.c (main): Use exit, not pthread_exit.
-+
-+1998-07-09 13:39 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Versions: Add __pthread_mutexattr_gettype and
-+ __pthread_mutexattr_settype.
-+ * lockfile.c: Use __pthread_mutexattr_settype instead of
-+ __pthread_mutexattr_setkind_np.
-+ * mutex.c: Define __pthread_mutexattr_gettype and
-+ __pthread_mutexattr_settype.
-+ * weak.c: Likewise.
-+ * sysdeps/pthread/pthread.h: Declare __pthread_mutexattr_gettype and
-+ __pthread_mutexattr_settype.
-+ * sysdeps/pthread/bits/libc-lock.h (__libc_lock_init_recursive):
-+ Use __pthread_mutexattr_settype.
-+
-+1998-07-08 22:26 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Versions: Add pthread_mutexattr_gettype, pthread_mutexattr_settype.
-+ * mutex.c: Define weak alias pthread_mutexattr_gettype and
-+ pthread_mutexattr_settype.
-+ * sysdeps/pthread/pthread.h: Declare these functions.
-+ Move pthread_sigmask and pthread_kill declaration in separate header.
-+ * sysdeps/unix/sysv/linux/bits/sigthread.h: New file.
-+
-+1998-07-07 15:20 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Makefile: Add rules to compile and run tests.
-+ * Examples/ex1.c: Little changes to fix warnings.
-+ * Examples/ex2.c: Likewise.
-+ * Examples/ex3.c: Likewise.
-+ * Examples/ex4.c: Likewise.
-+ * Examples/ex5.c: Likewise.
-+ * Examples/ex6.c: New file.
-+
-+1998-07-05 11:54 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Versions: Add pthread_attr_init to GLIBC_2.1 version in libc.
-+
-+1998-07-01 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * attr.c: Include <string.h>.
-+
-+1998-06-30 11:47 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * attr.c: Include errno.h. Use memcpy to copy sched_param.
-+ * internals.h: Include limits.h.
-+ * manager.c: Use memcpy to copy sched_param.
-+ * ptfork.c: Include errno.h.
-+ * pthread.c: Likewise.
-+ * semaphore.c: Likewise.
-+ * specific.c: Likewise.
-+ * spinlock.h: Likewise.
-+ * sysdeps/pthread/pthread.h: Include only allowed headers. Move
-+ type definition to ...
-+ * sysdeps/pthread/bits/pthreadtypes.h: ...here. New file.
-+
-+1998-06-29 12:34 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/pthread/pthread.h: Use __PMT not __P for function pointers.
-+
-+ * sysdeps/pthread/pthread.h: Define various PTHREAD_* symbols also
-+ as macros as demanded in POSIX.1, Annex C.
-+
-+1998-06-29 12:29 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * internals.h (struct pthread_request): For free use pthread_t
-+ instead of pthread_descr.
-+ * join.c (pthread_join): Pass thread_id, not th to manager.
-+ (pthread_detach): Likewise.
-+ * manager.c (__pthread_manager): Except thread ID in FREE_REQ case.
-+ (pthread_exited): Remove detached queue code.
-+ (pthread_handle_free): Expect thread ID parameter and use it to
-+ validate the thread decsriptor. Don't use detached queue.
-+ Patches by Xavier Leroy.
-+
-+1998-06-27 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * libpthread.map: Export accept, longjmp, sigaction, siglongjmp,
-+ _IO_flockfile, _IO_ftrylockfile, _IO_funlockfile,
-+ __pthread_atfork, __pthread_key_create, __pthread_once.
-+ * internals.h: Doc fix.
-+ * pthread.c (__pthread_initialize): Define again.
-+
-+1998-06-26 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_exited): If thread is not detached put it on
-+ special list.
-+ (pthread_handle_free): If thread is not on list with living threads
-+ search on list with detached threads.
-+
-+ * sysdeps/pthread/pthread.h (PTHREAD_RWLOCK_INITIALIZER): Correct
-+ for new definition of pthread_rwlock_t.
-+
-+ * spinlock.c: Correct test whether to compile
-+ __pthread_compare_and_swap or not.
-+
-+1998-06-25 19:27 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * attr.c: Finish user stack support. Change locking code to be safe
-+ in situations with different priorities.
-+ * cancel.c: Likewise.
-+ * condvar.c: Likewise.
-+ * internals.h: Likewise.
-+ * join.c: Likewise.
-+ * manager.c: Likewise.
-+ * mutex.c: Likewise.
-+ * pthread.c: Likewise.
-+ * ptlongjmp.c: Likewise.
-+ * queue.h: Likewise.
-+ * rwlock.c: Likewise.
-+ * semaphore.c: Likewise.
-+ * semaphore.h: Likewise.
-+ * signals.c: Likewise.
-+ * spinlock.c: Likewise.
-+ * spinlock.h: Likewise.
-+ * sysdeps/pthread/pthread.h: Likewise.
-+ Patches by Xavier Leroy.
-+
-+ * sysdeps/i386/i686/pt-machine.h: New file.
-+
-+1998-06-25 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/pthread/pthread.h: Make [sg]et_stacksize and
-+ [sg]et_stackaddr prototypes always available.
-+
-+ * sysdeps/unix/sysv/linux/bits/posix_opt.h: Define
-+ _POSIX_THREAD_ATTR_STACKSIZE and _POSIX_THREAD_ATTR_STACKADDR.
-+
-+1998-06-24 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_free): Undo patch from 980430.
-+ Reported by David Wragg <dpw@doc.ic.ac.uk>.
-+
-+1998-06-09 15:07 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c: Define __pthread_manager_adjust_prio and use it to
-+ increase priority when needed.
-+ * internals.h: Add prototype for __pthread_manager_adjust_prio.
-+ * mutex.c: Optimize mutexes to wake up only one thread.
-+ * pthread.c: Move PID of manager for global variable in structure
-+ element.
-+ Patches by Xavier Leroy.
-+
-+1998-06-07 13:47 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/pthread/bits/libc-lock.h: Optimize cleanup handlers a bit.
-+
-+1998-06-03 Andreas Jaeger <aj@arthur.rhein-neckar.de>
-+
-+ * attr.c: Correct typo.
-+
-+1998-05-01 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_free): Unmap guard before the stack.
-+ Patch by Matthias Urlichs.
-+
-+1998-04-30 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c (pthread_free): Detect already free child.
-+ Patch by Xavier Leroy, reported by Matthias Urlichs.
-+
-+1998-04-23 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * Makefile (linuxthreads-version): Renamed back from
-+ libpthread-version.
-+
-+1998-04-21 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * ptlongjmp.c: Add prototypes for __libc_siglongjmp and
-+ __libc_longjmp.
-+
-+1998-04-20 14:55 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Makefile (libpthread-routines): Add ptlongjmp and spinlock.
-+ * internals.h: Add definitions for new spinlock implementation.
-+ * ptlongjmp.c: New file.
-+ * spinlock.c: New file.
-+ * spinlock.h (acquire): Don't reschedule using __sched_yield, use
-+ new function __pthread_acquire to prevent deadlocks with thread
-+ with different priorities.
-+ Patches by Xavier Leroy <Xavier.Leroy@inria.fr>.
-+
-+1998-03-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * manager.c (__pthread_manager): Reduce first argument to select
-+ to include just the needed file descriptor.
-+
-+1998-03-17 00:06 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * manager.c: Fix last patch which caused core dumps.
-+
-+ * pthread.c: Correctly handle missing SIGRTMIN.
-+
-+1998-03-15 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * libpthread.map: Add __libc_internal_tsd_get and
-+ __libc_internal_tsd_set. Add missing cancelable functions. Export
-+ libc internal versions of the cancelable functions.
-+
-+1998-03-13 16:51 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * weaks.c: Define pthread_attr_init as GLIBC_2.0 and GLIBC_2.1.
-+
-+1998-03-13 00:46 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * attr.c: Implement pthread_attr_[gs]etguardsize,
-+ pthread_attr_[gs]setstackaddr, pthread_attr_[gs]etstacksize.
-+ Change pthread_attr_init to have two interfaces.
-+ * internals.h (struct _pthread_descr_struct): Add new fields for
-+ above functions.
-+ * libpthread.map: Add names in GLIBC_2.1 section.
-+ * manager.c (pthread_handle_create): Implement guardsize and
-+ user stack.
-+ (pthread_free): Likewise.
-+ * pthread.c (pthread_create): Add new interface for changed
-+ pthread_attr_t.
-+ * sysdeps/pthread/pthread.h: Add prototypes for new functions.
-+ * sysdeps/unix/sysv/linux/bits/local_lim.h: Add definition of
-+ PTHREAD_STACK_MIN.
-+
-+1998-03-11 00:42 Wolfram Gloger <wmglo@dent.med.uni-muenchen.de>
-+
-+ * manager.c: Enable resetting of the thread scheduling policy
-+ to SCHED_OTHER when the parent thread has a different one.
-+
-+1998-02-01 13:51 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * sysdeps/unix/sysv/linux/bits/posix_opt.h: Define
-+ _POSIX_ASYNCHRONOUS_IO.
-+
-+ * sysdeps/pthread/pthread.h: Define bits for Unix98 variants of
-+ mutexes.
-+ * mutex.c: Implement new mutex types.
-+
-+ * internals.h: Include <signal.h>.
-+
-+ * libpthread.map: Add __erno_location and __h_errno_location.
-+
-+ * errno.c: Return pointer to variable actually in use. This might
-+ not be the one in the thread structure.
-+ * internals.h (struct _pthread_descr_struct): Add new fields p_errnop
-+ and p_h_errnop.
-+ * manager.c (__pthread_manager): Set p_errnop and p_h_errnop member
-+ of manager thread structure.
-+ (pthread_handle_create): Set p_errnop and p_h_errnop members for new
-+ thread.
-+ * pthread.c: Adapt initializer for thread structures.
-+ (__pthread_initial_thread): Set p_errnop and p_h_errnop member.
-+ (__pthread_reset_main_thread): Reset p_errnop and p_h_errnop of
-+ current thread to global variables.
-+
-+1998-01-31 17:27 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * rwlock.c: New file.
-+ * Makefile (libpthread-routines): Add rwlock.
-+ * sysdeps/pthread/pthread.h: Define data structures and declare
-+ functions.
-+ * libpthread.map: Add new functions.
-+
-+1997-12-18 13:50 Philip Blundell <pb@nexus.co.uk>
-+
-+ * sysdeps/arm/pt-machine.h: New file; add ARM support.
-+ * sysdeps/arm/Implies: likewise.
-+ * README: Document it.
-+
-+1997-12-13 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * signals.c: Remove unneeded initializer for sigwaited, saving a
-+ warning.
-+
-+1997-04-11 01:18 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * semaphore.c (sem_init): Set sem_spinlock only if available.
-+
-+1997-12-04 01:48 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * mutex.c: Implement PTHREAD_MUTEX_CHECKERROR.
-+ * sysdeps/pthread/pthread.h: Define PTHREAD_MUTEX_CHECKERROR.
-+
-+ * Makefile: Update from LinuxThreads 0.7.
-+ * internals.h. Likewise.
-+ * manager.c: Likewise.
-+ * mutex.c: Likewise.
-+ * pthread.c: Likewise.
-+ * signals.c: Likewise.
-+ * specific.c: Likewise.
-+ * Examples/ex3.c: Likewise.
-+
-+1997-11-20 18:13 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * pthread.c (__pthread_reset_main_thread): Close pipe only if still
-+ open.
-+
-+1997-10-29 05:38 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * wrapsyscall.c: Add socket functions which are also cancelation
-+ points.
-+
-+1997-10-19 21:40 Wolfram Gloger <wg@wolfram.dent.med.uni-muenchen.de>
-+
-+ * specific.c (__libc_internal_tsd_set, __libc_internal_tsd_get):
-+ New functions for fast thread specific data within libc.
-+
-+ * internals.h: Add new array p_libc_specific to struct
-+ _pthread_descr_struct.
-+
-+ * sysdeps/pthread/bits/libc-lock.h: Declare new functions.
-+
-+1997-10-13 05:39 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * semaphore.h: Add __BEGIN_DECLS/__END_DECLS.
-+ Reported by Ralf Corsepius <corsepiu@faw.uni-ulm.de>.
-+
-+1997-08-29 03:05 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * internals.h (struct _pthread_descr_struct): Add definitions for
-+ two-level specific key handling.
-+ * manager.c (pthread_handle_create): Initialize specific memory array.
-+ * specific.c: Implement two-level key handling.
-+ * weaks.c: Don't provide dummy key handling.
-+ * sysdeps/pthread/bits/libc-lock.h: Typedef __libc_lock_t (no #define).
-+ Add definition of __libc_key_t.
-+ * sysdeps/unix/sysv/linux/bits/local_lim.h: Define PTHREAD_KEYS_MAX
-+ as 1024.
-+ Add definition of _POSIX_THREAD_DESTRUCTOR_ITERATIONS and
-+ PTHREAD_DESTRUCTOR_ITERATIONS.
-+
-+ * manager.c (pthread_handle_create): Compare mmap result with
-+ MAP_FAILED.
-+
-+ * ptfork.c: Rename to __pthread_atfork and make old name a weak alias.
-+ * sysdeps/pthread/bits/pthread.h: Add prototype for __pthread_atfork.
-+
-+1997-08-22 19:04 Richard Henderson <rth@cygnus.com>
-+
-+ sysdeps/sparc -> sysdeps/sparc/sparc32
-+ sysdeps/sparc64 -> sysdeps/sparc/sparc64
-+
-+ * internals.h: Change definition of THREAD_SELF to be an expression,
-+ not a statement that did a return.
-+ * sysdeps/alpha/pt-machine.h (THREAD_SELF): Update accordingly.
-+ * sysdeps/sparc/sparc32/pt-machine.h (THREAD_SELF, INIT_THREAD_SELF):
-+ Follow Solaris and use a "system reserved" register (%g6) to hold
-+ the thread descriptor.
-+ * sysdeps/sparc/sparc64/pt-machine.h: Likewise.
-+
-+1997-08-03 00:09 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * mutex.c: Correct pthread_once. Patch by Xavier Leroy.
-+ * sysdeps/pthread/pthread.h: Add prototype for __pthread_once.
-+ * sysdeps/pthread/bits/pthread.h: Add macros for __libc_once.
-+
-+ * semaphore.c: Include spinlock.h only when needed.
-+
-+ * specific.c (__pthread_setsepcific, __pthread_getspecific): Reject
-+ keys for entries not in use.
-+
-+ * weaks.c: Implement key handling functions for real.
-+
-+1997-06-29 01:04 Richard Henderson <richard@gnu.ai.mit.edu>
-+
-+ Initial sparc64-linux support:
-+ * linuxthreads/sysdeps/sparc64/Implies: New file.
-+ * linuxthreads/sysdeps/sparc64/pt-machine.h: Likewise.
-+
-+1997-06-29 00:48 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * semaphore.c: Include spinlock.h at correct place.
-+ Patch by HJ Lu.
-+
-+1997-06-13 10:06 Richard Henderson <rth@tamu.edu>
-+
-+ The Great Bit File Move:
-+ * sysdeps/alpha/semaphorebits.h: -> .../bits/semaphore.h.
-+ * sysdeps/powerpc/semaphorebits.h: Likewise.
-+ * sysdeps/pthread/cmpxchg/semaphorebits.h: Likewise.
-+ * sysdeps/pthread/no-cmpxchg/semaphorebits.h: Likewise.
-+ * sysdeps/pthread/libc-lock.h: -> bits/
-+ * sysdeps/pthread/stdio-lock.h: Likewise.
-+ * sysdeps/unix/sysv/linux/local_lim.h: Likewise.
-+ * sysdeps/unix/sysv/linux/posix_opt.h: Likewise.
-+ * semaphore.h: Likewise.
-+ * sysdeps/pthread/pthread.h: Likewise.
-+
-+ * lockfile.c: <foo.h> -> <bits/foo.h>.
-+ * semaphore.h: Likewise.
-+
-+ * Makefile: (headers): foo.h -> bits/foo.h.
-+ * sysdeps/pthread/Makefile: Likewise.
-+
-+1997-04-11 01:18 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-+
-+ * semaphore.c (sem_init): Set sem_spinlock only if available.
-+
-+ * sysdeps/m68k/pt-machine.h (testandset, __compare_and_swap): Fix
-+ asm constraints.
-+
-+1997-04-09 03:00 Ulrich Drepper <drepper@cygnus.com>
-+
-+ Update from LinuxThreads 0.6.
-+
-+ * attr.c (pthread_attr_getdetachstate): Use __sched_get_priority_max
-+ and __sched_get_priority_min instead of names without `__'.
-+
-+ * manager.c: Rewrite large parts to implement opaque pthread_t.
-+
-+ * cancel.c: Adapt for opaque pthread_t type.
-+ * condvar.c: Likewise.
-+ * errno.c: Likewise.
-+ * join.c: Likewise.
-+ * mutex.c: Likewise.
-+ * pthread.c: Likewise.
-+ * signals.c: Likewise.
-+ * specific.c: Likewise.
-+ * restart.h: Likewise.
-+ * queue.h: Likewise.
-+ * Examples/ex3.c: Likewise.
-+ * Examples/ex4.c: Likewise.
-+ * sysdeps/pthread/pthread.h: Likewise.
-+
-+ * pthread.c: Accumulate time for all threads in thread manager.
-+
-+ * semaphore.c: Implement fallback implementation for architectures
-+ sometimes missing compare-exchange operations.
-+
-+ * cancel.c (pthread_cancel): Validate handle argument.
-+ * join.c (pthread_join): Likewise.
-+ (pthread_detach): Likewise.
-+ * signals.c (pthread_kill): Likewise.
-+
-+ * spinlock.h (acquire): Use __sched_yield not sched_yield.
-+
-+ * queue.h (enqueue): Enqueue thread according to priority.
-+
-+ * internals.c (struct pthread_start_args): New struct for passing
-+ args to cloning function.
-+ (struct _pthread): Rename to _pthread_descr_struct and adapt for
-+ opaque pthread_t.
-+
-+ * Examples/Makefile (clean): Pass -f option to rm.
-+
-+ * sysdeps/i386/pt-machine.h: Add check for compare-exchange instruction
-+ and define TEST_FOR_COMPARE_AND_SWAP.
-+ * sysdeps/i386/i486/pt-machine.h: Removed.
-+
-+ * sysdeps/unix/sysv/linux/local_lim.h (PTHREAD_THREADS_MAX): Increase
-+ to 1024.
-+
-+1997-04-04 16:38 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * restart.h (suspend): Clear p_signal before suspending.
-+ (suspend_with_cancellation): Likewise.
-+ Patch by Xavier Leroy <Xavier.Leroy@inria.fr>.
-+
-+ * weaks.c: Make __pthread_key_create return 1.
-+ * sysdeps/pthread/libc-lock.h: Define __libc_key_create,
-+ __libc_getspecific, __libc_setspecific, and __libc_key_t.
-+ * sysdeps/pthread/stdio-lock.h: Don't care for implementation not
-+ using libio.
-+
-+1997-03-19 15:13 Miguel de Icaza <miguel@nuclecu.unam.mx>
-+
-+ * sysdeps/sparc/pt-machine (RELEASE): Fix.
-+
-+1997-03-01 07:55 Geoff Keating <geoffk@ozemail.com.au>
-+
-+ * sysdeps/powerpc/Implies: Added.
-+ * sysdeps/powerpc/pt-machine.h: Added.
-+ * sysdeps/powerpc/semaphorebits.h: Added.
-+
-+1997-01-22 01:22 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * linuxtheads/pthread.c (__pthread_initial_thread): Correct
-+ initializer.
-+ (__pthread_manager_thread): Likewise.
-+ Reported by Andreas Jaeger.
-+
-+1997-01-18 22:15 Richard Henderson <rth@tamu.edu>
-+
-+ Since sigset_t no longer fits in a register, we can't pass in the
-+ thread's initial mask so easily. Take this opportunity to simplify
-+ the clone implementation by only accepting a single void* argument.
-+
-+ * linuxthreads/manager.c (__pthread_manager): Put thread vitals
-+ in the thread struct instead of as arguments through clone.
-+ (pthread_start_thread): Look for them there.
-+ * linuxthreads/internals.h (struct _pthread): Add p_initial_fn,
-+ p_initial_fn_arg, p_initial_mask. Fix __pthread_manager proto.
-+ * linuxthreads/pthread.c (pthread_initialize_manager): Revise
-+ clone invocation.
-diff -Naur ../glibc-2.1.3/linuxthreads/Changes glibc-2.1.3/linuxthreads/Changes
---- ../glibc-2.1.3/linuxthreads/Changes 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Changes 1998-08-28 03:07:17.000000000 -0700
-@@ -0,0 +1,73 @@
-+Release 0.7:
-+- Destructors for thread-specific data now conform to the POSIX semantics
-+ (call destructors again if non-NULL TSD remains after a round of
-+ destruction).
-+- Implemented thread-specific data as a sparse array, allows more TSD keys
-+ and smaller thread descriptors (Ulrich Drepper).
-+- Added "error checking" mutexes.
-+- Protect against multiple sigwait() on the same signals.
-+- Simplified implementation of semaphores when compare_and_swap is
-+ not available.
-+- Fixed bug in fork() where stdin was closed if fork() was called before
-+ the first pthread_create().
-+- Fixed bug in the gethostby*_r functions (bad result if null bytes
-+ in addresses).
-+- Typos in manual pages corrected.
-+- First cut at a PowerPC port (not working yet, runs into problems
-+ with gcc and with the C library).
-+
-+Release 0.6:
-+- Validation of thread identifiers: no more crashes when operating on
-+ a thread that has exited (based on Pavel Krauz's ideas).
-+- Added fallback implementation of semaphores for the 386 and the
-+ Sparc.
-+- Fixed a bug in signal handling causing false restarts of suspended
-+ threads.
-+- Fixed a bug in realtime scheduling causing all threads to have
-+ default scheduling on Ix86 with libc5.
-+- With realtime scheduling, unlocking a mutex now restarts the
-+ highest priority thread waiting on the mutex, not the
-+ first-suspended thread (Richard Neitzel).
-+- Timing a process now returns cumulative times for all threads, not
-+ just times for the initial thread (suggested by Wolfram Gloger).
-+- Cleaned up name space (internal defs prefixed by __, weak aliases
-+ for non-portable extensions).
-+- MIPS port (contributed by Ralf Baechle).
-+
-+Release 0.5:
-+- Signal-safe semaphores a la POSIX 1003.1b added.
-+- Locking bug in pthread_mutex_trylock over recursive mutexes fixed.
-+- Race conditions in thread cancellation fixed.
-+- Sparc port (contributed by Miguel de Icaza).
-+- Support for getpwnam_r and getpwuid_r.
-+- Added pthread_kill_other_threads_np to be used in conjunction with
-+ exec*().
-+
-+Release 0.4:
-+- Manual pages for all functions.
-+- Synchronization bug causing accumulation of zombie processes fixed.
-+- Race condition in pthread_cond_timedwait fixed.
-+- Recursive mutexes are back by popular demand.
-+- Partial support for realtime scheduling (initiated by Richard Neitzel).
-+- pthread.h cleaned up a lot: now C++ compatible, added missing "const"
-+ qualifiers, added short documentation, put to GNU libc standards
-+ for name space pollution (Ulrich Drepper).
-+- Motorola 68k port (contributed by Andreas Schwab).
-+- Interaction with fork(2) cleaned up a lot.
-+
-+Release 0.3:
-+- Thread creation and reclaimation now performed by a centralized
-+ "thread manager" thread.
-+- Removed recursive mutexes to make regular mutexes more efficient.
-+- Now available as a shared library (contributed by Richard Henderson).
-+- Alpha port (contributed by Richard Henderson).
-+- Fixed many small discrepancies with Posix 1003.1c.
-+- Put under the LGPL instead of the GPL.
-+
-+Release 0.2:
-+- Reentrant libc functions (adapted from libc 5.3.9 by Peeter Joot)
-+- pthread_cond_wait did not reacquire the mutex correctly on return
-+- More efficient pthread_cond_broadcast
-+
-+Release 0.1:
-+- First public release
-diff -Naur ../glibc-2.1.3/linuxthreads/Examples/Makefile glibc-2.1.3/linuxthreads/Examples/Makefile
---- ../glibc-2.1.3/linuxthreads/Examples/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Examples/Makefile 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,15 @@
-+CC=gcc
-+CFLAGS=-g -O -Wall -I.. -D_REENTRANT
-+LIBPTHREAD=../libpthread.a
-+
-+PROGS=ex1 ex2 ex3 ex4 ex5 proxy
-+
-+all: $(PROGS)
-+
-+.c:
-+ $(CC) $(CFLAGS) -o $* $*.c $(LIBPTHREAD)
-+
-+$(PROGS):
-+
-+clean:
-+ rm -f $(PROGS)
-diff -Naur ../glibc-2.1.3/linuxthreads/Examples/ex1.c glibc-2.1.3/linuxthreads/Examples/ex1.c
---- ../glibc-2.1.3/linuxthreads/Examples/ex1.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Examples/ex1.c 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,35 @@
-+/* Creates two threads, one printing 10000 "a"s, the other printing
-+ 10000 "b"s.
-+ Illustrates: thread creation, thread joining. */
-+
-+#include <stddef.h>
-+#include <stdio.h>
-+#include <unistd.h>
-+#include "pthread.h"
-+
-+void * process(void * arg)
-+{
-+ int i;
-+ fprintf(stderr, "Starting process %s\n", (char *) arg);
-+ for (i = 0; i < 10000; i++) {
-+ write(1, (char *) arg, 1);
-+ }
-+ return NULL;
-+}
-+
-+int main(void)
-+{
-+ int retcode;
-+ pthread_t th_a, th_b;
-+ void * retval;
-+
-+ retcode = pthread_create(&th_a, NULL, process, (void *) "a");
-+ if (retcode != 0) fprintf(stderr, "create a failed %d\n", retcode);
-+ retcode = pthread_create(&th_b, NULL, process, (void *) "b");
-+ if (retcode != 0) fprintf(stderr, "create b failed %d\n", retcode);
-+ retcode = pthread_join(th_a, &retval);
-+ if (retcode != 0) fprintf(stderr, "join a failed %d\n", retcode);
-+ retcode = pthread_join(th_b, &retval);
-+ if (retcode != 0) fprintf(stderr, "join b failed %d\n", retcode);
-+ return 0;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/Examples/ex2.c glibc-2.1.3/linuxthreads/Examples/ex2.c
---- ../glibc-2.1.3/linuxthreads/Examples/ex2.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Examples/ex2.c 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,113 @@
-+/* The classic producer-consumer example.
-+ Illustrates mutexes and conditions.
-+ All integers between 0 and 9999 should be printed exactly twice,
-+ once to the right of the arrow and once to the left. */
-+
-+#include <stdio.h>
-+#include "pthread.h"
-+
-+#define BUFFER_SIZE 16
-+
-+/* Circular buffer of integers. */
-+
-+struct prodcons {
-+ int buffer[BUFFER_SIZE]; /* the actual data */
-+ pthread_mutex_t lock; /* mutex ensuring exclusive access to buffer */
-+ int readpos, writepos; /* positions for reading and writing */
-+ pthread_cond_t notempty; /* signaled when buffer is not empty */
-+ pthread_cond_t notfull; /* signaled when buffer is not full */
-+};
-+
-+/* Initialize a buffer */
-+
-+void init(struct prodcons * b)
-+{
-+ pthread_mutex_init(&b->lock, NULL);
-+ pthread_cond_init(&b->notempty, NULL);
-+ pthread_cond_init(&b->notfull, NULL);
-+ b->readpos = 0;
-+ b->writepos = 0;
-+}
-+
-+/* Store an integer in the buffer */
-+
-+void put(struct prodcons * b, int data)
-+{
-+ pthread_mutex_lock(&b->lock);
-+ /* Wait until buffer is not full */
-+ while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) {
-+ pthread_cond_wait(&b->notfull, &b->lock);
-+ /* pthread_cond_wait reacquired b->lock before returning */
-+ }
-+ /* Write the data and advance write pointer */
-+ b->buffer[b->writepos] = data;
-+ b->writepos++;
-+ if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
-+ /* Signal that the buffer is now not empty */
-+ pthread_cond_signal(&b->notempty);
-+ pthread_mutex_unlock(&b->lock);
-+}
-+
-+/* Read and remove an integer from the buffer */
-+
-+int get(struct prodcons * b)
-+{
-+ int data;
-+ pthread_mutex_lock(&b->lock);
-+ /* Wait until buffer is not empty */
-+ while (b->writepos == b->readpos) {
-+ pthread_cond_wait(&b->notempty, &b->lock);
-+ }
-+ /* Read the data and advance read pointer */
-+ data = b->buffer[b->readpos];
-+ b->readpos++;
-+ if (b->readpos >= BUFFER_SIZE) b->readpos = 0;
-+ /* Signal that the buffer is now not full */
-+ pthread_cond_signal(&b->notfull);
-+ pthread_mutex_unlock(&b->lock);
-+ return data;
-+}
-+
-+/* A test program: one thread inserts integers from 1 to 10000,
-+ the other reads them and prints them. */
-+
-+#define OVER (-1)
-+
-+struct prodcons buffer;
-+
-+void * producer(void * data)
-+{
-+ int n;
-+ for (n = 0; n < 10000; n++) {
-+ printf("%d --->\n", n);
-+ put(&buffer, n);
-+ }
-+ put(&buffer, OVER);
-+ return NULL;
-+}
-+
-+void * consumer(void * data)
-+{
-+ int d;
-+ while (1) {
-+ d = get(&buffer);
-+ if (d == OVER) break;
-+ printf("---> %d\n", d);
-+ }
-+ return NULL;
-+}
-+
-+int main(void)
-+{
-+ pthread_t th_a, th_b;
-+ void * retval;
-+
-+ init(&buffer);
-+ /* Create the threads */
-+ pthread_create(&th_a, NULL, producer, 0);
-+ pthread_create(&th_b, NULL, consumer, 0);
-+ /* Wait until producer and consumer finish. */
-+ pthread_join(th_a, &retval);
-+ pthread_join(th_b, &retval);
-+ return 0;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/Examples/ex3.c glibc-2.1.3/linuxthreads/Examples/ex3.c
---- ../glibc-2.1.3/linuxthreads/Examples/ex3.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Examples/ex3.c 1998-12-14 08:09:39.000000000 -0800
-@@ -0,0 +1,152 @@
-+/* Multi-thread searching.
-+ Illustrates: thread cancellation, cleanup handlers. */
-+
-+#include <errno.h>
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <pthread.h>
-+
-+/* Defines the number of searching threads */
-+#define NUM_THREADS 5
-+
-+/* Function prototypes */
-+void *search(void *);
-+void print_it(void *);
-+
-+/* Global variables */
-+pthread_t threads[NUM_THREADS];
-+pthread_mutex_t lock;
-+int tries;
-+volatile int started;
-+
-+int main(int argc, char ** argv)
-+{
-+ int i;
-+ int pid;
-+
-+ /* create a number to search for */
-+ pid = getpid();
-+ printf("Searching for the number = %d...\n", pid);
-+
-+ /* Initialize the mutex lock */
-+ pthread_mutex_init(&lock, NULL);
-+
-+ /* Create the searching threads */
-+ for (started=0; started<NUM_THREADS; started++)
-+ pthread_create(&threads[started], NULL, search, (void *)pid);
-+
-+ /* Wait for (join) all the searching threads */
-+ for (i=0; i<NUM_THREADS; i++)
-+ pthread_join(threads[i], NULL);
-+
-+ printf("It took %d tries to find the number.\n", tries);
-+
-+ /* Exit the program */
-+ return 0;
-+}
-+
-+/* This is the cleanup function that is called
-+ when the threads are cancelled */
-+
-+void print_it(void *arg)
-+{
-+ int *try = (int *) arg;
-+ pthread_t tid;
-+
-+ /* Get the calling thread's ID */
-+ tid = pthread_self();
-+
-+ /* Print where the thread was in its search when it was cancelled */
-+ printf("Thread %lx was canceled on its %d try.\n", tid, *try);
-+}
-+
-+/* This is the search routine that is executed in each thread */
-+
-+void *search(void *arg)
-+{
-+ int num = (int) arg;
-+ int i, j, ntries;
-+ pthread_t tid;
-+
-+ /* get the calling thread ID */
-+ tid = pthread_self();
-+
-+ /* use the thread ID to set the seed for the random number generator */
-+ /* Since srand and rand are not thread-safe, serialize with lock */
-+
-+ /* Try to lock the mutex lock --
-+ if locked, check to see if the thread has been cancelled
-+ if not locked then continue */
-+ while (pthread_mutex_trylock(&lock) == EBUSY)
-+ pthread_testcancel();
-+
-+ srand((int)tid);
-+ i = rand() & 0xFFFFFF;
-+ pthread_mutex_unlock(&lock);
-+ ntries = 0;
-+
-+ /* Set the cancellation parameters --
-+ - Enable thread cancellation
-+ - Defer the action of the cancellation */
-+
-+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
-+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
-+
-+ while (started < NUM_THREADS)
-+ sched_yield ();
-+
-+ /* Push the cleanup routine (print_it) onto the thread
-+ cleanup stack. This routine will be called when the
-+ thread is cancelled. Also note that the pthread_cleanup_push
-+ call must have a matching pthread_cleanup_pop call. The
-+ push and pop calls MUST be at the same lexical level
-+ within the code */
-+
-+ /* Pass address of `ntries' since the current value of `ntries' is not
-+ the one we want to use in the cleanup function */
-+
-+ pthread_cleanup_push(print_it, (void *)&ntries);
-+
-+ /* Loop forever */
-+ while (1) {
-+ i = (i + 1) & 0xFFFFFF;
-+ ntries++;
-+
-+ /* Does the random number match the target number? */
-+ if (num == i) {
-+ /* Try to lock the mutex lock --
-+ if locked, check to see if the thread has been cancelled
-+ if not locked then continue */
-+ while (pthread_mutex_trylock(&lock) == EBUSY)
-+ pthread_testcancel();
-+
-+ /* Set the global variable for the number of tries */
-+ tries = ntries;
-+ printf("Thread %lx found the number!\n", tid);
-+
-+ /* Cancel all the other threads */
-+ for (j=0; j<NUM_THREADS; j++)
-+ if (threads[j] != tid) pthread_cancel(threads[j]);
-+
-+ /* Break out of the while loop */
-+ break;
-+ }
-+
-+ /* Every 100 tries check to see if the thread has been cancelled. */
-+ if (ntries % 100 == 0) {
-+ pthread_testcancel();
-+ }
-+ }
-+
-+ /* The only way we can get here is when the thread breaks out
-+ of the while loop. In this case the thread that makes it here
-+ has found the number we are looking for and does not need to run
-+ the thread cleanup function. This is why the pthread_cleanup_pop
-+ function is called with a 0 argument; this will pop the cleanup
-+ function off the stack without executing it */
-+
-+ pthread_cleanup_pop(0);
-+ return((void *)0);
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/Examples/ex4.c glibc-2.1.3/linuxthreads/Examples/ex4.c
---- ../glibc-2.1.3/linuxthreads/Examples/ex4.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Examples/ex4.c 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,107 @@
-+/* Making a library function that uses static variables thread-safe.
-+ Illustrates: thread-specific data, pthread_once(). */
-+
-+#include <stddef.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <pthread.h>
-+
-+/* This is a typical example of a library function that uses
-+ static variables to accumulate results between calls.
-+ Here, it just returns the concatenation of all string arguments
-+ that were given to it. */
-+
-+#if 0
-+
-+char * str_accumulate(char * s)
-+{
-+ static char accu[1024] = { 0 };
-+ strcat(accu, s);
-+ return accu;
-+}
-+
-+#endif
-+
-+/* Of course, this cannot be used in a multi-threaded program
-+ because all threads store "accu" at the same location.
-+ So, we'll use thread-specific data to have a different "accu"
-+ for each thread. */
-+
-+/* Key identifying the thread-specific data */
-+static pthread_key_t str_key;
-+/* "Once" variable ensuring that the key for str_alloc will be allocated
-+ exactly once. */
-+static pthread_once_t str_alloc_key_once = PTHREAD_ONCE_INIT;
-+
-+/* Forward functions */
-+static void str_alloc_key(void);
-+static void str_alloc_destroy_accu(void * accu);
-+
-+/* Thread-safe version of str_accumulate */
-+
-+char * str_accumulate(const char * s)
-+{
-+ char * accu;
-+
-+ /* Make sure the key is allocated */
-+ pthread_once(&str_alloc_key_once, str_alloc_key);
-+ /* Get the thread-specific data associated with the key */
-+ accu = (char *) pthread_getspecific(str_key);
-+ /* It's initially NULL, meaning that we must allocate the buffer first. */
-+ if (accu == NULL) {
-+ accu = malloc(1024);
-+ if (accu == NULL) return NULL;
-+ accu[0] = 0;
-+ /* Store the buffer pointer in the thread-specific data. */
-+ pthread_setspecific(str_key, (void *) accu);
-+ printf("Thread %lx: allocating buffer at %p\n", pthread_self(), accu);
-+ }
-+ /* Now we can use accu just as in the non thread-safe code. */
-+ strcat(accu, s);
-+ return accu;
-+}
-+
-+/* Function to allocate the key for str_alloc thread-specific data. */
-+
-+static void str_alloc_key(void)
-+{
-+ pthread_key_create(&str_key, str_alloc_destroy_accu);
-+ printf("Thread %lx: allocated key %d\n", pthread_self(), str_key);
-+}
-+
-+/* Function to free the buffer when the thread exits. */
-+/* Called only when the thread-specific data is not NULL. */
-+
-+static void str_alloc_destroy_accu(void * accu)
-+{
-+ printf("Thread %lx: freeing buffer at %p\n", pthread_self(), accu);
-+ free(accu);
-+}
-+
-+/* Test program */
-+
-+void * process(void * arg)
-+{
-+ char * res;
-+ res = str_accumulate("Result of ");
-+ res = str_accumulate((char *) arg);
-+ res = str_accumulate(" thread");
-+ printf("Thread %lx: \"%s\"\n", pthread_self(), res);
-+ return NULL;
-+}
-+
-+int main(int argc, char ** argv)
-+{
-+ char * res;
-+ pthread_t th1, th2;
-+
-+ res = str_accumulate("Result of ");
-+ pthread_create(&th1, NULL, process, (void *) "first");
-+ pthread_create(&th2, NULL, process, (void *) "second");
-+ res = str_accumulate("initial thread");
-+ printf("Thread %lx: \"%s\"\n", pthread_self(), res);
-+ pthread_join(th1, NULL);
-+ pthread_join(th2, NULL);
-+ exit(0);
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/Examples/ex5.c glibc-2.1.3/linuxthreads/Examples/ex5.c
---- ../glibc-2.1.3/linuxthreads/Examples/ex5.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Examples/ex5.c 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,102 @@
-+/* The classic producer-consumer example, implemented with semaphores.
-+ All integers between 0 and 9999 should be printed exactly twice,
-+ once to the right of the arrow and once to the left. */
-+
-+#include <stdio.h>
-+#include "pthread.h"
-+#include "semaphore.h"
-+
-+#define BUFFER_SIZE 16
-+
-+/* Circular buffer of integers. */
-+
-+struct prodcons {
-+ int buffer[BUFFER_SIZE]; /* the actual data */
-+ int readpos, writepos; /* positions for reading and writing */
-+ sem_t sem_read; /* number of elements available for reading */
-+ sem_t sem_write; /* number of locations available for writing */
-+};
-+
-+/* Initialize a buffer */
-+
-+void init(struct prodcons * b)
-+{
-+ sem_init(&b->sem_write, 0, BUFFER_SIZE - 1);
-+ sem_init(&b->sem_read, 0, 0);
-+ b->readpos = 0;
-+ b->writepos = 0;
-+}
-+
-+/* Store an integer in the buffer */
-+
-+void put(struct prodcons * b, int data)
-+{
-+ /* Wait until buffer is not full */
-+ sem_wait(&b->sem_write);
-+ /* Write the data and advance write pointer */
-+ b->buffer[b->writepos] = data;
-+ b->writepos++;
-+ if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
-+ /* Signal that the buffer contains one more element for reading */
-+ sem_post(&b->sem_read);
-+}
-+
-+/* Read and remove an integer from the buffer */
-+
-+int get(struct prodcons * b)
-+{
-+ int data;
-+ /* Wait until buffer is not empty */
-+ sem_wait(&b->sem_read);
-+ /* Read the data and advance read pointer */
-+ data = b->buffer[b->readpos];
-+ b->readpos++;
-+ if (b->readpos >= BUFFER_SIZE) b->readpos = 0;
-+ /* Signal that the buffer has now one more location for writing */
-+ sem_post(&b->sem_write);
-+ return data;
-+}
-+
-+/* A test program: one thread inserts integers from 1 to 10000,
-+ the other reads them and prints them. */
-+
-+#define OVER (-1)
-+
-+struct prodcons buffer;
-+
-+void * producer(void * data)
-+{
-+ int n;
-+ for (n = 0; n < 10000; n++) {
-+ printf("%d --->\n", n);
-+ put(&buffer, n);
-+ }
-+ put(&buffer, OVER);
-+ return NULL;
-+}
-+
-+void * consumer(void * data)
-+{
-+ int d;
-+ while (1) {
-+ d = get(&buffer);
-+ if (d == OVER) break;
-+ printf("---> %d\n", d);
-+ }
-+ return NULL;
-+}
-+
-+int main(void)
-+{
-+ pthread_t th_a, th_b;
-+ void * retval;
-+
-+ init(&buffer);
-+ /* Create the threads */
-+ pthread_create(&th_a, NULL, producer, 0);
-+ pthread_create(&th_b, NULL, consumer, 0);
-+ /* Wait until producer and consumer finish. */
-+ pthread_join(th_a, &retval);
-+ pthread_join(th_b, &retval);
-+ return 0;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/Examples/ex6.c glibc-2.1.3/linuxthreads/Examples/ex6.c
---- ../glibc-2.1.3/linuxthreads/Examples/ex6.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Examples/ex6.c 1998-12-14 14:24:16.000000000 -0800
-@@ -0,0 +1,41 @@
-+#include <errno.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <pthread.h>
-+#include <unistd.h>
-+
-+void *
-+test_thread (void *v_param)
-+{
-+ return NULL;
-+}
-+
-+int
-+main (void)
-+{
-+ unsigned long count;
-+
-+ setvbuf (stdout, NULL, _IONBF, 0);
-+
-+ for (count = 0; count < 2000; ++count)
-+ {
-+ pthread_t thread;
-+ int status;
-+
-+ status = pthread_create (&thread, NULL, test_thread, NULL);
-+ if (status != 0)
-+ {
-+ printf ("status = %d, count = %lu: %s\n", status, count,
-+ strerror (errno));
-+ return 1;
-+ }
-+ else
-+ {
-+ printf ("count = %lu\n", count);
-+ }
-+ /* pthread_detach (thread); */
-+ pthread_join (thread, NULL);
-+ usleep (10);
-+ }
-+ return 0;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/FAQ.html glibc-2.1.3/linuxthreads/FAQ.html
---- ../glibc-2.1.3/linuxthreads/FAQ.html 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/FAQ.html 2000-02-01 14:11:26.000000000 -0800
-@@ -0,0 +1,1039 @@
-+<HTML>
-+<HEAD>
-+<TITLE>LinuxThreads Frequently Asked Questions</TITLE>
-+</HEAD>
-+<BODY>
-+<H1 ALIGN=center>LinuxThreads Frequently Asked Questions <BR>
-+ (with answers)</H1>
-+<H2 ALIGN=center>[For LinuxThreads version 0.8]</H2>
-+
-+<HR><P>
-+
-+<A HREF="#A">A. The big picture</A><BR>
-+<A HREF="#B">B. Getting more information</A><BR>
-+<A HREF="#C">C. Issues related to the C library</A><BR>
-+<A HREF="#D">D. Problems, weird behaviors, potential bugs</A><BR>
-+<A HREF="#E">E. Missing functions, wrong types, etc</A><BR>
-+<A HREF="#F">F. C++ issues</A><BR>
-+<A HREF="#G">G. Debugging LinuxThreads programs</A><BR>
-+<A HREF="#H">H. Compiling multithreaded code; errno madness</A><BR>
-+<A HREF="#I">I. X-Windows and other libraries</A><BR>
-+<A HREF="#J">J. Signals and threads</A><BR>
-+<A HREF="#K">K. Internals of LinuxThreads</A><P>
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="A">A. The big picture</A></H2>
-+
-+<H4><A NAME="A.1">A.1: What is LinuxThreads?</A></H4>
-+
-+LinuxThreads is a Linux library for multi-threaded programming.
-+It implements the Posix 1003.1c API (Application Programming
-+Interface) for threads. It runs on any Linux system with kernel 2.0.0
-+or more recent, and a suitable C library (see section <A HREF="C">C</A>).
-+<P>
-+
-+<H4><A NAME="A.2">A.2: What are threads?</A></H4>
-+
-+A thread is a sequential flow of control through a program.
-+Multi-threaded programming is, thus, a form of parallel programming
-+where several threads of control are executing concurrently in the
-+program. All threads execute in the same memory space, and can
-+therefore work concurrently on shared data.<P>
-+
-+Multi-threaded programming differs from Unix-style multi-processing in
-+that all threads share the same memory space (and a few other system
-+resources, such as file descriptors), instead of running in their own
-+memory space as is the case with Unix processes.<P>
-+
-+Threads are useful for two reasons. First, they allow a program to
-+exploit multi-processor machines: the threads can run in parallel on
-+several processors, allowing a single program to divide its work
-+between several processors, thus running faster than a single-threaded
-+program, which runs on only one processor at a time. Second, some
-+programs are best expressed as several threads of control that
-+communicate together, rather than as one big monolithic sequential
-+program. Examples include server programs, overlapping asynchronous
-+I/O, and graphical user interfaces.<P>
-+
-+<H4><A NAME="A.3">A.3: What is POSIX 1003.1c?</A></H4>
-+
-+It's an API for multi-threaded programming standardized by IEEE as
-+part of the POSIX standards. Most Unix vendors have endorsed the
-+POSIX 1003.1c standard. Implementations of the 1003.1c API are
-+already available under Sun Solaris 2.5, Digital Unix 4.0,
-+Silicon Graphics IRIX 6, and should soon be available from other
-+vendors such as IBM and HP. More generally, the 1003.1c API is
-+replacing relatively quickly the proprietary threads library that were
-+developed previously under Unix, such as Mach cthreads, Solaris
-+threads, and IRIX sprocs. Thus, multithreaded programs using the
-+1003.1c API are likely to run unchanged on a wide variety of Unix
-+platforms.<P>
-+
-+<H4><A NAME="A.4">A.4: What is the status of LinuxThreads?</A></H4>
-+
-+LinuxThreads implements almost all of Posix 1003.1c, as well as a few
-+extensions. The only part of LinuxThreads that does not conform yet
-+to Posix is signal handling (see section <A HREF="#J">J</A>). Apart
-+from the signal stuff, all the Posix 1003.1c base functionality,
-+as well as a number of optional extensions, are provided and conform
-+to the standard (to the best of my knowledge).
-+The signal stuff is hard to get right, at least without special kernel
-+support, and while I'm definitely looking at ways to implement the
-+Posix behavior for signals, this might take a long time before it's
-+completed.<P>
-+
-+<H4><A NAME="A.5">A.5: How stable is LinuxThreads?</A></H4>
-+
-+The basic functionality (thread creation and termination, mutexes,
-+conditions, semaphores) is very stable. Several industrial-strength
-+programs, such as the AOL multithreaded Web server, use LinuxThreads
-+and seem quite happy about it. There used to be some rough edges in
-+the LinuxThreads / C library interface with libc 5, but glibc 2
-+fixes all of those problems and is now the standard C library on major
-+Linux distributions (see section <A HREF="#C">C</A>). <P>
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="B">B. Getting more information</A></H2>
-+
-+<H4><A NAME="B.1">B.1: What are good books and other sources of
-+information on POSIX threads?</A></H4>
-+
-+The FAQ for comp.programming.threads lists several books:
-+<A HREF="http://www.serpentine.com/~bos/threads-faq/">http://www.serpentine.com/~bos/threads-faq/</A>.<P>
-+
-+There are also some online tutorials. Follow the links from the
-+LinuxThreads web page:
-+<A HREF="http://pauillac.inria.fr/~xleroy/linuxthreads">http://pauillac.inria.fr/~xleroy/linuxthreads</A>.<P>
-+
-+<H4><A NAME="B.2">B.2: I'd like to be informed of future developments on
-+LinuxThreads. Is there a mailing list for this purpose?</A></H4>
-+
-+I post LinuxThreads-related announcements on the newsgroup
-+<A HREF="news:comp.os.linux.announce">comp.os.linux.announce</A>,
-+and also on the mailing list
-+<code>linux-threads@magenet.com</code>.
-+You can subscribe to the latter by writing
-+<A HREF="mailto:majordomo@magenet.com">majordomo@magenet.com</A>.<P>
-+
-+<H4><A NAME="B.3">B.3: What are good places for discussing
-+LinuxThreads?</A></H4>
-+
-+For questions about programming with POSIX threads in general, use
-+the newsgroup
-+<A HREF="news:comp.programming.threads">comp.programming.threads</A>.
-+Be sure you read the
-+<A HREF="http://www.serpentine.com/~bos/threads-faq/">FAQ</A>
-+for this group before you post.<P>
-+
-+For Linux-specific questions, use
-+<A
-+HREF="news:comp.os.linux.development.apps">comp.os.linux.development.apps</A>
-+and <A
-+HREF="news:comp.os.linux.development.kernel">comp.os.linux.development.kernel</A>.
-+The latter is especially appropriate for questions relative to the
-+interface between the kernel and LinuxThreads.<P>
-+
-+<H4><A NAME="B.4">B.4: How should I report a possible bug in
-+LinuxThreads?</A></H4>
-+
-+If you're using glibc 2, the best way by far is to use the
-+<code>glibcbug</code> script to mail a bug report to the glibc
-+maintainers. <P>
-+
-+If you're using an older libc, or don't have the <code>glibcbug</code>
-+script on your machine, then e-mail me directly
-+(<code>Xavier.Leroy@inria.fr</code>). <P>
-+
-+In both cases, before sending the bug report, make sure that it is not
-+addressed already in this FAQ. Also, try to send a short program that
-+reproduces the weird behavior you observed. <P>
-+
-+<H4><A NAME="B.5">B.5: I'd like to read the POSIX 1003.1c standard. Is
-+it available online?</A></H4>
-+
-+Unfortunately, no. POSIX standards are copyrighted by IEEE, and
-+IEEE does not distribute them freely. You can buy paper copies from
-+IEEE, but the price is fairly high ($120 or so). If you disagree with
-+this policy and you're an IEEE member, be sure to let them know.<P>
-+
-+On the other hand, you probably don't want to read the standard. It's
-+very hard to read, written in standard-ese, and targeted to
-+implementors who already know threads inside-out. A good book on
-+POSIX threads provides the same information in a much more readable form.
-+I can personally recommend Dave Butenhof's book, <CITE>Programming
-+with POSIX threads</CITE> (Addison-Wesley). Butenhof was part of the
-+POSIX committee and also designed the Digital Unix implementations of
-+POSIX threads, and it shows.<P>
-+
-+Another good source of information is the X/Open Group Single Unix
-+specification which is available both
-+<A HREF="http://www.rdg.opengroup.org/onlinepubs/7908799/index.html">on-line</A>
-+and as a
-+<A HREF="http://www.UNIX-systems.org/gosolo2/">book and CD/ROM</A>.
-+That specification includes pretty much all the POSIX standards,
-+including 1003.1c, with some extensions and clarifications.<P>
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="C">C. Issues related to the C library</A></H2>
-+
-+<H4><A NAME="C.1">C.1: Which version of the C library should I use
-+with LinuxThreads?</A></H4>
-+
-+The best choice by far is glibc 2, a.k.a. libc 6. It offers very good
-+support for multi-threading, and LinuxThreads has been closely
-+integrated with glibc 2. The glibc 2 distribution contains the
-+sources of a specially adapted version of LinuxThreads.<P>
-+
-+glibc 2 comes preinstalled as the default C library on several Linux
-+distributions, such as RedHat 5 and up, and Debian 2.
-+Those distributions include the version of LinuxThreads matching
-+glibc 2.<P>
-+
-+<H4><A NAME="C.2">C.2: My system has libc 5 preinstalled, not glibc
-+2. Can I still use LinuxThreads?</H4>
-+
-+Yes, but you're likely to run into some problems, as libc 5 only
-+offers minimal support for threads and contains some bugs that affect
-+multithreaded programs. <P>
-+
-+The versions of libc 5 that work best with LinuxThreads are
-+libc 5.2.18 on the one hand, and libc 5.4.12 or later on the other hand.
-+Avoid 5.3.12 and 5.4.7: these have problems with the per-thread errno
-+variable. <P>
-+
-+<H4><A NAME="C.3">C.3: So, should I switch to glibc 2, or stay with a
-+recent libc 5?</A></H4>
-+
-+I'd recommend you switch to glibc 2. Even for single-threaded
-+programs, glibc 2 is more solid and more standard-conformant than libc
-+5. And the shortcomings of libc 5 almost preclude any serious
-+multi-threaded programming.<P>
-+
-+Switching an already installed
-+system from libc 5 to glibc 2 is not completely straightforward.
-+See the <A HREF="http://sunsite.unc.edu/LDP/HOWTO/Glibc2-HOWTO.html">Glibc2
-+HOWTO</A> for more information. Much easier is (re-)installing a
-+Linux distribution based on glibc 2, such as RedHat 6.<P>
-+
-+<H4><A NAME="C.4">C.4: Where can I find glibc 2 and the version of
-+LinuxThreads that goes with it?</A></H4>
-+
-+On <code>prep.ai.mit.edu</code> and its many, many mirrors around the world.
-+See <A
-+HREF="http://www.gnu.org/order/ftp.html">http://www.gnu.org/order/ftp.html</A>
-+for a list of mirrors.<P>
-+
-+<H4><A NAME="C.5">C.5: Where can I find libc 5 and the version of
-+LinuxThreads that goes with it?</A></H4>
-+
-+For libc 5, see <A HREF="ftp://sunsite.unc.edu/pub/Linux/devel/GCC/"><code>ftp://sunsite.unc.edu/pub/Linux/devel/GCC/</code></A>.<P>
-+
-+For the libc 5 version of LinuxThreads, see
-+<A HREF="ftp://ftp.inria.fr/INRIA/Projects/cristal/Xavier.Leroy/linuxthreads/">ftp://ftp.inria.fr/INRIA/Projects/cristal/Xavier.Leroy/linuxthreads/</A>.<P>
-+
-+<H4><A NAME="C.6">C.6: How can I recompile the glibc 2 version of the
-+LinuxThreads sources?</A></H4>
-+
-+You must transfer the whole glibc sources, then drop the LinuxThreads
-+sources in the <code>linuxthreads/</code> subdirectory, then recompile
-+glibc as a whole. There are now too many inter-dependencies between
-+LinuxThreads and glibc 2 to allow separate re-compilation of LinuxThreads.
-+<P>
-+
-+<H4><A NAME="C.7">C.7: What is the correspondence between LinuxThreads
-+version numbers, libc version numbers, and RedHat version
-+numbers?</A></H4>
-+
-+Here is a summary. (Information on Linux distributions other than
-+RedHat are welcome.)<P>
-+
-+<TABLE>
-+<TR><TD>LinuxThreads </TD> <TD>C library</TD> <TD>RedHat</TD></TR>
-+<TR><TD>0.7, 0.71 (for libc 5)</TD> <TD>libc 5.x</TD> <TD>RH 4.2</TD></TR>
-+<TR><TD>0.7, 0.71 (for glibc 2)</TD> <TD>glibc 2.0.x</TD> <TD>RH 5.x</TD></TR>
-+<TR><TD>0.8</TD> <TD>glibc 2.1.1</TD> <TD>RH 6.0</TD></TR>
-+<TR><TD>0.8</TD> <TD>glibc 2.1.2</TD> <TD>not yet released</TD></TR>
-+</TABLE>
-+<P>
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="D">D. Problems, weird behaviors, potential bugs</A></H2>
-+
-+<H4><A NAME="D.1">D.1: When I compile LinuxThreads, I run into problems in
-+file <code>libc_r/dirent.c</code></A></H4>
-+
-+You probably mean:
-+<PRE>
-+ libc_r/dirent.c:94: structure has no member named `dd_lock'
-+</PRE>
-+I haven't actually seen this problem, but several users reported it.
-+My understanding is that something is wrong in the include files of
-+your Linux installation (<code>/usr/include/*</code>). Make sure
-+you're using a supported version of the libc 5 library. (See question <A
-+HREF="#C.2">C.2</A>).<P>
-+
-+<H4><A NAME="D.2">D.2: When I compile LinuxThreads, I run into problems with
-+<CODE>/usr/include/sched.h</CODE>: there are several occurrences of
-+<CODE>_p</CODE> that the C compiler does not understand</A></H4>
-+
-+Yes, <CODE>/usr/include/sched.h</CODE> that comes with libc 5.3.12 is broken.
-+Replace it with the <code>sched.h</code> file contained in the
-+LinuxThreads distribution. But really you should not be using libc
-+5.3.12 with LinuxThreads! (See question <A HREF="#C.2">C.1</A>.)<P>
-+
-+<H4><A NAME="D.3">D.3: My program does <CODE>fdopen()</CODE> on a file
-+descriptor opened on a pipe. When I link it with LinuxThreads,
-+<CODE>fdopen()</CODE> always returns NULL!</A></H4>
-+
-+You're using one of the buggy versions of libc (5.3.12, 5.4.7., etc).
-+See question <A HREF="#C.1">C.1</A> above.<P>
-+
-+<H4><A NAME="D.4">D.4: My program creates a lot of threads, and after
-+a while <CODE>pthread_create()</CODE> no longer returns!</A></H4>
-+
-+This is known bug in the version of LinuxThreads that comes with glibc
-+2.1.1. An upgrade to 2.1.2 is recommended. <P>
-+
-+<H4><A NAME="D.5">D.5: When I'm running a program that creates N
-+threads, <code>top</code> or <code>ps</code>
-+display N+2 processes that are running my program. What do all these
-+processes correspond to?</A></H4>
-+
-+Due to the general "one process per thread" model, there's one process
-+for the initial thread and N processes for the threads it created
-+using <CODE>pthread_create</CODE>. That leaves one process
-+unaccounted for. That extra process corresponds to the "thread
-+manager" thread, a thread created internally by LinuxThreads to handle
-+thread creation and thread termination. This extra thread is asleep
-+most of the time.
-+
-+<H4><A NAME="D.6">D.6: Scheduling seems to be very unfair when there
-+is strong contention on a mutex: instead of giving the mutex to each
-+thread in turn, it seems that it's almost always the same thread that
-+gets the mutex. Isn't this completely broken behavior?</A></H4>
-+
-+That behavior has mostly disappeared in recent releases of
-+LinuxThreads (version 0.8 and up). It was fairly common in older
-+releases, though.
-+
-+What happens in LinuxThreads 0.7 and before is the following: when a
-+thread unlocks a mutex, all other threads that were waiting on the
-+mutex are sent a signal which makes them runnable. However, the
-+kernel scheduler may or may not restart them immediately. If the
-+thread that unlocked the mutex tries to lock it again immediately
-+afterwards, it is likely that it will succeed, because the threads
-+haven't yet restarted. This results in an apparently very unfair
-+behavior, when the same thread repeatedly locks and unlocks the mutex,
-+while other threads can't lock the mutex.<P>
-+
-+In LinuxThreads 0.8 and up, <code>pthread_unlock</code> restarts only
-+one waiting thread, and pre-assign the mutex to that thread. Hence,
-+if the thread that unlocked the mutex tries to lock it again
-+immediately, it will block until other waiting threads have had a
-+chance to lock and unlock the mutex. This results in much fairer
-+scheduling.<P>
-+
-+Notice however that even the old "unfair" behavior is perfectly
-+acceptable with respect to the POSIX standard: for the default
-+scheduling policy, POSIX makes no guarantees of fairness, such as "the
-+thread waiting for the mutex for the longest time always acquires it
-+first". Properly written multithreaded code avoids that kind of heavy
-+contention on mutexes, and does not run into fairness problems. If
-+you need scheduling guarantees, you should consider using the
-+real-time scheduling policies <code>SCHED_RR</code> and
-+<code>SCHED_FIFO</code>, which have precisely defined scheduling
-+behaviors. <P>
-+
-+<H4><A NAME="D.7">D.7: I have a simple test program with two threads
-+that do nothing but <CODE>printf()</CODE> in tight loops, and from the
-+printout it seems that only one thread is running, the other doesn't
-+print anything!</A></H4>
-+
-+Again, this behavior is characteristic of old releases of LinuxThreads
-+(0.7 and before); more recent versions (0.8 and up) should not exhibit
-+this behavior.<P>
-+
-+The reason for this behavior is explained in
-+question <A HREF="#D.6">D.6</A> above: <CODE>printf()</CODE> performs
-+locking on <CODE>stdout</CODE>, and thus your two threads contend very
-+heavily for the mutex associated with <CODE>stdout</CODE>. But if you
-+do some real work between two calls to <CODE>printf()</CODE>, you'll
-+see that scheduling becomes much smoother.<P>
-+
-+<H4><A NAME="D.8">D.8: I've looked at <code>&lt;pthread.h&gt;</code>
-+and there seems to be a gross error in the <code>pthread_cleanup_push</code>
-+macro: it opens a block with <code>{</code> but does not close it!
-+Surely you forgot a <code>}</code> at the end of the macro, right?
-+</A></H4>
-+
-+Nope. That's the way it should be. The closing brace is provided by
-+the <code>pthread_cleanup_pop</code> macro. The POSIX standard
-+requires <code>pthread_cleanup_push</code> and
-+<code>pthread_cleanup_pop</code> to be used in matching pairs, at the
-+same level of brace nesting. This allows
-+<code>pthread_cleanup_push</code> to open a block in order to
-+stack-allocate some data structure, and
-+<code>pthread_cleanup_pop</code> to close that block. It's ugly, but
-+it's the standard way of implementing cleanup handlers.<P>
-+
-+<H4><A NAME="D.9">D.9: I tried to use real-time threads and my program
-+loops like crazy and freezes the whole machine!</A></H4>
-+
-+Versions of LinuxThreads prior to 0.8 are susceptible to ``livelocks''
-+(one thread loops, consuming 100% of the CPU time) in conjunction with
-+real-time scheduling. Since real-time threads and processes have
-+higher priority than normal Linux processes, all other processes on
-+the machine, including the shell, the X server, etc, cannot run and
-+the machine appears frozen.<P>
-+
-+The problem is fixed in LinuxThreads 0.8.<P>
-+
-+<H4><A NAME="D.10">D.10: My application needs to create thousands of
-+threads, or maybe even more. Can I do this with
-+LinuxThreads?</A></H4>
-+
-+No. You're going to run into several hard limits:
-+<UL>
-+<LI>Each thread, from the kernel's standpoint, is one process. Stock
-+Linux kernels are limited to at most 512 processes for the super-user,
-+and half this number for regular users. This can be changed by
-+changing <code>NR_TASKS</code> in <code>include/linux/tasks.h</code>
-+and recompiling the kernel. On the x86 processors at least,
-+architectural constraints seem to limit <code>NR_TASKS</code> to 4090
-+at most.
-+<LI>LinuxThreads contains a table of all active threads. This table
-+has room for 1024 threads at most. To increase this limit, you must
-+change <code>PTHREAD_THREADS_MAX</code> in the LinuxThreads sources
-+and recompile.
-+<LI>By default, each thread reserves 2M of virtual memory space for
-+its stack. This space is just reserved; actual memory is allocated
-+for the stack on demand. But still, on a 32-bit processor, the total
-+virtual memory space available for the stacks is on the order of 1G,
-+meaning that more than 500 threads will have a hard time fitting in.
-+You can overcome this limitation by moving to a 64-bit platform, or by
-+allocating smaller stacks yourself using the <code>setstackaddr</code>
-+attribute.
-+<LI>Finally, the Linux kernel contains many algorithms that run in
-+time proportional to the number of process table entries. Increasing
-+this number drastically will slow down the kernel operations
-+noticeably.
-+</UL>
-+(Other POSIX threads libraries have similar limitations, by the way.)
-+For all those reasons, you'd better restructure your application so
-+that it doesn't need more than, say, 100 threads. For instance,
-+in the case of a multithreaded server, instead of creating a new
-+thread for each connection, maintain a fixed-size pool of worker
-+threads that pick incoming connection requests from a queue.<P>
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="E">E. Missing functions, wrong types, etc</A></H2>
-+
-+<H4><A NAME="E.1">E.1: Where is <CODE>pthread_yield()</CODE> ? How
-+comes LinuxThreads does not implement it?</A></H4>
-+
-+Because it's not part of the (final) POSIX 1003.1c standard.
-+Several drafts of the standard contained <CODE>pthread_yield()</CODE>,
-+but then the POSIX guys discovered it was redundant with
-+<CODE>sched_yield()</CODE> and dropped it. So, just use
-+<CODE>sched_yield()</CODE> instead.
-+
-+<H4><A NAME="E.2">E.2: I've found some type errors in
-+<code>&lt;pthread.h&gt;</code>.
-+For instance, the second argument to <CODE>pthread_create()</CODE>
-+should be a <CODE>pthread_attr_t</CODE>, not a
-+<CODE>pthread_attr_t *</CODE>. Also, didn't you forget to declare
-+<CODE>pthread_attr_default</CODE>?</A></H4>
-+
-+No, I didn't. What you're describing is draft 4 of the POSIX
-+standard, which is used in OSF DCE threads. LinuxThreads conforms to the
-+final standard. Even though the functions have the same names as in
-+draft 4 and DCE, their calling conventions are slightly different. In
-+particular, attributes are passed by reference, not by value, and
-+default attributes are denoted by the NULL pointer. Since draft 4/DCE
-+will eventually disappear, you'd better port your program to use the
-+standard interface.<P>
-+
-+<H4><A NAME="E.3">E.3: I'm porting an application from Solaris and I
-+have to rename all thread functions from <code>thr_blah</code> to
-+<CODE>pthread_blah</CODE>. This is very annoying. Why did you change
-+all the function names?</A></H4>
-+
-+POSIX did it. The <code>thr_*</code> functions correspond to Solaris
-+threads, an older thread interface that you'll find only under
-+Solaris. The <CODE>pthread_*</CODE> functions correspond to POSIX
-+threads, an international standard available for many, many platforms.
-+Even Solaris 2.5 and later support the POSIX threads interface. So,
-+do yourself a favor and rewrite your code to use POSIX threads: this
-+way, it will run unchanged under Linux, Solaris, and quite a lot of
-+other platforms.<P>
-+
-+<H4><A NAME="E.4">E.4: How can I suspend and resume a thread from
-+another thread? Solaris has the <CODE>thr_suspend()</CODE> and
-+<CODE>thr_resume()</CODE> functions to do that; why don't you?</A></H4>
-+
-+The POSIX standard provides <B>no</B> mechanism by which a thread A can
-+suspend the execution of another thread B, without cooperation from B.
-+The only way to implement a suspend/restart mechanism is to have B
-+check periodically some global variable for a suspend request
-+and then suspend itself on a condition variable, which another thread
-+can signal later to restart B.<P>
-+
-+Notice that <CODE>thr_suspend()</CODE> is inherently dangerous and
-+prone to race conditions. For one thing, there is no control on where
-+the target thread stops: it can very well be stopped in the middle of
-+a critical section, while holding mutexes. Also, there is no
-+guarantee on when the target thread will actually stop. For these
-+reasons, you'd be much better off using mutexes and conditions
-+instead. The only situations that really require the ability to
-+suspend a thread are debuggers and some kind of garbage collectors.<P>
-+
-+If you really must suspend a thread in LinuxThreads, you can send it a
-+<CODE>SIGSTOP</CODE> signal with <CODE>pthread_kill</CODE>. Send
-+<CODE>SIGCONT</CODE> for restarting it.
-+Beware, this is specific to LinuxThreads and entirely non-portable.
-+Indeed, a truly conforming POSIX threads implementation will stop all
-+threads when one thread receives the <CODE>SIGSTOP</CODE> signal!
-+One day, LinuxThreads will implement that behavior, and the
-+non-portable hack with <CODE>SIGSTOP</CODE> won't work anymore.<P>
-+
-+<H4><A NAME="E.5">E.5: Does LinuxThreads implement
-+<CODE>pthread_attr_setstacksize()</CODE> and
-+<CODE>pthread_attr_setstackaddr()</CODE>?</A></H4>
-+
-+These optional functions are provided in recent versions of
-+LinuxThreads (0.8 and up). Earlier releases did not provide these
-+optional components of the POSIX standard.<P>
-+
-+Even if <CODE>pthread_attr_setstacksize()</CODE> and
-+<CODE>pthread_attr_setstackaddr()</CODE> are now provided, we still
-+recommend that you do not use them unless you really have strong
-+reasons for doing so. The default stack allocation strategy for
-+LinuxThreads is nearly optimal: stacks start small (4k) and
-+automatically grow on demand to a fairly large limit (2M).
-+Moreover, there is no portable way to estimate the stack requirements
-+of a thread, so setting the stack size yourself makes your program
-+less reliable and non-portable.<P>
-+
-+<H4><A NAME="E.6">E.6: LinuxThreads does not support the
-+<CODE>PTHREAD_SCOPE_PROCESS</CODE> value of the "contentionscope"
-+attribute. Why? </A></H4>
-+
-+With a "one-to-one" model, as in LinuxThreads (one kernel execution
-+context per thread), there is only one scheduler for all processes and
-+all threads on the system. So, there is no way to obtain the behavior of
-+<CODE>PTHREAD_SCOPE_PROCESS</CODE>.
-+
-+<H4><A NAME="E.7">E.7: LinuxThreads does not implement process-shared
-+mutexes, conditions, and semaphores. Why?</A></H4>
-+
-+This is another optional component of the POSIX standard. Portable
-+applications should test <CODE>_POSIX_THREAD_PROCESS_SHARED</CODE>
-+before using this facility.
-+<P>
-+The goal of this extension is to allow different processes (with
-+different address spaces) to synchronize through mutexes, conditions
-+or semaphores allocated in shared memory (either SVR4 shared memory
-+segments or <CODE>mmap()</CODE>ed files).
-+<P>
-+The reason why this does not work in LinuxThreads is that mutexes,
-+conditions, and semaphores are not self-contained: their waiting
-+queues contain pointers to linked lists of thread descriptors, and
-+these pointers are meaningful only in one address space.
-+<P>
-+Matt Messier and I spent a significant amount of time trying to design a
-+suitable mechanism for sharing waiting queues between processes. We
-+came up with several solutions that combined two of the following
-+three desirable features, but none that combines all three:
-+<UL>
-+<LI>allow sharing between processes having different UIDs
-+<LI>supports cancellation
-+<LI>supports <CODE>pthread_cond_timedwait</CODE>
-+</UL>
-+We concluded that kernel support is required to share mutexes,
-+conditions and semaphores between processes. That's one place where
-+Linus Torvalds's intuition that "all we need in the kernel is
-+<CODE>clone()</CODE>" fails.
-+<P>
-+Until suitable kernel support is available, you'd better use
-+traditional interprocess communications to synchronize different
-+processes: System V semaphores and message queues, or pipes, or sockets.
-+<P>
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="F">F. C++ issues</A></H2>
-+
-+<H4><A NAME="F.1">F.1: Are there C++ wrappers for LinuxThreads?</A></H4>
-+
-+Douglas Schmidt's ACE library contains, among a lot of other
-+things, C++ wrappers for LinuxThreads and quite a number of other
-+thread libraries. Check out
-+<A HREF="http://www.cs.wustl.edu/~schmidt/ACE.html">http://www.cs.wustl.edu/~schmidt/ACE.html</A><P>
-+
-+<H4><A NAME="F.2">F.2: I'm trying to use LinuxThreads from a C++
-+program, and the compiler complains about the third argument to
-+<CODE>pthread_create()</CODE> !</A></H4>
-+
-+You're probably trying to pass a class member function or some
-+other C++ thing as third argument to <CODE>pthread_create()</CODE>.
-+Recall that <CODE>pthread_create()</CODE> is a C function, and it must
-+be passed a C function as third argument.<P>
-+
-+<H4><A NAME="F.3">F.3: I'm trying to use LinuxThreads in conjunction
-+with libg++, and I'm having all sorts of trouble.</A></H4>
-+
-+>From what I understand, thread support in libg++ is completely broken,
-+especially with respect to locking of iostreams. H.J.Lu wrote:
-+<BLOCKQUOTE>
-+If you want to use thread, I can only suggest egcs and glibc. You
-+can find egcs at
-+<A HREF="http://www.cygnus.com/egcs">http://www.cygnus.com/egcs</A>.
-+egcs has libsdtc++, which is MT safe under glibc 2. If you really
-+want to use the libg++, I have a libg++ add-on for egcs.
-+</BLOCKQUOTE>
-+<HR>
-+<P>
-+
-+<H2><A NAME="G">G. Debugging LinuxThreads programs</A></H2>
-+
-+<H4><A NAME="G.1">G.1: Can I debug LinuxThreads program using gdb?</A></H4>
-+
-+Yes, but not with the stock gdb 4.17. You need a specially patched
-+version of gdb 4.17 developed by Eric Paire and colleages at The Open
-+Group, Grenoble. The patches against gdb 4.17 are available at
-+<A HREF="http://www.gr.opengroup.org/java/jdk/linux/debug.htm"><code>http://www.gr.opengroup.org/java/jdk/linux/debug.htm</code></A>.
-+Precompiled binaries of the patched gdb are available in RedHat's RPM
-+format at <A
-+HREF="http://odin.appliedtheory.com/"><code>http://odin.appliedtheory.com/</code></A>.<P>
-+
-+Some Linux distributions provide an already-patched version of gdb;
-+others don't. For instance, the gdb in RedHat 5.2 is thread-aware,
-+but apparently not the one in RedHat 6.0. Just ask (politely) the
-+makers of your Linux distributions to please make sure that they apply
-+the correct patches to gdb.<P>
-+
-+<H4><A NAME="G.2">G.2: Does it work with post-mortem debugging?</A></H4>
-+
-+Not very well. Generally, the core file does not correspond to the
-+thread that crashed. The reason is that the kernel will not dump core
-+for a process that shares its memory with other processes, such as the
-+other threads of your program. So, the thread that crashes silently
-+disappears without generating a core file. Then, all other threads of
-+your program die on the same signal that killed the crashing thread.
-+(This is required behavior according to the POSIX standard.) The last
-+one that dies is no longer sharing its memory with anyone else, so the
-+kernel generates a core file for that thread. Unfortunately, that's
-+not the thread you are interested in.
-+
-+<H4><A NAME="G.3">G.3: Any other ways to debug multithreaded programs, then?</A></H4>
-+
-+Assertions and <CODE>printf()</CODE> are your best friends. Try to debug
-+sequential parts in a single-threaded program first. Then, put
-+<CODE>printf()</CODE> statements all over the place to get execution traces.
-+Also, check invariants often with the <CODE>assert()</CODE> macro. In truth,
-+there is no other effective way (save for a full formal proof of your
-+program) to track down concurrency bugs. Debuggers are not really
-+effective for subtle concurrency problems, because they disrupt
-+program execution too much.<P>
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="H">H. Compiling multithreaded code; errno madness</A></H2>
-+
-+<H4><A NAME="H.1">H.1: You say all multithreaded code must be compiled
-+with <CODE>_REENTRANT</CODE> defined. What difference does it make?</A></H4>
-+
-+It affects include files in three ways:
-+<UL>
-+<LI> The include files define prototypes for the reentrant variants of
-+some of the standard library functions,
-+e.g. <CODE>gethostbyname_r()</CODE> as a reentrant equivalent to
-+<CODE>gethostbyname()</CODE>.<P>
-+
-+<LI> If <CODE>_REENTRANT</CODE> is defined, some
-+<code>&lt;stdio.h&gt;</code> functions are no longer defined as macros,
-+e.g. <CODE>getc()</CODE> and <CODE>putc()</CODE>. In a multithreaded
-+program, stdio functions require additional locking, which the macros
-+don't perform, so we must call functions instead.<P>
-+
-+<LI> More importantly, <code>&lt;errno.h&gt;</code> redefines errno when
-+<CODE>_REENTRANT</CODE> is
-+defined, so that errno refers to the thread-specific errno location
-+rather than the global errno variable. This is achieved by the
-+following <code>#define</code> in <code>&lt;errno.h&gt;</code>:
-+<PRE>
-+ #define errno (*(__errno_location()))
-+</PRE>
-+which causes each reference to errno to call the
-+<CODE>__errno_location()</CODE> function for obtaining the location
-+where error codes are stored. libc provides a default definition of
-+<CODE>__errno_location()</CODE> that always returns
-+<code>&errno</code> (the address of the global errno variable). Thus,
-+for programs not linked with LinuxThreads, defining
-+<CODE>_REENTRANT</CODE> makes no difference w.r.t. errno processing.
-+But LinuxThreads redefines <CODE>__errno_location()</CODE> to return a
-+location in the thread descriptor reserved for holding the current
-+value of errno for the calling thread. Thus, each thread operates on
-+a different errno location.
-+</UL>
-+<P>
-+
-+<H4><A NAME="H.2">H.2: Why is it so important that each thread has its
-+own errno variable? </A></H4>
-+
-+If all threads were to store error codes in the same, global errno
-+variable, then the value of errno after a system call or library
-+function returns would be unpredictable: between the time a system
-+call stores its error code in the global errno and your code inspects
-+errno to see which error occurred, another thread might have stored
-+another error code in the same errno location. <P>
-+
-+<H4><A NAME="H.3">H.3: What happens if I link LinuxThreads with code
-+not compiled with <CODE>-D_REENTRANT</CODE>?</A></H4>
-+
-+Lots of trouble. If the code uses <CODE>getc()</CODE> or
-+<CODE>putc()</CODE>, it will perform I/O without proper interlocking
-+of the stdio buffers; this can cause lost output, duplicate output, or
-+just crash other stdio functions. If the code consults errno, it will
-+get back the wrong error code. The following code fragment is a
-+typical example:
-+<PRE>
-+ do {
-+ r = read(fd, buf, n);
-+ if (r == -1) {
-+ if (errno == EINTR) /* an error we can handle */
-+ continue;
-+ else { /* other errors are fatal */
-+ perror("read failed");
-+ exit(100);
-+ }
-+ }
-+ } while (...);
-+</PRE>
-+Assume this code is not compiled with <CODE>-D_REENTRANT</CODE>, and
-+linked with LinuxThreads. At run-time, <CODE>read()</CODE> is
-+interrupted. Since the C library was compiled with
-+<CODE>-D_REENTRANT</CODE>, <CODE>read()</CODE> stores its error code
-+in the location pointed to by <CODE>__errno_location()</CODE>, which
-+is the thread-local errno variable. Then, the code above sees that
-+<CODE>read()</CODE> returns -1 and looks up errno. Since
-+<CODE>_REENTRANT</CODE> is not defined, the reference to errno
-+accesses the global errno variable, which is most likely 0. Hence the
-+code concludes that it cannot handle the error and stops.<P>
-+
-+<H4><A NAME="H.4">H.4: With LinuxThreads, I can no longer use the signals
-+<code>SIGUSR1</code> and <code>SIGUSR2</code> in my programs! Why? </A></H4>
-+
-+The short answer is: because the Linux kernel you're using does not
-+support realtime signals. <P>
-+
-+LinuxThreads needs two signals for its internal operation.
-+One is used to suspend and restart threads blocked on mutex, condition
-+or semaphore operations. The other is used for thread
-+cancellation.<P>
-+
-+On ``old'' kernels (2.0 and early 2.1 kernels), there are only 32
-+signals available and the kernel reserves all of them but two:
-+<code>SIGUSR1</code> and <code>SIGUSR2</code>. So, LinuxThreads has
-+no choice but use those two signals.<P>
-+
-+On recent kernels (2.2 and up), more than 32 signals are provided in
-+the form of realtime signals. When run on one of those kernels,
-+LinuxThreads uses two reserved realtime signals for its internal
-+operation, thus leaving <code>SIGUSR1</code> and <code>SIGUSR2</code>
-+free for user code. (This works only with glibc, not with libc 5.) <P>
-+
-+<H4><A NAME="H.5">H.5: Is the stack of one thread visible from the
-+other threads? Can I pass a pointer into my stack to other threads?
-+</A></H4>
-+
-+Yes, you can -- if you're very careful. The stacks are indeed visible
-+from all threads in the system. Some non-POSIX thread libraries seem
-+to map the stacks for all threads at the same virtual addresses and
-+change the memory mapping when they switch from one thread to
-+another. But this is not the case for LinuxThreads, as it would make
-+context switching between threads more expensive, and at any rate
-+might not conform to the POSIX standard.<P>
-+
-+So, you can take the address of an "auto" variable and pass it to
-+other threads via shared data structures. However, you need to make
-+absolutely sure that the function doing this will not return as long
-+as other threads need to access this address. It's the usual mistake
-+of returning the address of an "auto" variable, only made much worse
-+because of concurrency. It's much, much safer to systematically
-+heap-allocate all shared data structures. <P>
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="I">I. X-Windows and other libraries</A></H2>
-+
-+<H4><A NAME="I.1">I.1: My program uses both Xlib and LinuxThreads.
-+It stops very early with an "Xlib: unknown 0 error" message. What
-+does this mean? </A></H4>
-+
-+That's a prime example of the errno problem described in question <A
-+HREF="#H.2">H.2</A>. The binaries for Xlib you're using have not been
-+compiled with <CODE>-D_REENTRANT</CODE>. It happens Xlib contains a
-+piece of code very much like the one in question <A
-+HREF="#H.2">H.2</A>. So, your Xlib fetches the error code from the
-+wrong errno location and concludes that an error it cannot handle
-+occurred.<P>
-+
-+<H4><A NAME="I.2">I.2: So, what can I do to build a multithreaded X
-+Windows client? </A></H4>
-+
-+The best solution is to use X libraries that have been compiled with
-+multithreading options set. Linux distributions that come with glibc
-+2 as the main C library generally provide thread-safe X libraries.
-+At least, that seems to be the case for RedHat 5 and later.<P>
-+
-+You can try to recompile yourself the X libraries with multithreading
-+options set. They contain optional support for multithreading; it's
-+just that the binaries provided by your Linux distribution were built
-+without this support. See the file <code>README.Xfree3.3</code> in
-+the LinuxThreads distribution for patches and info on how to compile
-+thread-safe X libraries from the Xfree3.3 distribution. The Xfree3.3
-+sources are readily available in most Linux distributions, e.g. as a
-+source RPM for RedHat. Be warned, however, that X Windows is a huge
-+system, and recompiling even just the libraries takes a lot of time
-+and disk space.<P>
-+
-+Another, less involving solution is to call X functions only from the
-+main thread of your program. Even if all threads have their own errno
-+location, the main thread uses the global errno variable for its errno
-+location. Thus, code not compiled with <code>-D_REENTRANT</code>
-+still "sees" the right error values if it executes in the main thread
-+only. <P>
-+
-+<H4><A NAME="I.2">This is a lot of work. Don't you have precompiled
-+thread-safe X libraries that you could distribute?</A></H4>
-+
-+No, I don't. Sorry. But consider installing a Linux distribution
-+that comes with thread-safe X libraries, such as RedHat 6.<P>
-+
-+<H4><A NAME="I.3">I.3: Can I use library FOO in a multithreaded
-+program?</A></H4>
-+
-+Most libraries cannot be used "as is" in a multithreaded program.
-+For one thing, they are not necessarily thread-safe: calling
-+simultaneously two functions of the library from two threads might not
-+work, due to internal use of global variables and the like. Second,
-+the libraries must have been compiled with <CODE>-D_REENTRANT</CODE> to avoid
-+the errno problems explained in question <A HREF="#H.2">H.2</A>.
-+<P>
-+
-+<H4><A NAME="I.4">I.4: What if I make sure that only one thread calls
-+functions in these libraries?</A></H4>
-+
-+This avoids problems with the library not being thread-safe. But
-+you're still vulnerable to errno problems. At the very least, a
-+recompile of the library with <CODE>-D_REENTRANT</CODE> is needed.
-+<P>
-+
-+<H4><A NAME="I.5">I.5: What if I make sure that only the main thread
-+calls functions in these libraries?</A></H4>
-+
-+That might actually work. As explained in question <A HREF="#I.1">I.1</A>,
-+the main thread uses the global errno variable, and can therefore
-+execute code not compiled with <CODE>-D_REENTRANT</CODE>.<P>
-+
-+<H4><A NAME="I.6">I.6: SVGAlib doesn't work with LinuxThreads. Why?
-+</A></H4>
-+
-+Because both LinuxThreads and SVGAlib use the signals
-+<code>SIGUSR1</code> and <code>SIGUSR2</code>. See question <A
-+HREF="#H.4">H.4</A>.
-+<P>
-+
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="J">J. Signals and threads</A></H2>
-+
-+<H4><A NAME="J.1">J.1: When it comes to signals, what is shared
-+between threads and what isn't?</A></H4>
-+
-+Signal handlers are shared between all threads: when a thread calls
-+<CODE>sigaction()</CODE>, it sets how the signal is handled not only
-+for itself, but for all other threads in the program as well.<P>
-+
-+On the other hand, signal masks are per-thread: each thread chooses
-+which signals it blocks independently of others. At thread creation
-+time, the newly created thread inherits the signal mask of the thread
-+calling <CODE>pthread_create()</CODE>. But afterwards, the new thread
-+can modify its signal mask independently of its creator thread.<P>
-+
-+<H4><A NAME="J.2">J.2: When I send a <CODE>SIGKILL</CODE> to a
-+particular thread using <CODE>pthread_kill</CODE>, all my threads are
-+killed!</A></H4>
-+
-+That's how it should be. The POSIX standard mandates that all threads
-+should terminate when the process (i.e. the collection of all threads
-+running the program) receives a signal whose effect is to
-+terminate the process (such as <CODE>SIGKILL</CODE> or <CODE>SIGINT</CODE>
-+when no handler is installed on that signal). This behavior makes a
-+lot of sense: when you type "ctrl-C" at the keyboard, or when a thread
-+crashes on a division by zero or a segmentation fault, you really want
-+all threads to stop immediately, not just the one that caused the
-+segmentation violation or that got the <CODE>SIGINT</CODE> signal.
-+(This assumes default behavior for those signals; see question
-+<A HREF="#J.3">J.3</A> if you install handlers for those signals.)<P>
-+
-+If you're trying to terminate a thread without bringing the whole
-+process down, use <code>pthread_cancel()</code>.<P>
-+
-+<H4><A NAME="J.3">J.3: I've installed a handler on a signal. Which
-+thread executes the handler when the signal is received?</A></H4>
-+
-+If the signal is generated by a thread during its execution (e.g. a
-+thread executes a division by zero and thus generates a
-+<CODE>SIGFPE</CODE> signal), then the handler is executed by that
-+thread. This also applies to signals generated by
-+<CODE>raise()</CODE>.<P>
-+
-+If the signal is sent to a particular thread using
-+<CODE>pthread_kill()</CODE>, then that thread executes the handler.<P>
-+
-+If the signal is sent via <CODE>kill()</CODE> or the tty interface
-+(e.g. by pressing ctrl-C), then the POSIX specs say that the handler
-+is executed by any thread in the process that does not currently block
-+the signal. In other terms, POSIX considers that the signal is sent
-+to the process (the collection of all threads) as a whole, and any
-+thread that is not blocking this signal can then handle it.<P>
-+
-+The latter case is where LinuxThreads departs from the POSIX specs.
-+In LinuxThreads, there is no real notion of ``the process as a whole'':
-+in the kernel, each thread is really a distinct process with a
-+distinct PID, and signals sent to the PID of a thread can only be
-+handled by that thread. As long as no thread is blocking the signal,
-+the behavior conforms to the standard: one (unspecified) thread of the
-+program handles the signal. But if the thread to which PID the signal
-+is sent blocks the signal, and some other thread does not block the
-+signal, then LinuxThreads will simply queue in
-+that thread and execute the handler only when that thread unblocks
-+the signal, instead of executing the handler immediately in the other
-+thread that does not block the signal.<P>
-+
-+This is to be viewed as a LinuxThreads bug, but I currently don't see
-+any way to implement the POSIX behavior without kernel support.<P>
-+
-+<H4><A NAME="J.3">J.3: How shall I go about mixing signals and threads
-+in my program? </A></H4>
-+
-+The less you mix them, the better. Notice that all
-+<CODE>pthread_*</CODE> functions are not async-signal safe, meaning
-+that you should not call them from signal handlers. This
-+recommendation is not to be taken lightly: your program can deadlock
-+if you call a <CODE>pthread_*</CODE> function from a signal handler!
-+<P>
-+
-+The only sensible things you can do from a signal handler is set a
-+global flag, or call <CODE>sem_post</CODE> on a semaphore, to record
-+the delivery of the signal. The remainder of the program can then
-+either poll the global flag, or use <CODE>sem_wait()</CODE> and
-+<CODE>sem_trywait()</CODE> on the semaphore.<P>
-+
-+Another option is to do nothing in the signal handler, and dedicate
-+one thread (preferably the initial thread) to wait synchronously for
-+signals, using <CODE>sigwait()</CODE>, and send messages to the other
-+threads accordingly.
-+
-+<H4><A NAME="J.4">J.4: When one thread is blocked in
-+<CODE>sigwait()</CODE>, other threads no longer receive the signals
-+<CODE>sigwait()</CODE> is waiting for! What happens? </A></H4>
-+
-+It's an unfortunate consequence of how LinuxThreads implements
-+<CODE>sigwait()</CODE>. Basically, it installs signal handlers on all
-+signals waited for, in order to record which signal was received.
-+Since signal handlers are shared with the other threads, this
-+temporarily deactivates any signal handlers you might have previously
-+installed on these signals.<P>
-+
-+Though surprising, this behavior actually seems to conform to the
-+POSIX standard. According to POSIX, <CODE>sigwait()</CODE> is
-+guaranteed to work as expected only if all other threads in the
-+program block the signals waited for (otherwise, the signals could be
-+delivered to other threads than the one doing <CODE>sigwait()</CODE>,
-+which would make <CODE>sigwait()</CODE> useless). In this particular
-+case, the problem described in this question does not appear.<P>
-+
-+One day, <CODE>sigwait()</CODE> will be implemented in the kernel,
-+along with others POSIX 1003.1b extensions, and <CODE>sigwait()</CODE>
-+will have a more natural behavior (as well as better performances).<P>
-+
-+<HR>
-+<P>
-+
-+<H2><A NAME="K">K. Internals of LinuxThreads</A></H2>
-+
-+<H4><A NAME="K.1">K.1: What is the implementation model for
-+LinuxThreads?</A></H4>
-+
-+LinuxThreads follows the so-called "one-to-one" model: each thread is
-+actually a separate process in the kernel. The kernel scheduler takes
-+care of scheduling the threads, just like it schedules regular
-+processes. The threads are created with the Linux
-+<code>clone()</code> system call, which is a generalization of
-+<code>fork()</code> allowing the new process to share the memory
-+space, file descriptors, and signal handlers of the parent.<P>
-+
-+Advantages of the "one-to-one" model include:
-+<UL>
-+<LI> minimal overhead on CPU-intensive multiprocessing (with
-+about one thread per processor);
-+<LI> minimal overhead on I/O operations;
-+<LI> a simple and robust implementation (the kernel scheduler does
-+most of the hard work for us).
-+</UL>
-+The main disadvantage is more expensive context switches on mutex and
-+condition operations, which must go through the kernel. This is
-+mitigated by the fact that context switches in the Linux kernel are
-+pretty efficient.<P>
-+
-+<H4><A NAME="K.2">K.2: Have you considered other implementation
-+models?</A></H4>
-+
-+There are basically two other models. The "many-to-one" model
-+relies on a user-level scheduler that context-switches between the
-+threads entirely in user code; viewed from the kernel, there is only
-+one process running. This model is completely out of the question for
-+me, since it does not take advantage of multiprocessors, and require
-+unholy magic to handle blocking I/O operations properly. There are
-+several user-level thread libraries available for Linux, but I found
-+all of them deficient in functionality, performance, and/or robustness.
-+<P>
-+
-+The "many-to-many" model combines both kernel-level and user-level
-+scheduling: several kernel-level threads run concurrently, each
-+executing a user-level scheduler that selects between user threads.
-+Most commercial Unix systems (Solaris, Digital Unix, IRIX) implement
-+POSIX threads this way. This model combines the advantages of both
-+the "many-to-one" and the "one-to-one" model, and is attractive
-+because it avoids the worst-case behaviors of both models --
-+especially on kernels where context switches are expensive, such as
-+Digital Unix. Unfortunately, it is pretty complex to implement, and
-+requires kernel support which Linux does not provide. Linus Torvalds
-+and other Linux kernel developers have always been pushing the
-+"one-to-one" model in the name of overall simplicity, and are doing a
-+pretty good job of making kernel-level context switches between
-+threads efficient. LinuxThreads is just following the general
-+direction they set.<P>
-+
-+<HR>
-+<ADDRESS>Xavier.Leroy@inria.fr</ADDRESS>
-+</BODY>
-+</HTML>
-diff -Naur ../glibc-2.1.3/linuxthreads/LICENSE glibc-2.1.3/linuxthreads/LICENSE
---- ../glibc-2.1.3/linuxthreads/LICENSE 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/LICENSE 1998-08-28 03:07:17.000000000 -0700
-@@ -0,0 +1,501 @@
-+GNU LIBRARY GENERAL PUBLIC LICENSE
-+**********************************
-+
-+ Version 2, June 1991
-+
-+ Copyright (C) 1991 Free Software Foundation, Inc.
-+ 59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA
-+
-+ Everyone is permitted to copy and distribute verbatim copies
-+ of this license document, but changing it is not allowed.
-+
-+ [This is the first released version of the library GPL. It is
-+ numbered 2 because it goes with version 2 of the ordinary GPL.]
-+
-+Preamble
-+========
-+
-+ The licenses for most software are designed to take away your
-+freedom to share and change it. By contrast, the GNU General Public
-+Licenses are intended to guarantee your freedom to share and change
-+free software--to make sure the software is free for all its users.
-+
-+ This license, the Library General Public License, applies to some
-+specially designated Free Software Foundation software, and to any
-+other libraries whose authors decide to use it. You can use it for
-+your libraries, too.
-+
-+ When we speak of free software, we are referring to freedom, not
-+price. Our General Public Licenses are designed to make sure that you
-+have the freedom to distribute copies of free software (and charge for
-+this service if you wish), that you receive source code or can get it
-+if you want it, that you can change the software or use pieces of it in
-+new free programs; and that you know you can do these things.
-+
-+ To protect your rights, we need to make restrictions that forbid
-+anyone to deny you these rights or to ask you to surrender the rights.
-+These restrictions translate to certain responsibilities for you if you
-+distribute copies of the library, or if you modify it.
-+
-+ For example, if you distribute copies of the library, whether gratis
-+or for a fee, you must give the recipients all the rights that we gave
-+you. You must make sure that they, too, receive or can get the source
-+code. If you link a program with the library, you must provide
-+complete object files to the recipients so that they can relink them
-+with the library, after making changes to the library and recompiling
-+it. And you must show them these terms so they know their rights.
-+
-+ Our method of protecting your rights has two steps: (1) copyright
-+the library, and (2) offer you this license which gives you legal
-+permission to copy, distribute and/or modify the library.
-+
-+ Also, for each distributor's protection, we want to make certain
-+that everyone understands that there is no warranty for this free
-+library. If the library is modified by someone else and passed on, we
-+want its recipients to know that what they have is not the original
-+version, so that any problems introduced by others will not reflect on
-+the original authors' reputations.
-+
-+ Finally, any free program is threatened constantly by software
-+patents. We wish to avoid the danger that companies distributing free
-+software will individually obtain patent licenses, thus in effect
-+transforming the program into proprietary software. To prevent this,
-+we have made it clear that any patent must be licensed for everyone's
-+free use or not licensed at all.
-+
-+ Most GNU software, including some libraries, is covered by the
-+ordinary GNU General Public License, which was designed for utility
-+programs. This license, the GNU Library General Public License,
-+applies to certain designated libraries. This license is quite
-+different from the ordinary one; be sure to read it in full, and don't
-+assume that anything in it is the same as in the ordinary license.
-+
-+ The reason we have a separate public license for some libraries is
-+that they blur the distinction we usually make between modifying or
-+adding to a program and simply using it. Linking a program with a
-+library, without changing the library, is in some sense simply using
-+the library, and is analogous to running a utility program or
-+application program. However, in a textual and legal sense, the linked
-+executable is a combined work, a derivative of the original library,
-+and the ordinary General Public License treats it as such.
-+
-+ Because of this blurred distinction, using the ordinary General
-+Public License for libraries did not effectively promote software
-+sharing, because most developers did not use the libraries. We
-+concluded that weaker conditions might promote sharing better.
-+
-+ However, unrestricted linking of non-free programs would deprive the
-+users of those programs of all benefit from the free status of the
-+libraries themselves. This Library General Public License is intended
-+to permit developers of non-free programs to use free libraries, while
-+preserving your freedom as a user of such programs to change the free
-+libraries that are incorporated in them. (We have not seen how to
-+achieve this as regards changes in header files, but we have achieved
-+it as regards changes in the actual functions of the Library.) The
-+hope is that this will lead to faster development of free libraries.
-+
-+ The precise terms and conditions for copying, distribution and
-+modification follow. Pay close attention to the difference between a
-+"work based on the library" and a "work that uses the library". The
-+former contains code derived from the library, while the latter only
-+works together with the library.
-+
-+ Note that it is possible for a library to be covered by the ordinary
-+General Public License rather than by this special one.
-+
-+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-+
-+ 0. This License Agreement applies to any software library which
-+ contains a notice placed by the copyright holder or other
-+ authorized party saying it may be distributed under the terms of
-+ this Library General Public License (also called "this License").
-+ Each licensee is addressed as "you".
-+
-+ A "library" means a collection of software functions and/or data
-+ prepared so as to be conveniently linked with application programs
-+ (which use some of those functions and data) to form executables.
-+
-+ The "Library", below, refers to any such software library or work
-+ which has been distributed under these terms. A "work based on the
-+ Library" means either the Library or any derivative work under
-+ copyright law: that is to say, a work containing the Library or a
-+ portion of it, either verbatim or with modifications and/or
-+ translated straightforwardly into another language. (Hereinafter,
-+ translation is included without limitation in the term
-+ "modification".)
-+
-+ "Source code" for a work means the preferred form of the work for
-+ making modifications to it. For a library, complete source code
-+ means all the source code for all modules it contains, plus any
-+ associated interface definition files, plus the scripts used to
-+ control compilation and installation of the library.
-+
-+ Activities other than copying, distribution and modification are
-+ not covered by this License; they are outside its scope. The act
-+ of running a program using the Library is not restricted, and
-+ output from such a program is covered only if its contents
-+ constitute a work based on the Library (independent of the use of
-+ the Library in a tool for writing it). Whether that is true
-+ depends on what the Library does and what the program that uses
-+ the Library does.
-+
-+ 1. You may copy and distribute verbatim copies of the Library's
-+ complete source code as you receive it, in any medium, provided
-+ that you conspicuously and appropriately publish on each copy an
-+ appropriate copyright notice and disclaimer of warranty; keep
-+ intact all the notices that refer to this License and to the
-+ absence of any warranty; and distribute a copy of this License
-+ along with the Library.
-+
-+ You may charge a fee for the physical act of transferring a copy,
-+ and you may at your option offer warranty protection in exchange
-+ for a fee.
-+
-+ 2. You may modify your copy or copies of the Library or any portion
-+ of it, thus forming a work based on the Library, and copy and
-+ distribute such modifications or work under the terms of Section 1
-+ above, provided that you also meet all of these conditions:
-+
-+ a. The modified work must itself be a software library.
-+
-+ b. You must cause the files modified to carry prominent notices
-+ stating that you changed the files and the date of any change.
-+
-+ c. You must cause the whole of the work to be licensed at no
-+ charge to all third parties under the terms of this License.
-+
-+ d. If a facility in the modified Library refers to a function or
-+ a table of data to be supplied by an application program that
-+ uses the facility, other than as an argument passed when the
-+ facility is invoked, then you must make a good faith effort
-+ to ensure that, in the event an application does not supply
-+ such function or table, the facility still operates, and
-+ performs whatever part of its purpose remains meaningful.
-+
-+ (For example, a function in a library to compute square roots
-+ has a purpose that is entirely well-defined independent of the
-+ application. Therefore, Subsection 2d requires that any
-+ application-supplied function or table used by this function
-+ must be optional: if the application does not supply it, the
-+ square root function must still compute square roots.)
-+
-+ These requirements apply to the modified work as a whole. If
-+ identifiable sections of that work are not derived from the
-+ Library, and can be reasonably considered independent and separate
-+ works in themselves, then this License, and its terms, do not
-+ apply to those sections when you distribute them as separate
-+ works. But when you distribute the same sections as part of a
-+ whole which is a work based on the Library, the distribution of
-+ the whole must be on the terms of this License, whose permissions
-+ for other licensees extend to the entire whole, and thus to each
-+ and every part regardless of who wrote it.
-+
-+ Thus, it is not the intent of this section to claim rights or
-+ contest your rights to work written entirely by you; rather, the
-+ intent is to exercise the right to control the distribution of
-+ derivative or collective works based on the Library.
-+
-+ In addition, mere aggregation of another work not based on the
-+ Library with the Library (or with a work based on the Library) on
-+ a volume of a storage or distribution medium does not bring the
-+ other work under the scope of this License.
-+
-+ 3. You may opt to apply the terms of the ordinary GNU General Public
-+ License instead of this License to a given copy of the Library.
-+ To do this, you must alter all the notices that refer to this
-+ License, so that they refer to the ordinary GNU General Public
-+ License, version 2, instead of to this License. (If a newer
-+ version than version 2 of the ordinary GNU General Public License
-+ has appeared, then you can specify that version instead if you
-+ wish.) Do not make any other change in these notices.
-+
-+ Once this change is made in a given copy, it is irreversible for
-+ that copy, so the ordinary GNU General Public License applies to
-+ all subsequent copies and derivative works made from that copy.
-+
-+ This option is useful when you wish to copy part of the code of
-+ the Library into a program that is not a library.
-+
-+ 4. You may copy and distribute the Library (or a portion or
-+ derivative of it, under Section 2) in object code or executable
-+ form under the terms of Sections 1 and 2 above provided that you
-+ accompany it with the complete corresponding machine-readable
-+ source code, which must be distributed under the terms of Sections
-+ 1 and 2 above on a medium customarily used for software
-+ interchange.
-+
-+ If distribution of object code is made by offering access to copy
-+ from a designated place, then offering equivalent access to copy
-+ the source code from the same place satisfies the requirement to
-+ distribute the source code, even though third parties are not
-+ compelled to copy the source along with the object code.
-+
-+ 5. A program that contains no derivative of any portion of the
-+ Library, but is designed to work with the Library by being
-+ compiled or linked with it, is called a "work that uses the
-+ Library". Such a work, in isolation, is not a derivative work of
-+ the Library, and therefore falls outside the scope of this License.
-+
-+ However, linking a "work that uses the Library" with the Library
-+ creates an executable that is a derivative of the Library (because
-+ it contains portions of the Library), rather than a "work that
-+ uses the library". The executable is therefore covered by this
-+ License. Section 6 states terms for distribution of such
-+ executables.
-+
-+ When a "work that uses the Library" uses material from a header
-+ file that is part of the Library, the object code for the work may
-+ be a derivative work of the Library even though the source code is
-+ not. Whether this is true is especially significant if the work
-+ can be linked without the Library, or if the work is itself a
-+ library. The threshold for this to be true is not precisely
-+ defined by law.
-+
-+ If such an object file uses only numerical parameters, data
-+ structure layouts and accessors, and small macros and small inline
-+ functions (ten lines or less in length), then the use of the object
-+ file is unrestricted, regardless of whether it is legally a
-+ derivative work. (Executables containing this object code plus
-+ portions of the Library will still fall under Section 6.)
-+
-+ Otherwise, if the work is a derivative of the Library, you may
-+ distribute the object code for the work under the terms of Section
-+ 6. Any executables containing that work also fall under Section 6,
-+ whether or not they are linked directly with the Library itself.
-+
-+ 6. As an exception to the Sections above, you may also compile or
-+ link a "work that uses the Library" with the Library to produce a
-+ work containing portions of the Library, and distribute that work
-+ under terms of your choice, provided that the terms permit
-+ modification of the work for the customer's own use and reverse
-+ engineering for debugging such modifications.
-+
-+ You must give prominent notice with each copy of the work that the
-+ Library is used in it and that the Library and its use are covered
-+ by this License. You must supply a copy of this License. If the
-+ work during execution displays copyright notices, you must include
-+ the copyright notice for the Library among them, as well as a
-+ reference directing the user to the copy of this License. Also,
-+ you must do one of these things:
-+
-+ a. Accompany the work with the complete corresponding
-+ machine-readable source code for the Library including
-+ whatever changes were used in the work (which must be
-+ distributed under Sections 1 and 2 above); and, if the work
-+ is an executable linked with the Library, with the complete
-+ machine-readable "work that uses the Library", as object code
-+ and/or source code, so that the user can modify the Library
-+ and then relink to produce a modified executable containing
-+ the modified Library. (It is understood that the user who
-+ changes the contents of definitions files in the Library will
-+ not necessarily be able to recompile the application to use
-+ the modified definitions.)
-+
-+ b. Accompany the work with a written offer, valid for at least
-+ three years, to give the same user the materials specified in
-+ Subsection 6a, above, for a charge no more than the cost of
-+ performing this distribution.
-+
-+ c. If distribution of the work is made by offering access to copy
-+ from a designated place, offer equivalent access to copy the
-+ above specified materials from the same place.
-+
-+ d. Verify that the user has already received a copy of these
-+ materials or that you have already sent this user a copy.
-+
-+ For an executable, the required form of the "work that uses the
-+ Library" must include any data and utility programs needed for
-+ reproducing the executable from it. However, as a special
-+ exception, the source code distributed need not include anything
-+ that is normally distributed (in either source or binary form)
-+ with the major components (compiler, kernel, and so on) of the
-+ operating system on which the executable runs, unless that
-+ component itself accompanies the executable.
-+
-+ It may happen that this requirement contradicts the license
-+ restrictions of other proprietary libraries that do not normally
-+ accompany the operating system. Such a contradiction means you
-+ cannot use both them and the Library together in an executable
-+ that you distribute.
-+
-+ 7. You may place library facilities that are a work based on the
-+ Library side-by-side in a single library together with other
-+ library facilities not covered by this License, and distribute
-+ such a combined library, provided that the separate distribution
-+ of the work based on the Library and of the other library
-+ facilities is otherwise permitted, and provided that you do these
-+ two things:
-+
-+ a. Accompany the combined library with a copy of the same work
-+ based on the Library, uncombined with any other library
-+ facilities. This must be distributed under the terms of the
-+ Sections above.
-+
-+ b. Give prominent notice with the combined library of the fact
-+ that part of it is a work based on the Library, and explaining
-+ where to find the accompanying uncombined form of the same
-+ work.
-+
-+ 8. You may not copy, modify, sublicense, link with, or distribute the
-+ Library except as expressly provided under this License. Any
-+ attempt otherwise to copy, modify, sublicense, link with, or
-+ distribute the Library is void, and will automatically terminate
-+ your rights under this License. However, parties who have
-+ received copies, or rights, from you under this License will not
-+ have their licenses terminated so long as such parties remain in
-+ full compliance.
-+
-+ 9. You are not required to accept this License, since you have not
-+ signed it. However, nothing else grants you permission to modify
-+ or distribute the Library or its derivative works. These actions
-+ are prohibited by law if you do not accept this License.
-+ Therefore, by modifying or distributing the Library (or any work
-+ based on the Library), you indicate your acceptance of this
-+ License to do so, and all its terms and conditions for copying,
-+ distributing or modifying the Library or works based on it.
-+
-+ 10. Each time you redistribute the Library (or any work based on the
-+ Library), the recipient automatically receives a license from the
-+ original licensor to copy, distribute, link with or modify the
-+ Library subject to these terms and conditions. You may not impose
-+ any further restrictions on the recipients' exercise of the rights
-+ granted herein. You are not responsible for enforcing compliance
-+ by third parties to this License.
-+
-+ 11. If, as a consequence of a court judgment or allegation of patent
-+ infringement or for any other reason (not limited to patent
-+ issues), conditions are imposed on you (whether by court order,
-+ agreement or otherwise) that contradict the conditions of this
-+ License, they do not excuse you from the conditions of this
-+ License. If you cannot distribute so as to satisfy simultaneously
-+ your obligations under this License and any other pertinent
-+ obligations, then as a consequence you may not distribute the
-+ Library at all. For example, if a patent license would not permit
-+ royalty-free redistribution of the Library by all those who
-+ receive copies directly or indirectly through you, then the only
-+ way you could satisfy both it and this License would be to refrain
-+ entirely from distribution of the Library.
-+
-+ If any portion of this section is held invalid or unenforceable
-+ under any particular circumstance, the balance of the section is
-+ intended to apply, and the section as a whole is intended to apply
-+ in other circumstances.
-+
-+ It is not the purpose of this section to induce you to infringe any
-+ patents or other property right claims or to contest validity of
-+ any such claims; this section has the sole purpose of protecting
-+ the integrity of the free software distribution system which is
-+ implemented by public license practices. Many people have made
-+ generous contributions to the wide range of software distributed
-+ through that system in reliance on consistent application of that
-+ system; it is up to the author/donor to decide if he or she is
-+ willing to distribute software through any other system and a
-+ licensee cannot impose that choice.
-+
-+ This section is intended to make thoroughly clear what is believed
-+ to be a consequence of the rest of this License.
-+
-+ 12. If the distribution and/or use of the Library is restricted in
-+ certain countries either by patents or by copyrighted interfaces,
-+ the original copyright holder who places the Library under this
-+ License may add an explicit geographical distribution limitation
-+ excluding those countries, so that distribution is permitted only
-+ in or among countries not thus excluded. In such case, this
-+ License incorporates the limitation as if written in the body of
-+ this License.
-+
-+ 13. The Free Software Foundation may publish revised and/or new
-+ versions of the Library General Public License from time to time.
-+ Such new versions will be similar in spirit to the present version,
-+ but may differ in detail to address new problems or concerns.
-+
-+ Each version is given a distinguishing version number. If the
-+ Library specifies a version number of this License which applies
-+ to it and "any later version", you have the option of following
-+ the terms and conditions either of that version or of any later
-+ version published by the Free Software Foundation. If the Library
-+ does not specify a license version number, you may choose any
-+ version ever published by the Free Software Foundation.
-+
-+ 14. If you wish to incorporate parts of the Library into other free
-+ programs whose distribution conditions are incompatible with these,
-+ write to the author to ask for permission. For software which is
-+ copyrighted by the Free Software Foundation, write to the Free
-+ Software Foundation; we sometimes make exceptions for this. Our
-+ decision will be guided by the two goals of preserving the free
-+ status of all derivatives of our free software and of promoting
-+ the sharing and reuse of software generally.
-+
-+ NO WARRANTY
-+
-+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-+ WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE
-+ LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT
-+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
-+ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-+ FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
-+ QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE
-+ LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
-+ SERVICING, REPAIR OR CORRECTION.
-+
-+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
-+ MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
-+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
-+ INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
-+ INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
-+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
-+ OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY
-+ OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
-+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-+
-+ END OF TERMS AND CONDITIONS
-+
-+How to Apply These Terms to Your New Libraries
-+==============================================
-+
-+ If you develop a new library, and you want it to be of the greatest
-+possible use to the public, we recommend making it free software that
-+everyone can redistribute and change. You can do so by permitting
-+redistribution under these terms (or, alternatively, under the terms of
-+the ordinary General Public License).
-+
-+ To apply these terms, attach the following notices to the library.
-+It is safest to attach them to the start of each source file to most
-+effectively convey the exclusion of warranty; and each file should have
-+at least the "copyright" line and a pointer to where the full notice is
-+found.
-+
-+ ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES.
-+ Copyright (C) YEAR NAME OF AUTHOR
-+
-+ This library is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU Library General Public License as published
-+ by the Free Software Foundation; either version 2 of the License, or (at
-+ your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License along
-+ with this program; if not, write to the Free Software Foundation, Inc.,
-+ 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+
-+ Also add information on how to contact you by electronic and paper
-+mail.
-+
-+ You should also get your employer (if you work as a programmer) or
-+your school, if any, to sign a "copyright disclaimer" for the library,
-+if necessary. Here is a sample; alter the names:
-+
-+ Yoyodyne, Inc., hereby disclaims all copyright interest in the library
-+ `Frob' (a library for tweaking knobs) written by James Random Hacker.
-+
-+ SIGNATURE OF TY COON, 1 April 1990
-+ Ty Coon, President of Vice
-+
-+ That's all there is to it!
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/Makefile glibc-2.1.3/linuxthreads/Makefile
---- ../glibc-2.1.3/linuxthreads/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Makefile 1999-12-07 08:50:23.000000000 -0800
-@@ -0,0 +1,68 @@
-+# Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
-+# This file is part of the GNU C Library.
-+
-+# The GNU C Library is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU Library General Public License as
-+# published by the Free Software Foundation; either version 2 of the
-+# License, or (at your option) any later version.
-+
-+# The GNU C Library is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# Library General Public License for more details.
-+
-+# You should have received a copy of the GNU Library General Public
-+# License along with the GNU C Library; see the file COPYING.LIB. If not,
-+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+# Boston, MA 02111-1307, USA.
-+
-+#
-+# Sub-makefile for linuxthreads portion of the library.
-+#
-+subdir := linuxthreads
-+
-+linuxthreads-version := $(shell sed -n 's/^.*$(subdir)-\([0-9.]*\).*$$/\1/p' \
-+ Banner)
-+
-+headers := pthread.h semaphore.h
-+distribute := internals.h queue.h restart.h spinlock.h
-+
-+routines := weaks no-tsd
-+
-+extra-libs := libpthread
-+extra-libs-others := $(extra-libs)
-+
-+libpthread-routines := attr cancel condvar join manager mutex ptfork \
-+ ptlongjmp pthread signals specific errno lockfile \
-+ semaphore spinlock wrapsyscall rwlock pt-machine \
-+ oldsemaphore events
-+
-+vpath %.c Examples
-+tests = ex1 ex2 ex3 ex4 ex5 ex6
-+
-+include ../Rules
-+
-+CFLAGS-mutex.c += -D__NO_WEAK_PTHREAD_ALIASES
-+CFLAGS-specific.c += -D__NO_WEAK_PTHREAD_ALIASES
-+CFLAGS-pthread.c += -D__NO_WEAK_PTHREAD_ALIASES
-+CFLAGS-ptfork.c += -D__NO_WEAK_PTHREAD_ALIASES
-+CFLAGS-cancel.c += -D__NO_WEAK_PTHREAD_ALIASES
-+
-+# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
-+# This ensures they will load libc.so for needed symbols if loaded by
-+# a statically-linked program that hasn't already loaded it.
-+$(objpfx)libpthread.so: $(common-objpfx)libc.so
-+
-+# Make sure we link with the thread library.
-+ifeq ($(build-shared),yes)
-+libpthread = $(objpfx)libpthread.so
-+else
-+libpthread = $(objpfx)libpthread.a
-+endif
-+
-+$(objpfx)ex1: $(libpthread)
-+$(objpfx)ex2: $(libpthread)
-+$(objpfx)ex3: $(libpthread)
-+$(objpfx)ex4: $(libpthread)
-+$(objpfx)ex5: $(libpthread)
-+$(objpfx)ex6: $(libpthread)
-diff -Naur ../glibc-2.1.3/linuxthreads/README glibc-2.1.3/linuxthreads/README
---- ../glibc-2.1.3/linuxthreads/README 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/README 1998-08-28 03:07:17.000000000 -0700
-@@ -0,0 +1,166 @@
-+ Linuxthreads - POSIX 1003.1c kernel threads for Linux
-+
-+ Copyright 1996, 1997 Xavier Leroy (Xavier.Leroy@inria.fr)
-+
-+
-+DESCRIPTION:
-+
-+This is release 0.7 (late beta) of LinuxThreads, a BiCapitalized
-+implementation of the Posix 1003.1c "pthread" interface for Linux.
-+
-+LinuxThreads provides kernel-level threads: each thread is a separate
-+Unix process, sharing its address space with the other threads through
-+the new system call clone(). Scheduling between threads is handled by
-+the kernel scheduler, just like scheduling between Unix processes.
-+
-+
-+REQUIREMENTS:
-+
-+- Linux version 2.0 and up (requires the new clone() system call
-+ and the new realtime scheduler).
-+
-+- For Intel platforms: libc 5.2.18 or later is required.
-+ 5.2.18 or 5.4.12 or later are recommended;
-+ 5.3.12 and 5.4.7 have problems (see the FAQ.html file for more info).
-+
-+- Also supports glibc 2 (a.k.a. libc 6), which actually comes with
-+ a specially-adapted version of this library.
-+
-+- Currently supports Intel, Alpha, Sparc, Motorola 68k, ARM and MIPS
-+ platforms.
-+
-+- Multiprocessors are supported.
-+
-+
-+INSTALLATION:
-+
-+- Edit the Makefile, set the variables in the "Configuration" section.
-+
-+- Do "make".
-+
-+- Do "make install".
-+
-+
-+USING LINUXTHREADS:
-+
-+ gcc -D_REENTRANT ... -lpthread
-+
-+A complete set of manual pages is included. Also see the subdirectory
-+Examples/ for some sample programs.
-+
-+
-+STATUS:
-+
-+- All functions in the Posix 1003.1c base interface implemented.
-+ Also supports priority scheduling.
-+
-+- For users of libc 5 (H.J.Lu's libc), a number of C library functions
-+ are reimplemented or wrapped to make them thread-safe, including:
-+ * malloc functions
-+ * stdio functions (define _REENTRANT before including <stdio.h>)
-+ * per-thread errno variable (define _REENTRANT before including <errno.h>)
-+ * directory reading functions (opendir(), etc)
-+ * sleep()
-+ * gmtime(), localtime()
-+
-+ New library functions provided:
-+ * flockfile(), funlockfile(), ftrylockfile()
-+ * reentrant versions of network database functions (gethostbyname_r(), etc)
-+ and password functions (getpwnam_r(), etc).
-+
-+- libc 6 (glibc 2) provides much better thread support than libc 5,
-+ and comes with a specially-adapted version of LinuxThreads.
-+ For serious multithreaded programming, you should consider switching
-+ to glibc 2. It is available from ftp.gnu.org:/pub/gnu and its mirrors.
-+
-+
-+WARNING:
-+
-+Many existing libraries are not compatible with LinuxThreads,
-+either because they are not inherently thread-safe, or because they
-+have not been compiled with the -D_REENTRANT. For more info, see the
-+FAQ.html file in this directory.
-+
-+A prime example of the latter is Xlib. If you link it with
-+LinuxThreads, you'll probably get an "unknown 0 error" very
-+early. This is just a consequence of the Xlib binaries using the
-+global variable "errno" to fetch error codes, while LinuxThreads and
-+the C library use the per-thread "errno" location.
-+
-+See the file README.Xfree3.3 for info on how to compile the Xfree 3.3
-+libraries to make them compatible with LinuxThreads.
-+
-+
-+KNOWN BUGS AND LIMITATIONS:
-+
-+- Threads share pretty much everything they should share according
-+ to the standard: memory space, file descriptors, signal handlers,
-+ current working directory, etc. One thing that they do not share
-+ is their pid's and parent pid's. According to the standard, they
-+ should have the same, but that's one thing we cannot achieve
-+ in this implementation (until the CLONE_PID flag to clone() becomes
-+ usable).
-+
-+- The current implementation uses the two signals SIGUSR1 and SIGUSR2,
-+ so user-level code cannot employ them. Ideally, there should be two
-+ signals reserved for this library. One signal is used for restarting
-+ threads blocked on mutexes or conditions; the other is for thread
-+ cancellation.
-+
-+ *** This is not anymore true when the application runs on a kernel
-+ newer than approximately 2.1.60.
-+
-+- The stacks for the threads are allocated high in the memory space,
-+ below the stack of the initial process, and spaced 2M apart.
-+ Stacks are allocated with the "grow on demand" flag, so they don't
-+ use much virtual space initially (4k, currently), but can grow
-+ up to 2M if needed.
-+
-+ Reserving such a large address space for each thread means that,
-+ on a 32-bit architecture, no more than about 1000 threads can
-+ coexist (assuming a 2Gb address space for user processes),
-+ but this is reasonable, since each thread uses up one entry in the
-+ kernel's process table, which is usually limited to 512 processes.
-+
-+ Another potential problem of the "grow on demand" scheme is that
-+ nothing prevents the user from mmap'ing something in the 2M address
-+ window reserved for a thread stack, possibly causing later extensions of
-+ that stack to fail. Mapping at fixed addresses should be avoided
-+ when using this library.
-+
-+- Signal handling does not fully conform to the Posix standard,
-+ due to the fact that threads are here distinct processes that can be
-+ sent signals individually, so there's no notion of sending a signal
-+ to "the" process (the collection of all threads).
-+ More precisely, here is a summary of the standard requirements
-+ and how they are met by the implementation:
-+
-+ 1- Synchronous signals (generated by the thread execution, e.g. SIGFPE)
-+ are delivered to the thread that raised them.
-+ (OK.)
-+
-+ 2- A fatal asynchronous signal terminates all threads in the process.
-+ (OK. The thread manager notices when a thread dies on a signal
-+ and kills all other threads with the same signal.)
-+
-+ 3- An asynchronous signal will be delivered to one of the threads
-+ of the program which does not block the signal (it is unspecified
-+ which).
-+ (No, the signal is delivered to the thread it's been sent to,
-+ based on the pid of the thread. If that thread is currently
-+ blocking the signal, the signal remains pending.)
-+
-+ 4- The signal will be delivered to at most one thread.
-+ (OK, except for signals generated from the terminal or sent to
-+ the process group, which will be delivered to all threads.)
-+
-+- The current implementation of the MIPS support assumes a MIPS ISA II
-+ processor or better. These processors support atomic operations by
-+ ll/sc instructions. Older R2000/R3000 series processors are not
-+ supported yet; support for these will have higher overhead.
-+
-+- The current implementation of the ARM support assumes that the SWP
-+ (atomic swap register with memory) instruction is available. This is
-+ the case for all processors except for the ARM1 and ARM2. On StrongARM,
-+ the SWP instruction does not bypass the cache, so multi-processor support
-+ will be more troublesome.
-diff -Naur ../glibc-2.1.3/linuxthreads/README.Xfree3.2 glibc-2.1.3/linuxthreads/README.Xfree3.2
---- ../glibc-2.1.3/linuxthreads/README.Xfree3.2 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/README.Xfree3.2 1998-08-28 03:07:17.000000000 -0700
-@@ -0,0 +1,352 @@
-+This file describes how to make a threaded X11R6.
-+
-+You need the source-code of XFree-3.2. I used the sources of X11R6.1
-+(files: xc-1.tar.gz xc-2.tar.gz xc-3.tar.gz) and the patches to
-+XFree-3.2 (files: README.X11.patch R6.1pl1-3.2.diff.gz cfont32.tgz).
-+
-+Untar the xc-?.tar.gz files in a directory called XF3.2 and apply
-+the XFree-3.2 patches as described in README.X11.patch or use the
-+whole XFree86 source.
-+
-+Now apply the thread patch with
-+
-+patch -p0 < XF3.2.xc.diff
-+
-+Go to the XF3.2/xc directory and make the whole thing:
-+nice make World >& world.log &
-+tail -f world.log
-+
-+Wait a few hours or interrupt the process after the shared libs
-+are made. The shared libs are:
-+
-+XF3.2/xc/lib/ICE/libICE.so.6.0*
-+XF3.2/xc/lib/PEX5/libPEX5.so.6.0*
-+XF3.2/xc/lib/SM/libSM.so.6.0*
-+XF3.2/xc/lib/X11/libX11.so.6.1*
-+XF3.2/xc/lib/XIE/libXIE.so.6.0*
-+XF3.2/xc/lib/XThrStub/libXThrStub.so.6.0*
-+XF3.2/xc/lib/Xaw/libXaw.so.6.1*
-+XF3.2/xc/lib/Xext/libXext.so.6.1*
-+XF3.2/xc/lib/Xi/libXi.so.6.0*
-+XF3.2/xc/lib/Xmu/libXmu.so.6.0*
-+XF3.2/xc/lib/Xt/libXt.so.6.0*
-+XF3.2/xc/lib/Xtst/libXtst.so.6.1*
-+
-+(The Program dga didn't compile, but I have not check out why.)
-+
-+Now you can copy the resulting libs
-+
-+cp XF3.2/xc/lib/*/*.so.?.? /usr/X11R6/lib/
-+
-+and create some links
-+
-+cd /usr/X11R6/lib/
-+ln -s libXThrStub.so.6.0 libXThrStub.so.6
-+ln -s libXThrStub.so.6 libXThrStub.so
-+
-+or use make install (not tested, and needs new configuration).
-+
-+It is possible with the libXThrSub to compile X11 programs without linking
-+libpthread to them and not necessary to recompile already installed
-+unthreaded X11 programs, because libXThrSub keeps the dynamic linker quit.
-+On the other hand you can link libpthread to a X11 program to use threads.
-+
-+I used linux 2.0.23 and libc 5.4.7 .
-+
-+Hans-Helmut Bühmann hans@expmech.ing.tu-bs.de
-+
-+----------------------------------------------------------------------------
-+
-+XF3.2.xc.diff:
-+-----------------------------------------------------------------------------
-+diff -u --recursive XF3.2.orig/xc/config/cf/linux.cf XF3.2/xc/config/cf/linux.cf
-+--- XF3.2.orig/xc/config/cf/linux.cf Sun Nov 10 17:05:30 1996
-++++ XF3.2/xc/config/cf/linux.cf Sun Nov 10 16:30:55 1996
-+@@ -61,6 +61,14 @@
-+ #define HasSnprintf YES
-+ #endif
-+
-++#define HasPosixThreads YES
-++#define ThreadedX YES
-++#define BuildThreadStubLibrary YES
-++#define NeedUIThrStubs YES
-++#define HasThreadSafeAPI NO
-++#define SystemMTDefines -D_REENTRANT
-++#define ThreadsLibraries -lpthread
-++
-+ #define AvoidNullMakeCommand YES
-+ #define StripInstalledPrograms YES
-+ #define CompressAllFonts YES
-+@@ -158,7 +166,7 @@
-+ #define LdPostLib /* Never needed */
-+
-+ #ifdef i386Architecture
-+-#define OptimizedCDebugFlags DefaultGcc2i386Opt -m486
-++#define OptimizedCDebugFlags DefaultGcc2i386Opt -m486 -pipe
-+ #define StandardDefines -Dlinux -D__i386__ -D_POSIX_SOURCE \
-+ -D_BSD_SOURCE -D_SVID_SOURCE -DX_LOCALE
-+ #define XawI18nDefines -DUSE_XWCHAR_STRING -DUSE_XMBTOWC
-+diff -u --recursive XF3.2.orig/xc/config/cf/lnxLib.tmpl XF3.2/xc/config/cf/lnxLib.tmpl
-+--- XF3.2.orig/xc/config/cf/lnxLib.tmpl Sun Nov 10 17:05:30 1996
-++++ XF3.2/xc/config/cf/lnxLib.tmpl Sat Nov 9 14:52:39 1996
-+@@ -19,7 +19,7 @@
-+
-+ #define CplusplusLibC
-+
-+-#define SharedX11Reqs
-++#define SharedX11Reqs -L$(BUILDLIBDIR) -lXThrStub
-+ #define SharedOldXReqs $(LDPRELIB) $(XLIBONLY)
-+ #define SharedXtReqs $(LDPRELIB) $(XLIBONLY) $(SMLIB) $(ICELIB)
-+ #define SharedXawReqs $(LDPRELIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
-+diff -u --recursive XF3.2.orig/xc/include/Xthreads.h XF3.2/xc/include/Xthreads.h
-+--- XF3.2.orig/xc/include/Xthreads.h Thu Dec 7 02:19:09 1995
-++++ XF3.2/xc/include/Xthreads.h Sat Nov 9 01:04:55 1996
-+@@ -229,12 +229,12 @@
-+ #define xcondition_wait(c,m) pthread_cond_wait(c,m)
-+ #define xcondition_signal(c) pthread_cond_signal(c)
-+ #define xcondition_broadcast(c) pthread_cond_broadcast(c)
-+-#ifdef _DECTHREADS_
-++#if defined(_DECTHREADS_) || defined(linux)
-+ static xthread_t _X_no_thread_id;
-+ #define xthread_have_id(id) !pthread_equal(id, _X_no_thread_id)
-+ #define xthread_clear_id(id) id = _X_no_thread_id
-+ #define xthread_equal(id1,id2) pthread_equal(id1, id2)
-+-#endif /* _DECTHREADS_ */
-++#endif /* _DECTHREADS_ || linux */
-+ #if _CMA_VENDOR_ == _CMA__IBM
-+ #ifdef DEBUG /* too much of a hack to enable normally */
-+ /* see also cma__obj_set_name() */
-+diff -u --recursive XF3.2.orig/xc/lib/X11/util/makekeys.c XF3.2/xc/lib/X11/util/makekeys.c
-+--- XF3.2.orig/xc/lib/X11/util/makekeys.c Mon Apr 18 02:22:22 1994
-++++ XF3.2/xc/lib/X11/util/makekeys.c Sat Nov 9 00:44:14 1996
-+@@ -73,7 +73,7 @@
-+ register char c;
-+ int first;
-+ int best_max_rehash;
-+- int best_z;
-++ int best_z = 0;
-+ int num_found;
-+ KeySym val;
-+
-+diff -u --recursive XF3.2.orig/xc/lib/XThrStub/Imakefile XF3.2/xc/lib/XThrStub/Imakefile
-+--- XF3.2.orig/xc/lib/XThrStub/Imakefile Sun Nov 10 17:08:12 1996
-++++ XF3.2/xc/lib/XThrStub/Imakefile Sat Nov 9 19:04:51 1996
-+@@ -25,7 +25,7 @@
-+ DEFINES = $(ALLOC_DEFINES)
-+ INCLUDES =
-+ SRCS = $(STUBSRCS)
-+- OBJS = $(STUBOBJS
-++ OBJS = $(STUBOBJS)
-+ LINTLIBS = $(LINTXLIB)
-+
-+ #include <Library.tmpl>
-+diff -u --recursive XF3.2.orig/xc/lib/XThrStub/UIThrStubs.c XF3.2/xc/lib/XThrStub/UIThrStubs.c
-+--- XF3.2.orig/xc/lib/XThrStub/UIThrStubs.c Sun Nov 10 17:08:12 1996
-++++ XF3.2/xc/lib/XThrStub/UIThrStubs.c Sun Nov 10 15:14:55 1996
-+@@ -37,16 +37,43 @@
-+ * specificies the thread library on the link line.
-+ */
-+
-++#if defined(linux)
-++#include <pthread.h>
-++#else
-+ #include <thread.h>
-+ #include <synch.h>
-++#endif
-+
-++#if defined(linux)
-++static pthread_t no_thread_id;
-++#endif /* defined(linux) */
-++
-++#if defined(linux)
-++#pragma weak pthread_self = _Xthr_self_stub_
-++pthread_t
-++_Xthr_self_stub_()
-++{
-++ return(no_thread_id);
-++}
-++#else /* defined(linux) */
-+ #pragma weak thr_self = _Xthr_self_stub_
-+ thread_t
-+ _Xthr_self_stub_()
-+ {
-+ return((thread_t)0);
-+ }
-++#endif /* defined(linux) */
-+
-++#if defined(linux)
-++#pragma weak pthread_mutex_init = _Xmutex_init_stub_
-++int
-++_Xmutex_init_stub_(m, a)
-++ pthread_mutex_t *m;
-++ __const pthread_mutexattr_t *a;
-++{
-++ return(0);
-++}
-++#else /* defined(linux) */
-+ #pragma weak mutex_init = _Xmutex_init_stub_
-+ int
-+ _Xmutex_init_stub_(m, t, a)
-+@@ -56,7 +83,17 @@
-+ {
-+ return(0);
-+ }
-++#endif /* defined(linux) */
-+
-++#if defined(linux)
-++#pragma weak pthread_mutex_destroy = _Xmutex_destroy_stub_
-++int
-++_Xmutex_destroy_stub_(m)
-++ pthread_mutex_t *m;
-++{
-++ return(0);
-++}
-++#else /* defined(linux) */
-+ #pragma weak mutex_destroy = _Xmutex_destroy_stub_
-+ int
-+ _Xmutex_destroy_stub_(m)
-+@@ -64,7 +101,17 @@
-+ {
-+ return(0);
-+ }
-++#endif /* defined(linux) */
-+
-++#if defined(linux)
-++#pragma weak pthread_mutex_lock = _Xmutex_lock_stub_
-++int
-++_Xmutex_lock_stub_(m)
-++ pthread_mutex_t *m;
-++{
-++ return(0);
-++}
-++#else /* defined(linux) */
-+ #pragma weak mutex_lock = _Xmutex_lock_stub_
-+ int
-+ _Xmutex_lock_stub_(m)
-+@@ -72,7 +119,17 @@
-+ {
-+ return(0);
-+ }
-++#endif /* defined(linux) */
-+
-++#if defined(linux)
-++#pragma weak pthread_mutex_unlock = _Xmutex_unlock_stub_
-++int
-++_Xmutex_unlock_stub_(m)
-++ pthread_mutex_t *m;
-++{
-++ return(0);
-++}
-++#else /* defined(linux) */
-+ #pragma weak mutex_unlock = _Xmutex_unlock_stub_
-+ int
-+ _Xmutex_unlock_stub_(m)
-+@@ -80,7 +137,18 @@
-+ {
-+ return(0);
-+ }
-++#endif /* defined(linux) */
-+
-++#if defined(linux)
-++#pragma weak pthread_cond_init = _Xcond_init_stub_
-++int
-++_Xcond_init_stub_(c, a)
-++ pthread_cond_t *c;
-++ __const pthread_condattr_t *a;
-++{
-++ return(0);
-++}
-++#else /* defined(linux) */
-+ #pragma weak cond_init = _Xcond_init_stub_
-+ int
-+ _Xcond_init_stub_(c, t, a)
-+@@ -90,7 +158,17 @@
-+ {
-+ return(0);
-+ }
-++#endif /* defined(linux) */
-+
-++#if defined(linux)
-++#pragma weak pthread_cond_destroy = _Xcond_destroy_stub_
-++int
-++_Xcond_destroy_stub_(c)
-++ pthread_cond_t *c;
-++{
-++ return(0);
-++}
-++#else /* defined(linux) */
-+ #pragma weak cond_destroy = _Xcond_destroy_stub_
-+ int
-+ _Xcond_destroy_stub_(c)
-+@@ -98,7 +176,18 @@
-+ {
-+ return(0);
-+ }
-++#endif /* defined(linux) */
-+
-++#if defined(linux)
-++#pragma weak pthread_cond_wait = _Xcond_wait_stub_
-++int
-++_Xcond_wait_stub_(c,m)
-++ pthread_cond_t *c;
-++ pthread_mutex_t *m;
-++{
-++ return(0);
-++}
-++#else /* defined(linux) */
-+ #pragma weak cond_wait = _Xcond_wait_stub_
-+ int
-+ _Xcond_wait_stub_(c,m)
-+@@ -107,7 +196,17 @@
-+ {
-+ return(0);
-+ }
-++#endif /* defined(linux) */
-+
-++#if defined(linux)
-++#pragma weak pthread_cond_signal = _Xcond_signal_stub_
-++int
-++_Xcond_signal_stub_(c)
-++ pthread_cond_t *c;
-++{
-++ return(0);
-++}
-++#else /* defined(linux) */
-+ #pragma weak cond_signal = _Xcond_signal_stub_
-+ int
-+ _Xcond_signal_stub_(c)
-+@@ -115,7 +214,17 @@
-+ {
-+ return(0);
-+ }
-++#endif /* defined(linux) */
-+
-++#if defined(linux)
-++#pragma weak pthread_cond_broadcast = _Xcond_broadcast_stub_
-++int
-++_Xcond_broadcast_stub_(c)
-++ pthread_cond_t *c;
-++{
-++ return(0);
-++}
-++#else /* defined(linux) */
-+ #pragma weak cond_broadcast = _Xcond_broadcast_stub_
-+ int
-+ _Xcond_broadcast_stub_(c)
-+@@ -123,3 +232,15 @@
-+ {
-+ return(0);
-+ }
-++#endif /* defined(linux) */
-++
-++#if defined(linux)
-++#pragma weak pthread_equal = _Xthr_equal_stub_
-++int
-++_Xthr_equal_stub_(t1, t2)
-++ pthread_t t1;
-++ pthread_t t2;
-++{
-++ return(1);
-++}
-++#endif /* defined(linux) */
-+-------------------------------------------------------------------------
-diff -Naur ../glibc-2.1.3/linuxthreads/Versions glibc-2.1.3/linuxthreads/Versions
---- ../glibc-2.1.3/linuxthreads/Versions 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/Versions 1999-09-07 01:05:19.000000000 -0700
-@@ -0,0 +1,121 @@
-+libc {
-+ GLIBC_2.0 {
-+ pthread_attr_destroy; pthread_attr_getdetachstate;
-+ pthread_attr_getinheritsched; pthread_attr_getschedparam;
-+ pthread_attr_getschedpolicy; pthread_attr_getscope; pthread_attr_init;
-+ pthread_attr_setdetachstate; pthread_attr_setinheritsched;
-+ pthread_attr_setschedparam; pthread_attr_setschedpolicy;
-+ pthread_attr_setscope; pthread_cond_broadcast; pthread_cond_destroy;
-+ pthread_cond_init; pthread_cond_signal; pthread_cond_wait;
-+ pthread_condattr_destroy; pthread_condattr_init; pthread_equal;
-+ pthread_exit; pthread_getschedparam; pthread_mutex_destroy;
-+ pthread_mutex_init; pthread_mutex_lock; pthread_mutex_unlock;
-+ pthread_mutexattr_getkind_np; pthread_mutexattr_setkind_np;
-+ pthread_self; pthread_setcancelstate; pthread_setcanceltype;
-+ pthread_setschedparam;
-+
-+ # Internal libc interface to libpthread
-+ __libc_internal_tsd_get; __libc_internal_tsd_set;
-+ }
-+ GLIBC_2.1 {
-+ pthread_attr_init;
-+ }
-+}
-+
-+ld.so {
-+ GLIBC_2.0 {
-+ # Internal libc interface to libpthread
-+ __libc_internal_tsd_get; __libc_internal_tsd_set;
-+ }
-+}
-+
-+libpthread {
-+ GLIBC_2.0 {
-+ # Hidden entry point (through macros).
-+ _pthread_cleanup_pop; _pthread_cleanup_pop_restore; _pthread_cleanup_push;
-+ _pthread_cleanup_push_defer;
-+
-+ # Internal libc interface to libpthread
-+ __libc_internal_tsd_get; __libc_internal_tsd_set;
-+
-+ # Overwritten libc functions.
-+ accept; close; connect; fcntl; fork; fsync; longjmp; lseek; msync;
-+ nanosleep; open; pause; raise; read; recv; recvfrom; recvmsg; send;
-+ sendmsg; sendto; sigaction; siglongjmp; system; tcdrain; wait;
-+ waitpid; write;
-+ __close; __connect; __fcntl; __lseek; __open; __read; __send; __wait;
-+ __write;
-+ _IO_flockfile; _IO_ftrylockfile; _IO_funlockfile;
-+ vfork; __fork;
-+
-+ # POSIX.1c extensions to libc.
-+ flockfile; funlockfile; ftrylockfile;
-+
-+ # Non-standard POSIX1.x functions.
-+ pthread_kill_other_threads_np; pthread_mutexattr_getkind_np;
-+ pthread_mutexattr_setkind_np;
-+
-+ # Real POSIX.1c functions.
-+ pthread_atfork; pthread_attr_destroy; pthread_attr_getdetachstate;
-+ pthread_attr_getinheritsched; pthread_attr_getschedparam;
-+ pthread_attr_getschedpolicy; pthread_attr_getscope; pthread_attr_init;
-+ pthread_attr_setdetachstate; pthread_attr_setinheritsched;
-+ pthread_attr_setschedparam; pthread_attr_setschedpolicy;
-+ pthread_attr_setscope; pthread_cancel; pthread_cond_broadcast;
-+ pthread_cond_destroy; pthread_cond_init; pthread_cond_signal;
-+ pthread_cond_timedwait; pthread_cond_wait; pthread_condattr_destroy;
-+ pthread_condattr_init; pthread_create; pthread_detach; pthread_equal;
-+ pthread_exit; pthread_getschedparam; pthread_getspecific; pthread_join;
-+ pthread_key_create; pthread_key_delete; pthread_kill;
-+ pthread_mutex_destroy; pthread_mutex_init; pthread_mutex_lock;
-+ pthread_mutex_trylock; pthread_mutex_unlock; pthread_mutexattr_destroy;
-+ pthread_mutexattr_init; pthread_once; pthread_self; pthread_setcancelstate;
-+ pthread_setcanceltype; pthread_setschedparam; pthread_setspecific;
-+ pthread_sigmask; pthread_testcancel;
-+
-+ sem_destroy; sem_getvalue; sem_init; sem_post; sem_trywait; sem_wait;
-+ sigwait;
-+
-+ # Protected names for functions used in other shared objects.
-+ __pthread_atfork; __pthread_initialize; __pthread_getspecific;
-+ __pthread_key_create; __pthread_mutex_destroy; __pthread_mutex_init;
-+ __pthread_mutex_lock; __pthread_mutex_trylock; __pthread_mutex_unlock;
-+ __pthread_mutexattr_destroy; __pthread_mutexattr_init;
-+ __pthread_mutexattr_settype; __pthread_once; __pthread_setspecific;
-+
-+ # The error functions.
-+ __errno_location; __h_errno_location;
-+ }
-+ GLIBC_2.1 {
-+ # Functions with changed interface.
-+ pthread_attr_init; pthread_create;
-+
-+ # Unix98 extensions.
-+ pthread_rwlock_init; pthread_rwlock_destroy; pthread_rwlock_rdlock;
-+ pthread_rwlock_tryrdlock; pthread_rwlock_wrlock; pthread_rwlock_trywrlock;
-+ pthread_rwlock_unlock; pthread_rwlockattr_init; pthread_rwlockattr_destroy;
-+ pthread_rwlockattr_getpshared; pthread_rwlockattr_setpshared;
-+ pthread_rwlockattr_getkind_np; pthread_rwlockattr_setkind_np;
-+
-+ pthread_attr_getguardsize; pthread_attr_setguardsize;
-+ pthread_attr_getstackaddr; pthread_attr_setstackaddr;
-+ pthread_attr_getstacksize; pthread_attr_setstacksize;
-+
-+ pthread_getconcurrency; pthread_setconcurrency;
-+
-+ pthread_mutexattr_gettype; pthread_mutexattr_settype;
-+
-+ sem_destroy; sem_getvalue; sem_init; sem_post; sem_trywait; sem_wait;
-+
-+ # helper functions
-+ __libc_current_sigrtmin; __libc_current_sigrtmax;
-+ __libc_allocate_rtsig;
-+ }
-+ GLIBC_2.1.1 {
-+ sem_close; sem_open; sem_unlink;
-+ }
-+ GLIBC_2.1.2 {
-+ __pthread_kill_other_threads_np;
-+ __vfork;
-+ }
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/attr.c glibc-2.1.3/linuxthreads/attr.c
---- ../glibc-2.1.3/linuxthreads/attr.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/attr.c 1998-10-28 08:30:49.000000000 -0800
-@@ -0,0 +1,199 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Handling of thread attributes */
-+
-+#include <errno.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <sys/param.h>
-+#include "pthread.h"
-+#include "internals.h"
-+
-+int __pthread_attr_init_2_1(pthread_attr_t *attr)
-+{
-+ size_t ps = __getpagesize ();
-+
-+ attr->__detachstate = PTHREAD_CREATE_JOINABLE;
-+ attr->__schedpolicy = SCHED_OTHER;
-+ attr->__schedparam.sched_priority = 0;
-+ attr->__inheritsched = PTHREAD_EXPLICIT_SCHED;
-+ attr->__scope = PTHREAD_SCOPE_SYSTEM;
-+ attr->__guardsize = ps;
-+ attr->__stackaddr = NULL;
-+ attr->__stackaddr_set = 0;
-+ attr->__stacksize = STACK_SIZE - ps;
-+ return 0;
-+}
-+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
-+default_symbol_version (__pthread_attr_init_2_1, pthread_attr_init, GLIBC_2.1);
-+
-+int __pthread_attr_init_2_0(pthread_attr_t *attr)
-+{
-+ attr->__detachstate = PTHREAD_CREATE_JOINABLE;
-+ attr->__schedpolicy = SCHED_OTHER;
-+ attr->__schedparam.sched_priority = 0;
-+ attr->__inheritsched = PTHREAD_EXPLICIT_SCHED;
-+ attr->__scope = PTHREAD_SCOPE_SYSTEM;
-+ return 0;
-+}
-+symbol_version (__pthread_attr_init_2_0, pthread_attr_init, GLIBC_2.0);
-+#else
-+strong_alias (__pthread_attr_init_2_1, pthread_attr_init)
-+#endif
-+
-+int pthread_attr_destroy(pthread_attr_t *attr)
-+{
-+ return 0;
-+}
-+
-+int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
-+{
-+ if (detachstate < PTHREAD_CREATE_JOINABLE ||
-+ detachstate > PTHREAD_CREATE_DETACHED)
-+ return EINVAL;
-+ attr->__detachstate = detachstate;
-+ return 0;
-+}
-+
-+int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
-+{
-+ *detachstate = attr->__detachstate;
-+ return 0;
-+}
-+
-+int pthread_attr_setschedparam(pthread_attr_t *attr,
-+ const struct sched_param *param)
-+{
-+ int max_prio = __sched_get_priority_max(attr->__schedpolicy);
-+ int min_prio = __sched_get_priority_min(attr->__schedpolicy);
-+
-+ if (param->sched_priority < min_prio || param->sched_priority > max_prio)
-+ return EINVAL;
-+ memcpy (&attr->__schedparam, param, sizeof (struct sched_param));
-+ return 0;
-+}
-+
-+int pthread_attr_getschedparam(const pthread_attr_t *attr,
-+ struct sched_param *param)
-+{
-+ memcpy (param, &attr->__schedparam, sizeof (struct sched_param));
-+ return 0;
-+}
-+
-+int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
-+{
-+ if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR)
-+ return EINVAL;
-+ attr->__schedpolicy = policy;
-+ return 0;
-+}
-+
-+int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
-+{
-+ *policy = attr->__schedpolicy;
-+ return 0;
-+}
-+
-+int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
-+{
-+ if (inherit != PTHREAD_INHERIT_SCHED && inherit != PTHREAD_EXPLICIT_SCHED)
-+ return EINVAL;
-+ attr->__inheritsched = inherit;
-+ return 0;
-+}
-+
-+int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
-+{
-+ *inherit = attr->__inheritsched;
-+ return 0;
-+}
-+
-+int pthread_attr_setscope(pthread_attr_t *attr, int scope)
-+{
-+ switch (scope) {
-+ case PTHREAD_SCOPE_SYSTEM:
-+ attr->__scope = scope;
-+ return 0;
-+ case PTHREAD_SCOPE_PROCESS:
-+ return ENOTSUP;
-+ default:
-+ return EINVAL;
-+ }
-+}
-+
-+int pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
-+{
-+ *scope = attr->__scope;
-+ return 0;
-+}
-+
-+int __pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
-+{
-+ size_t ps = __getpagesize ();
-+
-+ /* First round up the guard size. */
-+ guardsize = roundup (guardsize, ps);
-+
-+ /* The guard size must not be larger than the stack itself */
-+ if (guardsize >= attr->__stacksize) return EINVAL;
-+
-+ attr->__guardsize = guardsize;
-+
-+ return 0;
-+}
-+weak_alias (__pthread_attr_setguardsize, pthread_attr_setguardsize)
-+
-+int __pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
-+{
-+ *guardsize = attr->__guardsize;
-+ return 0;
-+}
-+weak_alias (__pthread_attr_getguardsize, pthread_attr_getguardsize)
-+
-+int __pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
-+{
-+ attr->__stackaddr = stackaddr;
-+ attr->__stackaddr_set = 1;
-+ return 0;
-+}
-+weak_alias (__pthread_attr_setstackaddr, pthread_attr_setstackaddr)
-+
-+int __pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
-+{
-+ /* XXX This function has a stupid definition. The standard specifies
-+ no error value but what is if no stack address was set? We simply
-+ return the value we have in the member. */
-+ *stackaddr = attr->__stackaddr;
-+ return 0;
-+}
-+weak_alias (__pthread_attr_getstackaddr, pthread_attr_getstackaddr)
-+
-+int __pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
-+{
-+ /* We don't accept value smaller than PTHREAD_STACK_MIN. */
-+ if (stacksize < PTHREAD_STACK_MIN)
-+ return EINVAL;
-+
-+ attr->__stacksize = stacksize;
-+ return 0;
-+}
-+weak_alias (__pthread_attr_setstacksize, pthread_attr_setstacksize)
-+
-+int __pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
-+{
-+ *stacksize = attr->__stacksize;
-+ return 0;
-+}
-+weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)
-diff -Naur ../glibc-2.1.3/linuxthreads/cancel.c glibc-2.1.3/linuxthreads/cancel.c
---- ../glibc-2.1.3/linuxthreads/cancel.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/cancel.c 2000-01-06 15:40:57.000000000 -0800
-@@ -0,0 +1,171 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Thread cancellation */
-+
-+#include <errno.h>
-+#include "pthread.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include "restart.h"
-+
-+int pthread_setcancelstate(int state, int * oldstate)
-+{
-+ pthread_descr self = thread_self();
-+ if (state < PTHREAD_CANCEL_ENABLE || state > PTHREAD_CANCEL_DISABLE)
-+ return EINVAL;
-+ if (oldstate != NULL) *oldstate = THREAD_GETMEM(self, p_cancelstate);
-+ THREAD_SETMEM(self, p_cancelstate, state);
-+ if (THREAD_GETMEM(self, p_canceled) &&
-+ THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE &&
-+ THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)
-+ pthread_exit(PTHREAD_CANCELED);
-+ return 0;
-+}
-+
-+int pthread_setcanceltype(int type, int * oldtype)
-+{
-+ pthread_descr self = thread_self();
-+ if (type < PTHREAD_CANCEL_DEFERRED || type > PTHREAD_CANCEL_ASYNCHRONOUS)
-+ return EINVAL;
-+ if (oldtype != NULL) *oldtype = THREAD_GETMEM(self, p_canceltype);
-+ THREAD_SETMEM(self, p_canceltype, type);
-+ if (THREAD_GETMEM(self, p_canceled) &&
-+ THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE &&
-+ THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)
-+ pthread_exit(PTHREAD_CANCELED);
-+ return 0;
-+}
-+
-+int pthread_cancel(pthread_t thread)
-+{
-+ pthread_handle handle = thread_handle(thread);
-+ int pid;
-+ int dorestart = 0;
-+ pthread_descr th;
-+ pthread_extricate_if *pextricate;
-+
-+ __pthread_lock(&handle->h_lock, NULL);
-+ if (invalid_handle(handle, thread)) {
-+ __pthread_unlock(&handle->h_lock);
-+ return ESRCH;
-+ }
-+
-+ th = handle->h_descr;
-+
-+ if (th->p_canceled) {
-+ __pthread_unlock(&handle->h_lock);
-+ return 0;
-+ }
-+
-+ pextricate = th->p_extricate;
-+ th->p_canceled = 1;
-+ pid = th->p_pid;
-+
-+ /* If the thread has registered an extrication interface, then
-+ invoke the interface. If it returns 1, then we succeeded in
-+ dequeuing the thread from whatever waiting object it was enqueued
-+ with. In that case, it is our responsibility to wake it up.
-+ And also to set the p_woken_by_cancel flag so the woken thread
-+ can tell that it was woken by cancellation. */
-+
-+ if (pextricate != NULL) {
-+ dorestart = pextricate->pu_extricate_func(pextricate->pu_object, th);
-+ th->p_woken_by_cancel = dorestart;
-+ }
-+
-+ __pthread_unlock(&handle->h_lock);
-+
-+ /* If the thread has suspended or is about to, then we unblock it by
-+ issuing a restart, instead of a cancel signal. Otherwise we send
-+ the cancel signal to unblock the thread from a cancellation point,
-+ or to initiate asynchronous cancellation. The restart is needed so
-+ we have proper accounting of restarts; suspend decrements the thread's
-+ resume count, and restart() increments it. This also means that suspend's
-+ handling of the cancel signal is obsolete. */
-+
-+ if (dorestart)
-+ restart(th);
-+ else
-+ kill(pid, __pthread_sig_cancel);
-+
-+ return 0;
-+}
-+
-+void pthread_testcancel(void)
-+{
-+ pthread_descr self = thread_self();
-+ if (THREAD_GETMEM(self, p_canceled)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)
-+ pthread_exit(PTHREAD_CANCELED);
-+}
-+
-+void _pthread_cleanup_push(struct _pthread_cleanup_buffer * buffer,
-+ void (*routine)(void *), void * arg)
-+{
-+ pthread_descr self = thread_self();
-+ buffer->__routine = routine;
-+ buffer->__arg = arg;
-+ buffer->__prev = THREAD_GETMEM(self, p_cleanup);
-+ THREAD_SETMEM(self, p_cleanup, buffer);
-+}
-+
-+void _pthread_cleanup_pop(struct _pthread_cleanup_buffer * buffer,
-+ int execute)
-+{
-+ pthread_descr self = thread_self();
-+ if (execute) buffer->__routine(buffer->__arg);
-+ THREAD_SETMEM(self, p_cleanup, buffer->__prev);
-+}
-+
-+void _pthread_cleanup_push_defer(struct _pthread_cleanup_buffer * buffer,
-+ void (*routine)(void *), void * arg)
-+{
-+ pthread_descr self = thread_self();
-+ buffer->__routine = routine;
-+ buffer->__arg = arg;
-+ buffer->__canceltype = THREAD_GETMEM(self, p_canceltype);
-+ buffer->__prev = THREAD_GETMEM(self, p_cleanup);
-+ THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_DEFERRED);
-+ THREAD_SETMEM(self, p_cleanup, buffer);
-+}
-+
-+void _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer * buffer,
-+ int execute)
-+{
-+ pthread_descr self = thread_self();
-+ if (execute) buffer->__routine(buffer->__arg);
-+ THREAD_SETMEM(self, p_cleanup, buffer->__prev);
-+ THREAD_SETMEM(self, p_canceltype, buffer->__canceltype);
-+ if (THREAD_GETMEM(self, p_canceled) &&
-+ THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE &&
-+ THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)
-+ pthread_exit(PTHREAD_CANCELED);
-+}
-+
-+void __pthread_perform_cleanup(void)
-+{
-+ pthread_descr self = thread_self();
-+ struct _pthread_cleanup_buffer * c;
-+ for (c = THREAD_GETMEM(self, p_cleanup); c != NULL; c = c->__prev)
-+ c->__routine(c->__arg);
-+}
-+
-+#ifndef PIC
-+/* We need a hook to force the cancelation wrappers to be linked in when
-+ static libpthread is used. */
-+extern const int __pthread_provide_wrappers;
-+static const int * const __pthread_require_wrappers =
-+ &__pthread_provide_wrappers;
-+#endif
-diff -Naur ../glibc-2.1.3/linuxthreads/condvar.c glibc-2.1.3/linuxthreads/condvar.c
---- ../glibc-2.1.3/linuxthreads/condvar.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/condvar.c 2000-02-16 17:44:56.000000000 -0800
-@@ -0,0 +1,417 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* and Pavel Krauz (krauz@fsid.cvut.cz). */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Condition variables */
-+
-+#include <errno.h>
-+#include <sched.h>
-+#include <stddef.h>
-+#include <sys/time.h>
-+#include "pthread.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include "queue.h"
-+#include "restart.h"
-+
-+static int pthread_cond_timedwait_relative_old(pthread_cond_t *,
-+ pthread_mutex_t *, const struct timespec *);
-+
-+static int pthread_cond_timedwait_relative_new(pthread_cond_t *,
-+ pthread_mutex_t *, const struct timespec *);
-+
-+static int (*pthread_cond_tw_rel)(pthread_cond_t *, pthread_mutex_t *,
-+ const struct timespec *) = pthread_cond_timedwait_relative_old;
-+
-+/* initialize this module */
-+void __pthread_init_condvar(int rt_sig_available)
-+{
-+ if (rt_sig_available)
-+ pthread_cond_tw_rel = pthread_cond_timedwait_relative_new;
-+}
-+
-+int pthread_cond_init(pthread_cond_t *cond,
-+ const pthread_condattr_t *cond_attr)
-+{
-+ __pthread_init_lock(&cond->__c_lock);
-+ cond->__c_waiting = NULL;
-+ return 0;
-+}
-+
-+int pthread_cond_destroy(pthread_cond_t *cond)
-+{
-+ if (cond->__c_waiting != NULL) return EBUSY;
-+ return 0;
-+}
-+
-+/* Function called by pthread_cancel to remove the thread from
-+ waiting on a condition variable queue. */
-+
-+static int cond_extricate_func(void *obj, pthread_descr th)
-+{
-+ volatile pthread_descr self = thread_self();
-+ pthread_cond_t *cond = obj;
-+ int did_remove = 0;
-+
-+ __pthread_lock(&cond->__c_lock, self);
-+ did_remove = remove_from_queue(&cond->__c_waiting, th);
-+ __pthread_unlock(&cond->__c_lock);
-+
-+ return did_remove;
-+}
-+
-+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-+{
-+ volatile pthread_descr self = thread_self();
-+ pthread_extricate_if extr;
-+ int already_canceled = 0;
-+
-+ /* Set up extrication interface */
-+ extr.pu_object = cond;
-+ extr.pu_extricate_func = cond_extricate_func;
-+
-+ /* Register extrication interface */
-+ __pthread_set_own_extricate_if(self, &extr);
-+
-+ /* Atomically enqueue thread for waiting, but only if it is not
-+ canceled. If the thread is canceled, then it will fall through the
-+ suspend call below, and then call pthread_exit without
-+ having to worry about whether it is still on the condition variable queue.
-+ This depends on pthread_cancel setting p_canceled before calling the
-+ extricate function. */
-+
-+ __pthread_lock(&cond->__c_lock, self);
-+ if (!(THREAD_GETMEM(self, p_canceled)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE))
-+ enqueue(&cond->__c_waiting, self);
-+ else
-+ already_canceled = 1;
-+ __pthread_unlock(&cond->__c_lock);
-+
-+ if (already_canceled) {
-+ __pthread_set_own_extricate_if(self, 0);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+
-+ pthread_mutex_unlock(mutex);
-+
-+ suspend(self);
-+ __pthread_set_own_extricate_if(self, 0);
-+
-+ /* Check for cancellation again, to provide correct cancellation
-+ point behavior */
-+
-+ if (THREAD_GETMEM(self, p_woken_by_cancel)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
-+ THREAD_SETMEM(self, p_woken_by_cancel, 0);
-+ pthread_mutex_lock(mutex);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+
-+ pthread_mutex_lock(mutex);
-+ return 0;
-+}
-+
-+/* The following function is used on kernels that don't have rt signals.
-+ SIGUSR1 is used as the restart signal. The different code is needed
-+ because that ordinary signal does not queue. */
-+
-+static int
-+pthread_cond_timedwait_relative_old(pthread_cond_t *cond,
-+ pthread_mutex_t *mutex,
-+ const struct timespec * abstime)
-+{
-+ volatile pthread_descr self = thread_self();
-+ sigset_t unblock, initial_mask;
-+ int already_canceled = 0;
-+ int was_signalled = 0;
-+ sigjmp_buf jmpbuf;
-+ pthread_extricate_if extr;
-+
-+ /* Set up extrication interface */
-+ extr.pu_object = cond;
-+ extr.pu_extricate_func = cond_extricate_func;
-+
-+ /* Register extrication interface */
-+ __pthread_set_own_extricate_if(self, &extr);
-+
-+ /* Enqueue to wait on the condition and check for cancellation. */
-+ __pthread_lock(&cond->__c_lock, self);
-+ if (!(THREAD_GETMEM(self, p_canceled)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE))
-+ enqueue(&cond->__c_waiting, self);
-+ else
-+ already_canceled = 1;
-+ __pthread_unlock(&cond->__c_lock);
-+
-+ if (already_canceled) {
-+ __pthread_set_own_extricate_if(self, 0);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+
-+ pthread_mutex_unlock(mutex);
-+
-+ if (atomic_decrement(&self->p_resume_count) == 0) {
-+ /* Set up a longjmp handler for the restart signal, unblock
-+ the signal and sleep. */
-+
-+ if (sigsetjmp(jmpbuf, 1) == 0) {
-+ THREAD_SETMEM(self, p_signal_jmp, &jmpbuf);
-+ THREAD_SETMEM(self, p_signal, 0);
-+ /* Unblock the restart signal */
-+ sigemptyset(&unblock);
-+ sigaddset(&unblock, __pthread_sig_restart);
-+ sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
-+
-+ while (1) {
-+ struct timeval now;
-+ struct timespec reltime;
-+
-+ /* Compute a time offset relative to now. */
-+ __gettimeofday (&now, NULL);
-+ reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
-+ reltime.tv_sec = abstime->tv_sec - now.tv_sec;
-+ if (reltime.tv_nsec < 0) {
-+ reltime.tv_nsec += 1000000000;
-+ reltime.tv_sec -= 1;
-+ }
-+
-+ /* Sleep for the required duration. If woken by a signal, resume waiting
-+ as required by Single Unix Specification. */
-+ if (reltime.tv_sec < 0 || __libc_nanosleep(&reltime, NULL) == 0)
-+ break;
-+ }
-+
-+ /* Block the restart signal again */
-+ sigprocmask(SIG_SETMASK, &initial_mask, NULL);
-+ was_signalled = 0;
-+ } else {
-+ was_signalled = 1;
-+ }
-+ THREAD_SETMEM(self, p_signal_jmp, NULL);
-+ }
-+
-+ /* Now was_signalled is true if we exited the above code
-+ due to the delivery of a restart signal. In that case,
-+ we know we have been dequeued and resumed and that the
-+ resume count is balanced. Otherwise, there are some
-+ cases to consider. First, try to bump up the resume count
-+ back to zero. If it goes to 1, it means restart() was
-+ invoked on this thread. The signal must be consumed
-+ and the count bumped down and everything is cool.
-+ Otherwise, no restart was delivered yet, so we remove
-+ the thread from the queue. If this succeeds, it's a clear
-+ case of timeout. If we fail to remove from the queue, then we
-+ must wait for a restart. */
-+
-+ if (!was_signalled) {
-+ if (atomic_increment(&self->p_resume_count) != -1) {
-+ __pthread_wait_for_restart_signal(self);
-+ atomic_decrement(&self->p_resume_count); /* should be zero now! */
-+ } else {
-+ int was_on_queue;
-+ __pthread_lock(&cond->__c_lock, self);
-+ was_on_queue = remove_from_queue(&cond->__c_waiting, self);
-+ __pthread_unlock(&cond->__c_lock);
-+
-+ if (was_on_queue) {
-+ __pthread_set_own_extricate_if(self, 0);
-+ pthread_mutex_lock(mutex);
-+ return ETIMEDOUT;
-+ }
-+
-+ suspend(self);
-+ }
-+ }
-+
-+ __pthread_set_own_extricate_if(self, 0);
-+
-+ /* The remaining logic is the same as in other cancellable waits,
-+ such as pthread_join sem_wait or pthread_cond wait. */
-+
-+ if (THREAD_GETMEM(self, p_woken_by_cancel)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
-+ THREAD_SETMEM(self, p_woken_by_cancel, 0);
-+ pthread_mutex_lock(mutex);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+
-+ pthread_mutex_lock(mutex);
-+ return 0;
-+}
-+
-+/* The following function is used on new (late 2.1 and 2.2 and higher) kernels
-+ that have rt signals which queue. */
-+
-+static int
-+pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
-+ pthread_mutex_t *mutex,
-+ const struct timespec * abstime)
-+{
-+ volatile pthread_descr self = thread_self();
-+ sigset_t unblock, initial_mask;
-+ int already_canceled = 0;
-+ int was_signalled = 0;
-+ sigjmp_buf jmpbuf;
-+ pthread_extricate_if extr;
-+
-+ /* Set up extrication interface */
-+ extr.pu_object = cond;
-+ extr.pu_extricate_func = cond_extricate_func;
-+
-+ /* Register extrication interface */
-+ __pthread_set_own_extricate_if(self, &extr);
-+
-+ /* Enqueue to wait on the condition and check for cancellation. */
-+ __pthread_lock(&cond->__c_lock, self);
-+ if (!(THREAD_GETMEM(self, p_canceled)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE))
-+ enqueue(&cond->__c_waiting, self);
-+ else
-+ already_canceled = 1;
-+ __pthread_unlock(&cond->__c_lock);
-+
-+ if (already_canceled) {
-+ __pthread_set_own_extricate_if(self, 0);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+
-+ pthread_mutex_unlock(mutex);
-+
-+ /* Set up a longjmp handler for the restart signal, unblock
-+ the signal and sleep. */
-+
-+ if (sigsetjmp(jmpbuf, 1) == 0) {
-+ THREAD_SETMEM(self, p_signal_jmp, &jmpbuf);
-+ THREAD_SETMEM(self, p_signal, 0);
-+ /* Unblock the restart signal */
-+ sigemptyset(&unblock);
-+ sigaddset(&unblock, __pthread_sig_restart);
-+ sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
-+
-+ while (1) {
-+ struct timeval now;
-+ struct timespec reltime;
-+
-+ /* Compute a time offset relative to now. */
-+ __gettimeofday (&now, NULL);
-+ reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
-+ reltime.tv_sec = abstime->tv_sec - now.tv_sec;
-+ if (reltime.tv_nsec < 0) {
-+ reltime.tv_nsec += 1000000000;
-+ reltime.tv_sec -= 1;
-+ }
-+
-+ /* Sleep for the required duration. If woken by a signal,
-+ resume waiting as required by Single Unix Specification. */
-+ if (reltime.tv_sec < 0 || __libc_nanosleep(&reltime, NULL) == 0)
-+ break;
-+ }
-+
-+ /* Block the restart signal again */
-+ sigprocmask(SIG_SETMASK, &initial_mask, NULL);
-+ was_signalled = 0;
-+ } else {
-+ was_signalled = 1;
-+ }
-+ THREAD_SETMEM(self, p_signal_jmp, NULL);
-+
-+ /* Now was_signalled is true if we exited the above code
-+ due to the delivery of a restart signal. In that case,
-+ everything is cool. We have been removed from the queue
-+ by the other thread, and consumed its signal.
-+
-+ Otherwise we this thread woke up spontaneously, or due to a signal other
-+ than restart. The next thing to do is to try to remove the thread
-+ from the queue. This may fail due to a race against another thread
-+ trying to do the same. In the failed case, we know we were signalled,
-+ and we may also have to consume a restart signal. */
-+
-+ if (!was_signalled) {
-+ int was_on_queue;
-+
-+ /* __pthread_lock will queue back any spurious restarts that
-+ may happen to it. */
-+
-+ __pthread_lock(&cond->__c_lock, self);
-+ was_on_queue = remove_from_queue(&cond->__c_waiting, self);
-+ __pthread_unlock(&cond->__c_lock);
-+
-+ if (was_on_queue) {
-+ __pthread_set_own_extricate_if(self, 0);
-+ pthread_mutex_lock(mutex);
-+ return ETIMEDOUT;
-+ }
-+
-+ /* Eat the outstanding restart() from the signaller */
-+ suspend(self);
-+ }
-+
-+ __pthread_set_own_extricate_if(self, 0);
-+
-+ /* The remaining logic is the same as in other cancellable waits,
-+ such as pthread_join sem_wait or pthread_cond wait. */
-+
-+ if (THREAD_GETMEM(self, p_woken_by_cancel)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
-+ THREAD_SETMEM(self, p_woken_by_cancel, 0);
-+ pthread_mutex_lock(mutex);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+
-+ pthread_mutex_lock(mutex);
-+ return 0;
-+}
-+
-+int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
-+ const struct timespec * abstime)
-+{
-+ /* Indirect call through pointer! */
-+ return pthread_cond_tw_rel(cond, mutex, abstime);
-+}
-+
-+int pthread_cond_signal(pthread_cond_t *cond)
-+{
-+ pthread_descr th;
-+
-+ __pthread_lock(&cond->__c_lock, NULL);
-+ th = dequeue(&cond->__c_waiting);
-+ __pthread_unlock(&cond->__c_lock);
-+ if (th != NULL) restart(th);
-+ return 0;
-+}
-+
-+int pthread_cond_broadcast(pthread_cond_t *cond)
-+{
-+ pthread_descr tosignal, th;
-+
-+ __pthread_lock(&cond->__c_lock, NULL);
-+ /* Copy the current state of the waiting queue and empty it */
-+ tosignal = cond->__c_waiting;
-+ cond->__c_waiting = NULL;
-+ __pthread_unlock(&cond->__c_lock);
-+ /* Now signal each process in the queue */
-+ while ((th = dequeue(&tosignal)) != NULL) restart(th);
-+ return 0;
-+}
-+
-+int pthread_condattr_init(pthread_condattr_t *attr)
-+{
-+ return 0;
-+}
-+
-+int pthread_condattr_destroy(pthread_condattr_t *attr)
-+{
-+ return 0;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/configure glibc-2.1.3/linuxthreads/configure
---- ../glibc-2.1.3/linuxthreads/configure 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/configure 1998-08-28 03:07:17.000000000 -0700
-@@ -0,0 +1,5 @@
-+# This is only to keep the GNU C library configure mechanism happy.
-+#
-+# Perhaps some day we need a real configuration script for different
-+# kernel versions or so.
-+exit 0
-diff -Naur ../glibc-2.1.3/linuxthreads/errno.c glibc-2.1.3/linuxthreads/errno.c
---- ../glibc-2.1.3/linuxthreads/errno.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/errno.c 1998-08-28 03:07:17.000000000 -0700
-@@ -0,0 +1,32 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Define the location of errno for the remainder of the C library */
-+
-+#include <errno.h>
-+#include <netdb.h>
-+#include "pthread.h"
-+#include "internals.h"
-+
-+int * __errno_location()
-+{
-+ pthread_descr self = thread_self();
-+ return THREAD_GETMEM (self, p_errnop);
-+}
-+
-+int * __h_errno_location()
-+{
-+ pthread_descr self = thread_self();
-+ return THREAD_GETMEM (self, p_h_errnop);
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/events.c glibc-2.1.3/linuxthreads/events.c
---- ../glibc-2.1.3/linuxthreads/events.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/events.c 1999-11-09 22:56:11.000000000 -0800
-@@ -0,0 +1,35 @@
-+/* Event functions used while debugging.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+/* The functions contained here do nothing, they just return. */
-+
-+void
-+__linuxthreads_create_event (void)
-+{
-+}
-+
-+void
-+__linuxthreads_death_event (void)
-+{
-+}
-+
-+void
-+__linuxthreads_reap_event (void)
-+{
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/internals.h glibc-2.1.3/linuxthreads/internals.h
---- ../glibc-2.1.3/linuxthreads/internals.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/internals.h 2000-01-20 18:32:38.000000000 -0800
-@@ -0,0 +1,444 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+#ifndef _INTERNALS_H
-+#define _INTERNALS_H 1
-+
-+/* Internal data structures */
-+
-+/* Includes */
-+
-+#include <bits/libc-tsd.h> /* for _LIBC_TSD_KEY_N */
-+#include <limits.h>
-+#include <setjmp.h>
-+#include <signal.h>
-+#include <unistd.h>
-+#include <sys/types.h>
-+#include "pt-machine.h"
-+#include "semaphore.h"
-+#include "../linuxthreads_db/thread_dbP.h"
-+
-+#ifndef THREAD_GETMEM
-+# define THREAD_GETMEM(descr, member) descr->member
-+#endif
-+#ifndef THREAD_GETMEM_NC
-+# define THREAD_GETMEM_NC(descr, member) descr->member
-+#endif
-+#ifndef THREAD_SETMEM
-+# define THREAD_SETMEM(descr, member, value) descr->member = (value)
-+#endif
-+#ifndef THREAD_SETMEM_NC
-+# define THREAD_SETMEM_NC(descr, member, value) descr->member = (value)
-+#endif
-+
-+/* Arguments passed to thread creation routine */
-+
-+struct pthread_start_args {
-+ void * (*start_routine)(void *); /* function to run */
-+ void * arg; /* its argument */
-+ sigset_t mask; /* initial signal mask for thread */
-+ int schedpolicy; /* initial scheduling policy (if any) */
-+ struct sched_param schedparam; /* initial scheduling parameters (if any) */
-+};
-+
-+
-+/* We keep thread specific data in a special data structure, a two-level
-+ array. The top-level array contains pointers to dynamically allocated
-+ arrays of a certain number of data pointers. So we can implement a
-+ sparse array. Each dynamic second-level array has
-+ PTHREAD_KEY_2NDLEVEL_SIZE
-+ entries. This value shouldn't be too large. */
-+#define PTHREAD_KEY_2NDLEVEL_SIZE 32
-+
-+/* We need to address PTHREAD_KEYS_MAX key with PTHREAD_KEY_2NDLEVEL_SIZE
-+ keys in each subarray. */
-+#define PTHREAD_KEY_1STLEVEL_SIZE \
-+ ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) \
-+ / PTHREAD_KEY_2NDLEVEL_SIZE)
-+
-+typedef void (*destr_function)(void *);
-+
-+struct pthread_key_struct {
-+ int in_use; /* already allocated? */
-+ destr_function destr; /* destruction routine */
-+};
-+
-+
-+#define PTHREAD_START_ARGS_INITIALIZER { NULL, NULL, {{0, }}, 0, { 0 } }
-+
-+/* The type of thread descriptors */
-+
-+typedef struct _pthread_descr_struct * pthread_descr;
-+
-+/* Callback interface for removing the thread from waiting on an
-+ object if it is cancelled while waiting or about to wait.
-+ This hold a pointer to the object, and a pointer to a function
-+ which ``extricates'' the thread from its enqueued state.
-+ The function takes two arguments: pointer to the wait object,
-+ and a pointer to the thread. It returns 1 if an extrication
-+ actually occured, and hence the thread must also be signalled.
-+ It returns 0 if the thread had already been extricated. */
-+
-+typedef struct _pthread_extricate_struct {
-+ void *pu_object;
-+ int (*pu_extricate_func)(void *, pthread_descr);
-+} pthread_extricate_if;
-+
-+/* Atomic counter made possible by compare_and_swap */
-+
-+struct pthread_atomic {
-+ long p_count;
-+ int p_spinlock;
-+};
-+
-+/* Context info for read write locks. The pthread_rwlock_info structure
-+ is information about a lock that has been read-locked by the thread
-+ in whose list this structure appears. The pthread_rwlock_context
-+ is embedded in the thread context and contains a pointer to the
-+ head of the list of lock info structures, as well as a count of
-+ read locks that are untracked, because no info structure could be
-+ allocated for them. */
-+
-+struct _pthread_rwlock_t;
-+
-+typedef struct _pthread_rwlock_info {
-+ struct _pthread_rwlock_info *pr_next;
-+ struct _pthread_rwlock_t *pr_lock;
-+ int pr_lock_count;
-+} pthread_readlock_info;
-+
-+struct _pthread_descr_struct {
-+ pthread_descr p_nextlive, p_prevlive;
-+ /* Double chaining of active threads */
-+ pthread_descr p_nextwaiting; /* Next element in the queue holding the thr */
-+ pthread_descr p_nextlock; /* can be on a queue and waiting on a lock */
-+ pthread_t p_tid; /* Thread identifier */
-+ int p_pid; /* PID of Unix process */
-+ int p_priority; /* Thread priority (== 0 if not realtime) */
-+ struct _pthread_fastlock * p_lock; /* Spinlock for synchronized accesses */
-+ int p_signal; /* last signal received */
-+ sigjmp_buf * p_signal_jmp; /* where to siglongjmp on a signal or NULL */
-+ sigjmp_buf * p_cancel_jmp; /* where to siglongjmp on a cancel or NULL */
-+ char p_terminated; /* true if terminated e.g. by pthread_exit */
-+ char p_detached; /* true if detached */
-+ char p_exited; /* true if the assoc. process terminated */
-+ void * p_retval; /* placeholder for return value */
-+ int p_retcode; /* placeholder for return code */
-+ pthread_descr p_joining; /* thread joining on that thread or NULL */
-+ struct _pthread_cleanup_buffer * p_cleanup; /* cleanup functions */
-+ char p_cancelstate; /* cancellation state */
-+ char p_canceltype; /* cancellation type (deferred/async) */
-+ char p_canceled; /* cancellation request pending */
-+ int * p_errnop; /* pointer to used errno variable */
-+ int p_errno; /* error returned by last system call */
-+ int * p_h_errnop; /* pointer to used h_errno variable */
-+ int p_h_errno; /* error returned by last netdb function */
-+ char * p_in_sighandler; /* stack address of sighandler, or NULL */
-+ char p_sigwaiting; /* true if a sigwait() is in progress */
-+ struct pthread_start_args p_start_args; /* arguments for thread creation */
-+ void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE]; /* thread-specific data */
-+ void * p_libc_specific[_LIBC_TSD_KEY_N]; /* thread-specific data for libc */
-+ int p_userstack; /* nonzero if the user provided the stack */
-+ void *p_guardaddr; /* address of guard area or NULL */
-+ size_t p_guardsize; /* size of guard area */
-+ pthread_descr p_self; /* Pointer to this structure */
-+ int p_nr; /* Index of descriptor in __pthread_handles */
-+ int p_report_events; /* Nonzero if events must be reported. */
-+ td_eventbuf_t p_eventbuf; /* Data for event. */
-+ struct pthread_atomic p_resume_count; /* number of times restart() was
-+ called on thread */
-+ char p_woken_by_cancel; /* cancellation performed wakeup */
-+ pthread_extricate_if *p_extricate; /* See above */
-+ pthread_readlock_info *p_readlock_list; /* List of readlock info structs */
-+ pthread_readlock_info *p_readlock_free; /* Free list of structs */
-+ int p_untracked_readlock_count; /* Readlocks not tracked by list */
-+ /* New elements must be added at the end. */
-+} __attribute__ ((aligned(32))); /* We need to align the structure so that
-+ doubles are aligned properly. This is 8
-+ bytes on MIPS and 16 bytes on MIPS64.
-+ 32 bytes might give better cache
-+ utilization. */
-+
-+/* The type of thread handles. */
-+
-+typedef struct pthread_handle_struct * pthread_handle;
-+
-+struct pthread_handle_struct {
-+ struct _pthread_fastlock h_lock; /* Fast lock for sychronized access */
-+ pthread_descr h_descr; /* Thread descriptor or NULL if invalid */
-+ char * h_bottom; /* Lowest address in the stack thread */
-+};
-+
-+/* The type of messages sent to the thread manager thread */
-+
-+struct pthread_request {
-+ pthread_descr req_thread; /* Thread doing the request */
-+ enum { /* Request kind */
-+ REQ_CREATE, REQ_FREE, REQ_PROCESS_EXIT, REQ_MAIN_THREAD_EXIT,
-+ REQ_POST, REQ_DEBUG
-+ } req_kind;
-+ union { /* Arguments for request */
-+ struct { /* For REQ_CREATE: */
-+ const pthread_attr_t * attr; /* thread attributes */
-+ void * (*fn)(void *); /* start function */
-+ void * arg; /* argument to start function */
-+ sigset_t mask; /* signal mask */
-+ } create;
-+ struct { /* For REQ_FREE: */
-+ pthread_t thread_id; /* identifier of thread to free */
-+ } free;
-+ struct { /* For REQ_PROCESS_EXIT: */
-+ int code; /* exit status */
-+ } exit;
-+ void * post; /* For REQ_POST: the semaphore */
-+ } req_args;
-+};
-+
-+
-+/* Signals used for suspend/restart and for cancellation notification. */
-+
-+extern int __pthread_sig_restart;
-+extern int __pthread_sig_cancel;
-+
-+/* Signal used for interfacing with gdb */
-+
-+extern int __pthread_sig_debug;
-+
-+/* Global array of thread handles, used for validating a thread id
-+ and retrieving the corresponding thread descriptor. Also used for
-+ mapping the available stack segments. */
-+
-+extern struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX];
-+
-+/* Descriptor of the initial thread */
-+
-+extern struct _pthread_descr_struct __pthread_initial_thread;
-+
-+/* Descriptor of the manager thread */
-+
-+extern struct _pthread_descr_struct __pthread_manager_thread;
-+
-+/* Descriptor of the main thread */
-+
-+extern pthread_descr __pthread_main_thread;
-+
-+/* Limit between the stack of the initial thread (above) and the
-+ stacks of other threads (below). Aligned on a STACK_SIZE boundary.
-+ Initially 0, meaning that the current thread is (by definition)
-+ the initial thread. */
-+
-+extern char *__pthread_initial_thread_bos;
-+
-+/* Indicate whether at least one thread has a user-defined stack (if 1),
-+ or all threads have stacks supplied by LinuxThreads (if 0). */
-+
-+extern int __pthread_nonstandard_stacks;
-+
-+/* File descriptor for sending requests to the thread manager.
-+ Initially -1, meaning that __pthread_initialize_manager must be called. */
-+
-+extern int __pthread_manager_request;
-+
-+/* Other end of the pipe for sending requests to the thread manager. */
-+
-+extern int __pthread_manager_reader;
-+
-+/* Limits of the thread manager stack. */
-+
-+extern char *__pthread_manager_thread_bos;
-+extern char *__pthread_manager_thread_tos;
-+
-+/* Pending request for a process-wide exit */
-+
-+extern int __pthread_exit_requested, __pthread_exit_code;
-+
-+/* Set to 1 by gdb if we're debugging */
-+
-+extern volatile int __pthread_threads_debug;
-+
-+/* Globally enabled events. */
-+extern volatile td_thr_events_t __pthread_threads_events;
-+
-+/* Pointer to descriptor of thread with last event. */
-+extern volatile pthread_descr __pthread_last_event;
-+
-+/* Return the handle corresponding to a thread id */
-+
-+static inline pthread_handle thread_handle(pthread_t id)
-+{
-+ return &__pthread_handles[id % PTHREAD_THREADS_MAX];
-+}
-+
-+/* Validate a thread handle. Must have acquired h->h_spinlock before. */
-+
-+static inline int invalid_handle(pthread_handle h, pthread_t id)
-+{
-+ return h->h_descr == NULL || h->h_descr->p_tid != id;
-+}
-+
-+/* Fill in defaults left unspecified by pt-machine.h. */
-+
-+/* The page size we can get from the system. This should likely not be
-+ changed by the machine file but, you never know. */
-+#ifndef PAGE_SIZE
-+#define PAGE_SIZE (sysconf (_SC_PAGE_SIZE))
-+#endif
-+
-+/* The max size of the thread stack segments. If the default
-+ THREAD_SELF implementation is used, this must be a power of two and
-+ a multiple of PAGE_SIZE. */
-+#ifndef STACK_SIZE
-+#define STACK_SIZE (2 * 1024 * 1024)
-+#endif
-+
-+/* The initial size of the thread stack. Must be a multiple of PAGE_SIZE. */
-+#ifndef INITIAL_STACK_SIZE
-+#define INITIAL_STACK_SIZE (4 * PAGE_SIZE)
-+#endif
-+
-+/* Size of the thread manager stack. The "- 32" avoids wasting space
-+ with some malloc() implementations. */
-+#ifndef THREAD_MANAGER_STACK_SIZE
-+#define THREAD_MANAGER_STACK_SIZE (2 * PAGE_SIZE - 32)
-+#endif
-+
-+/* The base of the "array" of thread stacks. The array will grow down from
-+ here. Defaults to the calculated bottom of the initial application
-+ stack. */
-+#ifndef THREAD_STACK_START_ADDRESS
-+#define THREAD_STACK_START_ADDRESS __pthread_initial_thread_bos
-+#endif
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#ifndef CURRENT_STACK_FRAME
-+#define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
-+#endif
-+
-+/* Recover thread descriptor for the current thread */
-+
-+extern pthread_descr __pthread_find_self (void) __attribute__ ((const));
-+
-+static inline pthread_descr thread_self (void) __attribute__ ((const));
-+static inline pthread_descr thread_self (void)
-+{
-+#ifdef THREAD_SELF
-+ return THREAD_SELF;
-+#else
-+ char *sp = CURRENT_STACK_FRAME;
-+ if (sp >= __pthread_initial_thread_bos)
-+ return &__pthread_initial_thread;
-+ else if (sp >= __pthread_manager_thread_bos
-+ && sp < __pthread_manager_thread_tos)
-+ return &__pthread_manager_thread;
-+ else if (__pthread_nonstandard_stacks)
-+ return __pthread_find_self();
-+ else
-+ return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1;
-+#endif
-+}
-+
-+/* Max number of times we must spin on a spinlock calling sched_yield().
-+ After MAX_SPIN_COUNT iterations, we put the calling thread to sleep. */
-+
-+#ifndef MAX_SPIN_COUNT
-+#define MAX_SPIN_COUNT 50
-+#endif
-+
-+/* Duration of sleep (in nanoseconds) when we can't acquire a spinlock
-+ after MAX_SPIN_COUNT iterations of sched_yield().
-+ With the 2.0 and 2.1 kernels, this MUST BE > 2ms.
-+ (Otherwise the kernel does busy-waiting for realtime threads,
-+ giving other threads no chance to run.) */
-+
-+#ifndef SPIN_SLEEP_DURATION
-+#define SPIN_SLEEP_DURATION 2000001
-+#endif
-+
-+/* Debugging */
-+
-+#ifdef DEBUG
-+#include <assert.h>
-+#define ASSERT assert
-+#define MSG __pthread_message
-+#else
-+#define ASSERT(x)
-+#define MSG(msg,arg...)
-+#endif
-+
-+/* Internal global functions */
-+
-+void __pthread_destroy_specifics(void);
-+void __pthread_perform_cleanup(void);
-+int __pthread_initialize_manager(void);
-+void __pthread_message(char * fmt, ...);
-+int __pthread_manager(void *reqfd);
-+int __pthread_manager_event(void *reqfd);
-+void __pthread_manager_sighandler(int sig);
-+void __pthread_reset_main_thread(void);
-+void __fresetlockfiles(void);
-+void __pthread_manager_adjust_prio(int thread_prio);
-+void __pthread_set_own_extricate_if(pthread_descr self, pthread_extricate_if *peif);
-+
-+extern int __pthread_attr_setguardsize __P ((pthread_attr_t *__attr,
-+ size_t __guardsize));
-+extern int __pthread_attr_getguardsize __P ((__const pthread_attr_t *__attr,
-+ size_t *__guardsize));
-+extern int __pthread_attr_setstackaddr __P ((pthread_attr_t *__attr,
-+ void *__stackaddr));
-+extern int __pthread_attr_getstackaddr __P ((__const pthread_attr_t *__attr,
-+ void **__stackaddr));
-+extern int __pthread_attr_setstacksize __P ((pthread_attr_t *__attr,
-+ size_t __stacksize));
-+extern int __pthread_attr_getstacksize __P ((__const pthread_attr_t *__attr,
-+ size_t *__stacksize));
-+extern int __pthread_getconcurrency __P ((void));
-+extern int __pthread_setconcurrency __P ((int __level));
-+extern int __pthread_mutexattr_gettype __P ((__const pthread_mutexattr_t *__attr,
-+ int *__kind));
-+extern void __pthread_kill_other_threads_np __P ((void));
-+
-+void __pthread_restart_old(pthread_descr th);
-+void __pthread_suspend_old(pthread_descr self);
-+
-+void __pthread_restart_new(pthread_descr th);
-+void __pthread_suspend_new(pthread_descr self);
-+
-+void __pthread_wait_for_restart_signal(pthread_descr self);
-+
-+void __pthread_init_condvar(int rt_sig_available);
-+
-+/* Global pointers to old or new suspend functions */
-+
-+extern void (*__pthread_restart)(pthread_descr);
-+extern void (*__pthread_suspend)(pthread_descr);
-+
-+/* Prototypes for the function without cancelation support when the
-+ normal version has it. */
-+extern int __libc_close (int fd);
-+extern int __libc_nanosleep (const struct timespec *requested_time,
-+ struct timespec *remaining);
-+extern ssize_t __libc_read (int fd, void *buf, size_t count);
-+extern pid_t __libc_waitpid (pid_t pid, int *stat_loc, int options);
-+extern ssize_t __libc_write (int fd, const void *buf, size_t count);
-+
-+/* Prototypes for some of the new semaphore functions. */
-+extern int __new_sem_post (sem_t * sem);
-+
-+/* The functions called the signal events. */
-+extern void __linuxthreads_create_event (void);
-+extern void __linuxthreads_death_event (void);
-+extern void __linuxthreads_reap_event (void);
-+
-+#endif /* internals.h */
-diff -Naur ../glibc-2.1.3/linuxthreads/join.c glibc-2.1.3/linuxthreads/join.c
---- ../glibc-2.1.3/linuxthreads/join.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/join.c 2000-01-06 15:40:57.000000000 -0800
-@@ -0,0 +1,207 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Thread termination and joining */
-+
-+#include <errno.h>
-+#include <sched.h>
-+#include <unistd.h>
-+#include "pthread.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include "restart.h"
-+
-+void pthread_exit(void * retval)
-+{
-+ pthread_descr self = thread_self();
-+ pthread_descr joining;
-+ struct pthread_request request;
-+
-+ /* Reset the cancellation flag to avoid looping if the cleanup handlers
-+ contain cancellation points */
-+ THREAD_SETMEM(self, p_canceled, 0);
-+ /* Call cleanup functions and destroy the thread-specific data */
-+ __pthread_perform_cleanup();
-+ __pthread_destroy_specifics();
-+ /* Store return value */
-+ __pthread_lock(THREAD_GETMEM(self, p_lock), self);
-+ THREAD_SETMEM(self, p_retval, retval);
-+ /* Say that we've terminated */
-+ THREAD_SETMEM(self, p_terminated, 1);
-+ /* See whether we have to signal the death. */
-+ if (THREAD_GETMEM(self, p_report_events))
-+ {
-+ /* See whether TD_DEATH is in any of the mask. */
-+ int idx = __td_eventword (TD_DEATH);
-+ uint32_t mask = __td_eventmask (TD_DEATH);
-+
-+ if ((mask & (__pthread_threads_events.event_bits[idx]
-+ | THREAD_GETMEM(self,
-+ p_eventbuf.eventmask).event_bits[idx]))
-+ != 0)
-+ {
-+ /* Yep, we have to signal the death. */
-+ THREAD_SETMEM(self, p_eventbuf.eventnum, TD_DEATH);
-+ THREAD_SETMEM(self, p_eventbuf.eventdata, self);
-+ __pthread_last_event = self;
-+
-+ /* Now call the function to signal the event. */
-+ __linuxthreads_death_event();
-+ }
-+ }
-+ /* See if someone is joining on us */
-+ joining = THREAD_GETMEM(self, p_joining);
-+ __pthread_unlock(THREAD_GETMEM(self, p_lock));
-+ /* Restart joining thread if any */
-+ if (joining != NULL) restart(joining);
-+ /* If this is the initial thread, block until all threads have terminated.
-+ If another thread calls exit, we'll be terminated from our signal
-+ handler. */
-+ if (self == __pthread_main_thread && __pthread_manager_request >= 0) {
-+ request.req_thread = self;
-+ request.req_kind = REQ_MAIN_THREAD_EXIT;
-+ __libc_write(__pthread_manager_request, (char *)&request, sizeof(request));
-+ suspend(self);
-+ }
-+ /* Exit the process (but don't flush stdio streams, and don't run
-+ atexit functions). */
-+ _exit(0);
-+}
-+
-+/* Function called by pthread_cancel to remove the thread from
-+ waiting on a condition variable queue. */
-+
-+static int join_extricate_func(void *obj, pthread_descr th)
-+{
-+ volatile pthread_descr self = thread_self();
-+ pthread_handle handle = obj;
-+ pthread_descr jo;
-+ int did_remove = 0;
-+
-+ __pthread_lock(&handle->h_lock, self);
-+ jo = handle->h_descr;
-+ did_remove = jo->p_joining != NULL;
-+ jo->p_joining = NULL;
-+ __pthread_unlock(&handle->h_lock);
-+
-+ return did_remove;
-+}
-+
-+int pthread_join(pthread_t thread_id, void ** thread_return)
-+{
-+ volatile pthread_descr self = thread_self();
-+ struct pthread_request request;
-+ pthread_handle handle = thread_handle(thread_id);
-+ pthread_descr th;
-+ pthread_extricate_if extr;
-+ int already_canceled = 0;
-+
-+ /* Set up extrication interface */
-+ extr.pu_object = handle;
-+ extr.pu_extricate_func = join_extricate_func;
-+
-+ __pthread_lock(&handle->h_lock, self);
-+ if (invalid_handle(handle, thread_id)) {
-+ __pthread_unlock(&handle->h_lock);
-+ return ESRCH;
-+ }
-+ th = handle->h_descr;
-+ if (th == self) {
-+ __pthread_unlock(&handle->h_lock);
-+ return EDEADLK;
-+ }
-+ /* If detached or already joined, error */
-+ if (th->p_detached || th->p_joining != NULL) {
-+ __pthread_unlock(&handle->h_lock);
-+ return EINVAL;
-+ }
-+ /* If not terminated yet, suspend ourselves. */
-+ if (! th->p_terminated) {
-+ /* Register extrication interface */
-+ __pthread_set_own_extricate_if(self, &extr);
-+ if (!(THREAD_GETMEM(self, p_canceled)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE))
-+ th->p_joining = self;
-+ else
-+ already_canceled = 1;
-+ __pthread_unlock(&handle->h_lock);
-+
-+ if (already_canceled) {
-+ __pthread_set_own_extricate_if(self, 0);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+
-+ suspend(self);
-+ /* Deregister extrication interface */
-+ __pthread_set_own_extricate_if(self, 0);
-+
-+ /* This is a cancellation point */
-+ if (THREAD_GETMEM(self, p_woken_by_cancel)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
-+ THREAD_SETMEM(self, p_woken_by_cancel, 0);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+ __pthread_lock(&handle->h_lock, self);
-+ }
-+ /* Get return value */
-+ if (thread_return != NULL) *thread_return = th->p_retval;
-+ __pthread_unlock(&handle->h_lock);
-+ /* Send notification to thread manager */
-+ if (__pthread_manager_request >= 0) {
-+ request.req_thread = self;
-+ request.req_kind = REQ_FREE;
-+ request.req_args.free.thread_id = thread_id;
-+ __libc_write(__pthread_manager_request,
-+ (char *) &request, sizeof(request));
-+ }
-+ return 0;
-+}
-+
-+int pthread_detach(pthread_t thread_id)
-+{
-+ int terminated;
-+ struct pthread_request request;
-+ pthread_handle handle = thread_handle(thread_id);
-+ pthread_descr th;
-+
-+ __pthread_lock(&handle->h_lock, NULL);
-+ if (invalid_handle(handle, thread_id)) {
-+ __pthread_unlock(&handle->h_lock);
-+ return ESRCH;
-+ }
-+ th = handle->h_descr;
-+ /* If already detached, error */
-+ if (th->p_detached) {
-+ __pthread_unlock(&handle->h_lock);
-+ return EINVAL;
-+ }
-+ /* If already joining, don't do anything. */
-+ if (th->p_joining != NULL) {
-+ __pthread_unlock(&handle->h_lock);
-+ return 0;
-+ }
-+ /* Mark as detached */
-+ th->p_detached = 1;
-+ terminated = th->p_terminated;
-+ __pthread_unlock(&handle->h_lock);
-+ /* If already terminated, notify thread manager to reclaim resources */
-+ if (terminated && __pthread_manager_request >= 0) {
-+ request.req_thread = thread_self();
-+ request.req_kind = REQ_FREE;
-+ request.req_args.free.thread_id = thread_id;
-+ __libc_write(__pthread_manager_request,
-+ (char *) &request, sizeof(request));
-+ }
-+ return 0;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/linuxthreads.texi glibc-2.1.3/linuxthreads/linuxthreads.texi
---- ../glibc-2.1.3/linuxthreads/linuxthreads.texi 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/linuxthreads.texi 1999-06-16 15:34:04.000000000 -0700
-@@ -0,0 +1,1428 @@
-+@node POSIX Threads
-+@c @node POSIX Threads, , Top, Top
-+@chapter POSIX Threads
-+@c %MENU% The standard threads library
-+
-+@c This chapter needs more work bigtime. -zw
-+
-+This chapter describes the pthreads (POSIX threads) library. This
-+library provides support functions for multithreaded programs: thread
-+primitives, synchronization objects, and so forth. It also implements
-+POSIX 1003.1b semaphores (not to be confused with System V semaphores).
-+
-+The threads operations (@samp{pthread_*}) do not use @var{errno}.
-+Instead they return an error code directly. The semaphore operations do
-+use @var{errno}.
-+
-+@menu
-+* Basic Thread Operations:: Creating, terminating, and waiting for threads.
-+* Thread Attributes:: Tuning thread scheduling.
-+* Cancellation:: Stopping a thread before it's done.
-+* Cleanup Handlers:: Deallocating resources when a thread is
-+ cancelled.
-+* Mutexes:: One way to synchronize threads.
-+* Condition Variables:: Another way.
-+* POSIX Semaphores:: And a third way.
-+* Thread-Specific Data:: Variables with different values in
-+ different threads.
-+* Threads and Signal Handling:: Why you should avoid mixing the two, and
-+ how to do it if you must.
-+* Miscellaneous Thread Functions:: A grab bag of utility routines.
-+@end menu
-+
-+@node Basic Thread Operations
-+@section Basic Thread Operations
-+
-+These functions are the thread equivalents of @code{fork}, @code{exit},
-+and @code{wait}.
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_create (pthread_t * @var{thread}, pthread_attr_t * @var{attr}, void * (*@var{start_routine})(void *), void * @var{arg})
-+@code{pthread_create} creates a new thread of control that executes
-+concurrently with the calling thread. The new thread calls the
-+function @var{start_routine}, passing it @var{arg} as first argument. The
-+new thread terminates either explicitly, by calling @code{pthread_exit},
-+or implicitly, by returning from the @var{start_routine} function. The
-+latter case is equivalent to calling @code{pthread_exit} with the result
-+returned by @var{start_routine} as exit code.
-+
-+The @var{attr} argument specifies thread attributes to be applied to the
-+new thread. @xref{Thread Attributes}, for details. The @var{attr}
-+argument can also be @code{NULL}, in which case default attributes are
-+used: the created thread is joinable (not detached) and has an ordinary
-+(not realtime) scheduling policy.
-+
-+On success, the identifier of the newly created thread is stored in the
-+location pointed by the @var{thread} argument, and a 0 is returned. On
-+error, a non-zero error code is returned.
-+
-+This function may return the following errors:
-+@table @code
-+@item EAGAIN
-+Not enough system resources to create a process for the new thread,
-+or more than @code{PTHREAD_THREADS_MAX} threads are already active.
-+@end table
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun void pthread_exit (void *@var{retval})
-+@code{pthread_exit} terminates the execution of the calling thread. All
-+cleanup handlers (@pxref{Cleanup Handlers}) that have been set for the
-+calling thread with @code{pthread_cleanup_push} are executed in reverse
-+order (the most recently pushed handler is executed first). Finalization
-+functions for thread-specific data are then called for all keys that
-+have non-@code{NULL} values associated with them in the calling thread
-+(@pxref{Thread-Specific Data}). Finally, execution of the calling
-+thread is stopped.
-+
-+The @var{retval} argument is the return value of the thread. It can be
-+retrieved from another thread using @code{pthread_join}.
-+
-+The @code{pthread_exit} function never returns.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_cancel (pthread_t @var{thread})
-+
-+@code{pthread_cancel} sends a cancellation request to the thread denoted
-+by the @var{thread} argument. If there is no such thread,
-+@code{pthread_cancel} fails and returns @code{ESRCH}. Otherwise it
-+returns 0. @xref{Cancellation}, for details.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_join (pthread_t @var{th}, void **thread_@var{return})
-+@code{pthread_join} suspends the execution of the calling thread until
-+the thread identified by @var{th} terminates, either by calling
-+@code{pthread_exit} or by being cancelled.
-+
-+If @var{thread_return} is not @code{NULL}, the return value of @var{th}
-+is stored in the location pointed to by @var{thread_return}. The return
-+value of @var{th} is either the argument it gave to @code{pthread_exit},
-+or @code{PTHREAD_CANCELED} if @var{th} was cancelled.
-+
-+The joined thread @code{th} must be in the joinable state: it must not
-+have been detached using @code{pthread_detach} or the
-+@code{PTHREAD_CREATE_DETACHED} attribute to @code{pthread_create}.
-+
-+When a joinable thread terminates, its memory resources (thread
-+descriptor and stack) are not deallocated until another thread performs
-+@code{pthread_join} on it. Therefore, @code{pthread_join} must be called
-+once for each joinable thread created to avoid memory leaks.
-+
-+At most one thread can wait for the termination of a given
-+thread. Calling @code{pthread_join} on a thread @var{th} on which
-+another thread is already waiting for termination returns an error.
-+
-+@code{pthread_join} is a cancellation point. If a thread is canceled
-+while suspended in @code{pthread_join}, the thread execution resumes
-+immediately and the cancellation is executed without waiting for the
-+@var{th} thread to terminate. If cancellation occurs during
-+@code{pthread_join}, the @var{th} thread remains not joined.
-+
-+On success, the return value of @var{th} is stored in the location
-+pointed to by @var{thread_return}, and 0 is returned. On error, one of
-+the following values is returned:
-+@table @code
-+@item ESRCH
-+No thread could be found corresponding to that specified by @var{th}.
-+@item EINVAL
-+The @var{th} thread has been detached, or another thread is already
-+waiting on termination of @var{th}.
-+@item EDEADLK
-+The @var{th} argument refers to the calling thread.
-+@end table
-+@end deftypefun
-+
-+@node Thread Attributes
-+@section Thread Attributes
-+
-+@comment pthread.h
-+@comment POSIX
-+
-+Threads have a number of attributes that may be set at creation time.
-+This is done by filling a thread attribute object @var{attr} of type
-+@code{pthread_attr_t}, then passing it as second argument to
-+@code{pthread_create}. Passing @code{NULL} is equivalent to passing a
-+thread attribute object with all attributes set to their default values.
-+
-+Attribute objects are consulted only when creating a new thread. The
-+same attribute object can be used for creating several threads.
-+Modifying an attribute object after a call to @code{pthread_create} does
-+not change the attributes of the thread previously created.
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_attr_init (pthread_attr_t *@var{attr})
-+@code{pthread_attr_init} initializes the thread attribute object
-+@var{attr} and fills it with default values for the attributes. (The
-+default values are listed below for each attribute.)
-+
-+Each attribute @var{attrname} (see below for a list of all attributes)
-+can be individually set using the function
-+@code{pthread_attr_set@var{attrname}} and retrieved using the function
-+@code{pthread_attr_get@var{attrname}}.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_attr_destroy (pthread_attr_t *@var{attr})
-+@code{pthread_attr_destroy} destroys the attribute object pointed to by
-+@var{attr} releasing any resources associated with it. @var{attr} is
-+left in an undefined state, and you must not use it again in a call to
-+any pthreads function until it has been reinitialized.
-+@end deftypefun
-+
-+@findex pthread_attr_setinheritsched
-+@findex pthread_attr_setschedparam
-+@findex pthread_attr_setschedpolicy
-+@findex pthread_attr_setscope
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_attr_set@var{attr} (pthread_attr_t *@var{obj}, int @var{value})
-+Set attribute @var{attr} to @var{value} in the attribute object pointed
-+to by @var{obj}. See below for a list of possible attributes and the
-+values they can take.
-+
-+On success, these functions return 0. If @var{value} is not meaningful
-+for the @var{attr} being modified, they will return the error code
-+@code{EINVAL}. Some of the functions have other failure modes; see
-+below.
-+@end deftypefun
-+
-+@findex pthread_attr_getinheritsched
-+@findex pthread_attr_getschedparam
-+@findex pthread_attr_getschedpolicy
-+@findex pthread_attr_getscope
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_attr_get@var{attr} (const pthread_attr_t *@var{obj}, int *@var{value})
-+Store the current setting of @var{attr} in @var{obj} into the variable
-+pointed to by @var{value}.
-+
-+These functions always return 0.
-+@end deftypefun
-+
-+The following thread attributes are supported:
-+@table @samp
-+@item detachstate
-+Choose whether the thread is created in the joinable state (value
-+@code{PTHREAD_CREATE_JOINABLE}) or in the detached state
-+(@code{PTHREAD_CREATE_DETACHED}). The default is
-+@code{PTHREAD_CREATE_JOINABLE}.
-+
-+In the joinable state, another thread can synchronize on the thread
-+termination and recover its termination code using @code{pthread_join},
-+but some of the thread resources are kept allocated after the thread
-+terminates, and reclaimed only when another thread performs
-+@code{pthread_join} on that thread.
-+
-+In the detached state, the thread resources are immediately freed when
-+it terminates, but @code{pthread_join} cannot be used to synchronize on
-+the thread termination.
-+
-+A thread created in the joinable state can later be put in the detached
-+thread using @code{pthread_detach}.
-+
-+@item schedpolicy
-+Select the scheduling policy for the thread: one of @code{SCHED_OTHER}
-+(regular, non-realtime scheduling), @code{SCHED_RR} (realtime,
-+round-robin) or @code{SCHED_FIFO} (realtime, first-in first-out).
-+The default is @code{SCHED_OTHER}.
-+@c Not doc'd in our manual: FIXME.
-+@c See @code{sched_setpolicy} for more information on scheduling policies.
-+
-+The realtime scheduling policies @code{SCHED_RR} and @code{SCHED_FIFO}
-+are available only to processes with superuser privileges.
-+@code{pthread_attr_setschedparam} will fail and return @code{ENOTSUP} if
-+you try to set a realtime policy when you are unprivileged.
-+
-+The scheduling policy of a thread can be changed after creation with
-+@code{pthread_setschedparam}.
-+
-+@item schedparam
-+Change the scheduling parameter (the scheduling priority)
-+for the thread. The default is 0.
-+
-+This attribute is not significant if the scheduling policy is
-+@code{SCHED_OTHER}; it only matters for the realtime policies
-+@code{SCHED_RR} and @code{SCHED_FIFO}.
-+
-+The scheduling priority of a thread can be changed after creation with
-+@code{pthread_setschedparam}.
-+
-+@item inheritsched
-+Choose whether the scheduling policy and scheduling parameter for the
-+newly created thread are determined by the values of the
-+@var{schedpolicy} and @var{schedparam} attributes (value
-+@code{PTHREAD_EXPLICIT_SCHED}) or are inherited from the parent thread
-+(value @code{PTHREAD_INHERIT_SCHED}). The default is
-+@code{PTHREAD_EXPLICIT_SCHED}.
-+
-+@item scope
-+Choose the scheduling contention scope for the created thread. The
-+default is @code{PTHREAD_SCOPE_SYSTEM}, meaning that the threads contend
-+for CPU time with all processes running on the machine. In particular,
-+thread priorities are interpreted relative to the priorities of all
-+other processes on the machine. The other possibility,
-+@code{PTHREAD_SCOPE_PROCESS}, means that scheduling contention occurs
-+only between the threads of the running process: thread priorities are
-+interpreted relative to the priorities of the other threads of the
-+process, regardless of the priorities of other processes.
-+
-+@code{PTHREAD_SCOPE_PROCESS} is not supported in LinuxThreads. If you
-+try to set the scope to this value @code{pthread_attr_setscope} will
-+fail and return @code{ENOTSUP}.
-+@end table
-+
-+@node Cancellation
-+@section Cancellation
-+
-+Cancellation is the mechanism by which a thread can terminate the
-+execution of another thread. More precisely, a thread can send a
-+cancellation request to another thread. Depending on its settings, the
-+target thread can then either ignore the request, honor it immediately,
-+or defer it till it reaches a cancellation point. When threads are
-+first created by @code{pthread_create}, they always defer cancellation
-+requests.
-+
-+When a thread eventually honors a cancellation request, it behaves as if
-+@code{pthread_exit(PTHREAD_CANCELED)} was called. All cleanup handlers
-+are executed in reverse order, finalization functions for
-+thread-specific data are called, and finally the thread stops executing.
-+If the cancelled thread was joinable, the return value
-+@code{PTHREAD_CANCELED} is provided to whichever thread calls
-+@var{pthread_join} on it. See @code{pthread_exit} for more information.
-+
-+Cancellation points are the points where the thread checks for pending
-+cancellation requests and performs them. The POSIX threads functions
-+@code{pthread_join}, @code{pthread_cond_wait},
-+@code{pthread_cond_timedwait}, @code{pthread_testcancel},
-+@code{sem_wait}, and @code{sigwait} are cancellation points. In
-+addition, these system calls are cancellation points:
-+
-+@multitable @columnfractions .33 .33 .33
-+@item @t{accept} @tab @t{open} @tab @t{sendmsg}
-+@item @t{close} @tab @t{pause} @tab @t{sendto}
-+@item @t{connect} @tab @t{read} @tab @t{system}
-+@item @t{fcntl} @tab @t{recv} @tab @t{tcdrain}
-+@item @t{fsync} @tab @t{recvfrom} @tab @t{wait}
-+@item @t{lseek} @tab @t{recvmsg} @tab @t{waitpid}
-+@item @t{msync} @tab @t{send} @tab @t{write}
-+@item @t{nanosleep}
-+@end multitable
-+
-+@noindent
-+All library functions that call these functions (such as
-+@code{printf}) are also cancellation points.
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_setcancelstate (int @var{state}, int *@var{oldstate})
-+@code{pthread_setcancelstate} changes the cancellation state for the
-+calling thread -- that is, whether cancellation requests are ignored or
-+not. The @var{state} argument is the new cancellation state: either
-+@code{PTHREAD_CANCEL_ENABLE} to enable cancellation, or
-+@code{PTHREAD_CANCEL_DISABLE} to disable cancellation (cancellation
-+requests are ignored).
-+
-+If @var{oldstate} is not @code{NULL}, the previous cancellation state is
-+stored in the location pointed to by @var{oldstate}, and can thus be
-+restored later by another call to @code{pthread_setcancelstate}.
-+
-+If the @var{state} argument is not @code{PTHREAD_CANCEL_ENABLE} or
-+@code{PTHREAD_CANCEL_DISABLE}, @code{pthread_setcancelstate} fails and
-+returns @code{EINVAL}. Otherwise it returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_setcanceltype (int @var{type}, int *@var{oldtype})
-+@code{pthread_setcanceltype} changes the type of responses to
-+cancellation requests for the calling thread: asynchronous (immediate)
-+or deferred. The @var{type} argument is the new cancellation type:
-+either @code{PTHREAD_CANCEL_ASYNCHRONOUS} to cancel the calling thread
-+as soon as the cancellation request is received, or
-+@code{PTHREAD_CANCEL_DEFERRED} to keep the cancellation request pending
-+until the next cancellation point. If @var{oldtype} is not @code{NULL},
-+the previous cancellation state is stored in the location pointed to by
-+@var{oldtype}, and can thus be restored later by another call to
-+@code{pthread_setcanceltype}.
-+
-+If the @var{type} argument is not @code{PTHREAD_CANCEL_DEFERRED} or
-+@code{PTHREAD_CANCEL_ASYNCHRONOUS}, @code{pthread_setcanceltype} fails
-+and returns @code{EINVAL}. Otherwise it returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun void pthread_testcancel (@var{void})
-+@code{pthread_testcancel} does nothing except testing for pending
-+cancellation and executing it. Its purpose is to introduce explicit
-+checks for cancellation in long sequences of code that do not call
-+cancellation point functions otherwise.
-+@end deftypefun
-+
-+@node Cleanup Handlers
-+@section Cleanup Handlers
-+
-+Cleanup handlers are functions that get called when a thread terminates,
-+either by calling @code{pthread_exit} or because of
-+cancellation. Cleanup handlers are installed and removed following a
-+stack-like discipline.
-+
-+The purpose of cleanup handlers is to free the resources that a thread
-+may hold at the time it terminates. In particular, if a thread exits or
-+is cancelled while it owns a locked mutex, the mutex will remain locked
-+forever and prevent other threads from executing normally. The best way
-+to avoid this is, just before locking the mutex, to install a cleanup
-+handler whose effect is to unlock the mutex. Cleanup handlers can be
-+used similarly to free blocks allocated with @code{malloc} or close file
-+descriptors on thread termination.
-+
-+Here is how to lock a mutex @var{mut} in such a way that it will be
-+unlocked if the thread is canceled while @var{mut} is locked:
-+
-+@smallexample
-+pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
-+pthread_mutex_lock(&mut);
-+/* do some work */
-+pthread_mutex_unlock(&mut);
-+pthread_cleanup_pop(0);
-+@end smallexample
-+
-+Equivalently, the last two lines can be replaced by
-+
-+@smallexample
-+pthread_cleanup_pop(1);
-+@end smallexample
-+
-+Notice that the code above is safe only in deferred cancellation mode
-+(see @code{pthread_setcanceltype}). In asynchronous cancellation mode, a
-+cancellation can occur between @code{pthread_cleanup_push} and
-+@code{pthread_mutex_lock}, or between @code{pthread_mutex_unlock} and
-+@code{pthread_cleanup_pop}, resulting in both cases in the thread trying
-+to unlock a mutex not locked by the current thread. This is the main
-+reason why asynchronous cancellation is difficult to use.
-+
-+If the code above must also work in asynchronous cancellation mode,
-+then it must switch to deferred mode for locking and unlocking the
-+mutex:
-+
-+@smallexample
-+pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
-+pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
-+pthread_mutex_lock(&mut);
-+/* do some work */
-+pthread_cleanup_pop(1);
-+pthread_setcanceltype(oldtype, NULL);
-+@end smallexample
-+
-+The code above can be rewritten in a more compact and efficient way,
-+using the non-portable functions @code{pthread_cleanup_push_defer_np}
-+and @code{pthread_cleanup_pop_restore_np}:
-+
-+@smallexample
-+pthread_cleanup_push_defer_np(pthread_mutex_unlock, (void *) &mut);
-+pthread_mutex_lock(&mut);
-+/* do some work */
-+pthread_cleanup_pop_restore_np(1);
-+@end smallexample
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun void pthread_cleanup_push (void (*@var{routine}) (void *), void *@var{arg})
-+
-+@code{pthread_cleanup_push} installs the @var{routine} function with
-+argument @var{arg} as a cleanup handler. From this point on to the
-+matching @code{pthread_cleanup_pop}, the function @var{routine} will be
-+called with arguments @var{arg} when the thread terminates, either
-+through @code{pthread_exit} or by cancellation. If several cleanup
-+handlers are active at that point, they are called in LIFO order: the
-+most recently installed handler is called first.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun void pthread_cleanup_pop (int @var{execute})
-+@code{pthread_cleanup_pop} removes the most recently installed cleanup
-+handler. If the @var{execute} argument is not 0, it also executes the
-+handler, by calling the @var{routine} function with arguments
-+@var{arg}. If the @var{execute} argument is 0, the handler is only
-+removed but not executed.
-+@end deftypefun
-+
-+Matching pairs of @code{pthread_cleanup_push} and
-+@code{pthread_cleanup_pop} must occur in the same function, at the same
-+level of block nesting. Actually, @code{pthread_cleanup_push} and
-+@code{pthread_cleanup_pop} are macros, and the expansion of
-+@code{pthread_cleanup_push} introduces an open brace @code{@{} with the
-+matching closing brace @code{@}} being introduced by the expansion of the
-+matching @code{pthread_cleanup_pop}.
-+
-+@comment pthread.h
-+@comment GNU
-+@deftypefun void pthread_cleanup_push_defer_np (void (*@var{routine}) (void *), void *@var{arg})
-+@code{pthread_cleanup_push_defer_np} is a non-portable extension that
-+combines @code{pthread_cleanup_push} and @code{pthread_setcanceltype}.
-+It pushes a cleanup handler just as @code{pthread_cleanup_push} does,
-+but also saves the current cancellation type and sets it to deferred
-+cancellation. This ensures that the cleanup mechanism is effective even
-+if the thread was initially in asynchronous cancellation mode.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment GNU
-+@deftypefun void pthread_cleanup_pop_restore_np (int @var{execute})
-+@code{pthread_cleanup_pop_restore_np} pops a cleanup handler introduced
-+by @code{pthread_cleanup_push_defer_np}, and restores the cancellation
-+type to its value at the time @code{pthread_cleanup_push_defer_np} was
-+called.
-+@end deftypefun
-+
-+@code{pthread_cleanup_push_defer_np} and
-+@code{pthread_cleanup_pop_restore_np} must occur in matching pairs, at
-+the same level of block nesting.
-+
-+The sequence
-+
-+@smallexample
-+pthread_cleanup_push_defer_np(routine, arg);
-+...
-+pthread_cleanup_pop_defer_np(execute);
-+@end smallexample
-+
-+@noindent
-+is functionally equivalent to (but more compact and efficient than)
-+
-+@smallexample
-+@{
-+ int oldtype;
-+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
-+ pthread_cleanup_push(routine, arg);
-+ ...
-+ pthread_cleanup_pop(execute);
-+ pthread_setcanceltype(oldtype, NULL);
-+@}
-+@end smallexample
-+
-+
-+@node Mutexes
-+@section Mutexes
-+
-+A mutex is a MUTual EXclusion device, and is useful for protecting
-+shared data structures from concurrent modifications, and implementing
-+critical sections and monitors.
-+
-+A mutex has two possible states: unlocked (not owned by any thread),
-+and locked (owned by one thread). A mutex can never be owned by two
-+different threads simultaneously. A thread attempting to lock a mutex
-+that is already locked by another thread is suspended until the owning
-+thread unlocks the mutex first.
-+
-+None of the mutex functions is a cancellation point, not even
-+@code{pthread_mutex_lock}, in spite of the fact that it can suspend a
-+thread for arbitrary durations. This way, the status of mutexes at
-+cancellation points is predictable, allowing cancellation handlers to
-+unlock precisely those mutexes that need to be unlocked before the
-+thread stops executing. Consequently, threads using deferred
-+cancellation should never hold a mutex for extended periods of time.
-+
-+It is not safe to call mutex functions from a signal handler. In
-+particular, calling @code{pthread_mutex_lock} or
-+@code{pthread_mutex_unlock} from a signal handler may deadlock the
-+calling thread.
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_mutex_init (pthread_mutex_t *@var{mutex}, const pthread_mutexattr_t *@var{mutexattr})
-+
-+@code{pthread_mutex_init} initializes the mutex object pointed to by
-+@var{mutex} according to the mutex attributes specified in @var{mutexattr}.
-+If @var{mutexattr} is @code{NULL}, default attributes are used instead.
-+
-+The LinuxThreads implementation supports only one mutex attribute,
-+the @var{mutex kind}, which is either ``fast'', ``recursive'', or
-+``error checking''. The kind of a mutex determines whether
-+it can be locked again by a thread that already owns it.
-+The default kind is ``fast''.
-+
-+Variables of type @code{pthread_mutex_t} can also be initialized
-+statically, using the constants @code{PTHREAD_MUTEX_INITIALIZER} (for
-+fast mutexes), @code{PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} (for
-+recursive mutexes), and @code{PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP}
-+(for error checking mutexes).
-+
-+@code{pthread_mutex_init} always returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_mutex_lock (pthread_mutex_t *mutex))
-+@code{pthread_mutex_lock} locks the given mutex. If the mutex is
-+currently unlocked, it becomes locked and owned by the calling thread,
-+and @code{pthread_mutex_lock} returns immediately. If the mutex is
-+already locked by another thread, @code{pthread_mutex_lock} suspends the
-+calling thread until the mutex is unlocked.
-+
-+If the mutex is already locked by the calling thread, the behavior of
-+@code{pthread_mutex_lock} depends on the kind of the mutex. If the mutex
-+is of the ``fast'' kind, the calling thread is suspended. It will
-+remain suspended forever, because no other thread can unlock the mutex.
-+If the mutex is of the ``error checking'' kind, @code{pthread_mutex_lock}
-+returns immediately with the error code @code{EDEADLK}. If the mutex is
-+of the ``recursive'' kind, @code{pthread_mutex_lock} succeeds and
-+returns immediately, recording the number of times the calling thread
-+has locked the mutex. An equal number of @code{pthread_mutex_unlock}
-+operations must be performed before the mutex returns to the unlocked
-+state.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_mutex_trylock (pthread_mutex_t *@var{mutex})
-+@code{pthread_mutex_trylock} behaves identically to
-+@code{pthread_mutex_lock}, except that it does not block the calling
-+thread if the mutex is already locked by another thread (or by the
-+calling thread in the case of a ``fast'' mutex). Instead,
-+@code{pthread_mutex_trylock} returns immediately with the error code
-+@code{EBUSY}.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_mutex_unlock (pthread_mutex_t *@var{mutex})
-+@code{pthread_mutex_unlock} unlocks the given mutex. The mutex is
-+assumed to be locked and owned by the calling thread on entrance to
-+@code{pthread_mutex_unlock}. If the mutex is of the ``fast'' kind,
-+@code{pthread_mutex_unlock} always returns it to the unlocked state. If
-+it is of the ``recursive'' kind, it decrements the locking count of the
-+mutex (number of @code{pthread_mutex_lock} operations performed on it by
-+the calling thread), and only when this count reaches zero is the mutex
-+actually unlocked.
-+
-+On ``error checking'' mutexes, @code{pthread_mutex_unlock} actually
-+checks at run-time that the mutex is locked on entrance, and that it was
-+locked by the same thread that is now calling
-+@code{pthread_mutex_unlock}. If these conditions are not met,
-+@code{pthread_mutex_unlock} returns @code{EPERM}, and the mutex remains
-+unchanged. ``Fast'' and ``recursive'' mutexes perform no such checks,
-+thus allowing a locked mutex to be unlocked by a thread other than its
-+owner. This is non-portable behavior and must not be relied upon.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_mutex_destroy (pthread_mutex_t *@var{mutex})
-+@code{pthread_mutex_destroy} destroys a mutex object, freeing the
-+resources it might hold. The mutex must be unlocked on entrance. In the
-+LinuxThreads implementation, no resources are associated with mutex
-+objects, thus @code{pthread_mutex_destroy} actually does nothing except
-+checking that the mutex is unlocked.
-+
-+If the mutex is locked by some thread, @code{pthread_mutex_destroy}
-+returns @code{EBUSY}. Otherwise it returns 0.
-+@end deftypefun
-+
-+If any of the above functions (except @code{pthread_mutex_init})
-+is applied to an uninitialized mutex, they will simply return
-+@code{EINVAL} and do nothing.
-+
-+A shared global variable @var{x} can be protected by a mutex as follows:
-+
-+@smallexample
-+int x;
-+pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
-+@end smallexample
-+
-+All accesses and modifications to @var{x} should be bracketed by calls to
-+@code{pthread_mutex_lock} and @code{pthread_mutex_unlock} as follows:
-+
-+@smallexample
-+pthread_mutex_lock(&mut);
-+/* operate on x */
-+pthread_mutex_unlock(&mut);
-+@end smallexample
-+
-+Mutex attributes can be specified at mutex creation time, by passing a
-+mutex attribute object as second argument to @code{pthread_mutex_init}.
-+Passing @code{NULL} is equivalent to passing a mutex attribute object
-+with all attributes set to their default values.
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_mutexattr_init (pthread_mutexattr_t *@var{attr})
-+@code{pthread_mutexattr_init} initializes the mutex attribute object
-+@var{attr} and fills it with default values for the attributes.
-+
-+This function always returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_mutexattr_destroy (pthread_mutexattr_t *@var{attr})
-+@code{pthread_mutexattr_destroy} destroys a mutex attribute object,
-+which must not be reused until it is
-+reinitialized. @code{pthread_mutexattr_destroy} does nothing in the
-+LinuxThreads implementation.
-+
-+This function always returns 0.
-+@end deftypefun
-+
-+LinuxThreads supports only one mutex attribute: the mutex kind, which is
-+either @code{PTHREAD_MUTEX_FAST_NP} for ``fast'' mutexes,
-+@code{PTHREAD_MUTEX_RECURSIVE_NP} for ``recursive'' mutexes, or
-+@code{PTHREAD_MUTEX_ERRORCHECK_NP} for ``error checking'' mutexes. As
-+the @code{NP} suffix indicates, this is a non-portable extension to the
-+POSIX standard and should not be employed in portable programs.
-+
-+The mutex kind determines what happens if a thread attempts to lock a
-+mutex it already owns with @code{pthread_mutex_lock}. If the mutex is of
-+the ``fast'' kind, @code{pthread_mutex_lock} simply suspends the calling
-+thread forever. If the mutex is of the ``error checking'' kind,
-+@code{pthread_mutex_lock} returns immediately with the error code
-+@code{EDEADLK}. If the mutex is of the ``recursive'' kind, the call to
-+@code{pthread_mutex_lock} returns immediately with a success return
-+code. The number of times the thread owning the mutex has locked it is
-+recorded in the mutex. The owning thread must call
-+@code{pthread_mutex_unlock} the same number of times before the mutex
-+returns to the unlocked state.
-+
-+The default mutex kind is ``fast'', that is, @code{PTHREAD_MUTEX_FAST_NP}.
-+
-+@comment pthread.h
-+@comment GNU
-+@deftypefun int pthread_mutexattr_setkind_np (pthread_mutexattr_t *@var{attr}, int @var{kind})
-+@code{pthread_mutexattr_setkind_np} sets the mutex kind attribute in
-+@var{attr} to the value specified by @var{kind}.
-+
-+If @var{kind} is not @code{PTHREAD_MUTEX_FAST_NP},
-+@code{PTHREAD_MUTEX_RECURSIVE_NP}, or
-+@code{PTHREAD_MUTEX_ERRORCHECK_NP}, this function will return
-+@code{EINVAL} and leave @var{attr} unchanged.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment GNU
-+@deftypefun int pthread_mutexattr_getkind_np (const pthread_mutexattr_t *@var{attr}, int *@var{kind})
-+@code{pthread_mutexattr_getkind_np} retrieves the current value of the
-+mutex kind attribute in @var{attr} and stores it in the location pointed
-+to by @var{kind}.
-+
-+This function always returns 0.
-+@end deftypefun
-+
-+@node Condition Variables
-+@section Condition Variables
-+
-+A condition (short for ``condition variable'') is a synchronization
-+device that allows threads to suspend execution until some predicate on
-+shared data is satisfied. The basic operations on conditions are: signal
-+the condition (when the predicate becomes true), and wait for the
-+condition, suspending the thread execution until another thread signals
-+the condition.
-+
-+A condition variable must always be associated with a mutex, to avoid
-+the race condition where a thread prepares to wait on a condition
-+variable and another thread signals the condition just before the first
-+thread actually waits on it.
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_cond_init (pthread_cond_t *@var{cond}, pthread_condattr_t *cond_@var{attr})
-+
-+@code{pthread_cond_init} initializes the condition variable @var{cond},
-+using the condition attributes specified in @var{cond_attr}, or default
-+attributes if @var{cond_attr} is @code{NULL}. The LinuxThreads
-+implementation supports no attributes for conditions, hence the
-+@var{cond_attr} parameter is actually ignored.
-+
-+Variables of type @code{pthread_cond_t} can also be initialized
-+statically, using the constant @code{PTHREAD_COND_INITIALIZER}.
-+
-+This function always returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_cond_signal (pthread_cond_t *@var{cond})
-+@code{pthread_cond_signal} restarts one of the threads that are waiting
-+on the condition variable @var{cond}. If no threads are waiting on
-+@var{cond}, nothing happens. If several threads are waiting on
-+@var{cond}, exactly one is restarted, but it is not specified which.
-+
-+This function always returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_cond_broadcast (pthread_cond_t *@var{cond})
-+@code{pthread_cond_broadcast} restarts all the threads that are waiting
-+on the condition variable @var{cond}. Nothing happens if no threads are
-+waiting on @var{cond}.
-+
-+This function always returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_cond_wait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex})
-+@code{pthread_cond_wait} atomically unlocks the @var{mutex} (as per
-+@code{pthread_unlock_mutex}) and waits for the condition variable
-+@var{cond} to be signaled. The thread execution is suspended and does
-+not consume any CPU time until the condition variable is signaled. The
-+@var{mutex} must be locked by the calling thread on entrance to
-+@code{pthread_cond_wait}. Before returning to the calling thread,
-+@code{pthread_cond_wait} re-acquires @var{mutex} (as per
-+@code{pthread_lock_mutex}).
-+
-+Unlocking the mutex and suspending on the condition variable is done
-+atomically. Thus, if all threads always acquire the mutex before
-+signaling the condition, this guarantees that the condition cannot be
-+signaled (and thus ignored) between the time a thread locks the mutex
-+and the time it waits on the condition variable.
-+
-+This function always returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_cond_timedwait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex}, const struct timespec *@var{abstime})
-+@code{pthread_cond_timedwait} atomically unlocks @var{mutex} and waits
-+on @var{cond}, as @code{pthread_cond_wait} does, but it also bounds the
-+duration of the wait. If @var{cond} has not been signaled before time
-+@var{abstime}, the mutex @var{mutex} is re-acquired and
-+@code{pthread_cond_timedwait} returns the error code @code{ETIMEDOUT}.
-+The wait can also be interrupted by a signal; in that case
-+@code{pthread_cond_timedwait} returns @code{EINTR}.
-+
-+The @var{abstime} parameter specifies an absolute time, with the same
-+origin as @code{time} and @code{gettimeofday}: an @var{abstime} of 0
-+corresponds to 00:00:00 GMT, January 1, 1970.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_cond_destroy (pthread_cond_t *@var{cond})
-+@code{pthread_cond_destroy} destroys the condition variable @var{cond},
-+freeing the resources it might hold. If any threads are waiting on the
-+condition variable, @code{pthread_cond_destroy} leaves @var{cond}
-+untouched and returns @code{EBUSY}. Otherwise it returns 0, and
-+@var{cond} must not be used again until it is reinitialized.
-+
-+In the LinuxThreads implementation, no resources are associated with
-+condition variables, so @code{pthread_cond_destroy} actually does
-+nothing.
-+@end deftypefun
-+
-+@code{pthread_cond_wait} and @code{pthread_cond_timedwait} are
-+cancellation points. If a thread is cancelled while suspended in one of
-+these functions, the thread immediately resumes execution, relocks the
-+mutex specified by @var{mutex}, and finally executes the cancellation.
-+Consequently, cleanup handlers are assured that @var{mutex} is locked
-+when they are called.
-+
-+It is not safe to call the condition variable functions from a signal
-+handler. In particular, calling @code{pthread_cond_signal} or
-+@code{pthread_cond_broadcast} from a signal handler may deadlock the
-+calling thread.
-+
-+Consider two shared variables @var{x} and @var{y}, protected by the
-+mutex @var{mut}, and a condition variable @var{cond} that is to be
-+signaled whenever @var{x} becomes greater than @var{y}.
-+
-+@smallexample
-+int x,y;
-+pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
-+pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-+@end smallexample
-+
-+Waiting until @var{x} is greater than @var{y} is performed as follows:
-+
-+@smallexample
-+pthread_mutex_lock(&mut);
-+while (x <= y) @{
-+ pthread_cond_wait(&cond, &mut);
-+@}
-+/* operate on x and y */
-+pthread_mutex_unlock(&mut);
-+@end smallexample
-+
-+Modifications on @var{x} and @var{y} that may cause @var{x} to become greater than
-+@var{y} should signal the condition if needed:
-+
-+@smallexample
-+pthread_mutex_lock(&mut);
-+/* modify x and y */
-+if (x > y) pthread_cond_broadcast(&cond);
-+pthread_mutex_unlock(&mut);
-+@end smallexample
-+
-+If it can be proved that at most one waiting thread needs to be waken
-+up (for instance, if there are only two threads communicating through
-+@var{x} and @var{y}), @code{pthread_cond_signal} can be used as a slightly more
-+efficient alternative to @code{pthread_cond_broadcast}. In doubt, use
-+@code{pthread_cond_broadcast}.
-+
-+To wait for @var{x} to becomes greater than @var{y} with a timeout of 5
-+seconds, do:
-+
-+@smallexample
-+struct timeval now;
-+struct timespec timeout;
-+int retcode;
-+
-+pthread_mutex_lock(&mut);
-+gettimeofday(&now);
-+timeout.tv_sec = now.tv_sec + 5;
-+timeout.tv_nsec = now.tv_usec * 1000;
-+retcode = 0;
-+while (x <= y && retcode != ETIMEDOUT) @{
-+ retcode = pthread_cond_timedwait(&cond, &mut, &timeout);
-+@}
-+if (retcode == ETIMEDOUT) @{
-+ /* timeout occurred */
-+@} else @{
-+ /* operate on x and y */
-+@}
-+pthread_mutex_unlock(&mut);
-+@end smallexample
-+
-+Condition attributes can be specified at condition creation time, by
-+passing a condition attribute object as second argument to
-+@code{pthread_cond_init}. Passing @code{NULL} is equivalent to passing
-+a condition attribute object with all attributes set to their default
-+values.
-+
-+The LinuxThreads implementation supports no attributes for
-+conditions. The functions on condition attributes are included only for
-+compliance with the POSIX standard.
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_condattr_init (pthread_condattr_t *@var{attr})
-+@deftypefunx int pthread_condattr_destroy (pthread_condattr_t *@var{attr})
-+@code{pthread_condattr_init} initializes the condition attribute object
-+@var{attr} and fills it with default values for the attributes.
-+@code{pthread_condattr_destroy} destroys the condition attribute object
-+@var{attr}.
-+
-+Both functions do nothing in the LinuxThreads implementation.
-+
-+@code{pthread_condattr_init} and @code{pthread_condattr_destroy} always
-+return 0.
-+@end deftypefun
-+
-+@node POSIX Semaphores
-+@section POSIX Semaphores
-+
-+@vindex SEM_VALUE_MAX
-+Semaphores are counters for resources shared between threads. The
-+basic operations on semaphores are: increment the counter atomically,
-+and wait until the counter is non-null and decrement it atomically.
-+
-+Semaphores have a maximum value past which they cannot be incremented.
-+The macro @code{SEM_VALUE_MAX} is defined to be this maximum value. In
-+the GNU C library, @code{SEM_VALUE_MAX} is equal to @code{INT_MAX}
-+(@pxref{Range of Type}), but it may be much smaller on other systems.
-+
-+The pthreads library implements POSIX 1003.1b semaphores. These should
-+not be confused with System V semaphores (@code{ipc}, @code{semctl} and
-+@code{semop}).
-+@c !!! SysV IPC is not doc'd at all in our manual
-+
-+All the semaphore functions and macros are defined in @file{semaphore.h}.
-+
-+@comment semaphore.h
-+@comment POSIX
-+@deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value})
-+@code{sem_init} initializes the semaphore object pointed to by
-+@var{sem}. The count associated with the semaphore is set initially to
-+@var{value}. The @var{pshared} argument indicates whether the semaphore
-+is local to the current process (@var{pshared} is zero) or is to be
-+shared between several processes (@var{pshared} is not zero).
-+
-+On success @code{sem_init} returns 0. On failure it returns -1 and sets
-+@var{errno} to one of the following values:
-+
-+@table @code
-+@item EINVAL
-+@var{value} exceeds the maximal counter value @code{SEM_VALUE_MAX}
-+
-+@item ENOSYS
-+@var{pshared} is not zero. LinuxThreads currently does not support
-+process-shared semaphores. (This will eventually change.)
-+@end table
-+@end deftypefun
-+
-+@comment semaphore.h
-+@comment POSIX
-+@deftypefun int sem_destroy (sem_t * @var{sem})
-+@code{sem_destroy} destroys a semaphore object, freeing the resources it
-+might hold. If any threads are waiting on the semaphore when
-+@code{sem_destroy} is called, it fails and sets @var{errno} to
-+@code{EBUSY}.
-+
-+In the LinuxThreads implementation, no resources are associated with
-+semaphore objects, thus @code{sem_destroy} actually does nothing except
-+checking that no thread is waiting on the semaphore. This will change
-+when process-shared semaphores are implemented.
-+@end deftypefun
-+
-+@comment semaphore.h
-+@comment POSIX
-+@deftypefun int sem_wait (sem_t * @var{sem})
-+@code{sem_wait} suspends the calling thread until the semaphore pointed
-+to by @var{sem} has non-zero count. It then atomically decreases the
-+semaphore count.
-+
-+@code{sem_wait} is a cancellation point. It always returns 0.
-+@end deftypefun
-+
-+@comment semaphore.h
-+@comment POSIX
-+@deftypefun int sem_trywait (sem_t * @var{sem})
-+@code{sem_trywait} is a non-blocking variant of @code{sem_wait}. If the
-+semaphore pointed to by @var{sem} has non-zero count, the count is
-+atomically decreased and @code{sem_trywait} immediately returns 0. If
-+the semaphore count is zero, @code{sem_trywait} immediately returns -1
-+and sets errno to @code{EAGAIN}.
-+@end deftypefun
-+
-+@comment semaphore.h
-+@comment POSIX
-+@deftypefun int sem_post (sem_t * @var{sem})
-+@code{sem_post} atomically increases the count of the semaphore pointed to
-+by @var{sem}. This function never blocks.
-+
-+@c !!! This para appears not to agree with the code.
-+On processors supporting atomic compare-and-swap (Intel 486, Pentium and
-+later, Alpha, PowerPC, MIPS II, Motorola 68k, Ultrasparc), the
-+@code{sem_post} function is can safely be called from signal handlers.
-+This is the only thread synchronization function provided by POSIX
-+threads that is async-signal safe. On the Intel 386 and earlier Sparc
-+chips, the current LinuxThreads implementation of @code{sem_post} is not
-+async-signal safe, because the hardware does not support the required
-+atomic operations.
-+
-+@code{sem_post} always succeeds and returns 0, unless the semaphore
-+count would exceed @code{SEM_VALUE_MAX} after being incremented. In
-+that case @code{sem_post} returns -1 and sets @var{errno} to
-+@code{EINVAL}. The semaphore count is left unchanged.
-+@end deftypefun
-+
-+@comment semaphore.h
-+@comment POSIX
-+@deftypefun int sem_getvalue (sem_t * @var{sem}, int * @var{sval})
-+@code{sem_getvalue} stores in the location pointed to by @var{sval} the
-+current count of the semaphore @var{sem}. It always returns 0.
-+@end deftypefun
-+
-+@node Thread-Specific Data
-+@section Thread-Specific Data
-+
-+Programs often need global or static variables that have different
-+values in different threads. Since threads share one memory space, this
-+cannot be achieved with regular variables. Thread-specific data is the
-+POSIX threads answer to this need.
-+
-+Each thread possesses a private memory block, the thread-specific data
-+area, or TSD area for short. This area is indexed by TSD keys. The TSD
-+area associates values of type @code{void *} to TSD keys. TSD keys are
-+common to all threads, but the value associated with a given TSD key can
-+be different in each thread.
-+
-+For concreteness, the TSD areas can be viewed as arrays of @code{void *}
-+pointers, TSD keys as integer indices into these arrays, and the value
-+of a TSD key as the value of the corresponding array element in the
-+calling thread.
-+
-+When a thread is created, its TSD area initially associates @code{NULL}
-+with all keys.
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_key_create (pthread_key_t *@var{key}, void (*destr_function) (void *))
-+@code{pthread_key_create} allocates a new TSD key. The key is stored in
-+the location pointed to by @var{key}. There is a limit of
-+@code{PTHREAD_KEYS_MAX} on the number of keys allocated at a given
-+time. The value initially associated with the returned key is
-+@code{NULL} in all currently executing threads.
-+
-+The @var{destr_function} argument, if not @code{NULL}, specifies a
-+destructor function associated with the key. When a thread terminates
-+via @code{pthread_exit} or by cancellation, @var{destr_function} is
-+called on the value associated with the key in that thread. The
-+@var{destr_function} is not called if a key is deleted with
-+@code{pthread_key_delete} or a value is changed with
-+@code{pthread_setspecific}. The order in which destructor functions are
-+called at thread termination time is unspecified.
-+
-+Before the destructor function is called, the @code{NULL} value is
-+associated with the key in the current thread. A destructor function
-+might, however, re-associate non-@code{NULL} values to that key or some
-+other key. To deal with this, if after all the destructors have been
-+called for all non-@code{NULL} values, there are still some
-+non-@code{NULL} values with associated destructors, then the process is
-+repeated. The LinuxThreads implementation stops the process after
-+@code{PTHREAD_DESTRUCTOR_ITERATIONS} iterations, even if some
-+non-@code{NULL} values with associated descriptors remain. Other
-+implementations may loop indefinitely.
-+
-+@code{pthread_key_create} returns 0 unless @code{PTHREAD_KEYS_MAX} keys
-+have already been allocated, in which case it fails and returns
-+@code{EAGAIN}.
-+@end deftypefun
-+
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_key_delete (pthread_key_t @var{key})
-+@code{pthread_key_delete} deallocates a TSD key. It does not check
-+whether non-@code{NULL} values are associated with that key in the
-+currently executing threads, nor call the destructor function associated
-+with the key.
-+
-+If there is no such key @var{key}, it returns @code{EINVAL}. Otherwise
-+it returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_setspecific (pthread_key_t @var{key}, const void *@var{pointer})
-+@code{pthread_setspecific} changes the value associated with @var{key}
-+in the calling thread, storing the given @var{pointer} instead.
-+
-+If there is no such key @var{key}, it returns @code{EINVAL}. Otherwise
-+it returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun {void *} pthread_getspecific (pthread_key_t @var{key})
-+@code{pthread_getspecific} returns the value currently associated with
-+@var{key} in the calling thread.
-+
-+If there is no such key @var{key}, it returns @code{NULL}.
-+@end deftypefun
-+
-+The following code fragment allocates a thread-specific array of 100
-+characters, with automatic reclaimation at thread exit:
-+
-+@smallexample
-+/* Key for the thread-specific buffer */
-+static pthread_key_t buffer_key;
-+
-+/* Once-only initialisation of the key */
-+static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
-+
-+/* Allocate the thread-specific buffer */
-+void buffer_alloc(void)
-+@{
-+ pthread_once(&buffer_key_once, buffer_key_alloc);
-+ pthread_setspecific(buffer_key, malloc(100));
-+@}
-+
-+/* Return the thread-specific buffer */
-+char * get_buffer(void)
-+@{
-+ return (char *) pthread_getspecific(buffer_key);
-+@}
-+
-+/* Allocate the key */
-+static void buffer_key_alloc()
-+@{
-+ pthread_key_create(&buffer_key, buffer_destroy);
-+@}
-+
-+/* Free the thread-specific buffer */
-+static void buffer_destroy(void * buf)
-+@{
-+ free(buf);
-+@}
-+@end smallexample
-+
-+@node Threads and Signal Handling
-+@section Threads and Signal Handling
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_sigmask (int @var{how}, const sigset_t *@var{newmask}, sigset_t *@var{oldmask})
-+@code{pthread_sigmask} changes the signal mask for the calling thread as
-+described by the @var{how} and @var{newmask} arguments. If @var{oldmask}
-+is not @code{NULL}, the previous signal mask is stored in the location
-+pointed to by @var{oldmask}.
-+
-+The meaning of the @var{how} and @var{newmask} arguments is the same as
-+for @code{sigprocmask}. If @var{how} is @code{SIG_SETMASK}, the signal
-+mask is set to @var{newmask}. If @var{how} is @code{SIG_BLOCK}, the
-+signals specified to @var{newmask} are added to the current signal mask.
-+If @var{how} is @code{SIG_UNBLOCK}, the signals specified to
-+@var{newmask} are removed from the current signal mask.
-+
-+Recall that signal masks are set on a per-thread basis, but signal
-+actions and signal handlers, as set with @code{sigaction}, are shared
-+between all threads.
-+
-+The @code{pthread_sigmask} function returns 0 on success, and one of the
-+following error codes on error:
-+@table @code
-+@item EINVAL
-+@var{how} is not one of @code{SIG_SETMASK}, @code{SIG_BLOCK}, or @code{SIG_UNBLOCK}
-+
-+@item EFAULT
-+@var{newmask} or @var{oldmask} point to invalid addresses
-+@end table
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_kill (pthread_t @var{thread}, int @var{signo})
-+@code{pthread_kill} sends signal number @var{signo} to the thread
-+@var{thread}. The signal is delivered and handled as described in
-+@ref{Signal Handling}.
-+
-+@code{pthread_kill} returns 0 on success, one of the following error codes
-+on error:
-+@table @code
-+@item EINVAL
-+@var{signo} is not a valid signal number
-+
-+@item ESRCH
-+The thread @var{thread} does not exist (e.g. it has already terminated)
-+@end table
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int sigwait (const sigset_t *@var{set}, int *@var{sig})
-+@code{sigwait} suspends the calling thread until one of the signals in
-+@var{set} is delivered to the calling thread. It then stores the number
-+of the signal received in the location pointed to by @var{sig} and
-+returns. The signals in @var{set} must be blocked and not ignored on
-+entrance to @code{sigwait}. If the delivered signal has a signal handler
-+function attached, that function is @emph{not} called.
-+
-+@code{sigwait} is a cancellation point. It always returns 0.
-+@end deftypefun
-+
-+For @code{sigwait} to work reliably, the signals being waited for must be
-+blocked in all threads, not only in the calling thread, since
-+otherwise the POSIX semantics for signal delivery do not guarantee
-+that it's the thread doing the @code{sigwait} that will receive the signal.
-+The best way to achieve this is block those signals before any threads
-+are created, and never unblock them in the program other than by
-+calling @code{sigwait}.
-+
-+Signal handling in LinuxThreads departs significantly from the POSIX
-+standard. According to the standard, ``asynchronous'' (external) signals
-+are addressed to the whole process (the collection of all threads),
-+which then delivers them to one particular thread. The thread that
-+actually receives the signal is any thread that does not currently block
-+the signal.
-+
-+In LinuxThreads, each thread is actually a kernel process with its own
-+PID, so external signals are always directed to one particular thread.
-+If, for instance, another thread is blocked in @code{sigwait} on that
-+signal, it will not be restarted.
-+
-+The LinuxThreads implementation of @code{sigwait} installs dummy signal
-+handlers for the signals in @var{set} for the duration of the
-+wait. Since signal handlers are shared between all threads, other
-+threads must not attach their own signal handlers to these signals, or
-+alternatively they should all block these signals (which is recommended
-+anyway).
-+
-+@node Miscellaneous Thread Functions
-+@section Miscellaneous Thread Functions
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun {pthread_t} pthread_self (@var{void})
-+@code{pthread_self} returns the thread identifier for the calling thread.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_equal (pthread_t thread1, pthread_t thread2)
-+@code{pthread_equal} determines if two thread identifiers refer to the same
-+thread.
-+
-+A non-zero value is returned if @var{thread1} and @var{thread2} refer to
-+the same thread. Otherwise, 0 is returned.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_detach (pthread_t @var{th})
-+@code{pthread_detach} puts the thread @var{th} in the detached
-+state. This guarantees that the memory resources consumed by @var{th}
-+will be freed immediately when @var{th} terminates. However, this
-+prevents other threads from synchronizing on the termination of @var{th}
-+using @code{pthread_join}.
-+
-+A thread can be created initially in the detached state, using the
-+@code{detachstate} attribute to @code{pthread_create}. In contrast,
-+@code{pthread_detach} applies to threads created in the joinable state,
-+and which need to be put in the detached state later.
-+
-+After @code{pthread_detach} completes, subsequent attempts to perform
-+@code{pthread_join} on @var{th} will fail. If another thread is already
-+joining the thread @var{th} at the time @code{pthread_detach} is called,
-+@code{pthread_detach} does nothing and leaves @var{th} in the joinable
-+state.
-+
-+On success, 0 is returned. On error, one of the following codes is
-+returned:
-+@table @code
-+@item ESRCH
-+No thread could be found corresponding to that specified by @var{th}
-+@item EINVAL
-+The thread @var{th} is already in the detached state
-+@end table
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_atfork (void (*@var{prepare})(void), void (*@var{parent})(void), void (*@var{child})(void))
-+
-+@code{pthread_atfork} registers handler functions to be called just
-+before and just after a new process is created with @code{fork}. The
-+@var{prepare} handler will be called from the parent process, just
-+before the new process is created. The @var{parent} handler will be
-+called from the parent process, just before @code{fork} returns. The
-+@var{child} handler will be called from the child process, just before
-+@code{fork} returns.
-+
-+@code{pthread_atfork} returns 0 on success and a non-zero error code on
-+error.
-+
-+One or more of the three handlers @var{prepare}, @var{parent} and
-+@var{child} can be given as @code{NULL}, meaning that no handler needs
-+to be called at the corresponding point.
-+
-+@code{pthread_atfork} can be called several times to install several
-+sets of handlers. At @code{fork} time, the @var{prepare} handlers are
-+called in LIFO order (last added with @code{pthread_atfork}, first
-+called before @code{fork}), while the @var{parent} and @var{child}
-+handlers are called in FIFO order (first added, first called).
-+
-+If there is insufficient memory available to register the handlers,
-+@code{pthread_atfork} fails and returns @code{ENOMEM}. Otherwise it
-+returns 0.
-+@end deftypefun
-+
-+To understand the purpose of @code{pthread_atfork}, recall that
-+@code{fork} duplicates the whole memory space, including mutexes in
-+their current locking state, but only the calling thread: other threads
-+are not running in the child process. Thus, if a mutex is locked by a
-+thread other than the thread calling @code{fork}, that mutex will remain
-+locked forever in the child process, possibly blocking the execution of
-+the child process. To avoid this, install handlers with
-+@code{pthread_atfork} as follows: the @var{prepare} handler locks the
-+global mutexes (in locking order), and the @var{parent} and @var{child}
-+handlers unlock them (in reverse order). Alternatively, @var{prepare}
-+and @var{parent} can be set to @code{NULL} and @var{child} to a function
-+that calls @code{pthread_mutex_init} on the global mutexes.
-+
-+@comment pthread.h
-+@comment GNU
-+@deftypefun void pthread_kill_other_threads_np (@var{void})
-+@code{pthread_kill_other_threads_np} is a non-portable LinuxThreads extension.
-+It causes all threads in the program to terminate immediately, except
-+the calling thread which proceeds normally. It is intended to be
-+called just before a thread calls one of the @code{exec} functions,
-+e.g. @code{execve}.
-+
-+Termination of the other threads is not performed through
-+@code{pthread_cancel} and completely bypasses the cancellation
-+mechanism. Hence, the current settings for cancellation state and
-+cancellation type are ignored, and the cleanup handlers are not
-+executed in the terminated threads.
-+
-+According to POSIX 1003.1c, a successful @code{exec*} in one of the
-+threads should automatically terminate all other threads in the program.
-+This behavior is not yet implemented in LinuxThreads. Calling
-+@code{pthread_kill_other_threads_np} before @code{exec*} achieves much
-+of the same behavior, except that if @code{exec*} ultimately fails, then
-+all other threads are already killed.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_once (pthread_once_t *once_@var{control}, void (*@var{init_routine}) (void))
-+
-+The purpose of @code{pthread_once} is to ensure that a piece of
-+initialization code is executed at most once. The @var{once_control}
-+argument points to a static or extern variable statically initialized
-+to @code{PTHREAD_ONCE_INIT}.
-+
-+The first time @code{pthread_once} is called with a given
-+@var{once_control} argument, it calls @var{init_routine} with no
-+argument and changes the value of the @var{once_control} variable to
-+record that initialization has been performed. Subsequent calls to
-+@code{pthread_once} with the same @code{once_control} argument do
-+nothing.
-+
-+@code{pthread_once} always returns 0.
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_setschedparam (pthread_t target_@var{thread}, int @var{policy}, const struct sched_param *@var{param})
-+
-+@code{pthread_setschedparam} sets the scheduling parameters for the
-+thread @var{target_thread} as indicated by @var{policy} and
-+@var{param}. @var{policy} can be either @code{SCHED_OTHER} (regular,
-+non-realtime scheduling), @code{SCHED_RR} (realtime, round-robin) or
-+@code{SCHED_FIFO} (realtime, first-in first-out). @var{param} specifies
-+the scheduling priority for the two realtime policies. See
-+@code{sched_setpolicy} for more information on scheduling policies.
-+
-+The realtime scheduling policies @code{SCHED_RR} and @code{SCHED_FIFO}
-+are available only to processes with superuser privileges.
-+
-+On success, @code{pthread_setschedparam} returns 0. On error it returns
-+one of the following codes:
-+@table @code
-+@item EINVAL
-+@var{policy} is not one of @code{SCHED_OTHER}, @code{SCHED_RR},
-+@code{SCHED_FIFO}, or the priority value specified by @var{param} is not
-+valid for the specified policy
-+
-+@item EPERM
-+Realtime scheduling was requested but the calling process does not have
-+sufficient privileges.
-+
-+@item ESRCH
-+The @var{target_thread} is invalid or has already terminated
-+
-+@item EFAULT
-+@var{param} points outside the process memory space
-+@end table
-+@end deftypefun
-+
-+@comment pthread.h
-+@comment POSIX
-+@deftypefun int pthread_getschedparam (pthread_t target_@var{thread}, int *@var{policy}, struct sched_param *@var{param})
-+
-+@code{pthread_getschedparam} retrieves the scheduling policy and
-+scheduling parameters for the thread @var{target_thread} and stores them
-+in the locations pointed to by @var{policy} and @var{param},
-+respectively.
-+
-+@code{pthread_getschedparam} returns 0 on success, or one of the
-+following error codes on failure:
-+@table @code
-+@item ESRCH
-+The @var{target_thread} is invalid or has already terminated.
-+
-+@item EFAULT
-+@var{policy} or @var{param} point outside the process memory space.
-+
-+@end table
-+@end deftypefun
-diff -Naur ../glibc-2.1.3/linuxthreads/lockfile.c glibc-2.1.3/linuxthreads/lockfile.c
---- ../glibc-2.1.3/linuxthreads/lockfile.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/lockfile.c 1999-12-27 08:10:10.000000000 -0800
-@@ -0,0 +1,88 @@
-+/* lockfile - Handle locking and unlocking of stream.
-+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <bits/libc-lock.h>
-+#include <stdio.h>
-+#include <pthread.h>
-+
-+#ifdef USE_IN_LIBIO
-+#include "../libio/libioP.h"
-+#endif
-+
-+void
-+__flockfile (FILE *stream)
-+{
-+#ifdef USE_IN_LIBIO
-+ __pthread_mutex_lock (stream->_lock);
-+#else
-+#endif
-+}
-+#ifdef USE_IN_LIBIO
-+#undef _IO_flockfile
-+strong_alias (__flockfile, _IO_flockfile)
-+#endif
-+weak_alias (__flockfile, flockfile);
-+
-+
-+void
-+__funlockfile (FILE *stream)
-+{
-+#ifdef USE_IN_LIBIO
-+ __pthread_mutex_unlock (stream->_lock);
-+#else
-+#endif
-+}
-+#ifdef USE_IN_LIBIO
-+#undef _IO_funlockfile
-+strong_alias (__funlockfile, _IO_funlockfile)
-+#endif
-+weak_alias (__funlockfile, funlockfile);
-+
-+
-+int
-+__ftrylockfile (FILE *stream)
-+{
-+#ifdef USE_IN_LIBIO
-+ return __pthread_mutex_trylock (stream->_lock);
-+#else
-+#endif
-+}
-+#ifdef USE_IN_LIBIO
-+strong_alias (__ftrylockfile, _IO_ftrylockfile)
-+#endif
-+weak_alias (__ftrylockfile, ftrylockfile);
-+
-+
-+void
-+__fresetlockfiles (void)
-+{
-+#ifdef USE_IN_LIBIO
-+ _IO_FILE *fp;
-+ pthread_mutexattr_t attr;
-+
-+ __pthread_mutexattr_init (&attr);
-+ __pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE_NP);
-+
-+ for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
-+ if (fp->_lock)
-+ __pthread_mutex_init (fp->_lock, &attr);
-+
-+ __pthread_mutexattr_destroy (&attr);
-+#endif
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/man/Makefile glibc-2.1.3/linuxthreads/man/Makefile
---- ../glibc-2.1.3/linuxthreads/man/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/Makefile 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,31 @@
-+SOURCES=pthread_atfork.man pthread_attr_init.man pthread_cancel.man \
-+ pthread_cleanup_push.man pthread_cond_init.man \
-+ pthread_condattr_init.man pthread_create.man pthread_detach.man \
-+ pthread_equal.man pthread_exit.man pthread_join.man \
-+ pthread_key_create.man pthread_mutex_init.man \
-+ pthread_mutexattr_init.man pthread_once.man pthread_self.man \
-+ pthread_setschedparam.man pthread_sigmask.man sem_init.man \
-+ pthread_kill_other_threads_np.man
-+
-+MANPAGES=$(SOURCES:.man=.3thr)
-+
-+PREPRO=perl troffprepro
-+
-+MANDIR=/usr/man/man3
-+
-+all: $(MANPAGES)
-+
-+.SUFFIXES: .man .3thr
-+
-+.man.3thr:
-+ $(PREPRO) $*.man $*.3thr
-+
-+$(MANPAGES): troffprepro
-+
-+clean:
-+ rm -f *.3thr
-+ rm -f *~
-+
-+install:
-+ install *.3thr $(MANDIR)
-+ @echo "*** Remember to run /usr/sbin/makewhatis `dirname $(MANDIR)` at some point"
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_atfork.man glibc-2.1.3/linuxthreads/man/pthread_atfork.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_atfork.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_atfork.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,58 @@
-+.TH PTHREAD_ATFORK 3 LinuxThreads
-+
-+.SH NAME
-+pthread_atfork \- register handlers to be called at fork(2) time
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
-+
-+.SH DESCRIPTION
-+
-+!pthread_atfork! registers handler functions to be called just before
-+and just after a new process is created with !fork!(2). The |prepare|
-+handler will be called from the parent process, just before the new
-+process is created. The |parent| handler will be called from the parent
-+process, just before !fork!(2) returns. The |child| handler will be
-+called from the child process, just before !fork!(2) returns.
-+
-+One or several of the three handlers |prepare|, |parent| and |child|
-+can be given as !NULL!, meaning that no handler needs to be called at
-+the corresponding point.
-+
-+!pthread_atfork! can be called several times to install several sets
-+of handlers. At !fork!(2) time, the |prepare| handlers are called in
-+LIFO order (last added with !pthread_atfork!, first called before !fork!),
-+while the |parent| and |child| handlers are called in FIFO order
-+(first added, first called).
-+
-+To understand the purpose of !pthread_atfork!, recall that !fork!(2)
-+duplicates the whole memory space, including mutexes in their current
-+locking state, but only the calling thread: other threads are not
-+running in the child process. Thus, if a mutex is locked by a thread
-+other than the thread calling !fork!, that mutex will remain locked
-+forever in the child process, possibly blocking the execution of the
-+child process. To avoid this, install handlers with !pthread_atfork!
-+as follows: the |prepare| handler locks the global mutexes (in locking
-+order), and the |parent| and |child| handlers unlock them (in
-+reverse order). Alternatively, |prepare| and |parent| can be set to
-+!NULL! and |child| to a function that calls !pthread_mutex_init! on
-+the global mutexes.
-+
-+.SH "RETURN VALUE"
-+
-+!pthread_atfork! returns 0 on success and a non-zero error code on error.
-+
-+.SH ERRORS
-+.TP
-+!ENOMEM!
-+insufficient memory available to register the handlers.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!fork!(2),
-+!pthread_mutex_lock!(3),
-+!pthread_mutex_unlock!(3).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_attr_init.man glibc-2.1.3/linuxthreads/man/pthread_attr_init.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_attr_init.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_attr_init.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,221 @@
-+.TH PTHREAD_ATTR_INIT 3 LinuxThreads
-+
-+.XREF pthread_attr_destroy
-+.XREF pthread_attr_setdetachstate
-+.XREF pthread_attr_getdetachstate
-+.XREF pthread_attr_setschedparam
-+.XREF pthread_attr_getschedparam
-+.XREF pthread_attr_setschedpolicy
-+.XREF pthread_attr_getschedpolicy
-+.XREF pthread_attr_setinheritsched
-+.XREF pthread_attr_getinheritsched
-+.XREF pthread_attr_setscope
-+.XREF pthread_attr_getscope
-+
-+.SH NAME
-+pthread_attr_init, pthread_attr_destroy, pthread_attr_setdetachstate, pthread_attr_getdetachstate, pthread_attr_setschedparam, pthread_attr_getschedparam, pthread_attr_setschedpolicy, pthread_attr_getschedpolicy, pthread_attr_setinheritsched, pthread_attr_getinheritsched, pthread_attr_setscope, pthread_attr_getscope \- thread creation attributes
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_attr_init(pthread_attr_t *attr);
-+
-+int pthread_attr_destroy(pthread_attr_t *attr);
-+
-+int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
-+
-+int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
-+
-+int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
-+
-+int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
-+
-+int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
-+
-+int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
-+
-+int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
-+
-+int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit);
-+
-+int pthread_attr_setscope(pthread_attr_t *attr, int scope);
-+
-+int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);
-+
-+.SH DESCRIPTION
-+
-+Setting attributes for threads is achieved by filling a
-+thread attribute object |attr| of type !pthread_attr_t!, then passing it as
-+second argument to !pthread_create!(3). Passing !NULL! is equivalent to
-+passing a thread attribute object with all attributes set to their
-+default values.
-+
-+!pthread_attr_init! initializes the thread attribute object |attr| and
-+fills it with default values for the attributes. (The default values
-+are listed below for each attribute.)
-+
-+Each attribute |attrname| (see below for a list of all attributes) can
-+be individually set using the function !pthread_attr_set!|attrname|
-+and retrieved using the function !pthread_attr_get!|attrname|.
-+
-+!pthread_attr_destroy! destroys a thread attribute object, which
-+must not be reused until it is reinitialized. !pthread_attr_destroy!
-+does nothing in the LinuxThreads implementation.
-+
-+Attribute objects are consulted only when creating a new thread. The
-+same attribute object can be used for creating several
-+threads. Modifying an attribute object after a call to
-+!pthread_create! does not change the attributes of the thread
-+previously created.
-+
-+The following thread attributes are supported:
-+
-+.SS detachstate
-+
-+Control whether the thread is created in the joinable state (value
-+!PTHREAD_CREATE_JOINABLE!) or in the detached state
-+(!PTHREAD_CREATE_DETACHED!).
-+
-+Default value: !PTHREAD_CREATE_JOINABLE!.
-+
-+In the joinable state, another thread can synchronize on the thread
-+termination and recover its termination code using !pthread_join!(3),
-+but some of the thread resources are kept allocated after the thread
-+terminates, and reclaimed only when another thread performs
-+!pthread_join!(3) on that thread.
-+
-+In the detached state, the thread resources are immediately freed when
-+it terminates, but !pthread_join!(3) cannot be used to synchronize on
-+the thread termination.
-+
-+A thread created in the joinable state can later be put in the
-+detached thread using !pthread_detach!(3).
-+
-+.SS schedpolicy
-+
-+Select the scheduling policy for the thread: one of
-+!SCHED_OTHER! (regular, non-realtime scheduling),
-+!SCHED_RR! (realtime, round-robin) or
-+!SCHED_FIFO! (realtime, first-in first-out). See
-+!sched_setpolicy!(2) for more information on scheduling policies.
-+
-+Default value: !SCHED_OTHER!.
-+
-+The realtime scheduling policies !SCHED_RR! and !SCHED_FIFO! are
-+available only to processes with superuser privileges.
-+
-+The scheduling policy of a thread can be changed after creation with
-+!pthread_setschedparam!(3).
-+
-+.SS schedparam
-+
-+Contain the scheduling parameters (essentially, the scheduling
-+priority) for the thread. See !sched_setparam!(2) for more information
-+on scheduling parameters.
-+
-+Default value: priority is 0.
-+
-+This attribute is not significant if the scheduling policy is !SCHED_OTHER!;
-+it only matters for the realtime policies !SCHED_RR! and !SCHED_FIFO!.
-+
-+The scheduling priority of a thread can be changed after creation with
-+!pthread_setschedparam!(3).
-+
-+.SS inheritsched
-+
-+Indicate whether the scheduling policy and scheduling parameters for
-+the newly created thread are determined by the values of the
-+|schedpolicy| and |schedparam| attributes (value
-+!PTHREAD_EXPLICIT_SCHED!) or are inherited from the parent thread
-+(value !PTHREAD_INHERIT_SCHED!).
-+
-+Default value: !PTHREAD_EXPLICIT_SCHED!.
-+
-+.SS scope
-+
-+Define the scheduling contention scope for the created thread. The
-+only value supported in the LinuxThreads implementation is
-+!PTHREAD_SCOPE_SYSTEM!, meaning that the threads contend for CPU time
-+with all processes running on the machine. In particular, thread
-+priorities are interpreted relative to the priorities of all other
-+processes on the machine. The other value specified by the standard,
-+!PTHREAD_SCOPE_PROCESS!, means that scheduling contention occurs only
-+between the threads of the running process: thread priorities are
-+interpreted relative to the priorities of the other threads of the
-+process, regardless of the priorities of other processes.
-+!PTHREAD_SCOPE_PROCESS! is not supported in LinuxThreads.
-+
-+Default value: !PTHREAD_SCOPE_SYSTEM!.
-+
-+.SH "RETURN VALUE"
-+
-+All functions return 0 on success and a non-zero error code on error.
-+On success, the !pthread_attr_get!|attrname| functions also store the
-+current value of the attribute |attrname| in the location pointed to
-+by their second argument.
-+
-+.SH ERRORS
-+
-+The !pthread_attr_setdetachstate! function returns the following error
-+codes on error:
-+.RS
-+.TP
-+!EINVAL!
-+the specified |detachstate| is not one of !PTHREAD_CREATE_JOINABLE! or
-+!PTHREAD_CREATE_DETACHED!.
-+.RE
-+
-+The !pthread_attr_setschedparam! function returns the following error
-+codes on error:
-+.RS
-+.TP
-+!EINVAL!
-+the priority specified in |param| is outside the range of allowed
-+priorities for the scheduling policy currently in |attr|
-+(1 to 99 for !SCHED_FIFO! and !SCHED_RR!; 0 for !SCHED_OTHER!).
-+.RE
-+
-+The !pthread_attr_setschedpolicy! function returns the following error
-+codes on error:
-+.RS
-+.TP
-+!EINVAL!
-+the specified |policy| is not one of !SCHED_OTHER!, !SCHED_FIFO!, or
-+!SCHED_RR!.
-+
-+.TP
-+!ENOTSUP!
-+|policy| is !SCHED_FIFO! or !SCHED_RR!, and the effective user of the
-+calling process is not super-user.
-+.RE
-+
-+The !pthread_attr_setinheritsched! function returns the following error
-+codes on error:
-+.RS
-+.TP
-+!EINVAL!
-+the specified |inherit| is not one of !PTHREAD_INHERIT_SCHED! or
-+!PTHREAD_EXPLICIT_SCHED!.
-+.RE
-+
-+The !pthread_attr_setscope! function returns the following error
-+codes on error:
-+.RS
-+.TP
-+!EINVAL!
-+the specified |scope| is not one of !PTHREAD_SCOPE_SYSTEM! or
-+!PTHREAD_SCOPE_PROCESS!.
-+
-+.TP
-+!ENOTSUP!
-+the specified |scope| is !PTHREAD_SCOPE_PROCESS! (not supported).
-+.RE
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_create!(3),
-+!pthread_join!(3),
-+!pthread_detach!(3),
-+!pthread_setschedparam!(3).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_cancel.man glibc-2.1.3/linuxthreads/man/pthread_cancel.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_cancel.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_cancel.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,155 @@
-+.TH PTHREAD_CANCEL 3 LinuxThreads
-+
-+.XREF pthread_setcancelstate
-+.XREF pthread_setcanceltype
-+.XREF pthread_testcancel
-+
-+.SH NAME
-+pthread_cancel, pthread_setcancelstate, pthread_setcanceltype, pthread_testcancel \- thread cancellation
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_cancel(pthread_t thread);
-+
-+int pthread_setcancelstate(int state, int *oldstate);
-+
-+int pthread_setcanceltype(int type, int *oldtype);
-+
-+void pthread_testcancel(void);
-+
-+.SH DESCRIPTION
-+
-+Cancellation is the mechanism by which a thread can terminate the
-+execution of another thread. More precisely, a thread can send a
-+cancellation request to another thread. Depending on its settings, the
-+target thread can then either ignore the request, honor it
-+immediately, or defer it till it reaches a cancellation point.
-+
-+When a thread eventually honors a cancellation request, it performs as
-+if !pthread_exit(PTHREAD_CANCELED)! has been called at that point:
-+all cleanup handlers are executed in reverse order, finalization
-+functions for thread-specific data are called, and finally the thread
-+stops executing with the return value !PTHREAD_CANCELED!. See
-+!pthread_exit!(3) for more information.
-+
-+!pthread_cancel! sends a cancellation request to the thread denoted
-+by the |thread| argument.
-+
-+!pthread_setcancelstate! changes the cancellation state for the
-+calling thread -- that is, whether cancellation requests are ignored
-+or not. The |state| argument is the new cancellation state: either
-+!PTHREAD_CANCEL_ENABLE! to enable cancellation, or
-+!PTHREAD_CANCEL_DISABLE! to disable cancellation (cancellation
-+requests are ignored). If |oldstate| is not !NULL!, the previous
-+cancellation state is stored in the location pointed to by |oldstate|,
-+and can thus be restored later by another call to
-+!pthread_setcancelstate!.
-+
-+!pthread_setcanceltype! changes the type of responses to cancellation
-+requests for the calling thread: asynchronous (immediate) or deferred.
-+The |type| argument is the new cancellation type: either
-+!PTHREAD_CANCEL_ASYNCHRONOUS! to cancel the calling thread as soon as
-+the cancellation request is received, or !PTHREAD_CANCEL_DEFERRED! to
-+keep the cancellation request pending until the next cancellation
-+point. If |oldtype| is not !NULL!, the previous
-+cancellation state is stored in the location pointed to by |oldtype|,
-+and can thus be restored later by another call to
-+!pthread_setcanceltype!.
-+
-+Threads are always created by !pthread_create!(3) with cancellation
-+enabled and deferred. That is, the initial cancellation state is
-+!PTHREAD_CANCEL_ENABLE! and the initial type is
-+!PTHREAD_CANCEL_DEFERRED!.
-+
-+Cancellation points are those points in the program execution where a
-+test for pending cancellation requests is performed and cancellation
-+is executed if positive. The following POSIX threads functions
-+are cancellation points:
-+
-+!pthread_join!(3)
-+.br
-+!pthread_cond_wait!(3)
-+.br
-+!pthread_cond_timedwait!(3)
-+.br
-+!pthread_testcancel!(3)
-+.br
-+!sem_wait!(3)
-+.br
-+!sigwait!(3)
-+
-+All other POSIX threads functions are guaranteed not to be
-+cancellation points. That is, they never perform cancellation in
-+deferred cancellation mode.
-+
-+!pthread_testcancel! does nothing except testing for pending
-+cancellation and executing it. Its purpose is to introduce explicit
-+checks for cancellation in long sequences of code that do not call
-+cancellation point functions otherwise.
-+
-+.SH "RETURN VALUE"
-+
-+!pthread_cancel!, !pthread_setcancelstate! and
-+!pthread_setcanceltype! return 0 on success and a non-zero error code
-+on error.
-+
-+.SH ERRORS
-+!pthread_cancel! returns the following error code on error:
-+.RS
-+.TP
-+!ESRCH!
-+no thread could be found corresponding to that specified by the |thread| ID.
-+.RE
-+
-+!pthread_setcancelstate! returns the following error code on error:
-+.RS
-+.TP
-+!EINVAL!
-+the |state| argument is not !PTHREAD_CANCEL_ENABLE! nor
-+!PTHREAD_CANCEL_DISABLE!
-+.RE
-+
-+!pthread_setcanceltype! returns the following error code on error:
-+.RS
-+.TP
-+!EINVAL!
-+the |type| argument is not !PTHREAD_CANCEL_DEFERRED! nor
-+!PTHREAD_CANCEL_ASYNCHRONOUS!
-+.RE
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_exit!(3),
-+!pthread_cleanup_push!(3),
-+!pthread_cleanup_pop!(3).
-+
-+.SH BUGS
-+
-+POSIX specifies that a number of system calls (basically, all
-+system calls that may block, such as !read!(2), !write!(2), !wait!(2),
-+etc.) and library functions that may call these system calls (e.g.
-+!fprintf!(3)) are cancellation points. LinuxThreads is not yet
-+integrated enough with the C library to implement this, and thus none
-+of the C library functions is a cancellation point.
-+
-+For system calls at least, there is a workaround. Cancellation
-+requests are transmitted to the target thread by sending it a
-+signal. That signal will interrupt all blocking system calls, causing
-+them to return immediately with the !EINTR! error. So, checking for
-+cancellation during a !read! system call, for instance, can be
-+achieved as follows:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+pthread_testcancel();
-+retcode = read(fd, buffer, length);
-+pthread_testcancel();
-+.ft
-+.LP
-+.RE
-+.fi
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_cleanup_push.man glibc-2.1.3/linuxthreads/man/pthread_cleanup_push.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_cleanup_push.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_cleanup_push.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,194 @@
-+.TH PTHREAD_CLEANUP 3 LinuxThreads
-+
-+.XREF pthread_cleanup_pop
-+.XREF pthread_cleanup_push_defer_np
-+.XREF pthread_cleanup_pop_restore_np
-+
-+.SH NAME
-+pthread_cleanup_push, pthread_cleanup_pop, pthread_cleanup_push_defer_np, pthread_cleanup_pop_restore_np \- install and remove cleanup handlers
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+void pthread_cleanup_push(void (*routine) (void *), void *arg);
-+
-+void pthread_cleanup_pop(int execute);
-+
-+void pthread_cleanup_push_defer_np(void (*routine) (void *), void *arg);
-+
-+void pthread_cleanup_pop_restore_np(int execute);
-+
-+.SH DESCRIPTION
-+
-+Cleanup handlers are functions that get called when a thread
-+terminates, either by calling !pthread_exit!(3) or because of
-+cancellation. Cleanup handlers are installed and removed following a
-+stack-like discipline.
-+
-+The purpose of cleanup handlers is to free the resources that a thread
-+may hold at the time it terminates. In particular, if a thread
-+exits or is cancelled while it owns a locked mutex, the mutex will
-+remain locked forever and prevent other threads from executing
-+normally. The best way to avoid this is, just before locking the
-+mutex, to install a cleanup handler whose effect is to unlock the
-+mutex. Cleanup handlers can be used similarly to free blocks allocated
-+with !malloc!(3) or close file descriptors on thread termination.
-+
-+!pthread_cleanup_push! installs the |routine| function with argument
-+|arg| as a cleanup handler. From this point on to the matching
-+!pthread_cleanup_pop!, the function |routine| will be called with
-+arguments |arg| when the thread terminates, either through !pthread_exit!(3)
-+or by cancellation. If several cleanup handlers are active at that
-+point, they are called in LIFO order: the most recently installed
-+handler is called first.
-+
-+!pthread_cleanup_pop! removes the most recently installed cleanup
-+handler. If the |execute| argument is not 0, it also executes the
-+handler, by calling the |routine| function with arguments |arg|. If
-+the |execute| argument is 0, the handler is only removed but not
-+executed.
-+
-+Matching pairs of !pthread_cleanup_push! and !pthread_cleanup_pop!
-+must occur in the same function, at the same level of block nesting.
-+Actually, !pthread_cleanup_push! and !pthread_cleanup_pop! are macros,
-+and the expansion of !pthread_cleanup_push! introduces an open brace !{!
-+with the matching closing brace !}! being introduced by the expansion
-+of the matching !pthread_cleanup_pop!.
-+
-+!pthread_cleanup_push_defer_np! is a non-portable extension that
-+combines !pthread_cleanup_push! and !pthread_setcanceltype!(3).
-+It pushes a cleanup handler just as !pthread_cleanup_push! does, but
-+also saves the current cancellation type and sets it to deferred
-+cancellation. This ensures that the cleanup mechanism is effective
-+even if the thread was initially in asynchronous cancellation mode.
-+
-+!pthread_cleanup_pop_restore_np! pops a cleanup handler introduced by
-+!pthread_cleanup_push_defer_np!, and restores the cancellation type to
-+its value at the time !pthread_cleanup_push_defer_np! was called.
-+
-+!pthread_cleanup_push_defer_np! and !pthread_cleanup_pop_restore_np!
-+must occur in matching pairs, at the same level of block nesting.
-+
-+The following sequence
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+pthread_cleanup_push_defer_np(routine, arg);
-+...
-+pthread_cleanup_pop_defer_np(execute);
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+is functionally equivalent to (but more compact and more efficient than)
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+{ int oldtype;
-+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
-+ pthread_cleanup_push(routine, arg);
-+ ...
-+ pthread_cleanup_pop(execute);
-+ pthread_setcanceltype(oldtype, NULL);
-+}
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+.SH "RETURN VALUE"
-+
-+None.
-+
-+.SH ERRORS
-+
-+None.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_exit!(3),
-+!pthread_cancel!(3),
-+!pthread_setcanceltype!(3).
-+
-+.SH EXAMPLE
-+
-+Here is how to lock a mutex |mut| in such a way that it will be
-+unlocked if the thread is canceled while |mut| is locked:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
-+pthread_mutex_lock(&mut);
-+/* do some work */
-+pthread_mutex_unlock(&mut);
-+pthread_cleanup_pop(0);
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+Equivalently, the last two lines can be replaced by
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+pthread_cleanup_pop(1);
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+Notice that the code above is safe only in deferred cancellation mode
-+(see !pthread_setcanceltype!(3)). In asynchronous cancellation mode,
-+a cancellation can occur between !pthread_cleanup_push! and
-+!pthread_mutex_lock!, or between !pthread_mutex_unlock! and
-+!pthread_cleanup_pop!, resulting in both cases in the thread trying to
-+unlock a mutex not locked by the current thread. This is the main
-+reason why asynchronous cancellation is difficult to use.
-+
-+If the code above must also work in asynchronous cancellation mode,
-+then it must switch to deferred mode for locking and unlocking the
-+mutex:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
-+pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
-+pthread_mutex_lock(&mut);
-+/* do some work */
-+pthread_cleanup_pop(1);
-+pthread_setcanceltype(oldtype, NULL);
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+The code above can be rewritten in a more compact and more
-+efficient way, using the non-portable functions
-+!pthread_cleanup_push_defer_np! and !pthread_cleanup_pop_restore_np!:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+pthread_cleanup_push_restore_np(pthread_mutex_unlock, (void *) &mut);
-+pthread_mutex_lock(&mut);
-+/* do some work */
-+pthread_cleanup_pop_restore_np(1);
-+.ft
-+.LP
-+.RE
-+.fi
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_cond_init.man glibc-2.1.3/linuxthreads/man/pthread_cond_init.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_cond_init.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_cond_init.man 1999-06-16 15:34:07.000000000 -0700
-@@ -0,0 +1,234 @@
-+.TH PTHREAD_COND 3 LinuxThreads
-+
-+.XREF pthread_cond_signal
-+.XREF pthread_cond_broadcast
-+.XREF pthread_cond_wait
-+.XREF pthread_cond_timedwait
-+.XREF pthread_cond_destroy
-+
-+.SH NAME
-+pthread_cond_init, pthread_cond_destroy, pthread_cond_signal, pthread_cond_broadcast, pthread_cond_wait, pthread_cond_timedwait \- operations on conditions
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-+
-+int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
-+
-+int pthread_cond_signal(pthread_cond_t *cond);
-+
-+int pthread_cond_broadcast(pthread_cond_t *cond);
-+
-+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
-+
-+int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
-+
-+int pthread_cond_destroy(pthread_cond_t *cond);
-+
-+.SH DESCRIPTION
-+
-+A condition (short for ``condition variable'') is a synchronization
-+device that allows threads to suspend execution and relinquish the
-+processors until some predicate on shared data is satisfied. The basic
-+operations on conditions are: signal the condition (when the
-+predicate becomes true), and wait for the condition, suspending the
-+thread execution until another thread signals the condition.
-+
-+A condition variable must always be associated with a mutex, to avoid
-+the race condition where a thread prepares to wait on a condition
-+variable and another thread signals the condition just before the
-+first thread actually waits on it.
-+
-+!pthread_cond_init! initializes the condition variable |cond|, using the
-+condition attributes specified in |cond_attr|, or default attributes
-+if |cond_attr| is !NULL!. The LinuxThreads implementation supports no
-+attributes for conditions, hence the |cond_attr| parameter is actually
-+ignored.
-+
-+Variables of type !pthread_cond_t! can also be initialized
-+statically, using the constant !PTHREAD_COND_INITIALIZER!.
-+
-+!pthread_cond_signal! restarts one of the threads that are waiting on
-+the condition variable |cond|. If no threads are waiting on |cond|,
-+nothing happens. If several threads are waiting on |cond|, exactly one
-+is restarted, but it is not specified which.
-+
-+!pthread_cond_broadcast! restarts all the threads that are waiting on
-+the condition variable |cond|. Nothing happens if no threads are
-+waiting on |cond|.
-+
-+!pthread_cond_wait! atomically unlocks the |mutex| (as per
-+!pthread_unlock_mutex!) and waits for the condition variable |cond| to
-+be signaled. The thread execution is suspended and does not consume
-+any CPU time until the condition variable is signaled. The |mutex|
-+must be locked by the calling thread on entrance to
-+!pthread_cond_wait!. Before returning to the calling thread,
-+!pthread_cond_wait! re-acquires |mutex| (as per !pthread_lock_mutex!).
-+
-+Unlocking the mutex and suspending on the condition variable is done
-+atomically. Thus, if all threads always acquire the mutex before
-+signaling the condition, this guarantees that the condition cannot be
-+signaled (and thus ignored) between the time a thread locks the mutex
-+and the time it waits on the condition variable.
-+
-+!pthread_cond_timedwait! atomically unlocks |mutex| and waits on
-+|cond|, as !pthread_cond_wait! does, but it also bounds the duration
-+of the wait. If |cond| has not been signaled within the amount of time
-+specified by |abstime|, the mutex |mutex| is re-acquired and
-+!pthread_cond_timedwait! returns the error !ETIMEDOUT!.
-+The |abstime| parameter specifies an absolute time, with the same
-+origin as !time!(2) and !gettimeofday!(2): an |abstime| of 0
-+corresponds to 00:00:00 GMT, January 1, 1970.
-+
-+!pthread_cond_destroy! destroys a condition variable, freeing the
-+resources it might hold. No threads must be waiting on the condition
-+variable on entrance to !pthread_cond_destroy!. In the LinuxThreads
-+implementation, no resources are associated with condition variables,
-+thus !pthread_cond_destroy! actually does nothing except checking that
-+the condition has no waiting threads.
-+
-+.SH CANCELLATION
-+
-+!pthread_cond_wait! and !pthread_cond_timedwait! are cancellation
-+points. If a thread is cancelled while suspended in one of these
-+functions, the thread immediately resumes execution, then locks again
-+the |mutex| argument to !pthread_cond_wait! and
-+!pthread_cond_timedwait!, and finally executes the cancellation.
-+Consequently, cleanup handlers are assured that |mutex| is locked when
-+they are called.
-+
-+.SH "ASYNC-SIGNAL SAFETY"
-+
-+The condition functions are not async-signal safe, and should not be
-+called from a signal handler. In particular, calling
-+!pthread_cond_signal! or !pthread_cond_broadcast! from a signal
-+handler may deadlock the calling thread.
-+
-+.SH "RETURN VALUE"
-+
-+All condition variable functions return 0 on success and a non-zero
-+error code on error.
-+
-+.SH ERRORS
-+
-+!pthread_cond_init!, !pthread_cond_signal!, !pthread_cond_broadcast!,
-+and !pthread_cond_wait! never return an error code.
-+
-+The !pthread_cond_timedwait! function returns the following error codes
-+on error:
-+.RS
-+.TP
-+!ETIMEDOUT!
-+the condition variable was not signaled until the timeout specified by
-+|abstime|
-+
-+.TP
-+!EINTR!
-+!pthread_cond_timedwait! was interrupted by a signal
-+.RE
-+
-+The !pthread_cond_destroy! function returns the following error code
-+on error:
-+.RS
-+.TP
-+!EBUSY!
-+some threads are currently waiting on |cond|.
-+.RE
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_condattr_init!(3),
-+!pthread_mutex_lock!(3),
-+!pthread_mutex_unlock!(3),
-+!gettimeofday!(2),
-+!nanosleep!(2).
-+
-+.SH EXAMPLE
-+
-+Consider two shared variables |x| and |y|, protected by the mutex |mut|,
-+and a condition variable |cond| that is to be signaled whenever |x|
-+becomes greater than |y|.
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+int x,y;
-+pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
-+pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+Waiting until |x| is greater than |y| is performed as follows:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+pthread_mutex_lock(&mut);
-+while (x <= y) {
-+ pthread_cond_wait(&cond, &mut);
-+}
-+/* operate on x and y */
-+pthread_mutex_unlock(&mut);
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+Modifications on |x| and |y| that may cause |x| to become greater than
-+|y| should signal the condition if needed:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+pthread_mutex_lock(&mut);
-+/* modify x and y */
-+if (x > y) pthread_cond_broadcast(&cond);
-+pthread_mutex_unlock(&mut);
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+If it can be proved that at most one waiting thread needs to be waken
-+up (for instance, if there are only two threads communicating through
-+|x| and |y|), !pthread_cond_signal! can be used as a slightly more
-+efficient alternative to !pthread_cond_broadcast!. In doubt, use
-+!pthread_cond_broadcast!.
-+
-+To wait for |x| to becomes greater than |y| with a timeout of 5
-+seconds, do:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+struct timeval now;
-+struct timespec timeout;
-+int retcode;
-+
-+pthread_mutex_lock(&mut);
-+gettimeofday(&now);
-+timeout.tv_sec = now.tv_sec + 5;
-+timeout.tv_nsec = now.tv_usec * 1000;
-+retcode = 0;
-+while (x <= y && retcode != ETIMEDOUT) {
-+ retcode = pthread_cond_timedwait(&cond, &mut, &timeout);
-+}
-+if (retcode == ETIMEDOUT) {
-+ /* timeout occurred */
-+} else {
-+ /* operate on x and y */
-+}
-+pthread_mutex_unlock(&mut);
-+.ft
-+.LP
-+.RE
-+.fi
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_condattr_init.man glibc-2.1.3/linuxthreads/man/pthread_condattr_init.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_condattr_init.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_condattr_init.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,39 @@
-+.TH PTHREAD_CONDATTR 3 LinuxThreads
-+
-+.XREF pthread_condattr_destroy
-+
-+.SH NAME
-+pthread_condattr_init, pthread_condattr_destroy \- condition creation attributes
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_condattr_init(pthread_condattr_t *attr);
-+
-+int pthread_condattr_destroy(pthread_condattr_t *attr);
-+
-+.SH DESCRIPTION
-+
-+Condition attributes can be specified at condition creation time, by passing a
-+condition attribute object as second argument to !pthread_cond_init!(3).
-+Passing !NULL! is equivalent to passing a condition attribute object with
-+all attributes set to their default values.
-+
-+The LinuxThreads implementation supports no attributes for
-+conditions. The functions on condition attributes are included only
-+for compliance with the POSIX standard.
-+
-+!pthread_condattr_init! initializes the condition attribute object
-+|attr| and fills it with default values for the attributes.
-+!pthread_condattr_destroy! destroys a condition attribute object,
-+which must not be reused until it is reinitialized. Both functions do
-+nothing in the LinuxThreads implementation.
-+
-+.SH "RETURN VALUE"
-+!pthread_condattr_init! and !pthread_condattr_destroy! always return 0.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_cond_init!(3).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_create.man glibc-2.1.3/linuxthreads/man/pthread_create.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_create.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_create.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,46 @@
-+.TH PTHREAD_CREATE 3 LinuxThreads
-+
-+.SH NAME
-+pthread_create \- create a new thread
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);
-+
-+.SH DESCRIPTION
-+!pthread_create! creates a new thread of control that executes
-+concurrently with the calling thread. The new thread applies the
-+function |start_routine| passing it |arg| as first argument. The new
-+thread terminates either explicitly, by calling !pthread_exit!(3),
-+or implicitly, by returning from the |start_routine| function. The
-+latter case is equivalent to calling !pthread_exit!(3) with the result
-+returned by |start_routine| as exit code.
-+
-+The |attr| argument specifies thread attributes to be applied to the
-+new thread. See !pthread_attr_init!(3) for a complete list of thread
-+attributes. The |attr| argument can also be !NULL!, in which case
-+default attributes are used: the created thread is joinable (not
-+detached) and has default (non real-time) scheduling policy.
-+
-+.SH "RETURN VALUE"
-+On success, the identifier of the newly created thread is stored in
-+the location pointed by the |thread| argument, and a 0 is returned. On
-+error, a non-zero error code is returned.
-+
-+.SH ERRORS
-+.TP
-+!EAGAIN!
-+not enough system resources to create a process for the new thread.
-+.TP
-+!EAGAIN!
-+more than !PTHREAD_THREADS_MAX! threads are already active.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_exit!(3),
-+!pthread_join!(3),
-+!pthread_detach!(3),
-+!pthread_attr_init!(3).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_detach.man glibc-2.1.3/linuxthreads/man/pthread_detach.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_detach.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_detach.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,44 @@
-+.TH PTHREAD_DETACH 3 LinuxThreads
-+
-+.SH NAME
-+pthread_detach \- put a running thread in the detached state
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_detach(pthread_t th);
-+
-+.SH DESCRIPTION
-+!pthread_detach! put the thread |th| in the detached state. This
-+guarantees that the memory resources consumed by |th| will be freed
-+immediately when |th| terminates. However, this prevents other threads
-+from synchronizing on the termination of |th| using !pthread_join!.
-+
-+A thread can be created initially in the detached state, using the
-+!detachstate! attribute to !pthread_create!(3). In contrast,
-+!pthread_detach! applies to threads created in the joinable state, and
-+which need to be put in the detached state later.
-+
-+After !pthread_detach! completes, subsequent attempts to perform
-+!pthread_join! on |th| will fail. If another thread is already joining
-+the thread |th| at the time !pthread_detach! is called,
-+!pthread_detach! does nothing and leaves |th| in the joinable state.
-+
-+.SH "RETURN VALUE"
-+On success, 0 is returned. On error, a non-zero error code is returned.
-+
-+.SH ERRORS
-+.TP
-+!ESRCH!
-+No thread could be found corresponding to that specified by |th|
-+.TP
-+!EINVAL!
-+the thread |th| is already in the detached state
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_create!(3),
-+!pthread_join!(3),
-+!pthread_attr_setdetachstate!(3).
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_equal.man glibc-2.1.3/linuxthreads/man/pthread_equal.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_equal.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_equal.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,23 @@
-+.TH PTHREAD_EQUAL 3 LinuxThreads
-+
-+.SH NAME
-+pthread_equal \- compare two thread identifiers
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_equal(pthread_t thread1, pthread_t thread2);
-+
-+.SH DESCRIPTION
-+!pthread_equal! determines if two thread identifiers refer to the same
-+thread.
-+
-+.SH "RETURN VALUE"
-+A non-zero value is returned if |thread1| and |thread2| refer to the
-+same thread. Otherwise, 0 is returned.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_self!(3).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_exit.man glibc-2.1.3/linuxthreads/man/pthread_exit.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_exit.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_exit.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,32 @@
-+.TH PTHREAD_EXIT 3 LinuxThreads
-+
-+.SH NAME
-+pthread_exit \- terminate the calling thread
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+void pthread_exit(void *retval);
-+
-+.SH DESCRIPTION
-+!pthread_exit! terminates the execution of the calling thread.
-+All cleanup handlers that have been set for the calling thread with
-+!pthread_cleanup_push!(3) are executed in reverse order (the most
-+recently pushed handler is executed first). Finalization functions for
-+thread-specific data are then called for all keys that have non-!NULL!
-+values associated with them in the calling thread (see
-+!pthread_key_create!(3)). Finally, execution of the calling thread is
-+stopped.
-+
-+The |retval| argument is the return value of the thread. It can be
-+consulted from another thread using !pthread_join!(3).
-+
-+.SH "RETURN VALUE"
-+The !pthread_exit! function never returns.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_create!(3),
-+!pthread_join!(3).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_join.man glibc-2.1.3/linuxthreads/man/pthread_join.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_join.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_join.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,70 @@
-+.TH PTHREAD_JOIN 3 LinuxThreads
-+
-+.SH NAME
-+pthread_join \- wait for termination of another thread
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_join(pthread_t th, void **thread_return);
-+
-+.SH DESCRIPTION
-+!pthread_join! suspends the execution of the calling thread until the
-+thread identified by |th| terminates, either by calling !pthread_exit!(3)
-+or by being cancelled.
-+
-+If |thread_return| is not !NULL!, the return value of |th| is stored
-+in the location pointed to by |thread_return|. The return value of
-+|th| is either the argument it gave to !pthread_exit!(3), or
-+!PTHREAD_CANCELED! if |th| was cancelled.
-+
-+The joined thread !th! must be in the joinable state: it must not have
-+been detached using !pthread_detach!(3) or the
-+!PTHREAD_CREATE_DETACHED! attribute to !pthread_create!(3).
-+
-+When a joinable thread terminates, its memory resources (thread
-+descriptor and stack) are not deallocated until another thread
-+performs !pthread_join! on it. Therefore, !pthread_join! must be
-+called once for each joinable thread created to avoid memory leaks.
-+
-+At most one thread can wait for the termination of a given
-+thread. Calling !pthread_join! on a thread |th| on which another
-+thread is already waiting for termination returns an error.
-+
-+.SH CANCELLATION
-+
-+!pthread_join! is a cancellation point. If a thread is canceled while
-+suspended in !pthread_join!, the thread execution resumes immediately
-+and the cancellation is executed without waiting for the |th| thread
-+to terminate. If cancellation occurs during !pthread_join!, the |th|
-+thread remains not joined.
-+
-+.SH "RETURN VALUE"
-+On success, the return value of |th| is stored in the location pointed
-+to by |thread_return|, and 0 is returned. On error, a non-zero error
-+code is returned.
-+
-+.SH ERRORS
-+.TP
-+!ESRCH!
-+No thread could be found corresponding to that specified by |th|.
-+.TP
-+!EINVAL!
-+The |th| thread has been detached.
-+.TP
-+!EINVAL!
-+Another thread is already waiting on termination of |th|.
-+.TP
-+!EDEADLK!
-+The |th| argument refers to the calling thread.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_exit!(3),
-+!pthread_detach!(3),
-+!pthread_create!(3),
-+!pthread_attr_setdetachstate!(3),
-+!pthread_cleanup_push!(3),
-+!pthread_key_create!(3).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_key_create.man glibc-2.1.3/linuxthreads/man/pthread_key_create.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_key_create.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_key_create.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,151 @@
-+.TH PTHREAD_SPECIFIC 3 LinuxThreads
-+
-+.SH NAME
-+pthread_key_create, pthread_key_delete, pthread_setspecific, pthread_getspecific \- management of thread-specific data
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *));
-+
-+int pthread_key_delete(pthread_key_t key);
-+
-+int pthread_setspecific(pthread_key_t key, const void *pointer);
-+
-+void * pthread_getspecific(pthread_key_t key);
-+
-+.SH DESCRIPTION
-+
-+Programs often need global or static variables that have different
-+values in different threads. Since threads share one memory space,
-+this cannot be achieved with regular variables. Thread-specific data
-+is the POSIX threads answer to this need.
-+
-+Each thread possesses a private memory block, the thread-specific data
-+area, or TSD area for short. This area is indexed by TSD keys. The TSD
-+area associates values of type !void *! to TSD keys. TSD keys are
-+common to all threads, but the value associated with a given TSD key
-+can be different in each thread.
-+
-+For concreteness, the TSD areas can be viewed as arrays of !void *!
-+pointers, TSD keys as integer indices into these arrays, and the value
-+of a TSD key as the value of the corresponding array element in the
-+calling thread.
-+
-+When a thread is created, its TSD area initially associates !NULL!
-+with all keys.
-+
-+!pthread_key_create! allocates a new TSD key. The key is stored in the
-+location pointed to by |key|. There is a limit of !PTHREAD_KEYS_MAX!
-+on the number of keys allocated at a given time. The value initially
-+associated with the returned key is !NULL! in all currently executing
-+threads.
-+
-+The |destr_function| argument, if not !NULL!, specifies a destructor
-+function associated with the key. When a thread terminates via
-+!pthread_exit! or by cancellation, |destr_function| is called with
-+arguments the value associated with the key in that thread. The
-+|destr_function| is not called if that value is !NULL!. The order in
-+which destructor functions are called at thread termination time is
-+unspecified.
-+
-+Before the destructor function is called, the !NULL! value is
-+associated with the key in the current thread. A destructor function
-+might, however, re-associate non-!NULL! values to that key or some
-+other key. To deal with this, if after all the destructors have been
-+called for all non-!NULL! values, there are still some non-!NULL!
-+values with associated destructors, then the process is repeated. The
-+LinuxThreads implementation stops the process after
-+!PTHREAD_DESTRUCTOR_ITERATIONS! iterations, even if some non-!NULL!
-+values with associated descriptors remain. Other implementations may
-+loop indefinitely.
-+
-+!pthread_key_delete! deallocates a TSD key. It does not check whether
-+non-!NULL! values are associated with that key in the currently
-+executing threads, nor call the destructor function associated with
-+the key.
-+
-+!pthread_setspecific! changes the value associated with |key| in the
-+calling thread, storing the given |pointer| instead.
-+
-+!pthread_getspecific! returns the value currently associated with
-+|key| in the calling thread.
-+
-+.SH "RETURN VALUE"
-+
-+!pthread_key_create!, !pthread_key_delete!, and !pthread_setspecific!
-+return 0 on success and a non-zero error code on failure. If
-+successful, !pthread_key_create! stores the newly allocated key in the
-+location pointed to by its |key| argument.
-+
-+!pthread_getspecific! returns the value associated with |key| on
-+success, and !NULL! on error.
-+
-+.SH ERRORS
-+!pthread_key_create! returns the following error code on error:
-+.RS
-+.TP
-+!EAGAIN!
-+!PTHREAD_KEYS_MAX! keys are already allocated
-+.RE
-+
-+!pthread_key_delete! and !pthread_setspecific! return the following
-+error code on error:
-+.RS
-+.TP
-+!EINVAL!
-+|key| is not a valid, allocated TSD key
-+.RE
-+
-+!pthread_getspecific! returns !NULL! if |key| is not a valid,
-+allocated TSD key.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+pthread_create(3), pthread_exit(3), pthread_testcancel(3).
-+
-+.SH EXAMPLE
-+
-+The following code fragment allocates a thread-specific array of 100
-+characters, with automatic reclaimation at thread exit:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+/* Key for the thread-specific buffer */
-+static pthread_key_t buffer_key;
-+
-+/* Once-only initialisation of the key */
-+static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
-+
-+/* Allocate the thread-specific buffer */
-+void buffer_alloc(void)
-+{
-+ pthread_once(&buffer_key_once, buffer_key_alloc);
-+ pthread_setspecific(buffer_key, malloc(100));
-+}
-+
-+/* Return the thread-specific buffer */
-+char * get_buffer(void)
-+{
-+ return (char *) pthread_getspecific(buffer_key);
-+}
-+
-+/* Allocate the key */
-+static void buffer_key_alloc()
-+{
-+ pthread_key_create(&buffer_key, buffer_destroy);
-+}
-+
-+/* Free the thread-specific buffer */
-+static void buffer_destroy(void * buf)
-+{
-+ free(buf);
-+}
-+.ft
-+.LP
-+.RE
-+.fi
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_kill_other_threads_np.man glibc-2.1.3/linuxthreads/man/pthread_kill_other_threads_np.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_kill_other_threads_np.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_kill_other_threads_np.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,40 @@
-+.TH PTHREAD_KILL_OTHER_THREADS_NP 3 LinuxThreads
-+
-+.SH NAME
-+pthread_kill_other_threads_np \- terminate all threads in program except calling thread
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+void pthread_kill_other_threads_np(void);
-+
-+.SH DESCRIPTION
-+!pthread_kill_other_threads_np! is a non-portable LinuxThreads extension.
-+It causes all threads in the program to terminate immediately, except
-+the calling thread which proceeds normally. It is intended to be
-+called just before a thread calls one of the !exec! functions,
-+e.g. !execve!(2).
-+
-+Termination of the other threads is not performed through
-+!pthread_cancel!(3) and completely bypasses the cancellation
-+mechanism. Hence, the current settings for cancellation state and
-+cancellation type are ignored, and the cleanup handlers are not
-+executed in the terminated threads.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!execve!(2),
-+!pthread_setcancelstate!(3),
-+!pthread_setcanceltype!(3),
-+!pthread_cancel!(3).
-+
-+.SH BUGS
-+
-+According to POSIX 1003.1c, a successful !exec*! in one of the threads
-+should terminate automatically all other threads in the program.
-+This behavior is not yet implemented in LinuxThreads.
-+Calling !pthread_kill_other_threads_np! before !exec*! achieves much
-+of the same behavior, except that if !exec*! ultimately fails, then
-+all other threads are already killed.
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_mutex_init.man glibc-2.1.3/linuxthreads/man/pthread_mutex_init.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_mutex_init.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_mutex_init.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,213 @@
-+.TH PTHREAD_MUTEX 3 LinuxThreads
-+
-+.XREF pthread_mutex_lock
-+.XREF pthread_mutex_unlock
-+.XREF pthread_mutex_trylock
-+.XREF pthread_mutex_destroy
-+
-+.SH NAME
-+pthread_mutex_init, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, pthread_mutex_destroy \- operations on mutexes
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
-+
-+pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-+
-+pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-+
-+int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
-+
-+int pthread_mutex_lock(pthread_mutex_t *mutex));
-+
-+int pthread_mutex_trylock(pthread_mutex_t *mutex);
-+
-+int pthread_mutex_unlock(pthread_mutex_t *mutex);
-+
-+int pthread_mutex_destroy(pthread_mutex_t *mutex);
-+
-+.SH DESCRIPTION
-+A mutex is a MUTual EXclusion device, and is useful for protecting
-+shared data structures from concurrent modifications, and implementing
-+critical sections and monitors.
-+
-+A mutex has two possible states: unlocked (not owned by any thread),
-+and locked (owned by one thread). A mutex can never be owned by two
-+different threads simultaneously. A thread attempting to lock a mutex
-+that is already locked by another thread is suspended until the owning
-+thread unlocks the mutex first.
-+
-+!pthread_mutex_init! initializes the mutex object pointed to by
-+|mutex| according to the mutex attributes specified in |mutexattr|.
-+If |mutexattr| is !NULL!, default attributes are used instead.
-+
-+The LinuxThreads implementation supports only one mutex attributes,
-+the |mutex kind|, which is either ``fast'', ``recursive'', or
-+``error checking''. The kind of a mutex determines whether
-+it can be locked again by a thread that already owns it.
-+The default kind is ``fast''. See !pthread_mutexattr_init!(3) for more
-+information on mutex attributes.
-+
-+Variables of type !pthread_mutex_t! can also be initialized
-+statically, using the constants !PTHREAD_MUTEX_INITIALIZER! (for fast
-+mutexes), !PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP! (for recursive
-+mutexes), and !PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP! (for error checking
-+mutexes).
-+
-+!pthread_mutex_lock! locks the given mutex. If the mutex is currently
-+unlocked, it becomes locked and owned by the calling thread, and
-+!pthread_mutex_lock! returns immediately. If the mutex is already
-+locked by another thread, !pthread_mutex_lock! suspends the calling
-+thread until the mutex is unlocked.
-+
-+If the mutex is already locked by the calling thread, the behavior of
-+!pthread_mutex_lock! depends on the kind of the mutex. If the mutex is
-+of the ``fast'' kind, the calling thread is suspended until the mutex
-+is unlocked, thus effectively causing the calling thread to
-+deadlock. If the mutex is of the ``error checking'' kind,
-+!pthread_mutex_lock! returns immediately with the error code !EDEADLK!.
-+If the mutex is of the ``recursive'' kind, !pthread_mutex_lock!
-+succeeds and returns immediately, recording the number of times the
-+calling thread has locked the mutex. An equal number of
-+!pthread_mutex_unlock! operations must be performed before the mutex
-+returns to the unlocked state.
-+
-+!pthread_mutex_trylock! behaves identically to !pthread_mutex_lock!,
-+except that it does not block the calling thread if the mutex is
-+already locked by another thread (or by the calling thread in the case
-+of a ``fast'' mutex). Instead, !pthread_mutex_trylock! returns
-+immediately with the error code !EBUSY!.
-+
-+!pthread_mutex_unlock! unlocks the given mutex. The mutex is assumed
-+to be locked and owned by the calling thread on entrance to
-+!pthread_mutex_unlock!. If the mutex is of the ``fast'' kind,
-+!pthread_mutex_unlock! always returns it to the unlocked state. If it
-+is of the ``recursive'' kind, it decrements the locking count of the
-+mutex (number of !pthread_mutex_lock! operations performed on it by
-+the calling thread), and only when this count reaches zero is the
-+mutex actually unlocked.
-+
-+On ``error checking'' mutexes, !pthread_mutex_unlock! actually checks
-+at run-time that the mutex is locked on entrance, and that it was
-+locked by the same thread that is now calling !pthread_mutex_unlock!.
-+If these conditions are not met, an error code is returned and the
-+mutex remains unchanged. ``Fast'' and ``recursive'' mutexes perform
-+no such checks, thus allowing a locked mutex to be unlocked by a
-+thread other than its owner. This is non-portable behavior and must
-+not be relied upon.
-+
-+!pthread_mutex_destroy! destroys a mutex object, freeing the resources
-+it might hold. The mutex must be unlocked on entrance. In the
-+LinuxThreads implementation, no resources are associated with mutex
-+objects, thus !pthread_mutex_destroy! actually does nothing except
-+checking that the mutex is unlocked.
-+
-+.SH CANCELLATION
-+
-+None of the mutex functions is a cancellation point, not even
-+!pthread_mutex_lock!, in spite of the fact that it can suspend a
-+thread for arbitrary durations. This way, the status of mutexes at
-+cancellation points is predictable, allowing cancellation handlers to
-+unlock precisely those mutexes that need to be unlocked before the
-+thread stops executing. Consequently, threads using deferred
-+cancellation should never hold a mutex for extended periods of time.
-+
-+.SH "ASYNC-SIGNAL SAFETY"
-+
-+The mutex functions are not async-signal safe. What this means is that
-+they should not be called from a signal handler. In particular,
-+calling !pthread_mutex_lock! or !pthread_mutex_unlock! from a signal
-+handler may deadlock the calling thread.
-+
-+.SH "RETURN VALUE"
-+
-+!pthread_mutex_init! always returns 0. The other mutex functions
-+return 0 on success and a non-zero error code on error.
-+
-+.SH ERRORS
-+
-+The !pthread_mutex_lock! function returns the following error code
-+on error:
-+.RS
-+.TP
-+!EINVAL!
-+the mutex has not been properly initialized.
-+
-+.TP
-+!EDEADLK!
-+the mutex is already locked by the calling thread
-+(``error checking'' mutexes only).
-+.RE
-+
-+The !pthread_mutex_trylock! function returns the following error codes
-+on error:
-+.RS
-+.TP
-+!EBUSY!
-+the mutex could not be acquired because it was currently locked.
-+
-+.TP
-+!EINVAL!
-+the mutex has not been properly initialized.
-+.RE
-+
-+The !pthread_mutex_unlock! function returns the following error code
-+on error:
-+.RS
-+.TP
-+!EINVAL!
-+the mutex has not been properly initialized.
-+
-+.TP
-+!EPERM!
-+the calling thread does not own the mutex (``error checking'' mutexes only).
-+.RE
-+
-+The !pthread_mutex_destroy! function returns the following error code
-+on error:
-+.RS
-+.TP
-+!EBUSY!
-+the mutex is currently locked.
-+.RE
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_mutexattr_init!(3),
-+!pthread_mutexattr_setkind_np!(3),
-+!pthread_cancel!(3).
-+
-+.SH EXAMPLE
-+
-+A shared global variable |x| can be protected by a mutex as follows:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+int x;
-+pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+All accesses and modifications to |x| should be bracketed by calls to
-+!pthread_mutex_lock! and !pthread_mutex_unlock! as follows:
-+
-+.RS
-+.ft 3
-+.nf
-+.sp
-+pthread_mutex_lock(&mut);
-+/* operate on x */
-+pthread_mutex_unlock(&mut);
-+.ft
-+.LP
-+.RE
-+.fi
-+
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_mutexattr_init.man glibc-2.1.3/linuxthreads/man/pthread_mutexattr_init.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_mutexattr_init.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_mutexattr_init.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,84 @@
-+.TH PTHREAD_MUTEXATTR 3 LinuxThreads
-+
-+.XREF pthread_mutexattr_destroy
-+.XREF pthread_mutexattr_setkind_np
-+.XREF pthread_mutexattr_getkind_np
-+
-+.SH NAME
-+pthread_mutexattr_init, pthread_mutexattr_destroy, pthread_mutexattr_setkind_np, pthread_mutexattr_getkind_np \- mutex creation attributes
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_mutexattr_init(pthread_mutexattr_t *attr);
-+
-+int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
-+
-+int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind);
-+
-+int pthread_mutexattr_getkind_np(const pthread_mutexattr_t *attr, int *kind);
-+
-+.SH DESCRIPTION
-+
-+Mutex attributes can be specified at mutex creation time, by passing a
-+mutex attribute object as second argument to !pthread_mutex_init!(3).
-+Passing !NULL! is equivalent to passing a mutex attribute object with
-+all attributes set to their default values.
-+
-+!pthread_mutexattr_init! initializes the mutex attribute object |attr|
-+and fills it with default values for the attributes.
-+
-+!pthread_mutexattr_destroy! destroys a mutex attribute object, which
-+must not be reused until it is reinitialized. !pthread_mutexattr_destroy!
-+does nothing in the LinuxThreads implementation.
-+
-+LinuxThreads supports only one mutex attribute: the mutex kind, which
-+is either !PTHREAD_MUTEX_FAST_NP! for ``fast'' mutexes,
-+!PTHREAD_MUTEX_RECURSIVE_NP! for ``recursive'' mutexes,
-+or !PTHREAD_MUTEX_ERRORCHECK_NP! for ``error checking'' mutexes.
-+As the !NP! suffix indicates, this is a non-portable extension to the
-+POSIX standard and should not be employed in portable programs.
-+
-+The mutex kind determines what happens if a thread attempts to lock a
-+mutex it already owns with !pthread_mutex_lock!(3). If the mutex is of
-+the ``fast'' kind, !pthread_mutex_lock!(3) simply suspends the calling
-+thread forever. If the mutex is of the ``error checking'' kind,
-+!pthread_mutex_lock!(3) returns immediately with the error code
-+!EDEADLK!. If the mutex is of the ``recursive'' kind, the call to
-+!pthread_mutex_lock!(3) returns immediately with a success return
-+code. The number of times the thread owning the mutex has locked it is
-+recorded in the mutex. The owning thread must call
-+!pthread_mutex_unlock!(3) the same number of times before the mutex
-+returns to the unlocked state.
-+
-+The default mutex kind is ``fast'', that is, !PTHREAD_MUTEX_FAST_NP!.
-+
-+!pthread_mutexattr_setkind_np! sets the mutex kind attribute in |attr|
-+to the value specified by |kind|.
-+
-+!pthread_mutexattr_getkind_np! retrieves the current value of the
-+mutex kind attribute in |attr| and stores it in the location pointed
-+to by |kind|.
-+
-+.SH "RETURN VALUE"
-+!pthread_mutexattr_init!, !pthread_mutexattr_destroy! and
-+!pthread_mutexattr_getkind_np! always return 0.
-+
-+!pthread_mutexattr_setkind_np! returns 0 on success and a non-zero
-+error code on error.
-+
-+.SH ERRORS
-+
-+On error, !pthread_mutexattr_setkind_np! returns the following error code:
-+.TP
-+!EINVAL!
-+|kind| is neither !PTHREAD_MUTEX_FAST_NP! nor !PTHREAD_MUTEX_RECURSIVE_NP!
-+nor !PTHREAD_MUTEX_ERRORCHECK_NP!
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_mutex_init!(3),
-+!pthread_mutex_lock!(3),
-+!pthread_mutex_unlock!(3).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_once.man glibc-2.1.3/linuxthreads/man/pthread_once.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_once.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_once.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,34 @@
-+.TH PTHREAD_ONCE 3 LinuxThreads
-+
-+.SH NAME
-+pthread_once \- once-only initialization
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+pthread_once_t once_control = PTHREAD_ONCE_INIT;
-+
-+int pthread_once(pthread_once_t *once_control, void (*init_routine) (void));
-+
-+.SH DESCRIPTION
-+
-+The purpose of !pthread_once! is to ensure that a piece of
-+initialization code is executed at most once. The |once_control|
-+argument points to a static or extern variable statically initialized
-+to !PTHREAD_ONCE_INIT!.
-+
-+The first time !pthread_once! is called with a given |once_control|
-+argument, it calls |init_routine| with no argument and changes the
-+value of the |once_control| variable to record that initialization has
-+been performed. Subsequent calls to !pthread_once! with the same
-+!once_control! argument do nothing.
-+
-+.SH "RETURN VALUE"
-+!pthread_once! always returns 0.
-+
-+.SH ERRORS
-+None.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_self.man glibc-2.1.3/linuxthreads/man/pthread_self.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_self.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_self.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,23 @@
-+.TH PTHREAD_SELF 3 LinuxThreads
-+
-+.SH NAME
-+pthread_self \- return identifier of current thread
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+pthread_t pthread_self(void);
-+
-+.SH DESCRIPTION
-+!pthread_self! return the thread identifier for the calling thread.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_equal!(3),
-+!pthread_join!(3),
-+!pthread_detach!(3),
-+!pthread_setschedparam!(3),
-+!pthread_getschedparam!(3).
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_setschedparam.man glibc-2.1.3/linuxthreads/man/pthread_setschedparam.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_setschedparam.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_setschedparam.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,79 @@
-+.TH PTHREAD_SETSCHEDPARAM 3 LinuxThreads
-+
-+.XREF pthread_getschedparam
-+
-+.SH NAME
-+pthread_setschedparam, pthread_getschedparam \- control thread scheduling parameters
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+
-+int pthread_setschedparam(pthread_t target_thread, int policy, const struct sched_param *param);
-+
-+int pthread_getschedparam(pthread_t target_thread, int *policy, struct sched_param *param);
-+
-+.SH DESCRIPTION
-+
-+!pthread_setschedparam! sets the scheduling parameters for the thread
-+|target_thread| as indicated by |policy| and |param|. |policy| can be
-+either !SCHED_OTHER! (regular, non-realtime scheduling), !SCHED_RR!
-+(realtime, round-robin) or !SCHED_FIFO! (realtime, first-in
-+first-out). |param| specifies the scheduling priority for the two
-+realtime policies. See !sched_setpolicy!(2) for more information on
-+scheduling policies.
-+
-+The realtime scheduling policies !SCHED_RR! and !SCHED_FIFO! are
-+available only to processes with superuser privileges.
-+
-+!pthread_getschedparam! retrieves the scheduling policy and scheduling
-+parameters for the thread |target_thread| and store them in the
-+locations pointed to by |policy| and |param|, respectively.
-+
-+.SH "RETURN VALUE"
-+!pthread_setschedparam! and !pthread_getschedparam! return 0 on
-+success and a non-zero error code on error.
-+
-+.SH ERRORS
-+On error, !pthread_setschedparam! returns the following error codes:
-+.RS
-+.TP
-+!EINVAL!
-+|policy| is not one of !SCHED_OTHER!, !SCHED_RR!, !SCHED_FIFO!
-+
-+.TP
-+!EINVAL!
-+the priority value specified by |param| is not valid for the specified policy
-+
-+.TP
-+!EPERM!
-+the calling process does not have superuser permissions
-+
-+.TP
-+!ESRCH!
-+the |target_thread| is invalid or has already terminated
-+
-+.TP
-+!EFAULT!
-+|param| points outside the process memory space
-+.RE
-+
-+On error, !pthread_getschedparam! returns the following error codes:
-+.RS
-+.TP
-+!ESRCH!
-+the |target_thread| is invalid or has already terminated
-+
-+.TP
-+!EFAULT!
-+|policy| or |param| point outside the process memory space
-+.RE
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!sched_setscheduler!(2),
-+!sched_getscheduler!(2),
-+!sched_getparam!(2),
-+!pthread_attr_setschedpolicy!(3),
-+!pthread_attr_setschedparam!(3).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/pthread_sigmask.man glibc-2.1.3/linuxthreads/man/pthread_sigmask.man
---- ../glibc-2.1.3/linuxthreads/man/pthread_sigmask.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/pthread_sigmask.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,123 @@
-+.TH PTHREAD_SIGNAL 3 LinuxThreads
-+
-+.XREF pthread_kill
-+.XREF sigwait
-+
-+.SH NAME
-+pthread_sigmask, pthread_kill, sigwait \- handling of signals in threads
-+
-+.SH SYNOPSIS
-+#include <pthread.h>
-+.br
-+#include <signal.h>
-+
-+int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask);
-+
-+int pthread_kill(pthread_t thread, int signo);
-+
-+int sigwait(const sigset_t *set, int *sig);
-+
-+.SH DESCRIPTION
-+
-+!pthread_sigmask! changes the signal mask for the calling thread as
-+described by the |how| and |newmask| arguments. If |oldmask| is not
-+!NULL!, the previous signal mask is stored in the location pointed to
-+by |oldmask|.
-+
-+The meaning of the |how| and |newmask| arguments is the same as for
-+!sigprocmask!(2). If |how| is !SIG_SETMASK!, the signal mask is set to
-+|newmask|. If |how| is !SIG_BLOCK!, the signals specified to |newmask|
-+are added to the current signal mask. If |how| is !SIG_UNBLOCK!, the
-+signals specified to |newmask| are removed from the current signal
-+mask.
-+
-+Recall that signal masks are set on a per-thread basis, but signal
-+actions and signal handlers, as set with !sigaction!(2), are shared
-+between all threads.
-+
-+!pthread_kill! send signal number |signo| to the thread
-+|thread|. The signal is delivered and handled as described in
-+!kill!(2).
-+
-+!sigwait! suspends the calling thread until one of the signals
-+in |set| is delivered to the calling thread. It then stores the number
-+of the signal received in the location pointed to by |sig| and
-+returns. The signals in |set| must be blocked and not ignored on
-+entrance to !sigwait!. If the delivered signal has a signal handler
-+function attached, that function is |not| called.
-+
-+.SH CANCELLATION
-+
-+!sigwait! is a cancellation point.
-+
-+.SH "RETURN VALUE"
-+
-+On success, 0 is returned. On failure, a non-zero error code is returned.
-+
-+.SH ERRORS
-+
-+The !pthread_sigmask! function returns the following error codes
-+on error:
-+.RS
-+.TP
-+!EINVAL!
-+|how| is not one of !SIG_SETMASK!, !SIG_BLOCK!, or !SIG_UNBLOCK!
-+
-+.TP
-+!EFAULT!
-+|newmask| or |oldmask| point to invalid addresses
-+.RE
-+
-+The !pthread_kill! function returns the following error codes
-+on error:
-+.RS
-+.TP
-+!EINVAL!
-+|signo| is not a valid signal number
-+
-+.TP
-+!ESRCH!
-+the thread |thread| does not exist (e.g. it has already terminated)
-+.RE
-+
-+The !sigwait! function never returns an error.
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!sigprocmask!(2),
-+!kill!(2),
-+!sigaction!(2),
-+!sigsuspend!(2).
-+
-+.SH NOTES
-+
-+For !sigwait! to work reliably, the signals being waited for must be
-+blocked in all threads, not only in the calling thread, since
-+otherwise the POSIX semantics for signal delivery do not guarantee
-+that it's the thread doing the !sigwait! that will receive the signal.
-+The best way to achieve this is block those signals before any threads
-+are created, and never unblock them in the program other than by
-+calling !sigwait!.
-+
-+.SH BUGS
-+
-+Signal handling in LinuxThreads departs significantly from the POSIX
-+standard. According to the standard, ``asynchronous'' (external)
-+signals are addressed to the whole process (the collection of all
-+threads), which then delivers them to one particular thread. The
-+thread that actually receives the signal is any thread that does
-+not currently block the signal.
-+
-+In LinuxThreads, each thread is actually a kernel process with its own
-+PID, so external signals are always directed to one particular thread.
-+If, for instance, another thread is blocked in !sigwait! on that
-+signal, it will not be restarted.
-+
-+The LinuxThreads implementation of !sigwait! installs dummy signal
-+handlers for the signals in |set| for the duration of the wait. Since
-+signal handlers are shared between all threads, other threads must not
-+attach their own signal handlers to these signals, or alternatively
-+they should all block these signals (which is recommended anyway --
-+see the Notes section).
-diff -Naur ../glibc-2.1.3/linuxthreads/man/sem_init.man glibc-2.1.3/linuxthreads/man/sem_init.man
---- ../glibc-2.1.3/linuxthreads/man/sem_init.man 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/sem_init.man 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,132 @@
-+.TH SEMAPHORES 3 LinuxThreads
-+
-+.XREF sem_wait
-+.XREF sem_trywait
-+.XREF sem_post
-+.XREF sem_getvalue
-+.XREF sem_destroy
-+
-+.SH NAME
-+sem_init, sem_wait, sem_trywait, sem_post, sem_getvalue, sem_destroy \- operations on semaphores
-+
-+.SH SYNOPSIS
-+#include <semaphore.h>
-+
-+int sem_init(sem_t *sem, int pshared, unsigned int value);
-+
-+int sem_wait(sem_t * sem);
-+
-+int sem_trywait(sem_t * sem);
-+
-+int sem_post(sem_t * sem);
-+
-+int sem_getvalue(sem_t * sem, int * sval);
-+
-+int sem_destroy(sem_t * sem);
-+
-+.SH DESCRIPTION
-+This manual page documents POSIX 1003.1b semaphores, not to be
-+confused with SystemV semaphores as described in !ipc!(5), !semctl!(2)
-+and !semop!(2).
-+
-+Semaphores are counters for resources shared between threads. The
-+basic operations on semaphores are: increment the counter atomically,
-+and wait until the counter is non-null and decrement it atomically.
-+
-+!sem_init! initializes the semaphore object pointed to by |sem|. The
-+count associated with the semaphore is set initially to |value|. The
-+|pshared| argument indicates whether the semaphore is local to the
-+current process (|pshared| is zero) or is to be shared between several
-+processes (|pshared| is not zero). LinuxThreads currently does not
-+support process-shared semaphores, thus !sem_init! always returns with
-+error !ENOSYS! if |pshared| is not zero.
-+
-+!sem_wait! suspends the calling thread until the semaphore pointed to
-+by |sem| has non-zero count. It then atomically decreases the
-+semaphore count.
-+
-+!sem_trywait! is a non-blocking variant of !sem_wait!. If the
-+semaphore pointed to by |sem| has non-zero count, the count is
-+atomically decreased and !sem_trywait! immediately returns 0.
-+If the semaphore count is zero, !sem_trywait! immediately returns with
-+error !EAGAIN!.
-+
-+!sem_post! atomically increases the count of the semaphore pointed to
-+by |sem|. This function never blocks and can safely be used in
-+asynchronous signal handlers.
-+
-+!sem_getvalue! stores in the location pointed to by |sval| the current
-+count of the semaphore |sem|.
-+
-+!sem_destroy! destroys a semaphore object, freeing the resources it
-+might hold. No threads should be waiting on the semaphore at the time
-+!sem_destroy! is called. In the LinuxThreads implementation, no
-+resources are associated with semaphore objects, thus !sem_destroy!
-+actually does nothing except checking that no thread is waiting on the
-+semaphore.
-+
-+.SH CANCELLATION
-+
-+!sem_wait! is a cancellation point.
-+
-+.SH "ASYNC-SIGNAL SAFETY"
-+
-+On processors supporting atomic compare-and-swap (Intel 486, Pentium
-+and later, Alpha, PowerPC, MIPS II, Motorola 68k), the !sem_post!
-+function is async-signal safe and can therefore be
-+called from signal handlers. This is the only thread synchronization
-+function provided by POSIX threads that is async-signal safe.
-+
-+On the Intel 386 and the Sparc, the current LinuxThreads
-+implementation of !sem_post! is not async-signal safe by lack of the
-+required atomic operations.
-+
-+.SH "RETURN VALUE"
-+
-+The !sem_wait! and !sem_getvalue! functions always return 0.
-+All other semaphore functions return 0 on success and -1 on error, in
-+addition to writing an error code in !errno!.
-+
-+.SH ERRORS
-+
-+The !sem_init! function sets !errno! to the following codes on error:
-+.RS
-+.TP
-+!EINVAL!
-+|value| exceeds the maximal counter value !SEM_VALUE_MAX!
-+.TP
-+!ENOSYS!
-+|pshared| is not zero
-+.RE
-+
-+The !sem_trywait! function sets !errno! to the following error code on error:
-+.RS
-+.TP
-+!EAGAIN!
-+the semaphore count is currently 0
-+.RE
-+
-+The !sem_post! function sets !errno! to the following error code on error:
-+.RS
-+.TP
-+!ERANGE!
-+after incrementation, the semaphore value would exceed !SEM_VALUE_MAX!
-+(the semaphore count is left unchanged in this case)
-+.RE
-+
-+The !sem_destroy! function sets !errno! to the following error code on error:
-+.RS
-+.TP
-+!EBUSY!
-+some threads are currently blocked waiting on the semaphore.
-+.RE
-+
-+.SH AUTHOR
-+Xavier Leroy <Xavier.Leroy@inria.fr>
-+
-+.SH "SEE ALSO"
-+!pthread_mutex_init!(3),
-+!pthread_cond_init!(3),
-+!pthread_cancel!(3),
-+!ipc!(5).
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/man/troffprepro glibc-2.1.3/linuxthreads/man/troffprepro
---- ../glibc-2.1.3/linuxthreads/man/troffprepro 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/man/troffprepro 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,68 @@
-+#!/usr/local/bin/perl
-+
-+$insynopsis = 0;
-+
-+open(INPUT, $ARGV[0]) || die("cannot open $ARGV[0]");
-+open(OUTPUT, "> $ARGV[1]") || die("cannot create $ARGV[1]");
-+
-+select(OUTPUT);
-+
-+line:
-+while(<INPUT>) {
-+ if (/^\.XREF (.*)$/) {
-+ $xref = $1;
-+ $_ = $ARGV[1];
-+ m/^.*\.(([1-8]).*)$/;
-+ $suffix = $1;
-+ $extension = $2;
-+ open(XREF, "> $xref.$suffix");
-+ print XREF ".so man$extension/$ARGV[1]\n";
-+ close(XREF);
-+ next line;
-+ }
-+ if (/^\.SH/) {
-+ $insynopsis = /SYNOPSIS/;
-+ print $_;
-+ next;
-+ }
-+ if ($insynopsis) {
-+ if (/^#/) {
-+ print ".B ", $_;
-+ }
-+ elsif (/^[a-z]/) {
-+ chop;
-+# if (m/^([a-zA-Z][a-zA-Z0-9_]*\s+[a-zA-Z][a-zA-Z0-9_]*)\(/) {
-+# print ".B \"", $1, "\"\n";
-+# $_ = '(' . $';
-+# }
-+# s/([a-zA-Z][a-zA-Z0-9_]*)(\s*[,()=])/" \1 "\2/g;
-+ s/([ *])([a-zA-Z][a-zA-Z0-9_]*)(\s*[,)=])/\1" \2 "\3/g;
-+ print ".BI \"", $_, "\"\n";
-+ }
-+ else {
-+ print $_;
-+ }
-+ next;
-+ }
-+ chop;
-+ s/!([^!]+)!\|([^|]+)\|([^\s]*)\s*/\n.BI "\1" "\2\3"\n/g;
-+ s/([!|])([^!|]+)\1([^\s]*)\s*/do subst($1,$2,$3)/eg;
-+ s/^\n+//;
-+ s/\n+$//;
-+ s/\n\n+/\n/g;
-+ print $_, "\n";
-+}
-+
-+close(INPUT);
-+close(OUTPUT);
-+
-+sub subst {
-+ local ($a, $b, $c) = @_;
-+ if ($c) {
-+ "\n" . ($a eq "!" ? ".BR " : ".IR ") . "\"$b\" $c\n"
-+ } else {
-+ "\n" . ($a eq "!" ? ".B " : ".I ") . "\"$b\"\n"
-+ }
-+}
-+
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/manager.c glibc-2.1.3/linuxthreads/manager.c
---- ../glibc-2.1.3/linuxthreads/manager.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/manager.c 2000-01-20 18:32:38.000000000 -0800
-@@ -0,0 +1,699 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* The "thread manager" thread: manages creation and termination of threads */
-+
-+#include <errno.h>
-+#include <sched.h>
-+#include <stddef.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <sys/poll.h> /* for poll */
-+#include <sys/mman.h> /* for mmap */
-+#include <sys/param.h>
-+#include <sys/time.h>
-+#include <sys/wait.h> /* for waitpid macros */
-+
-+#include "pthread.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include "restart.h"
-+#include "semaphore.h"
-+
-+/* Array of active threads. Entry 0 is reserved for the initial thread. */
-+struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX] =
-+{ { LOCK_INITIALIZER, &__pthread_initial_thread, 0},
-+ { LOCK_INITIALIZER, &__pthread_manager_thread, 0}, /* All NULLs */ };
-+
-+/* For debugging purposes put the maximum number of threads in a variable. */
-+const int __linuxthreads_pthread_threads_max = PTHREAD_THREADS_MAX;
-+
-+/* Indicate whether at least one thread has a user-defined stack (if 1),
-+ or if all threads have stacks supplied by LinuxThreads (if 0). */
-+int __pthread_nonstandard_stacks;
-+
-+/* Number of active entries in __pthread_handles (used by gdb) */
-+volatile int __pthread_handles_num = 2;
-+
-+/* Whether to use debugger additional actions for thread creation
-+ (set to 1 by gdb) */
-+volatile int __pthread_threads_debug;
-+
-+/* Globally enabled events. */
-+volatile td_thr_events_t __pthread_threads_events;
-+
-+/* Pointer to thread descriptor with last event. */
-+volatile pthread_descr __pthread_last_event;
-+
-+/* Mapping from stack segment to thread descriptor. */
-+/* Stack segment numbers are also indices into the __pthread_handles array. */
-+/* Stack segment number 0 is reserved for the initial thread. */
-+
-+static inline pthread_descr thread_segment(int seg)
-+{
-+ return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg - 1) * STACK_SIZE)
-+ - 1;
-+}
-+
-+/* Flag set in signal handler to record child termination */
-+
-+static volatile int terminated_children = 0;
-+
-+/* Flag set when the initial thread is blocked on pthread_exit waiting
-+ for all other threads to terminate */
-+
-+static int main_thread_exiting = 0;
-+
-+/* Counter used to generate unique thread identifier.
-+ Thread identifier is pthread_threads_counter + segment. */
-+
-+static pthread_t pthread_threads_counter = 0;
-+
-+/* Forward declarations */
-+
-+static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
-+ void * (*start_routine)(void *), void *arg,
-+ sigset_t *mask, int father_pid,
-+ int report_events,
-+ td_thr_events_t *event_maskp);
-+static void pthread_handle_free(pthread_t th_id);
-+static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode);
-+static void pthread_reap_children(void);
-+static void pthread_kill_all_threads(int sig, int main_thread_also);
-+
-+/* The server thread managing requests for thread creation and termination */
-+
-+int __pthread_manager(void *arg)
-+{
-+ int reqfd = (int) (long int) arg;
-+ struct pollfd ufd;
-+ sigset_t mask;
-+ int n;
-+ struct pthread_request request;
-+
-+ /* If we have special thread_self processing, initialize it. */
-+#ifdef INIT_THREAD_SELF
-+ INIT_THREAD_SELF(&__pthread_manager_thread, 1);
-+#endif
-+ /* Set the error variable. */
-+ __pthread_manager_thread.p_errnop = &__pthread_manager_thread.p_errno;
-+ __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno;
-+ /* Block all signals except __pthread_sig_cancel and SIGTRAP */
-+ sigfillset(&mask);
-+ sigdelset(&mask, __pthread_sig_cancel); /* for thread termination */
-+ sigdelset(&mask, SIGTRAP); /* for debugging purposes */
-+ sigprocmask(SIG_SETMASK, &mask, NULL);
-+ /* Raise our priority to match that of main thread */
-+ __pthread_manager_adjust_prio(__pthread_main_thread->p_priority);
-+ /* Synchronize debugging of the thread manager */
-+ n = __libc_read(reqfd, (char *)&request, sizeof(request));
-+ ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG);
-+ ufd.fd = reqfd;
-+ ufd.events = POLLIN;
-+ /* Enter server loop */
-+ while(1) {
-+ n = __poll(&ufd, 1, 2000);
-+
-+ /* Check for termination of the main thread */
-+ if (getppid() == 1) {
-+ pthread_kill_all_threads(SIGKILL, 0);
-+ _exit(0);
-+ }
-+ /* Check for dead children */
-+ if (terminated_children) {
-+ terminated_children = 0;
-+ pthread_reap_children();
-+ }
-+ /* Read and execute request */
-+ if (n == 1 && (ufd.revents & POLLIN)) {
-+ n = __libc_read(reqfd, (char *)&request, sizeof(request));
-+ ASSERT(n == sizeof(request));
-+ switch(request.req_kind) {
-+ case REQ_CREATE:
-+ request.req_thread->p_retcode =
-+ pthread_handle_create((pthread_t *) &request.req_thread->p_retval,
-+ request.req_args.create.attr,
-+ request.req_args.create.fn,
-+ request.req_args.create.arg,
-+ &request.req_args.create.mask,
-+ request.req_thread->p_pid,
-+ request.req_thread->p_report_events,
-+ &request.req_thread->p_eventbuf.eventmask);
-+ restart(request.req_thread);
-+ break;
-+ case REQ_FREE:
-+ pthread_handle_free(request.req_args.free.thread_id);
-+ break;
-+ case REQ_PROCESS_EXIT:
-+ pthread_handle_exit(request.req_thread,
-+ request.req_args.exit.code);
-+ break;
-+ case REQ_MAIN_THREAD_EXIT:
-+ main_thread_exiting = 1;
-+ if (__pthread_main_thread->p_nextlive == __pthread_main_thread) {
-+ restart(__pthread_main_thread);
-+ return 0;
-+ }
-+ break;
-+ case REQ_POST:
-+ __new_sem_post(request.req_args.post);
-+ break;
-+ case REQ_DEBUG:
-+ /* Make gdb aware of new thread and gdb will restart the
-+ new thread when it is ready to handle the new thread. */
-+ if (__pthread_threads_debug && __pthread_sig_debug > 0)
-+ raise(__pthread_sig_debug);
-+ break;
-+ }
-+ }
-+ }
-+}
-+
-+int __pthread_manager_event(void *arg)
-+{
-+ /* If we have special thread_self processing, initialize it. */
-+#ifdef INIT_THREAD_SELF
-+ INIT_THREAD_SELF(&__pthread_manager_thread, 1);
-+#endif
-+
-+ /* Get the lock the manager will free once all is correctly set up. */
-+ __pthread_lock (THREAD_GETMEM((&__pthread_manager_thread), p_lock), NULL);
-+ /* Free it immediately. */
-+ __pthread_unlock (THREAD_GETMEM((&__pthread_manager_thread), p_lock));
-+
-+ return __pthread_manager(arg);
-+}
-+
-+/* Process creation */
-+
-+static int pthread_start_thread(void *arg)
-+{
-+ pthread_descr self = (pthread_descr) arg;
-+ struct pthread_request request;
-+ void * outcome;
-+ /* Initialize special thread_self processing, if any. */
-+#ifdef INIT_THREAD_SELF
-+ INIT_THREAD_SELF(self, self->p_nr);
-+#endif
-+ /* Make sure our pid field is initialized, just in case we get there
-+ before our father has initialized it. */
-+ THREAD_SETMEM(self, p_pid, __getpid());
-+ /* Initial signal mask is that of the creating thread. (Otherwise,
-+ we'd just inherit the mask of the thread manager.) */
-+ sigprocmask(SIG_SETMASK, &self->p_start_args.mask, NULL);
-+ /* Set the scheduling policy and priority for the new thread, if needed */
-+ if (THREAD_GETMEM(self, p_start_args.schedpolicy) >= 0)
-+ /* Explicit scheduling attributes were provided: apply them */
-+ __sched_setscheduler(THREAD_GETMEM(self, p_pid),
-+ THREAD_GETMEM(self, p_start_args.schedpolicy),
-+ &self->p_start_args.schedparam);
-+ else if (__pthread_manager_thread.p_priority > 0)
-+ /* Default scheduling required, but thread manager runs in realtime
-+ scheduling: switch new thread to SCHED_OTHER policy */
-+ {
-+ struct sched_param default_params;
-+ default_params.sched_priority = 0;
-+ __sched_setscheduler(THREAD_GETMEM(self, p_pid),
-+ SCHED_OTHER, &default_params);
-+ }
-+ /* Make gdb aware of new thread */
-+ if (__pthread_threads_debug && __pthread_sig_debug > 0) {
-+ request.req_thread = self;
-+ request.req_kind = REQ_DEBUG;
-+ __libc_write(__pthread_manager_request,
-+ (char *) &request, sizeof(request));
-+ suspend(self);
-+ }
-+ /* Run the thread code */
-+ outcome = self->p_start_args.start_routine(THREAD_GETMEM(self,
-+ p_start_args.arg));
-+ /* Exit with the given return value */
-+ pthread_exit(outcome);
-+ return 0;
-+}
-+
-+static int pthread_start_thread_event(void *arg)
-+{
-+ pthread_descr self = (pthread_descr) arg;
-+
-+#ifdef INIT_THREAD_SELF
-+ INIT_THREAD_SELF(self, self->p_nr);
-+#endif
-+ /* Make sure our pid field is initialized, just in case we get there
-+ before our father has initialized it. */
-+ THREAD_SETMEM(self, p_pid, __getpid());
-+ /* Get the lock the manager will free once all is correctly set up. */
-+ __pthread_lock (THREAD_GETMEM(self, p_lock), NULL);
-+ /* Free it immediately. */
-+ __pthread_unlock (THREAD_GETMEM(self, p_lock));
-+
-+ /* Continue with the real function. */
-+ return pthread_start_thread (arg);
-+}
-+
-+static int pthread_allocate_stack(const pthread_attr_t *attr,
-+ pthread_descr default_new_thread,
-+ int pagesize,
-+ pthread_descr * out_new_thread,
-+ char ** out_new_thread_bottom,
-+ char ** out_guardaddr,
-+ size_t * out_guardsize)
-+{
-+ pthread_descr new_thread;
-+ char * new_thread_bottom;
-+ char * guardaddr;
-+ size_t stacksize, guardsize;
-+
-+ if (attr != NULL && attr->__stackaddr_set)
-+ {
-+ /* The user provided a stack. */
-+ new_thread =
-+ (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1;
-+ new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
-+ guardaddr = NULL;
-+ guardsize = 0;
-+ __pthread_nonstandard_stacks = 1;
-+ }
-+ else
-+ {
-+ stacksize = STACK_SIZE - pagesize;
-+ if (attr != NULL)
-+ stacksize = MIN (stacksize, roundup(attr->__stacksize, pagesize));
-+ /* Allocate space for stack and thread descriptor at default address */
-+ new_thread = default_new_thread;
-+ new_thread_bottom = (char *) (new_thread + 1) - stacksize;
-+ if (mmap((caddr_t)((char *)(new_thread + 1) - INITIAL_STACK_SIZE),
-+ INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
-+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
-+ -1, 0) == MAP_FAILED)
-+ /* Bad luck, this segment is already mapped. */
-+ return -1;
-+ /* We manage to get a stack. Now see whether we need a guard
-+ and allocate it if necessary. Notice that the default
-+ attributes (stack_size = STACK_SIZE - pagesize) do not need
-+ a guard page, since the RLIMIT_STACK soft limit prevents stacks
-+ from running into one another. */
-+ if (stacksize == STACK_SIZE - pagesize)
-+ {
-+ /* We don't need a guard page. */
-+ guardaddr = NULL;
-+ guardsize = 0;
-+ }
-+ else
-+ {
-+ /* Put a bad page at the bottom of the stack */
-+ guardsize = attr->__guardsize;
-+ guardaddr = (void *)new_thread_bottom - guardsize;
-+ if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0)
-+ == MAP_FAILED)
-+ {
-+ /* We don't make this an error. */
-+ guardaddr = NULL;
-+ guardsize = 0;
-+ }
-+ }
-+ }
-+ /* Clear the thread data structure. */
-+ memset (new_thread, '\0', sizeof (*new_thread));
-+ *out_new_thread = new_thread;
-+ *out_new_thread_bottom = new_thread_bottom;
-+ *out_guardaddr = guardaddr;
-+ *out_guardsize = guardsize;
-+ return 0;
-+}
-+
-+static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
-+ void * (*start_routine)(void *), void *arg,
-+ sigset_t * mask, int father_pid,
-+ int report_events,
-+ td_thr_events_t *event_maskp)
-+{
-+ size_t sseg;
-+ int pid;
-+ pthread_descr new_thread;
-+ char * new_thread_bottom;
-+ pthread_t new_thread_id;
-+ char *guardaddr = NULL;
-+ size_t guardsize = 0;
-+ int pagesize = __getpagesize();
-+
-+ /* First check whether we have to change the policy and if yes, whether
-+ we can do this. Normally this should be done by examining the
-+ return value of the __sched_setscheduler call in pthread_start_thread
-+ but this is hard to implement. FIXME */
-+ if (attr != NULL && attr->__schedpolicy != SCHED_OTHER && geteuid () != 0)
-+ return EPERM;
-+ /* Find a free segment for the thread, and allocate a stack if needed */
-+ for (sseg = 2; ; sseg++)
-+ {
-+ if (sseg >= PTHREAD_THREADS_MAX)
-+ return EAGAIN;
-+ if (__pthread_handles[sseg].h_descr != NULL)
-+ continue;
-+ if (pthread_allocate_stack(attr, thread_segment(sseg), pagesize,
-+ &new_thread, &new_thread_bottom,
-+ &guardaddr, &guardsize) == 0)
-+ break;
-+ }
-+ __pthread_handles_num++;
-+ /* Allocate new thread identifier */
-+ pthread_threads_counter += PTHREAD_THREADS_MAX;
-+ new_thread_id = sseg + pthread_threads_counter;
-+ /* Initialize the thread descriptor. Elements which have to be
-+ initialized to zero already have this value. */
-+ new_thread->p_tid = new_thread_id;
-+ new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
-+ new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
-+ new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
-+ new_thread->p_errnop = &new_thread->p_errno;
-+ new_thread->p_h_errnop = &new_thread->p_h_errno;
-+ new_thread->p_guardaddr = guardaddr;
-+ new_thread->p_guardsize = guardsize;
-+ new_thread->p_self = new_thread;
-+ new_thread->p_nr = sseg;
-+ /* Initialize the thread handle */
-+ __pthread_init_lock(&__pthread_handles[sseg].h_lock);
-+ __pthread_handles[sseg].h_descr = new_thread;
-+ __pthread_handles[sseg].h_bottom = new_thread_bottom;
-+ /* Determine scheduling parameters for the thread */
-+ new_thread->p_start_args.schedpolicy = -1;
-+ if (attr != NULL) {
-+ new_thread->p_detached = attr->__detachstate;
-+ new_thread->p_userstack = attr->__stackaddr_set;
-+
-+ switch(attr->__inheritsched) {
-+ case PTHREAD_EXPLICIT_SCHED:
-+ new_thread->p_start_args.schedpolicy = attr->__schedpolicy;
-+ memcpy (&new_thread->p_start_args.schedparam, &attr->__schedparam,
-+ sizeof (struct sched_param));
-+ break;
-+ case PTHREAD_INHERIT_SCHED:
-+ new_thread->p_start_args.schedpolicy = __sched_getscheduler(father_pid);
-+ __sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
-+ break;
-+ }
-+ new_thread->p_priority =
-+ new_thread->p_start_args.schedparam.sched_priority;
-+ }
-+ /* Finish setting up arguments to pthread_start_thread */
-+ new_thread->p_start_args.start_routine = start_routine;
-+ new_thread->p_start_args.arg = arg;
-+ new_thread->p_start_args.mask = *mask;
-+ /* Raise priority of thread manager if needed */
-+ __pthread_manager_adjust_prio(new_thread->p_priority);
-+ /* Do the cloning. We have to use two different functions depending
-+ on whether we are debugging or not. */
-+ pid = 0; /* Note that the thread never can have PID zero. */
-+ if (report_events)
-+ {
-+ /* See whether the TD_CREATE event bit is set in any of the
-+ masks. */
-+ int idx = __td_eventword (TD_CREATE);
-+ uint32_t mask = __td_eventmask (TD_CREATE);
-+
-+ if ((mask & (__pthread_threads_events.event_bits[idx]
-+ | event_maskp->event_bits[idx])) != 0)
-+ {
-+ /* Lock the mutex the child will use now so that it will stop. */
-+ __pthread_lock(new_thread->p_lock, NULL);
-+
-+ /* We have to report this event. */
-+ pid = __clone(pthread_start_thread_event, (void **) new_thread,
-+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
-+ __pthread_sig_cancel, new_thread);
-+ if (pid != -1)
-+ {
-+ /* Now fill in the information about the new thread in
-+ the newly created thread's data structure. We cannot let
-+ the new thread do this since we don't know whether it was
-+ already scheduled when we send the event. */
-+ new_thread->p_eventbuf.eventdata = new_thread;
-+ new_thread->p_eventbuf.eventnum = TD_CREATE;
-+ __pthread_last_event = new_thread;
-+
-+ /* We have to set the PID here since the callback function
-+ in the debug library will need it and we cannot guarantee
-+ the child got scheduled before the debugger. */
-+ new_thread->p_pid = pid;
-+
-+ /* Now call the function which signals the event. */
-+ __linuxthreads_create_event ();
-+
-+ /* Now restart the thread. */
-+ __pthread_unlock(new_thread->p_lock);
-+ }
-+ }
-+ }
-+ if (pid == 0)
-+ pid = __clone(pthread_start_thread, (void **) new_thread,
-+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
-+ __pthread_sig_cancel, new_thread);
-+ /* Check if cloning succeeded */
-+ if (pid == -1) {
-+ /* Free the stack if we allocated it */
-+ if (attr == NULL || !attr->__stackaddr_set)
-+ {
-+ if (new_thread->p_guardsize != 0)
-+ munmap(new_thread->p_guardaddr, new_thread->p_guardsize);
-+ munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
-+ INITIAL_STACK_SIZE);
-+ }
-+ __pthread_handles[sseg].h_descr = NULL;
-+ __pthread_handles[sseg].h_bottom = NULL;
-+ __pthread_handles_num--;
-+ return errno;
-+ }
-+ /* Insert new thread in doubly linked list of active threads */
-+ new_thread->p_prevlive = __pthread_main_thread;
-+ new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
-+ __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
-+ __pthread_main_thread->p_nextlive = new_thread;
-+ /* Set pid field of the new thread, in case we get there before the
-+ child starts. */
-+ new_thread->p_pid = pid;
-+ /* We're all set */
-+ *thread = new_thread_id;
-+ return 0;
-+}
-+
-+
-+/* Try to free the resources of a thread when requested by pthread_join
-+ or pthread_detach on a terminated thread. */
-+
-+static void pthread_free(pthread_descr th)
-+{
-+ pthread_handle handle;
-+ pthread_readlock_info *iter, *next;
-+
-+ ASSERT(th->p_exited);
-+ /* Make the handle invalid */
-+ handle = thread_handle(th->p_tid);
-+ __pthread_lock(&handle->h_lock, NULL);
-+ handle->h_descr = NULL;
-+ handle->h_bottom = (char *)(-1L);
-+ __pthread_unlock(&handle->h_lock);
-+#ifdef FREE_THREAD_SELF
-+ FREE_THREAD_SELF(th, th->p_nr);
-+#endif
-+ /* One fewer threads in __pthread_handles */
-+ __pthread_handles_num--;
-+
-+ /* Destroy read lock list, and list of free read lock structures.
-+ If the former is not empty, it means the thread exited while
-+ holding read locks! */
-+
-+ for (iter = th->p_readlock_list; iter != NULL; iter = next)
-+ {
-+ next = iter->pr_next;
-+ free(iter);
-+ }
-+
-+ for (iter = th->p_readlock_free; iter != NULL; iter = next)
-+ {
-+ next = iter->pr_next;
-+ free(iter);
-+ }
-+
-+ /* If initial thread, nothing to free */
-+ if (th == &__pthread_initial_thread) return;
-+ if (!th->p_userstack)
-+ {
-+ /* Free the stack and thread descriptor area */
-+ if (th->p_guardsize != 0)
-+ munmap(th->p_guardaddr, th->p_guardsize);
-+ munmap((caddr_t) ((char *)(th+1) - STACK_SIZE), STACK_SIZE);
-+ }
-+}
-+
-+/* Handle threads that have exited */
-+
-+static void pthread_exited(pid_t pid)
-+{
-+ pthread_descr th;
-+ int detached;
-+ /* Find thread with that pid */
-+ for (th = __pthread_main_thread->p_nextlive;
-+ th != __pthread_main_thread;
-+ th = th->p_nextlive) {
-+ if (th->p_pid == pid) {
-+ /* Remove thread from list of active threads */
-+ th->p_nextlive->p_prevlive = th->p_prevlive;
-+ th->p_prevlive->p_nextlive = th->p_nextlive;
-+ /* Mark thread as exited, and if detached, free its resources */
-+ __pthread_lock(th->p_lock, NULL);
-+ th->p_exited = 1;
-+ /* If we have to signal this event do it now. */
-+ if (th->p_report_events)
-+ {
-+ /* See whether TD_DEATH is in any of the mask. */
-+ int idx = __td_eventword (TD_REAP);
-+ uint32_t mask = __td_eventmask (TD_REAP);
-+
-+ if ((mask & (__pthread_threads_events.event_bits[idx]
-+ | th->p_eventbuf.eventmask.event_bits[idx])) != 0)
-+ {
-+ /* Yep, we have to signal the death. */
-+ th->p_eventbuf.eventnum = TD_DEATH;
-+ th->p_eventbuf.eventdata = th;
-+ __pthread_last_event = th;
-+
-+ /* Now call the function to signal the event. */
-+ __linuxthreads_reap_event();
-+ }
-+ }
-+ detached = th->p_detached;
-+ __pthread_unlock(th->p_lock);
-+ if (detached)
-+ pthread_free(th);
-+ break;
-+ }
-+ }
-+ /* If all threads have exited and the main thread is pending on a
-+ pthread_exit, wake up the main thread and terminate ourselves. */
-+ if (main_thread_exiting &&
-+ __pthread_main_thread->p_nextlive == __pthread_main_thread) {
-+ restart(__pthread_main_thread);
-+ _exit(0);
-+ }
-+}
-+
-+static void pthread_reap_children(void)
-+{
-+ pid_t pid;
-+ int status;
-+
-+ while ((pid = __libc_waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) {
-+ pthread_exited(pid);
-+ if (WIFSIGNALED(status)) {
-+ /* If a thread died due to a signal, send the same signal to
-+ all other threads, including the main thread. */
-+ pthread_kill_all_threads(WTERMSIG(status), 1);
-+ _exit(0);
-+ }
-+ }
-+}
-+
-+/* Try to free the resources of a thread when requested by pthread_join
-+ or pthread_detach on a terminated thread. */
-+
-+static void pthread_handle_free(pthread_t th_id)
-+{
-+ pthread_handle handle = thread_handle(th_id);
-+ pthread_descr th;
-+
-+ __pthread_lock(&handle->h_lock, NULL);
-+ if (invalid_handle(handle, th_id)) {
-+ /* pthread_reap_children has deallocated the thread already,
-+ nothing needs to be done */
-+ __pthread_unlock(&handle->h_lock);
-+ return;
-+ }
-+ th = handle->h_descr;
-+ if (th->p_exited) {
-+ __pthread_unlock(&handle->h_lock);
-+ pthread_free(th);
-+ } else {
-+ /* The Unix process of the thread is still running.
-+ Mark the thread as detached so that the thread manager will
-+ deallocate its resources when the Unix process exits. */
-+ th->p_detached = 1;
-+ __pthread_unlock(&handle->h_lock);
-+ }
-+}
-+
-+/* Send a signal to all running threads */
-+
-+static void pthread_kill_all_threads(int sig, int main_thread_also)
-+{
-+ pthread_descr th;
-+ for (th = __pthread_main_thread->p_nextlive;
-+ th != __pthread_main_thread;
-+ th = th->p_nextlive) {
-+ kill(th->p_pid, sig);
-+ }
-+ if (main_thread_also) {
-+ kill(__pthread_main_thread->p_pid, sig);
-+ }
-+}
-+
-+/* Process-wide exit() */
-+
-+static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
-+{
-+ pthread_descr th;
-+ __pthread_exit_requested = 1;
-+ __pthread_exit_code = exitcode;
-+ /* Send the CANCEL signal to all running threads, including the main
-+ thread, but excluding the thread from which the exit request originated
-+ (that thread must complete the exit, e.g. calling atexit functions
-+ and flushing stdio buffers). */
-+ for (th = issuing_thread->p_nextlive;
-+ th != issuing_thread;
-+ th = th->p_nextlive) {
-+ kill(th->p_pid, __pthread_sig_cancel);
-+ }
-+ /* Now, wait for all these threads, so that they don't become zombies
-+ and their times are properly added to the thread manager's times. */
-+ for (th = issuing_thread->p_nextlive;
-+ th != issuing_thread;
-+ th = th->p_nextlive) {
-+ waitpid(th->p_pid, NULL, __WCLONE);
-+ }
-+ restart(issuing_thread);
-+ _exit(0);
-+}
-+
-+/* Handler for __pthread_sig_cancel in thread manager thread */
-+
-+void __pthread_manager_sighandler(int sig)
-+{
-+ terminated_children = 1;
-+}
-+
-+/* Adjust priority of thread manager so that it always run at a priority
-+ higher than all threads */
-+
-+void __pthread_manager_adjust_prio(int thread_prio)
-+{
-+ struct sched_param param;
-+
-+ if (thread_prio <= __pthread_manager_thread.p_priority) return;
-+ param.sched_priority =
-+ thread_prio < __sched_get_priority_max(SCHED_FIFO)
-+ ? thread_prio + 1 : thread_prio;
-+ __sched_setscheduler(__pthread_manager_thread.p_pid, SCHED_FIFO, &param);
-+ __pthread_manager_thread.p_priority = thread_prio;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/mutex.c glibc-2.1.3/linuxthreads/mutex.c
---- ../glibc-2.1.3/linuxthreads/mutex.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/mutex.c 1998-11-19 09:03:45.000000000 -0800
-@@ -0,0 +1,199 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Mutexes */
-+
-+#include <errno.h>
-+#include <sched.h>
-+#include <stddef.h>
-+#include "pthread.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include "queue.h"
-+#include "restart.h"
-+
-+int __pthread_mutex_init(pthread_mutex_t * mutex,
-+ const pthread_mutexattr_t * mutex_attr)
-+{
-+ __pthread_init_lock(&mutex->__m_lock);
-+ mutex->__m_kind =
-+ mutex_attr == NULL ? PTHREAD_MUTEX_FAST_NP : mutex_attr->__mutexkind;
-+ mutex->__m_count = 0;
-+ mutex->__m_owner = NULL;
-+ return 0;
-+}
-+strong_alias (__pthread_mutex_init, pthread_mutex_init)
-+
-+int __pthread_mutex_destroy(pthread_mutex_t * mutex)
-+{
-+ if (mutex->__m_lock.__status != 0) return EBUSY;
-+ return 0;
-+}
-+strong_alias (__pthread_mutex_destroy, pthread_mutex_destroy)
-+
-+int __pthread_mutex_trylock(pthread_mutex_t * mutex)
-+{
-+ pthread_descr self;
-+ int retcode;
-+
-+ switch(mutex->__m_kind) {
-+ case PTHREAD_MUTEX_FAST_NP:
-+ retcode = __pthread_trylock(&mutex->__m_lock);
-+ return retcode;
-+ case PTHREAD_MUTEX_RECURSIVE_NP:
-+ self = thread_self();
-+ if (mutex->__m_owner == self) {
-+ mutex->__m_count++;
-+ return 0;
-+ }
-+ retcode = __pthread_trylock(&mutex->__m_lock);
-+ if (retcode == 0) {
-+ mutex->__m_owner = self;
-+ mutex->__m_count = 0;
-+ }
-+ return retcode;
-+ case PTHREAD_MUTEX_ERRORCHECK_NP:
-+ retcode = __pthread_trylock(&mutex->__m_lock);
-+ if (retcode == 0) {
-+ mutex->__m_owner = thread_self();
-+ }
-+ return retcode;
-+ default:
-+ return EINVAL;
-+ }
-+}
-+strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
-+
-+int __pthread_mutex_lock(pthread_mutex_t * mutex)
-+{
-+ pthread_descr self;
-+
-+ switch(mutex->__m_kind) {
-+ case PTHREAD_MUTEX_FAST_NP:
-+ __pthread_lock(&mutex->__m_lock, NULL);
-+ return 0;
-+ case PTHREAD_MUTEX_RECURSIVE_NP:
-+ self = thread_self();
-+ if (mutex->__m_owner == self) {
-+ mutex->__m_count++;
-+ return 0;
-+ }
-+ __pthread_lock(&mutex->__m_lock, self);
-+ mutex->__m_owner = self;
-+ mutex->__m_count = 0;
-+ return 0;
-+ case PTHREAD_MUTEX_ERRORCHECK_NP:
-+ self = thread_self();
-+ if (mutex->__m_owner == self) return EDEADLK;
-+ __pthread_lock(&mutex->__m_lock, self);
-+ mutex->__m_owner = self;
-+ return 0;
-+ default:
-+ return EINVAL;
-+ }
-+}
-+strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
-+
-+int __pthread_mutex_unlock(pthread_mutex_t * mutex)
-+{
-+ switch (mutex->__m_kind) {
-+ case PTHREAD_MUTEX_FAST_NP:
-+ __pthread_unlock(&mutex->__m_lock);
-+ return 0;
-+ case PTHREAD_MUTEX_RECURSIVE_NP:
-+ if (mutex->__m_count > 0) {
-+ mutex->__m_count--;
-+ return 0;
-+ }
-+ mutex->__m_owner = NULL;
-+ __pthread_unlock(&mutex->__m_lock);
-+ return 0;
-+ case PTHREAD_MUTEX_ERRORCHECK_NP:
-+ if (mutex->__m_owner != thread_self() || mutex->__m_lock.__status == 0)
-+ return EPERM;
-+ mutex->__m_owner = NULL;
-+ __pthread_unlock(&mutex->__m_lock);
-+ return 0;
-+ default:
-+ return EINVAL;
-+ }
-+}
-+strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock)
-+
-+int __pthread_mutexattr_init(pthread_mutexattr_t *attr)
-+{
-+ attr->__mutexkind = PTHREAD_MUTEX_FAST_NP;
-+ return 0;
-+}
-+strong_alias (__pthread_mutexattr_init, pthread_mutexattr_init)
-+
-+int __pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
-+{
-+ return 0;
-+}
-+strong_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy)
-+
-+int __pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind)
-+{
-+ if (kind != PTHREAD_MUTEX_FAST_NP
-+ && kind != PTHREAD_MUTEX_RECURSIVE_NP
-+ && kind != PTHREAD_MUTEX_ERRORCHECK_NP)
-+ return EINVAL;
-+ attr->__mutexkind = kind;
-+ return 0;
-+}
-+weak_alias (__pthread_mutexattr_settype, pthread_mutexattr_settype)
-+strong_alias ( __pthread_mutexattr_settype, __pthread_mutexattr_setkind_np)
-+weak_alias (__pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np)
-+
-+int __pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *kind)
-+{
-+ *kind = attr->__mutexkind;
-+ return 0;
-+}
-+weak_alias (__pthread_mutexattr_gettype, pthread_mutexattr_gettype)
-+strong_alias (__pthread_mutexattr_gettype, __pthread_mutexattr_getkind_np)
-+weak_alias (__pthread_mutexattr_getkind_np, pthread_mutexattr_getkind_np)
-+
-+/* Once-only execution */
-+
-+static pthread_mutex_t once_masterlock = PTHREAD_MUTEX_INITIALIZER;
-+static pthread_cond_t once_finished = PTHREAD_COND_INITIALIZER;
-+
-+enum { NEVER = 0, IN_PROGRESS = 1, DONE = 2 };
-+
-+int __pthread_once(pthread_once_t * once_control, void (*init_routine)(void))
-+{
-+ /* Test without locking first for speed */
-+ if (*once_control == DONE) return 0;
-+ /* Lock and test again */
-+ pthread_mutex_lock(&once_masterlock);
-+ /* If init_routine is being called from another routine, wait until
-+ it completes. */
-+ while (*once_control == IN_PROGRESS) {
-+ pthread_cond_wait(&once_finished, &once_masterlock);
-+ }
-+ /* Here *once_control is stable and either NEVER or DONE. */
-+ if (*once_control == NEVER) {
-+ *once_control = IN_PROGRESS;
-+ pthread_mutex_unlock(&once_masterlock);
-+ init_routine();
-+ pthread_mutex_lock(&once_masterlock);
-+ *once_control = DONE;
-+ pthread_cond_broadcast(&once_finished);
-+ }
-+ pthread_mutex_unlock(&once_masterlock);
-+ return 0;
-+}
-+strong_alias (__pthread_once, pthread_once)
-diff -Naur ../glibc-2.1.3/linuxthreads/no-tsd.c glibc-2.1.3/linuxthreads/no-tsd.c
---- ../glibc-2.1.3/linuxthreads/no-tsd.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/no-tsd.c 1999-06-30 08:55:08.000000000 -0700
-@@ -0,0 +1,33 @@
-+/* libc-internal interface for thread-specific data.
-+ Copyright (C) 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <bits/libc-tsd.h>
-+
-+/* This file provides uinitialized (common) definitions for the
-+ hooks used internally by libc to access thread-specific data.
-+
-+ When -lpthread is used, it provides initialized definitions for these
-+ variables (in specific.c), which override these uninitialized definitions.
-+
-+ If -lpthread is not used, these uninitialized variables default to zero,
-+ which the __libc_tsd_* macros check for. */
-+
-+void *(*__libc_internal_tsd_get) __P ((enum __libc_tsd_key_t));
-+int (*__libc_internal_tsd_set) __P ((enum __libc_tsd_key_t,
-+ __const void *));
-diff -Naur ../glibc-2.1.3/linuxthreads/oldsemaphore.c glibc-2.1.3/linuxthreads/oldsemaphore.c
---- ../glibc-2.1.3/linuxthreads/oldsemaphore.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/oldsemaphore.c 2000-01-06 15:40:57.000000000 -0800
-@@ -0,0 +1,235 @@
-+/*
-+ * This file contains the old semaphore code that we need to
-+ * preserve for glibc-2.0 backwards compatibility. Port to glibc 2.1
-+ * done by Cristian Gafton.
-+ */
-+
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Semaphores a la POSIX 1003.1b */
-+
-+#include <errno.h>
-+#include "pthread.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include "restart.h"
-+#include "queue.h"
-+
-+typedef struct {
-+ long int sem_status;
-+ int sem_spinlock;
-+} old_sem_t;
-+
-+/* Maximum value the semaphore can have. */
-+#define SEM_VALUE_MAX ((int) ((~0u) >> 1))
-+
-+static inline int sem_compare_and_swap(old_sem_t *sem, long oldval, long newval)
-+{
-+ return compare_and_swap(&sem->sem_status, oldval, newval, &sem->sem_spinlock);
-+}
-+
-+/* The state of a semaphore is represented by a long int encoding
-+ either the semaphore count if >= 0 and no thread is waiting on it,
-+ or the head of the list of threads waiting for the semaphore.
-+ To distinguish the two cases, we encode the semaphore count N
-+ as 2N+1, so that it has the lowest bit set.
-+
-+ A sequence of sem_wait operations on a semaphore initialized to N
-+ result in the following successive states:
-+ 2N+1, 2N-1, ..., 3, 1, &first_waiting_thread, &second_waiting_thread, ...
-+*/
-+
-+static void sem_restart_list(pthread_descr waiting);
-+
-+int __old_sem_init(old_sem_t *sem, int pshared, unsigned int value)
-+{
-+ if (value > SEM_VALUE_MAX) {
-+ errno = EINVAL;
-+ return -1;
-+ }
-+ if (pshared) {
-+ errno = ENOSYS;
-+ return -1;
-+ }
-+ sem->sem_spinlock = 0;
-+ sem->sem_status = ((long)value << 1) + 1;
-+ return 0;
-+}
-+
-+/* Function called by pthread_cancel to remove the thread from
-+ waiting inside __old_sem_wait. Here we simply unconditionally
-+ indicate that the thread is to be woken, by returning 1. */
-+
-+static int old_sem_extricate_func(void *obj, pthread_descr th)
-+{
-+ return 1;
-+}
-+
-+int __old_sem_wait(old_sem_t * sem)
-+{
-+ long oldstatus, newstatus;
-+ volatile pthread_descr self = thread_self();
-+ pthread_descr * th;
-+ pthread_extricate_if extr;
-+
-+ /* Set up extrication interface */
-+ extr.pu_object = 0;
-+ extr.pu_extricate_func = old_sem_extricate_func;
-+
-+ while (1) {
-+ /* Register extrication interface */
-+ __pthread_set_own_extricate_if(self, &extr);
-+ do {
-+ oldstatus = sem->sem_status;
-+ if ((oldstatus & 1) && (oldstatus != 1))
-+ newstatus = oldstatus - 2;
-+ else {
-+ newstatus = (long) self;
-+ self->p_nextwaiting = (pthread_descr) oldstatus;
-+ }
-+ }
-+ while (! sem_compare_and_swap(sem, oldstatus, newstatus));
-+ if (newstatus & 1) {
-+ /* We got the semaphore. */
-+ __pthread_set_own_extricate_if(self, 0);
-+ return 0;
-+ }
-+ /* Wait for sem_post or cancellation */
-+ suspend(self);
-+ __pthread_set_own_extricate_if(self, 0);
-+
-+ /* This is a cancellation point */
-+ if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) {
-+ /* Remove ourselves from the waiting list if we're still on it */
-+ /* First check if we're at the head of the list. */
-+ do {
-+ oldstatus = sem->sem_status;
-+ if (oldstatus != (long) self) break;
-+ newstatus = (long) self->p_nextwaiting;
-+ }
-+ while (! sem_compare_and_swap(sem, oldstatus, newstatus));
-+ /* Now, check if we're somewhere in the list.
-+ There's a race condition with sem_post here, but it does not matter:
-+ the net result is that at the time pthread_exit is called,
-+ self is no longer reachable from sem->sem_status. */
-+ if (oldstatus != (long) self && (oldstatus & 1) == 0) {
-+ for (th = &(((pthread_descr) oldstatus)->p_nextwaiting);
-+ *th != NULL && *th != (pthread_descr) 1;
-+ th = &((*th)->p_nextwaiting)) {
-+ if (*th == self) {
-+ *th = self->p_nextwaiting;
-+ break;
-+ }
-+ }
-+ }
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+ }
-+}
-+
-+int __old_sem_trywait(old_sem_t * sem)
-+{
-+ long oldstatus, newstatus;
-+
-+ do {
-+ oldstatus = sem->sem_status;
-+ if ((oldstatus & 1) == 0 || (oldstatus == 1)) {
-+ errno = EAGAIN;
-+ return -1;
-+ }
-+ newstatus = oldstatus - 2;
-+ }
-+ while (! sem_compare_and_swap(sem, oldstatus, newstatus));
-+ return 0;
-+}
-+
-+int __old_sem_post(old_sem_t * sem)
-+{
-+ long oldstatus, newstatus;
-+
-+ do {
-+ oldstatus = sem->sem_status;
-+ if ((oldstatus & 1) == 0)
-+ newstatus = 3;
-+ else {
-+ if (oldstatus >= SEM_VALUE_MAX) {
-+ /* Overflow */
-+ errno = ERANGE;
-+ return -1;
-+ }
-+ newstatus = oldstatus + 2;
-+ }
-+ }
-+ while (! sem_compare_and_swap(sem, oldstatus, newstatus));
-+ if ((oldstatus & 1) == 0)
-+ sem_restart_list((pthread_descr) oldstatus);
-+ return 0;
-+}
-+
-+int __old_sem_getvalue(old_sem_t * sem, int * sval)
-+{
-+ long status = sem->sem_status;
-+ if (status & 1)
-+ *sval = (int)((unsigned long) status >> 1);
-+ else
-+ *sval = 0;
-+ return 0;
-+}
-+
-+int __old_sem_destroy(old_sem_t * sem)
-+{
-+ if ((sem->sem_status & 1) == 0) {
-+ errno = EBUSY;
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+/* Auxiliary function for restarting all threads on a waiting list,
-+ in priority order. */
-+
-+static void sem_restart_list(pthread_descr waiting)
-+{
-+ pthread_descr th, towake, *p;
-+
-+ /* Sort list of waiting threads by decreasing priority (insertion sort) */
-+ towake = NULL;
-+ while (waiting != (pthread_descr) 1) {
-+ th = waiting;
-+ waiting = waiting->p_nextwaiting;
-+ p = &towake;
-+ while (*p != NULL && th->p_priority < (*p)->p_priority)
-+ p = &((*p)->p_nextwaiting);
-+ th->p_nextwaiting = *p;
-+ *p = th;
-+ }
-+ /* Wake up threads in priority order */
-+ while (towake != NULL) {
-+ th = towake;
-+ towake = towake->p_nextwaiting;
-+ th->p_nextwaiting = NULL;
-+ restart(th);
-+ }
-+}
-+
-+#if defined PIC && DO_VERSIONING
-+symbol_version (__old_sem_init, sem_init, GLIBC_2.0);
-+symbol_version (__old_sem_wait, sem_wait, GLIBC_2.0);
-+symbol_version (__old_sem_trywait, sem_trywait, GLIBC_2.0);
-+symbol_version (__old_sem_post, sem_post, GLIBC_2.0);
-+symbol_version (__old_sem_getvalue, sem_getvalue, GLIBC_2.0);
-+symbol_version (__old_sem_destroy, sem_destroy, GLIBC_2.0);
-+#endif
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/pt-machine.c glibc-2.1.3/linuxthreads/pt-machine.c
---- ../glibc-2.1.3/linuxthreads/pt-machine.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/pt-machine.c 1998-10-09 04:19:05.000000000 -0700
-@@ -0,0 +1,22 @@
-+/* "Instantiation of machine-dependent pthreads inline functions.
-+ Copyright (C) 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#define PT_EI
-+
-+#include <pt-machine.h>
-diff -Naur ../glibc-2.1.3/linuxthreads/ptfork.c glibc-2.1.3/linuxthreads/ptfork.c
---- ../glibc-2.1.3/linuxthreads/ptfork.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/ptfork.c 1999-09-07 01:05:20.000000000 -0700
-@@ -0,0 +1,105 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* The "atfork" stuff */
-+
-+#include <errno.h>
-+#include <stddef.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include "pthread.h"
-+#include "internals.h"
-+
-+struct handler_list {
-+ void (*handler)(void);
-+ struct handler_list * next;
-+};
-+
-+static pthread_mutex_t pthread_atfork_lock = PTHREAD_MUTEX_INITIALIZER;
-+static struct handler_list * pthread_atfork_prepare = NULL;
-+static struct handler_list * pthread_atfork_parent = NULL;
-+static struct handler_list * pthread_atfork_child = NULL;
-+
-+static void pthread_insert_list(struct handler_list ** list,
-+ void (*handler)(void),
-+ struct handler_list * newlist,
-+ int at_end)
-+{
-+ if (handler == NULL) return;
-+ if (at_end) {
-+ while(*list != NULL) list = &((*list)->next);
-+ }
-+ newlist->handler = handler;
-+ newlist->next = *list;
-+ *list = newlist;
-+}
-+
-+struct handler_list_block {
-+ struct handler_list prepare, parent, child;
-+};
-+
-+int __pthread_atfork(void (*prepare)(void),
-+ void (*parent)(void),
-+ void (*child)(void))
-+{
-+ struct handler_list_block * block =
-+ (struct handler_list_block *) malloc(sizeof(struct handler_list_block));
-+ if (block == NULL) return ENOMEM;
-+ pthread_mutex_lock(&pthread_atfork_lock);
-+ /* "prepare" handlers are called in LIFO */
-+ pthread_insert_list(&pthread_atfork_prepare, prepare, &block->prepare, 0);
-+ /* "parent" handlers are called in FIFO */
-+ pthread_insert_list(&pthread_atfork_parent, parent, &block->parent, 1);
-+ /* "child" handlers are called in FIFO */
-+ pthread_insert_list(&pthread_atfork_child, child, &block->child, 1);
-+ pthread_mutex_unlock(&pthread_atfork_lock);
-+ return 0;
-+}
-+strong_alias (__pthread_atfork, pthread_atfork)
-+
-+static inline void pthread_call_handlers(struct handler_list * list)
-+{
-+ for (/*nothing*/; list != NULL; list = list->next) (list->handler)();
-+}
-+
-+extern int __libc_fork(void);
-+
-+pid_t __fork(void)
-+{
-+ pid_t pid;
-+ struct handler_list * prepare, * child, * parent;
-+
-+ pthread_mutex_lock(&pthread_atfork_lock);
-+ prepare = pthread_atfork_prepare;
-+ child = pthread_atfork_child;
-+ parent = pthread_atfork_parent;
-+ pthread_mutex_unlock(&pthread_atfork_lock);
-+ pthread_call_handlers(prepare);
-+ pid = __libc_fork();
-+ if (pid == 0) {
-+ __pthread_reset_main_thread();
-+ __fresetlockfiles();
-+ pthread_call_handlers(child);
-+ } else {
-+ pthread_call_handlers(parent);
-+ }
-+ return pid;
-+}
-+weak_alias (__fork, fork);
-+
-+pid_t __vfork(void)
-+{
-+ return __fork();
-+}
-+weak_alias (__vfork, vfork);
-diff -Naur ../glibc-2.1.3/linuxthreads/pthread.c glibc-2.1.3/linuxthreads/pthread.c
---- ../glibc-2.1.3/linuxthreads/pthread.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/pthread.c 2000-01-20 18:32:38.000000000 -0800
-@@ -0,0 +1,840 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Thread creation, initialization, and basic low-level routines */
-+
-+#include <errno.h>
-+#include <stddef.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <fcntl.h>
-+#include <sys/wait.h>
-+#include <sys/resource.h>
-+#include "pthread.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include "restart.h"
-+
-+/* Descriptor of the initial thread */
-+
-+struct _pthread_descr_struct __pthread_initial_thread = {
-+ &__pthread_initial_thread, /* pthread_descr p_nextlive */
-+ &__pthread_initial_thread, /* pthread_descr p_prevlive */
-+ NULL, /* pthread_descr p_nextwaiting */
-+ NULL, /* pthread_descr p_nextlock */
-+ PTHREAD_THREADS_MAX, /* pthread_t p_tid */
-+ 0, /* int p_pid */
-+ 0, /* int p_priority */
-+ &__pthread_handles[0].h_lock, /* struct _pthread_fastlock * p_lock */
-+ 0, /* int p_signal */
-+ NULL, /* sigjmp_buf * p_signal_buf */
-+ NULL, /* sigjmp_buf * p_cancel_buf */
-+ 0, /* char p_terminated */
-+ 0, /* char p_detached */
-+ 0, /* char p_exited */
-+ NULL, /* void * p_retval */
-+ 0, /* int p_retval */
-+ NULL, /* pthread_descr p_joining */
-+ NULL, /* struct _pthread_cleanup_buffer * p_cleanup */
-+ 0, /* char p_cancelstate */
-+ 0, /* char p_canceltype */
-+ 0, /* char p_canceled */
-+ NULL, /* int *p_errnop */
-+ 0, /* int p_errno */
-+ NULL, /* int *p_h_errnop */
-+ 0, /* int p_h_errno */
-+ NULL, /* char * p_in_sighandler */
-+ 0, /* char p_sigwaiting */
-+ PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */
-+ {NULL}, /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */
-+ {NULL}, /* void * p_libc_specific[_LIBC_TSD_KEY_N] */
-+ 0, /* int p_userstack */
-+ NULL, /* void * p_guardaddr */
-+ 0, /* size_t p_guardsize */
-+ &__pthread_initial_thread, /* pthread_descr p_self */
-+ 0, /* Always index 0 */
-+ 0, /* int p_report_events */
-+ {{{0, }}, 0, NULL}, /* td_eventbuf_t p_eventbuf */
-+ ATOMIC_INITIALIZER, /* struct pthread_atomic p_resume_count */
-+ 0, /* char p_woken_by_cancel */
-+ NULL, /* struct pthread_extricate_if *p_extricate */
-+ NULL, /* pthread_readlock_info *p_readlock_list; */
-+ NULL, /* pthread_readlock_info *p_readlock_free; */
-+ 0 /* int p_untracked_readlock_count; */
-+};
-+
-+/* Descriptor of the manager thread; none of this is used but the error
-+ variables, the p_pid and p_priority fields,
-+ and the address for identification. */
-+
-+struct _pthread_descr_struct __pthread_manager_thread = {
-+ NULL, /* pthread_descr p_nextlive */
-+ NULL, /* pthread_descr p_prevlive */
-+ NULL, /* pthread_descr p_nextwaiting */
-+ NULL, /* pthread_descr p_nextlock */
-+ 0, /* int p_tid */
-+ 0, /* int p_pid */
-+ 0, /* int p_priority */
-+ &__pthread_handles[1].h_lock, /* struct _pthread_fastlock * p_lock */
-+ 0, /* int p_signal */
-+ NULL, /* sigjmp_buf * p_signal_buf */
-+ NULL, /* sigjmp_buf * p_cancel_buf */
-+ 0, /* char p_terminated */
-+ 0, /* char p_detached */
-+ 0, /* char p_exited */
-+ NULL, /* void * p_retval */
-+ 0, /* int p_retval */
-+ NULL, /* pthread_descr p_joining */
-+ NULL, /* struct _pthread_cleanup_buffer * p_cleanup */
-+ 0, /* char p_cancelstate */
-+ 0, /* char p_canceltype */
-+ 0, /* char p_canceled */
-+ &__pthread_manager_thread.p_errno, /* int *p_errnop */
-+ 0, /* int p_errno */
-+ NULL, /* int *p_h_errnop */
-+ 0, /* int p_h_errno */
-+ NULL, /* char * p_in_sighandler */
-+ 0, /* char p_sigwaiting */
-+ PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */
-+ {NULL}, /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */
-+ {NULL}, /* void * p_libc_specific[_LIBC_TSD_KEY_N] */
-+ 0, /* int p_userstack */
-+ NULL, /* void * p_guardaddr */
-+ 0, /* size_t p_guardsize */
-+ &__pthread_manager_thread, /* pthread_descr p_self */
-+ 1, /* Always index 1 */
-+ 0, /* int p_report_events */
-+ {{{0, }}, 0, NULL}, /* td_eventbuf_t p_eventbuf */
-+ ATOMIC_INITIALIZER, /* struct pthread_atomic p_resume_count */
-+ 0, /* char p_woken_by_cancel */
-+ NULL, /* struct pthread_extricate_if *p_extricate */
-+ NULL, /* pthread_readlock_info *p_readlock_list; */
-+ NULL, /* pthread_readlock_info *p_readlock_free; */
-+ 0 /* int p_untracked_readlock_count; */
-+};
-+
-+/* Pointer to the main thread (the father of the thread manager thread) */
-+/* Originally, this is the initial thread, but this changes after fork() */
-+
-+pthread_descr __pthread_main_thread = &__pthread_initial_thread;
-+
-+/* Limit between the stack of the initial thread (above) and the
-+ stacks of other threads (below). Aligned on a STACK_SIZE boundary. */
-+
-+char *__pthread_initial_thread_bos = NULL;
-+
-+/* File descriptor for sending requests to the thread manager. */
-+/* Initially -1, meaning that the thread manager is not running. */
-+
-+int __pthread_manager_request = -1;
-+
-+/* Other end of the pipe for sending requests to the thread manager. */
-+
-+int __pthread_manager_reader;
-+
-+/* Limits of the thread manager stack */
-+
-+char *__pthread_manager_thread_bos = NULL;
-+char *__pthread_manager_thread_tos = NULL;
-+
-+/* For process-wide exit() */
-+
-+int __pthread_exit_requested = 0;
-+int __pthread_exit_code = 0;
-+
-+/* Pointers that select new or old suspend/resume functions
-+ based on availability of rt signals. */
-+
-+void (*__pthread_restart)(pthread_descr) = __pthread_restart_old;
-+void (*__pthread_suspend)(pthread_descr) = __pthread_suspend_old;
-+
-+/* Communicate relevant LinuxThreads constants to gdb */
-+
-+const int __pthread_threads_max = PTHREAD_THREADS_MAX;
-+const int __pthread_sizeof_handle = sizeof(struct pthread_handle_struct);
-+const int __pthread_offsetof_descr = offsetof(struct pthread_handle_struct,
-+ h_descr);
-+const int __pthread_offsetof_pid = offsetof(struct _pthread_descr_struct,
-+ p_pid);
-+
-+/* These variables are used by the setup code. */
-+extern int _errno;
-+extern int _h_errno;
-+
-+/* Forward declarations */
-+
-+static void pthread_exit_process(int retcode, void *arg);
-+#ifndef __i386__
-+static void pthread_handle_sigcancel(int sig);
-+static void pthread_handle_sigrestart(int sig);
-+#else
-+static void pthread_handle_sigcancel(int sig, struct sigcontext ctx);
-+static void pthread_handle_sigrestart(int sig, struct sigcontext ctx);
-+#endif
-+static void pthread_handle_sigdebug(int sig);
-+
-+/* Signal numbers used for the communication.
-+ In these variables we keep track of the used variables. If the
-+ platform does not support any real-time signals we will define the
-+ values to some unreasonable value which will signal failing of all
-+ the functions below. */
-+#ifndef __SIGRTMIN
-+static int current_rtmin = -1;
-+static int current_rtmax = -1;
-+int __pthread_sig_restart = SIGUSR1;
-+int __pthread_sig_cancel = SIGUSR2;
-+int __pthread_sig_debug = 0;
-+#else
-+static int current_rtmin;
-+static int current_rtmax;
-+
-+#if __SIGRTMAX - __SIGRTMIN >= 3
-+int __pthread_sig_restart = __SIGRTMIN;
-+int __pthread_sig_cancel = __SIGRTMIN + 1;
-+int __pthread_sig_debug = __SIGRTMIN + 2;
-+#else
-+int __pthread_sig_restart = SIGUSR1;
-+int __pthread_sig_cancel = SIGUSR2;
-+int __pthread_sig_debug = 0;
-+#endif
-+
-+static int rtsigs_initialized;
-+
-+#include "testrtsig.h"
-+
-+static void
-+init_rtsigs (void)
-+{
-+ if (!kernel_has_rtsig ())
-+ {
-+ current_rtmin = -1;
-+ current_rtmax = -1;
-+#if __SIGRTMAX - __SIGRTMIN >= 3
-+ __pthread_sig_restart = SIGUSR1;
-+ __pthread_sig_cancel = SIGUSR2;
-+ __pthread_sig_debug = 0;
-+#endif
-+ __pthread_init_condvar(0);
-+ }
-+ else
-+ {
-+#if __SIGRTMAX - __SIGRTMIN >= 3
-+ current_rtmin = __SIGRTMIN + 3;
-+ __pthread_restart = __pthread_restart_new;
-+ __pthread_suspend = __pthread_wait_for_restart_signal;
-+ __pthread_init_condvar(1);
-+#else
-+ current_rtmin = __SIGRTMIN;
-+ __pthread_init_condvar(0);
-+#endif
-+
-+ current_rtmax = __SIGRTMAX;
-+ }
-+
-+ rtsigs_initialized = 1;
-+}
-+#endif
-+
-+/* Return number of available real-time signal with highest priority. */
-+int
-+__libc_current_sigrtmin (void)
-+{
-+#ifdef __SIGRTMIN
-+ if (!rtsigs_initialized)
-+ init_rtsigs ();
-+#endif
-+ return current_rtmin;
-+}
-+
-+/* Return number of available real-time signal with lowest priority. */
-+int
-+__libc_current_sigrtmax (void)
-+{
-+#ifdef __SIGRTMIN
-+ if (!rtsigs_initialized)
-+ init_rtsigs ();
-+#endif
-+ return current_rtmax;
-+}
-+
-+/* Allocate real-time signal with highest/lowest available
-+ priority. Please note that we don't use a lock since we assume
-+ this function to be called at program start. */
-+int
-+__libc_allocate_rtsig (int high)
-+{
-+#ifndef __SIGRTMIN
-+ return -1;
-+#else
-+ if (!rtsigs_initialized)
-+ init_rtsigs ();
-+ if (current_rtmin == -1 || current_rtmin > current_rtmax)
-+ /* We don't have anymore signal available. */
-+ return -1;
-+
-+ return high ? current_rtmin++ : current_rtmax--;
-+#endif
-+}
-+
-+/* Initialize the pthread library.
-+ Initialization is split in two functions:
-+ - a constructor function that blocks the __pthread_sig_restart signal
-+ (must do this very early, since the program could capture the signal
-+ mask with e.g. sigsetjmp before creating the first thread);
-+ - a regular function called from pthread_create when needed. */
-+
-+static void pthread_initialize(void) __attribute__((constructor));
-+
-+static void pthread_initialize(void)
-+{
-+ struct sigaction sa;
-+ sigset_t mask;
-+ struct rlimit limit;
-+ int max_stack;
-+
-+ /* If already done (e.g. by a constructor called earlier!), bail out */
-+ if (__pthread_initial_thread_bos != NULL) return;
-+#ifdef TEST_FOR_COMPARE_AND_SWAP
-+ /* Test if compare-and-swap is available */
-+ __pthread_has_cas = compare_and_swap_is_available();
-+#endif
-+ /* For the initial stack, reserve at least STACK_SIZE bytes of stack
-+ below the current stack address, and align that on a
-+ STACK_SIZE boundary. */
-+ __pthread_initial_thread_bos =
-+ (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));
-+ /* Update the descriptor for the initial thread. */
-+ __pthread_initial_thread.p_pid = __getpid();
-+ /* If we have special thread_self processing, initialize that for the
-+ main thread now. */
-+#ifdef INIT_THREAD_SELF
-+ INIT_THREAD_SELF(&__pthread_initial_thread, 0);
-+#endif
-+ /* The errno/h_errno variable of the main thread are the global ones. */
-+ __pthread_initial_thread.p_errnop = &_errno;
-+ __pthread_initial_thread.p_h_errnop = &_h_errno;
-+ /* Play with the stack size limit to make sure that no stack ever grows
-+ beyond STACK_SIZE minus two pages (one page for the thread descriptor
-+ immediately beyond, and one page to act as a guard page). */
-+ getrlimit(RLIMIT_STACK, &limit);
-+ max_stack = STACK_SIZE - 2 * __getpagesize();
-+ if (limit.rlim_cur > max_stack) {
-+ limit.rlim_cur = max_stack;
-+ setrlimit(RLIMIT_STACK, &limit);
-+ }
-+#ifdef __SIGRTMIN
-+ /* Initialize real-time signals. */
-+ init_rtsigs ();
-+#endif
-+ /* Setup signal handlers for the initial thread.
-+ Since signal handlers are shared between threads, these settings
-+ will be inherited by all other threads. */
-+#ifndef __i386__
-+ sa.sa_handler = pthread_handle_sigrestart;
-+#else
-+ sa.sa_handler = (__sighandler_t) pthread_handle_sigrestart;
-+#endif
-+ sigemptyset(&sa.sa_mask);
-+ sa.sa_flags = 0;
-+ __sigaction(__pthread_sig_restart, &sa, NULL);
-+#ifndef __i386__
-+ sa.sa_handler = pthread_handle_sigcancel;
-+#else
-+ sa.sa_handler = (__sighandler_t) pthread_handle_sigcancel;
-+#endif
-+ sa.sa_flags = 0;
-+ __sigaction(__pthread_sig_cancel, &sa, NULL);
-+ if (__pthread_sig_debug > 0) {
-+ sa.sa_handler = pthread_handle_sigdebug;
-+ sigemptyset(&sa.sa_mask);
-+ sa.sa_flags = 0;
-+ __sigaction(__pthread_sig_debug, &sa, NULL);
-+ }
-+ /* Initially, block __pthread_sig_restart. Will be unblocked on demand. */
-+ sigemptyset(&mask);
-+ sigaddset(&mask, __pthread_sig_restart);
-+ sigprocmask(SIG_BLOCK, &mask, NULL);
-+ /* Register an exit function to kill all other threads. */
-+ /* Do it early so that user-registered atexit functions are called
-+ before pthread_exit_process. */
-+ __on_exit(pthread_exit_process, NULL);
-+}
-+
-+void __pthread_initialize(void)
-+{
-+ pthread_initialize();
-+}
-+
-+int __pthread_initialize_manager(void)
-+{
-+ int manager_pipe[2];
-+ int pid;
-+ struct pthread_request request;
-+
-+ /* If basic initialization not done yet (e.g. we're called from a
-+ constructor run before our constructor), do it now */
-+ if (__pthread_initial_thread_bos == NULL) pthread_initialize();
-+ /* Setup stack for thread manager */
-+ __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
-+ if (__pthread_manager_thread_bos == NULL) return -1;
-+ __pthread_manager_thread_tos =
-+ __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;
-+ /* Setup pipe to communicate with thread manager */
-+ if (pipe(manager_pipe) == -1) {
-+ free(__pthread_manager_thread_bos);
-+ return -1;
-+ }
-+ /* Start the thread manager */
-+ pid = 0;
-+ if (__pthread_initial_thread.p_report_events)
-+ {
-+ /* It's a bit more complicated. We have to report the creation of
-+ the manager thread. */
-+ int idx = __td_eventword (TD_CREATE);
-+ uint32_t mask = __td_eventmask (TD_CREATE);
-+
-+ if ((mask & (__pthread_threads_events.event_bits[idx]
-+ | __pthread_initial_thread.p_eventbuf.eventmask.event_bits[idx]))
-+ != 0)
-+ {
-+ pid = __clone(__pthread_manager_event,
-+ (void **) __pthread_manager_thread_tos,
-+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
-+ (void *)(long)manager_pipe[0]);
-+
-+ if (pid != -1)
-+ {
-+ /* Now fill in the information about the new thread in
-+ the newly created thread's data structure. We cannot let
-+ the new thread do this since we don't know whether it was
-+ already scheduled when we send the event. */
-+ __pthread_manager_thread.p_eventbuf.eventdata =
-+ &__pthread_manager_thread;
-+ __pthread_manager_thread.p_eventbuf.eventnum = TD_CREATE;
-+ __pthread_last_event = &__pthread_manager_thread;
-+ __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
-+ __pthread_manager_thread.p_pid = pid;
-+
-+ /* Now call the function which signals the event. */
-+ __linuxthreads_create_event ();
-+
-+ /* Now restart the thread. */
-+ __pthread_unlock(__pthread_manager_thread.p_lock);
-+ }
-+ }
-+ }
-+
-+ if (pid == 0)
-+ pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
-+ CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
-+ (void *)(long)manager_pipe[0]);
-+ if (pid == -1) {
-+ free(__pthread_manager_thread_bos);
-+ __libc_close(manager_pipe[0]);
-+ __libc_close(manager_pipe[1]);
-+ return -1;
-+ }
-+ __pthread_manager_request = manager_pipe[1]; /* writing end */
-+ __pthread_manager_reader = manager_pipe[0]; /* reading end */
-+ __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
-+ __pthread_manager_thread.p_pid = pid;
-+ /* Make gdb aware of new thread manager */
-+ if (__pthread_threads_debug && __pthread_sig_debug > 0)
-+ {
-+ raise(__pthread_sig_debug);
-+ /* We suspend ourself and gdb will wake us up when it is
-+ ready to handle us. */
-+ __pthread_wait_for_restart_signal(thread_self());
-+ }
-+ /* Synchronize debugging of the thread manager */
-+ request.req_kind = REQ_DEBUG;
-+ __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
-+ return 0;
-+}
-+
-+/* Thread creation */
-+
-+int __pthread_create_2_1(pthread_t *thread, const pthread_attr_t *attr,
-+ void * (*start_routine)(void *), void *arg)
-+{
-+ pthread_descr self = thread_self();
-+ struct pthread_request request;
-+ if (__pthread_manager_request < 0) {
-+ if (__pthread_initialize_manager() < 0) return EAGAIN;
-+ }
-+ request.req_thread = self;
-+ request.req_kind = REQ_CREATE;
-+ request.req_args.create.attr = attr;
-+ request.req_args.create.fn = start_routine;
-+ request.req_args.create.arg = arg;
-+ sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
-+ &request.req_args.create.mask);
-+ __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
-+ suspend(self);
-+ if (THREAD_GETMEM(self, p_retcode) == 0)
-+ *thread = (pthread_t) THREAD_GETMEM(self, p_retval);
-+ return THREAD_GETMEM(self, p_retcode);
-+}
-+
-+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
-+default_symbol_version (__pthread_create_2_1, pthread_create, GLIBC_2.1);
-+
-+int __pthread_create_2_0(pthread_t *thread, const pthread_attr_t *attr,
-+ void * (*start_routine)(void *), void *arg)
-+{
-+ /* The ATTR attribute is not really of type `pthread_attr_t *'. It has
-+ the old size and access to the new members might crash the program.
-+ We convert the struct now. */
-+ pthread_attr_t new_attr;
-+
-+ if (attr != NULL)
-+ {
-+ size_t ps = __getpagesize ();
-+
-+ memcpy (&new_attr, attr,
-+ (size_t) &(((pthread_attr_t*)NULL)->__guardsize));
-+ new_attr.__guardsize = ps;
-+ new_attr.__stackaddr_set = 0;
-+ new_attr.__stackaddr = NULL;
-+ new_attr.__stacksize = STACK_SIZE - ps;
-+ attr = &new_attr;
-+ }
-+ return __pthread_create_2_1 (thread, attr, start_routine, arg);
-+}
-+symbol_version (__pthread_create_2_0, pthread_create, GLIBC_2.0);
-+#else
-+strong_alias (__pthread_create_2_1, pthread_create)
-+#endif
-+
-+/* Simple operations on thread identifiers */
-+
-+pthread_t pthread_self(void)
-+{
-+ pthread_descr self = thread_self();
-+ return THREAD_GETMEM(self, p_tid);
-+}
-+
-+int pthread_equal(pthread_t thread1, pthread_t thread2)
-+{
-+ return thread1 == thread2;
-+}
-+
-+/* Helper function for thread_self in the case of user-provided stacks */
-+
-+#ifndef THREAD_SELF
-+
-+pthread_descr __pthread_find_self()
-+{
-+ char * sp = CURRENT_STACK_FRAME;
-+ pthread_handle h;
-+
-+ /* __pthread_handles[0] is the initial thread, __pthread_handles[1] is
-+ the manager threads handled specially in thread_self(), so start at 2 */
-+ h = __pthread_handles + 2;
-+ while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) h++;
-+ return h->h_descr;
-+}
-+
-+#endif
-+
-+/* Thread scheduling */
-+
-+int pthread_setschedparam(pthread_t thread, int policy,
-+ const struct sched_param *param)
-+{
-+ pthread_handle handle = thread_handle(thread);
-+ pthread_descr th;
-+
-+ __pthread_lock(&handle->h_lock, NULL);
-+ if (invalid_handle(handle, thread)) {
-+ __pthread_unlock(&handle->h_lock);
-+ return ESRCH;
-+ }
-+ th = handle->h_descr;
-+ if (__sched_setscheduler(th->p_pid, policy, param) == -1) {
-+ __pthread_unlock(&handle->h_lock);
-+ return errno;
-+ }
-+ th->p_priority = policy == SCHED_OTHER ? 0 : param->sched_priority;
-+ __pthread_unlock(&handle->h_lock);
-+ if (__pthread_manager_request >= 0)
-+ __pthread_manager_adjust_prio(th->p_priority);
-+ return 0;
-+}
-+
-+int pthread_getschedparam(pthread_t thread, int *policy,
-+ struct sched_param *param)
-+{
-+ pthread_handle handle = thread_handle(thread);
-+ int pid, pol;
-+
-+ __pthread_lock(&handle->h_lock, NULL);
-+ if (invalid_handle(handle, thread)) {
-+ __pthread_unlock(&handle->h_lock);
-+ return ESRCH;
-+ }
-+ pid = handle->h_descr->p_pid;
-+ __pthread_unlock(&handle->h_lock);
-+ pol = __sched_getscheduler(pid);
-+ if (pol == -1) return errno;
-+ if (__sched_getparam(pid, param) == -1) return errno;
-+ *policy = pol;
-+ return 0;
-+}
-+
-+/* Process-wide exit() request */
-+
-+static void pthread_exit_process(int retcode, void *arg)
-+{
-+ struct pthread_request request;
-+ pthread_descr self = thread_self();
-+
-+ if (__pthread_manager_request >= 0) {
-+ request.req_thread = self;
-+ request.req_kind = REQ_PROCESS_EXIT;
-+ request.req_args.exit.code = retcode;
-+ __libc_write(__pthread_manager_request,
-+ (char *) &request, sizeof(request));
-+ suspend(self);
-+ /* Main thread should accumulate times for thread manager and its
-+ children, so that timings for main thread account for all threads. */
-+ if (self == __pthread_main_thread)
-+ waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
-+ }
-+}
-+
-+/* The handler for the RESTART signal just records the signal received
-+ in the thread descriptor, and optionally performs a siglongjmp
-+ (for pthread_cond_timedwait). */
-+
-+#ifndef __i386__
-+static void pthread_handle_sigrestart(int sig)
-+{
-+ pthread_descr self = thread_self();
-+#else
-+static void pthread_handle_sigrestart(int sig, struct sigcontext ctx)
-+{
-+ pthread_descr self;
-+ asm volatile ("movw %w0,%%gs" : : "r" (ctx.gs));
-+ self = thread_self();
-+#endif
-+ THREAD_SETMEM(self, p_signal, sig);
-+ if (THREAD_GETMEM(self, p_signal_jmp) != NULL)
-+ siglongjmp(*THREAD_GETMEM(self, p_signal_jmp), 1);
-+}
-+
-+/* The handler for the CANCEL signal checks for cancellation
-+ (in asynchronous mode), for process-wide exit and exec requests.
-+ For the thread manager thread, redirect the signal to
-+ __pthread_manager_sighandler. */
-+
-+#ifndef __i386__
-+static void pthread_handle_sigcancel(int sig)
-+{
-+ pthread_descr self = thread_self();
-+ sigjmp_buf * jmpbuf;
-+#else
-+static void pthread_handle_sigcancel(int sig, struct sigcontext ctx)
-+{
-+ pthread_descr self;
-+ sigjmp_buf * jmpbuf;
-+ asm volatile ("movw %w0,%%gs" : : "r" (ctx.gs));
-+ self = thread_self();
-+#endif
-+
-+ if (self == &__pthread_manager_thread)
-+ {
-+ __pthread_manager_sighandler(sig);
-+ return;
-+ }
-+ if (__pthread_exit_requested) {
-+ /* Main thread should accumulate times for thread manager and its
-+ children, so that timings for main thread account for all threads. */
-+ if (self == __pthread_main_thread)
-+ waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
-+ _exit(__pthread_exit_code);
-+ }
-+ if (THREAD_GETMEM(self, p_canceled)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
-+ if (THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)
-+ pthread_exit(PTHREAD_CANCELED);
-+ jmpbuf = THREAD_GETMEM(self, p_cancel_jmp);
-+ if (jmpbuf != NULL) {
-+ THREAD_SETMEM(self, p_cancel_jmp, NULL);
-+ siglongjmp(*jmpbuf, 1);
-+ }
-+ }
-+}
-+
-+/* Handler for the DEBUG signal.
-+ The debugging strategy is as follows:
-+ On reception of a REQ_DEBUG request (sent by new threads created to
-+ the thread manager under debugging mode), the thread manager throws
-+ __pthread_sig_debug to itself. The debugger (if active) intercepts
-+ this signal, takes into account new threads and continue execution
-+ of the thread manager by propagating the signal because it doesn't
-+ know what it is specifically done for. In the current implementation,
-+ the thread manager simply discards it. */
-+
-+static void pthread_handle_sigdebug(int sig)
-+{
-+ /* Nothing */
-+}
-+
-+/* Reset the state of the thread machinery after a fork().
-+ Close the pipe used for requests and set the main thread to the forked
-+ thread.
-+ Notice that we can't free the stack segments, as the forked thread
-+ may hold pointers into them. */
-+
-+void __pthread_reset_main_thread()
-+{
-+ pthread_descr self = thread_self();
-+
-+ if (__pthread_manager_request != -1) {
-+ /* Free the thread manager stack */
-+ free(__pthread_manager_thread_bos);
-+ __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
-+ /* Close the two ends of the pipe */
-+ __libc_close(__pthread_manager_request);
-+ __libc_close(__pthread_manager_reader);
-+ __pthread_manager_request = __pthread_manager_reader = -1;
-+ }
-+
-+ /* Update the pid of the main thread */
-+ THREAD_SETMEM(self, p_pid, __getpid());
-+ /* Make the forked thread the main thread */
-+ __pthread_main_thread = self;
-+ THREAD_SETMEM(self, p_nextlive, self);
-+ THREAD_SETMEM(self, p_prevlive, self);
-+ /* Now this thread modifies the global variables. */
-+ THREAD_SETMEM(self, p_errnop, &_errno);
-+ THREAD_SETMEM(self, p_h_errnop, &_h_errno);
-+}
-+
-+/* Process-wide exec() request */
-+
-+void __pthread_kill_other_threads_np(void)
-+{
-+ struct sigaction sa;
-+ /* Terminate all other threads and thread manager */
-+ pthread_exit_process(0, NULL);
-+ /* Make current thread the main thread in case the calling thread
-+ changes its mind, does not exec(), and creates new threads instead. */
-+ __pthread_reset_main_thread();
-+ /* Reset the signal handlers behaviour for the signals the
-+ implementation uses since this would be passed to the new
-+ process. */
-+ sigemptyset(&sa.sa_mask);
-+ sa.sa_flags = 0;
-+ sa.sa_handler = SIG_DFL;
-+ __sigaction(__pthread_sig_restart, &sa, NULL);
-+ __sigaction(__pthread_sig_cancel, &sa, NULL);
-+ if (__pthread_sig_debug > 0)
-+ __sigaction(__pthread_sig_debug, &sa, NULL);
-+}
-+weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np)
-+
-+/* Concurrency symbol level. */
-+static int current_level;
-+
-+int __pthread_setconcurrency(int level)
-+{
-+ /* We don't do anything unless we have found a useful interpretation. */
-+ current_level = level;
-+ return 0;
-+}
-+weak_alias (__pthread_setconcurrency, pthread_setconcurrency)
-+
-+int __pthread_getconcurrency(void)
-+{
-+ return current_level;
-+}
-+weak_alias (__pthread_getconcurrency, pthread_getconcurrency)
-+
-+void __pthread_set_own_extricate_if(pthread_descr self, pthread_extricate_if *peif)
-+{
-+ __pthread_lock(self->p_lock, self);
-+ THREAD_SETMEM(self, p_extricate, peif);
-+ __pthread_unlock(self->p_lock);
-+}
-+
-+/* Primitives for controlling thread execution */
-+
-+void __pthread_wait_for_restart_signal(pthread_descr self)
-+{
-+ sigset_t mask;
-+
-+ sigprocmask(SIG_SETMASK, NULL, &mask); /* Get current signal mask */
-+ sigdelset(&mask, __pthread_sig_restart); /* Unblock the restart signal */
-+ do {
-+ self->p_signal = 0;
-+ sigsuspend(&mask); /* Wait for signal */
-+ } while (self->p_signal !=__pthread_sig_restart );
-+}
-+
-+/* The _old variants are for 2.0 and early 2.1 kernels which don't have RT signals.
-+ On these kernels, we use SIGUSR1 and SIGUSR2 for restart and cancellation.
-+ Since the restart signal does not queue, we use an atomic counter to create
-+ queuing semantics. This is needed to resolve a rare race condition in
-+ pthread_cond_timedwait_relative. */
-+
-+void __pthread_restart_old(pthread_descr th)
-+{
-+ if (atomic_increment(&th->p_resume_count) == -1)
-+ kill(th->p_pid, __pthread_sig_restart);
-+}
-+
-+void __pthread_suspend_old(pthread_descr self)
-+{
-+ if (atomic_decrement(&self->p_resume_count) <= 0)
-+ __pthread_wait_for_restart_signal(self);
-+}
-+
-+void __pthread_restart_new(pthread_descr th)
-+{
-+ kill(th->p_pid, __pthread_sig_restart);
-+}
-+
-+/* There is no __pthread_suspend_new because it would just
-+ be a wasteful wrapper for __pthread_wait_for_restart_signal */
-+
-+/* Debugging aid */
-+
-+#ifdef DEBUG
-+#include <stdarg.h>
-+
-+void __pthread_message(char * fmt, ...)
-+{
-+ char buffer[1024];
-+ va_list args;
-+ sprintf(buffer, "%05d : ", __getpid());
-+ va_start(args, fmt);
-+ vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args);
-+ va_end(args);
-+ __libc_write(2, buffer, strlen(buffer));
-+}
-+
-+#endif
-+
-+
-+#ifndef PIC
-+/* We need a hook to force the cancelation wrappers to be linked in when
-+ static libpthread is used. */
-+extern const int __pthread_provide_wrappers;
-+static const int *const __pthread_require_wrappers =
-+ &__pthread_provide_wrappers;
-+#endif
-diff -Naur ../glibc-2.1.3/linuxthreads/ptlongjmp.c glibc-2.1.3/linuxthreads/ptlongjmp.c
---- ../glibc-2.1.3/linuxthreads/ptlongjmp.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/ptlongjmp.c 1998-10-28 08:30:49.000000000 -0800
-@@ -0,0 +1,55 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Redefine siglongjmp and longjmp so that they interact correctly
-+ with cleanup handlers */
-+
-+#include <setjmp.h>
-+#include "pthread.h"
-+#include "internals.h"
-+
-+/* These functions are not declared anywhere since they shouldn't be
-+ used at another place but here. */
-+extern void __libc_siglongjmp (sigjmp_buf env, int val)
-+ __attribute__ ((noreturn));
-+extern void __libc_longjmp (sigjmp_buf env, int val)
-+ __attribute__ ((noreturn));
-+
-+
-+static void pthread_cleanup_upto(__jmp_buf target)
-+{
-+ pthread_descr self = thread_self();
-+ struct _pthread_cleanup_buffer * c;
-+
-+ for (c = THREAD_GETMEM(self, p_cleanup);
-+ c != NULL && _JMPBUF_UNWINDS(target, c);
-+ c = c->__prev)
-+ c->__routine(c->__arg);
-+ THREAD_SETMEM(self, p_cleanup, c);
-+ if (THREAD_GETMEM(self, p_in_sighandler)
-+ && _JMPBUF_UNWINDS(target, THREAD_GETMEM(self, p_in_sighandler)))
-+ THREAD_SETMEM(self, p_in_sighandler, NULL);
-+}
-+
-+void siglongjmp(sigjmp_buf env, int val)
-+{
-+ pthread_cleanup_upto(env->__jmpbuf);
-+ __libc_siglongjmp(env, val);
-+}
-+
-+void longjmp(jmp_buf env, int val)
-+{
-+ pthread_cleanup_upto(env->__jmpbuf);
-+ __libc_longjmp(env, val);
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/queue.h glibc-2.1.3/linuxthreads/queue.h
---- ../glibc-2.1.3/linuxthreads/queue.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/queue.h 2000-01-20 18:32:38.000000000 -0800
-@@ -0,0 +1,61 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Waiting queues */
-+
-+/* Waiting queues are represented by lists of thread descriptors
-+ linked through their p_nextwaiting field. The lists are kept
-+ sorted by decreasing priority, and then decreasing waiting time. */
-+
-+static inline void enqueue(pthread_descr * q, pthread_descr th)
-+{
-+ int prio = th->p_priority;
-+ ASSERT(th->p_nextwaiting == NULL);
-+ for (; *q != NULL; q = &((*q)->p_nextwaiting)) {
-+ if (prio > (*q)->p_priority) {
-+ th->p_nextwaiting = *q;
-+ *q = th;
-+ return;
-+ }
-+ }
-+ *q = th;
-+}
-+
-+static inline pthread_descr dequeue(pthread_descr * q)
-+{
-+ pthread_descr th;
-+ th = *q;
-+ if (th != NULL) {
-+ *q = th->p_nextwaiting;
-+ th->p_nextwaiting = NULL;
-+ }
-+ return th;
-+}
-+
-+static inline int remove_from_queue(pthread_descr * q, pthread_descr th)
-+{
-+ for (; *q != NULL; q = &((*q)->p_nextwaiting)) {
-+ if (*q == th) {
-+ *q = th->p_nextwaiting;
-+ th->p_nextwaiting = NULL;
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static inline int queue_is_empty(pthread_descr * q)
-+{
-+ return *q == NULL;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/restart.h glibc-2.1.3/linuxthreads/restart.h
---- ../glibc-2.1.3/linuxthreads/restart.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/restart.h 2000-01-06 15:40:57.000000000 -0800
-@@ -0,0 +1,27 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+#include <signal.h>
-+
-+/* Primitives for controlling thread execution */
-+
-+static inline void restart(pthread_descr th)
-+{
-+ __pthread_restart(th); /* see pthread.c */
-+}
-+
-+static inline void suspend(pthread_descr self)
-+{
-+ __pthread_suspend(self); /* see pthread.c */
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/rwlock.c glibc-2.1.3/linuxthreads/rwlock.c
---- ../glibc-2.1.3/linuxthreads/rwlock.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/rwlock.c 2000-01-20 18:32:38.000000000 -0800
-@@ -0,0 +1,486 @@
-+/* Read-write lock implementation.
-+ Copyright (C) 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Xavier Leroy <Xavier.Leroy@inria.fr>
-+ and Ulrich Drepper <drepper@cygnus.com>, 1998.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <errno.h>
-+#include <pthread.h>
-+#include <stdlib.h>
-+#include "internals.h"
-+#include "queue.h"
-+#include "spinlock.h"
-+#include "restart.h"
-+
-+/*
-+ * Check whether the calling thread already owns one or more read locks on the
-+ * specified lock. If so, return a pointer to the read lock info structure
-+ * corresponding to that lock.
-+ */
-+
-+static pthread_readlock_info *
-+rwlock_is_in_list(pthread_descr self, pthread_rwlock_t *rwlock)
-+{
-+ pthread_readlock_info *info;
-+
-+ for (info = self->p_readlock_list; info != NULL; info = info->pr_next)
-+ {
-+ if (info->pr_lock == rwlock)
-+ return info;
-+ }
-+
-+ return NULL;
-+}
-+
-+/*
-+ * Add a new lock to the thread's list of locks for which it has a read lock.
-+ * A new info node must be allocated for this, which is taken from the thread's
-+ * free list, or by calling malloc. If malloc fails, a null pointer is
-+ * returned. Otherwise the lock info structure is initialized and pushed
-+ * onto the thread's list.
-+ */
-+
-+static pthread_readlock_info *
-+rwlock_add_to_list(pthread_descr self, pthread_rwlock_t *rwlock)
-+{
-+ pthread_readlock_info *info = self->p_readlock_free;
-+
-+ if (info != NULL)
-+ self->p_readlock_free = info->pr_next;
-+ else
-+ info = malloc(sizeof *info);
-+
-+ if (info == NULL)
-+ return NULL;
-+
-+ info->pr_lock_count = 1;
-+ info->pr_lock = rwlock;
-+ info->pr_next = self->p_readlock_list;
-+ self->p_readlock_list = info;
-+
-+ return info;
-+}
-+
-+/*
-+ * If the thread owns a read lock over the given pthread_rwlock_t,
-+ * and this read lock is tracked in the thread's lock list,
-+ * this function returns a pointer to the info node in that list.
-+ * It also decrements the lock count within that node, and if
-+ * it reaches zero, it removes the node from the list.
-+ * If nothing is found, it returns a null pointer.
-+ */
-+
-+static pthread_readlock_info *
-+rwlock_remove_from_list(pthread_descr self, pthread_rwlock_t *rwlock)
-+{
-+ pthread_readlock_info **pinfo;
-+
-+ for (pinfo = &self->p_readlock_list; *pinfo != NULL; pinfo = &(*pinfo)->pr_next)
-+ {
-+ if ((*pinfo)->pr_lock == rwlock)
-+ {
-+ pthread_readlock_info *info = *pinfo;
-+ if (--info->pr_lock_count == 0)
-+ *pinfo = info->pr_next;
-+ return info;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+/*
-+ * This function checks whether the conditions are right to place a read lock.
-+ * It returns 1 if so, otherwise zero. The rwlock's internal lock must be
-+ * locked upon entry.
-+ */
-+
-+static int
-+rwlock_can_rdlock(pthread_rwlock_t *rwlock, int have_lock_already)
-+{
-+ /* Can't readlock; it is write locked. */
-+ if (rwlock->__rw_writer != NULL)
-+ return 0;
-+
-+ /* Lock prefers readers; get it. */
-+ if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP)
-+ return 1;
-+
-+ /* Lock prefers writers, but none are waiting. */
-+ if (queue_is_empty(&rwlock->__rw_write_waiting))
-+ return 1;
-+
-+ /* Writers are waiting, but this thread already has a read lock */
-+ if (have_lock_already)
-+ return 1;
-+
-+ /* Writers are waiting, and this is a new lock */
-+ return 0;
-+}
-+
-+/*
-+ * This function helps support brain-damaged recursive read locking
-+ * semantics required by Unix 98, while maintaining write priority.
-+ * This basically determines whether this thread already holds a read lock
-+ * already. It returns 1 if so, otherwise it returns 0.
-+ *
-+ * If the thread has any ``untracked read locks'' then it just assumes
-+ * that this lock is among them, just to be safe, and returns 1.
-+ *
-+ * Also, if it finds the thread's lock in the list, it sets the pointer
-+ * referenced by pexisting to refer to the list entry.
-+ *
-+ * If the thread has no untracked locks, and the lock is not found
-+ * in its list, then it is added to the list. If this fails,
-+ * then *pout_of_mem is set to 1.
-+ */
-+
-+static int
-+rwlock_have_already(pthread_descr *pself, pthread_rwlock_t *rwlock,
-+ pthread_readlock_info **pexisting, int *pout_of_mem)
-+{
-+ pthread_readlock_info *existing = NULL;
-+ int out_of_mem = 0, have_lock_already = 0;
-+ pthread_descr self = *pself;
-+
-+ if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_WRITER_NP)
-+ {
-+ if (!self)
-+ self = thread_self();
-+
-+ existing = rwlock_is_in_list(self, rwlock);
-+
-+ if (existing != NULL || self->p_untracked_readlock_count > 0)
-+ have_lock_already = 1;
-+ else
-+ {
-+ existing = rwlock_add_to_list(self, rwlock);
-+ if (existing == NULL)
-+ out_of_mem = 1;
-+ }
-+ }
-+
-+ *pout_of_mem = out_of_mem;
-+ *pexisting = existing;
-+ *pself = self;
-+
-+ return have_lock_already;
-+}
-+
-+int
-+pthread_rwlock_init (pthread_rwlock_t *rwlock,
-+ const pthread_rwlockattr_t *attr)
-+{
-+ __pthread_init_lock(&rwlock->__rw_lock);
-+ rwlock->__rw_readers = 0;
-+ rwlock->__rw_writer = NULL;
-+ rwlock->__rw_read_waiting = NULL;
-+ rwlock->__rw_write_waiting = NULL;
-+
-+ if (attr == NULL)
-+ {
-+ rwlock->__rw_kind = PTHREAD_RWLOCK_DEFAULT_NP;
-+ rwlock->__rw_pshared = PTHREAD_PROCESS_PRIVATE;
-+ }
-+ else
-+ {
-+ rwlock->__rw_kind = attr->__lockkind;
-+ rwlock->__rw_pshared = attr->__pshared;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int
-+pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
-+{
-+ int readers;
-+ _pthread_descr writer;
-+
-+ __pthread_lock (&rwlock->__rw_lock, NULL);
-+ readers = rwlock->__rw_readers;
-+ writer = rwlock->__rw_writer;
-+ __pthread_unlock (&rwlock->__rw_lock);
-+
-+ if (readers > 0 || writer != NULL)
-+ return EBUSY;
-+
-+ return 0;
-+}
-+
-+int
-+pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
-+{
-+ pthread_descr self = NULL;
-+ pthread_readlock_info *existing;
-+ int out_of_mem, have_lock_already;
-+
-+ have_lock_already = rwlock_have_already(&self, rwlock,
-+ &existing, &out_of_mem);
-+
-+ for (;;)
-+ {
-+ if (self == NULL)
-+ self = thread_self ();
-+
-+ __pthread_lock (&rwlock->__rw_lock, self);
-+
-+ if (rwlock_can_rdlock(rwlock, have_lock_already))
-+ break;
-+
-+ enqueue (&rwlock->__rw_read_waiting, self);
-+ __pthread_unlock (&rwlock->__rw_lock);
-+ suspend (self); /* This is not a cancellation point */
-+ }
-+
-+ ++rwlock->__rw_readers;
-+ __pthread_unlock (&rwlock->__rw_lock);
-+
-+ if (have_lock_already || out_of_mem)
-+ {
-+ if (existing != NULL)
-+ existing->pr_lock_count++;
-+ else
-+ self->p_untracked_readlock_count++;
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
-+{
-+ pthread_descr self = thread_self();
-+ pthread_readlock_info *existing;
-+ int out_of_mem, have_lock_already;
-+ int retval = EBUSY;
-+
-+ have_lock_already = rwlock_have_already(&self, rwlock,
-+ &existing, &out_of_mem);
-+
-+ __pthread_lock (&rwlock->__rw_lock, self);
-+
-+ /* 0 is passed to here instead of have_lock_already.
-+ This is to meet Single Unix Spec requirements:
-+ if writers are waiting, pthread_rwlock_tryrdlock
-+ does not acquire a read lock, even if the caller has
-+ one or more read locks already. */
-+
-+ if (rwlock_can_rdlock(rwlock, 0))
-+ {
-+ ++rwlock->__rw_readers;
-+ retval = 0;
-+ }
-+
-+ __pthread_unlock (&rwlock->__rw_lock);
-+
-+ if (retval == 0)
-+ {
-+ if (have_lock_already || out_of_mem)
-+ {
-+ if (existing != NULL)
-+ existing->pr_lock_count++;
-+ else
-+ self->p_untracked_readlock_count++;
-+ }
-+ }
-+
-+ return retval;
-+}
-+
-+
-+int
-+pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
-+{
-+ pthread_descr self = thread_self ();
-+
-+ while(1)
-+ {
-+ __pthread_lock (&rwlock->__rw_lock, self);
-+ if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL)
-+ {
-+ rwlock->__rw_writer = self;
-+ __pthread_unlock (&rwlock->__rw_lock);
-+ return 0;
-+ }
-+
-+ /* Suspend ourselves, then try again */
-+ enqueue (&rwlock->__rw_write_waiting, self);
-+ __pthread_unlock (&rwlock->__rw_lock);
-+ suspend (self); /* This is not a cancellation point */
-+ }
-+}
-+
-+
-+int
-+pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
-+{
-+ int result = EBUSY;
-+
-+ __pthread_lock (&rwlock->__rw_lock, NULL);
-+ if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL)
-+ {
-+ rwlock->__rw_writer = thread_self ();
-+ result = 0;
-+ }
-+ __pthread_unlock (&rwlock->__rw_lock);
-+
-+ return result;
-+}
-+
-+
-+int
-+pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
-+{
-+ pthread_descr torestart;
-+ pthread_descr th;
-+
-+ __pthread_lock (&rwlock->__rw_lock, NULL);
-+ if (rwlock->__rw_writer != NULL)
-+ {
-+ /* Unlocking a write lock. */
-+ if (rwlock->__rw_writer != thread_self ())
-+ {
-+ __pthread_unlock (&rwlock->__rw_lock);
-+ return EPERM;
-+ }
-+ rwlock->__rw_writer = NULL;
-+
-+ if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
-+ || (th = dequeue (&rwlock->__rw_write_waiting)) == NULL)
-+ {
-+ /* Restart all waiting readers. */
-+ torestart = rwlock->__rw_read_waiting;
-+ rwlock->__rw_read_waiting = NULL;
-+ __pthread_unlock (&rwlock->__rw_lock);
-+ while ((th = dequeue (&torestart)) != NULL)
-+ restart (th);
-+ }
-+ else
-+ {
-+ /* Restart one waiting writer. */
-+ __pthread_unlock (&rwlock->__rw_lock);
-+ restart (th);
-+ }
-+ }
-+ else
-+ {
-+ /* Unlocking a read lock. */
-+ if (rwlock->__rw_readers == 0)
-+ {
-+ __pthread_unlock (&rwlock->__rw_lock);
-+ return EPERM;
-+ }
-+
-+ --rwlock->__rw_readers;
-+ if (rwlock->__rw_readers == 0)
-+ /* Restart one waiting writer, if any. */
-+ th = dequeue (&rwlock->__rw_write_waiting);
-+ else
-+ th = NULL;
-+
-+ __pthread_unlock (&rwlock->__rw_lock);
-+ if (th != NULL)
-+ restart (th);
-+
-+ /* Recursive lock fixup */
-+
-+ if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_WRITER_NP)
-+ {
-+ pthread_descr self = thread_self();
-+ pthread_readlock_info *victim = rwlock_remove_from_list(self, rwlock);
-+
-+ if (victim != NULL)
-+ {
-+ if (victim->pr_lock_count == 0)
-+ {
-+ victim->pr_next = self->p_readlock_free;
-+ self->p_readlock_free = victim;
-+ }
-+ }
-+ else
-+ {
-+ if (self->p_untracked_readlock_count > 0)
-+ self->p_untracked_readlock_count--;
-+ }
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+int
-+pthread_rwlockattr_init (pthread_rwlockattr_t *attr)
-+{
-+ attr->__lockkind = 0;
-+ attr->__pshared = 0;
-+
-+ return 0;
-+}
-+
-+
-+int
-+pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr)
-+{
-+ return 0;
-+}
-+
-+
-+int
-+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared)
-+{
-+ *pshared = attr->__pshared;
-+ return 0;
-+}
-+
-+
-+int
-+pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
-+{
-+ if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED)
-+ return EINVAL;
-+
-+ attr->__pshared = pshared;
-+
-+ return 0;
-+}
-+
-+
-+int
-+pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t *attr, int *pref)
-+{
-+ *pref = attr->__lockkind;
-+ return 0;
-+}
-+
-+
-+int
-+pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref)
-+{
-+ if (pref != PTHREAD_RWLOCK_PREFER_READER_NP
-+ && pref != PTHREAD_RWLOCK_PREFER_WRITER_NP
-+ && pref != PTHREAD_RWLOCK_DEFAULT_NP)
-+ return EINVAL;
-+
-+ attr->__lockkind = pref;
-+
-+ return 0;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/semaphore.c glibc-2.1.3/linuxthreads/semaphore.c
---- ../glibc-2.1.3/linuxthreads/semaphore.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/semaphore.c 2000-01-06 15:40:57.000000000 -0800
-@@ -0,0 +1,209 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Semaphores a la POSIX 1003.1b */
-+
-+#include <errno.h>
-+#include "pthread.h"
-+#include "semaphore.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include "restart.h"
-+#include "queue.h"
-+
-+int __new_sem_init(sem_t *sem, int pshared, unsigned int value)
-+{
-+ if (value > SEM_VALUE_MAX) {
-+ errno = EINVAL;
-+ return -1;
-+ }
-+ if (pshared) {
-+ errno = ENOSYS;
-+ return -1;
-+ }
-+ __pthread_init_lock((struct _pthread_fastlock *) &sem->__sem_lock);
-+ sem->__sem_value = value;
-+ sem->__sem_waiting = NULL;
-+ return 0;
-+}
-+
-+/* Function called by pthread_cancel to remove the thread from
-+ waiting inside __new_sem_wait. */
-+
-+static int new_sem_extricate_func(void *obj, pthread_descr th)
-+{
-+ volatile pthread_descr self = thread_self();
-+ sem_t *sem = obj;
-+ int did_remove = 0;
-+
-+ __pthread_lock((struct _pthread_fastlock *) &sem->__sem_lock, self);
-+ did_remove = remove_from_queue(&sem->__sem_waiting, th);
-+ __pthread_unlock((struct _pthread_fastlock *) &sem->__sem_lock);
-+
-+ return did_remove;
-+}
-+
-+int __new_sem_wait(sem_t * sem)
-+{
-+ volatile pthread_descr self = thread_self();
-+ pthread_extricate_if extr;
-+ int already_canceled = 0;
-+
-+ /* Set up extrication interface */
-+ extr.pu_object = sem;
-+ extr.pu_extricate_func = new_sem_extricate_func;
-+
-+ __pthread_lock((struct _pthread_fastlock *) &sem->__sem_lock, self);
-+ if (sem->__sem_value > 0) {
-+ sem->__sem_value--;
-+ __pthread_unlock((struct _pthread_fastlock *) &sem->__sem_lock);
-+ return 0;
-+ }
-+ /* Register extrication interface */
-+ __pthread_set_own_extricate_if(self, &extr);
-+ /* Enqueue only if not already cancelled. */
-+ if (!(THREAD_GETMEM(self, p_canceled)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE))
-+ enqueue(&sem->__sem_waiting, self);
-+ else
-+ already_canceled = 1;
-+ __pthread_unlock((struct _pthread_fastlock *) &sem->__sem_lock);
-+
-+ if (already_canceled) {
-+ __pthread_set_own_extricate_if(self, 0);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+
-+ /* Wait for sem_post or cancellation, or fall through if already canceled */
-+ suspend(self);
-+ __pthread_set_own_extricate_if(self, 0);
-+
-+ /* Terminate only if the wakeup came from cancellation. */
-+ /* Otherwise ignore cancellation because we got the semaphore. */
-+
-+ if (THREAD_GETMEM(self, p_woken_by_cancel)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
-+ THREAD_SETMEM(self, p_woken_by_cancel, 0);
-+ pthread_exit(PTHREAD_CANCELED);
-+ }
-+ /* We got the semaphore */
-+ return 0;
-+}
-+
-+int __new_sem_trywait(sem_t * sem)
-+{
-+ int retval;
-+
-+ __pthread_lock((struct _pthread_fastlock *) &sem->__sem_lock, NULL);
-+ if (sem->__sem_value == 0) {
-+ errno = EAGAIN;
-+ retval = -1;
-+ } else {
-+ sem->__sem_value--;
-+ retval = 0;
-+ }
-+ __pthread_unlock((struct _pthread_fastlock *) &sem->__sem_lock);
-+ return retval;
-+}
-+
-+int __new_sem_post(sem_t * sem)
-+{
-+ pthread_descr self = thread_self();
-+ pthread_descr th;
-+ struct pthread_request request;
-+
-+ if (THREAD_GETMEM(self, p_in_sighandler) == NULL) {
-+ __pthread_lock((struct _pthread_fastlock *) &sem->__sem_lock, self);
-+ if (sem->__sem_waiting == NULL) {
-+ if (sem->__sem_value >= SEM_VALUE_MAX) {
-+ /* Overflow */
-+ errno = ERANGE;
-+ __pthread_unlock((struct _pthread_fastlock *) &sem->__sem_lock);
-+ return -1;
-+ }
-+ sem->__sem_value++;
-+ __pthread_unlock((struct _pthread_fastlock *) &sem->__sem_lock);
-+ } else {
-+ th = dequeue(&sem->__sem_waiting);
-+ __pthread_unlock((struct _pthread_fastlock *) &sem->__sem_lock);
-+ restart(th);
-+ }
-+ } else {
-+ /* If we're in signal handler, delegate post operation to
-+ the thread manager. */
-+ if (__pthread_manager_request < 0) {
-+ if (__pthread_initialize_manager() < 0) {
-+ errno = EAGAIN;
-+ return -1;
-+ }
-+ }
-+ request.req_kind = REQ_POST;
-+ request.req_args.post = sem;
-+ __libc_write(__pthread_manager_request,
-+ (char *) &request, sizeof(request));
-+ }
-+ return 0;
-+}
-+
-+int __new_sem_getvalue(sem_t * sem, int * sval)
-+{
-+ *sval = sem->__sem_value;
-+ return 0;
-+}
-+
-+int __new_sem_destroy(sem_t * sem)
-+{
-+ if (sem->__sem_waiting != NULL) {
-+ __set_errno (EBUSY);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+sem_t *sem_open(const char *name, int oflag, ...)
-+{
-+ __set_errno (ENOSYS);
-+ return SEM_FAILED;
-+}
-+
-+int sem_close(sem_t *sem)
-+{
-+ __set_errno (ENOSYS);
-+ return -1;
-+}
-+
-+int sem_unlink(const char *name)
-+{
-+ __set_errno (ENOSYS);
-+ return -1;
-+}
-+
-+#if defined PIC && DO_VERSIONING
-+default_symbol_version (__new_sem_init, sem_init, GLIBC_2.1);
-+default_symbol_version (__new_sem_wait, sem_wait, GLIBC_2.1);
-+default_symbol_version (__new_sem_trywait, sem_trywait, GLIBC_2.1);
-+default_symbol_version (__new_sem_post, sem_post, GLIBC_2.1);
-+default_symbol_version (__new_sem_getvalue, sem_getvalue, GLIBC_2.1);
-+default_symbol_version (__new_sem_destroy, sem_destroy, GLIBC_2.1);
-+#else
-+# ifdef weak_alias
-+weak_alias (__new_sem_init, sem_init)
-+weak_alias (__new_sem_wait, sem_wait)
-+weak_alias (__new_sem_trywait, sem_trywait)
-+weak_alias (__new_sem_post, sem_post)
-+weak_alias (__new_sem_getvalue, sem_getvalue)
-+weak_alias (__new_sem_destroy, sem_destroy)
-+# endif
-+#endif
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/semaphore.h glibc-2.1.3/linuxthreads/semaphore.h
---- ../glibc-2.1.3/linuxthreads/semaphore.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/semaphore.h 2000-02-23 13:17:31.000000000 -0800
-@@ -0,0 +1,80 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+#ifndef _SEMAPHORE_H
-+#define _SEMAPHORE_H 1
-+
-+#include <features.h>
-+#include <sys/types.h>
-+
-+#ifndef _PTHREAD_DESCR_DEFINED
-+/* Thread descriptors. Needed for `sem_t' definition. */
-+typedef struct _pthread_descr_struct *_pthread_descr;
-+# define _PTHREAD_DESCR_DEFINED
-+#endif
-+
-+/* System specific semaphore definition. */
-+typedef struct
-+{
-+ struct
-+ {
-+ long int status;
-+ int spinlock;
-+ } __sem_lock;
-+ int __sem_value;
-+ _pthread_descr __sem_waiting;
-+} sem_t;
-+
-+
-+
-+/* Value returned if `sem_open' failed. */
-+#define SEM_FAILED ((sem_t *) 0)
-+
-+/* Maximum value the semaphore can have. */
-+#define SEM_VALUE_MAX ((int) ((~0u) >> 1))
-+
-+
-+__BEGIN_DECLS
-+
-+/* Initialize semaphore object SEM to VALUE. If PSHARED then share it
-+ with other processes. */
-+extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));
-+
-+/* Free resources associated with semaphore object SEM. */
-+extern int sem_destroy __P ((sem_t *__sem));
-+
-+/* Open a named semaphore NAME with open flaot OFLAG. */
-+extern sem_t *sem_open __P ((__const char *__name, int __oflag, ...));
-+
-+/* Close descriptor for named semaphore SEM. */
-+extern int sem_close __P ((sem_t *__sem));
-+
-+/* Remove named semaphore NAME. */
-+extern int sem_unlink __P ((__const char *__name));
-+
-+/* Wait for SEM being posted. */
-+extern int sem_wait __P ((sem_t *__sem));
-+
-+/* Test whether SEM is posted. */
-+extern int sem_trywait __P ((sem_t *__sem));
-+
-+/* Post SEM. */
-+extern int sem_post __P ((sem_t *__sem));
-+
-+/* Get current value of SEM and store it in *SVAL. */
-+extern int sem_getvalue __P ((sem_t *__sem, int *__sval));
-+
-+__END_DECLS
-+
-+#endif /* semaphore.h */
-diff -Naur ../glibc-2.1.3/linuxthreads/shlib-versions glibc-2.1.3/linuxthreads/shlib-versions
---- ../glibc-2.1.3/linuxthreads/shlib-versions 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/shlib-versions 1998-08-28 03:07:18.000000000 -0700
-@@ -0,0 +1,2 @@
-+# Xavier Leroy's Linux clone based thread library.
-+.*-.*-linux.* libpthread=0
-diff -Naur ../glibc-2.1.3/linuxthreads/signals.c glibc-2.1.3/linuxthreads/signals.c
---- ../glibc-2.1.3/linuxthreads/signals.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/signals.c 1999-09-28 08:29:01.000000000 -0700
-@@ -0,0 +1,233 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Handling of signals */
-+
-+#include <errno.h>
-+#include <signal.h>
-+#include "pthread.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include <ucontext.h>
-+#include <sigcontextinfo.h>
-+
-+int pthread_sigmask(int how, const sigset_t * newmask, sigset_t * oldmask)
-+{
-+ sigset_t mask;
-+
-+ if (newmask != NULL) {
-+ mask = *newmask;
-+ /* Don't allow __pthread_sig_restart to be unmasked.
-+ Don't allow __pthread_sig_cancel to be masked. */
-+ switch(how) {
-+ case SIG_SETMASK:
-+ sigaddset(&mask, __pthread_sig_restart);
-+ sigdelset(&mask, __pthread_sig_cancel);
-+ break;
-+ case SIG_BLOCK:
-+ sigdelset(&mask, __pthread_sig_cancel);
-+ break;
-+ case SIG_UNBLOCK:
-+ sigdelset(&mask, __pthread_sig_restart);
-+ break;
-+ }
-+ newmask = &mask;
-+ }
-+ if (sigprocmask(how, newmask, oldmask) == -1)
-+ return errno;
-+ else
-+ return 0;
-+}
-+
-+int pthread_kill(pthread_t thread, int signo)
-+{
-+ pthread_handle handle = thread_handle(thread);
-+ int pid;
-+
-+ __pthread_lock(&handle->h_lock, NULL);
-+ if (invalid_handle(handle, thread)) {
-+ __pthread_unlock(&handle->h_lock);
-+ return ESRCH;
-+ }
-+ pid = handle->h_descr->p_pid;
-+ __pthread_unlock(&handle->h_lock);
-+ if (kill(pid, signo) == -1)
-+ return errno;
-+ else
-+ return 0;
-+}
-+
-+/* User-provided signal handlers */
-+typedef void (*arch_sighandler_t) __PMT ((int, SIGCONTEXT));
-+static union
-+{
-+ arch_sighandler_t old;
-+ void (*rt) (int, struct siginfo *, struct ucontext *);
-+} sighandler[NSIG];
-+
-+/* The wrapper around user-provided signal handlers */
-+static void pthread_sighandler(int signo, SIGCONTEXT ctx)
-+{
-+ pthread_descr self = thread_self();
-+ char * in_sighandler;
-+ /* If we're in a sigwait operation, just record the signal received
-+ and return without calling the user's handler */
-+ if (THREAD_GETMEM(self, p_sigwaiting)) {
-+ THREAD_SETMEM(self, p_sigwaiting, 0);
-+ THREAD_SETMEM(self, p_signal, signo);
-+ return;
-+ }
-+ /* Record that we're in a signal handler and call the user's
-+ handler function */
-+ in_sighandler = THREAD_GETMEM(self, p_in_sighandler);
-+ if (in_sighandler == NULL)
-+ THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME);
-+ sighandler[signo].old(signo, SIGCONTEXT_EXTRA_ARGS ctx);
-+ if (in_sighandler == NULL)
-+ THREAD_SETMEM(self, p_in_sighandler, NULL);
-+}
-+
-+/* The same, this time for real-time signals. */
-+static void pthread_sighandler_rt(int signo, struct siginfo *si,
-+ struct ucontext *uc)
-+{
-+ pthread_descr self = thread_self();
-+ char * in_sighandler;
-+ /* If we're in a sigwait operation, just record the signal received
-+ and return without calling the user's handler */
-+ if (THREAD_GETMEM(self, p_sigwaiting)) {
-+ THREAD_SETMEM(self, p_sigwaiting, 0);
-+ THREAD_SETMEM(self, p_signal, signo);
-+ return;
-+ }
-+ /* Record that we're in a signal handler and call the user's
-+ handler function */
-+ in_sighandler = THREAD_GETMEM(self, p_in_sighandler);
-+ if (in_sighandler == NULL)
-+ THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME);
-+ sighandler[signo].rt(signo, si, uc);
-+ if (in_sighandler == NULL)
-+ THREAD_SETMEM(self, p_in_sighandler, NULL);
-+}
-+
-+/* The wrapper around sigaction. Install our own signal handler
-+ around the signal. */
-+int sigaction(int sig, const struct sigaction * act,
-+ struct sigaction * oact)
-+{
-+ struct sigaction newact;
-+ struct sigaction *newactp;
-+
-+ if (sig == __pthread_sig_restart ||
-+ sig == __pthread_sig_cancel ||
-+ (sig == __pthread_sig_debug && __pthread_sig_debug > 0))
-+ return EINVAL;
-+ if (act)
-+ {
-+ newact = *act;
-+ if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL
-+ && sig > 0 && sig < NSIG)
-+ {
-+ if (act->sa_flags & SA_SIGINFO)
-+ newact.sa_handler = (__sighandler_t) pthread_sighandler_rt;
-+ else
-+ newact.sa_handler = (__sighandler_t) pthread_sighandler;
-+ }
-+ newactp = &newact;
-+ }
-+ else
-+ newactp = NULL;
-+ if (__sigaction(sig, newactp, oact) == -1)
-+ return -1;
-+ if (sig > 0 && sig < NSIG)
-+ {
-+ if (oact != NULL)
-+ oact->sa_handler = (__sighandler_t) sighandler[sig].old;
-+ if (act)
-+ /* For the assignment is does not matter whether it's a normal
-+ or real-time signal. */
-+ sighandler[sig].old = (arch_sighandler_t) act->sa_handler;
-+ }
-+ return 0;
-+}
-+
-+/* A signal handler that does nothing */
-+static void pthread_null_sighandler(int sig) { }
-+
-+/* sigwait -- synchronously wait for a signal */
-+int sigwait(const sigset_t * set, int * sig)
-+{
-+ volatile pthread_descr self = thread_self();
-+ sigset_t mask;
-+ int s;
-+ sigjmp_buf jmpbuf;
-+ struct sigaction sa;
-+
-+ /* Get ready to block all signals except those in set
-+ and the cancellation signal.
-+ Also check that handlers are installed on all signals in set,
-+ and if not, install our dummy handler. This is conformant to
-+ POSIX: "The effect of sigwait() on the signal actions for the
-+ signals in set is unspecified." */
-+ sigfillset(&mask);
-+ sigdelset(&mask, __pthread_sig_cancel);
-+ for (s = 1; s <= NSIG; s++) {
-+ if (sigismember(set, s) &&
-+ s != __pthread_sig_restart &&
-+ s != __pthread_sig_cancel &&
-+ s != __pthread_sig_debug) {
-+ sigdelset(&mask, s);
-+ if (sighandler[s].old == NULL ||
-+ sighandler[s].old == (arch_sighandler_t) SIG_DFL ||
-+ sighandler[s].old == (arch_sighandler_t) SIG_IGN) {
-+ sa.sa_handler = pthread_null_sighandler;
-+ sigemptyset(&sa.sa_mask);
-+ sa.sa_flags = 0;
-+ sigaction(s, &sa, NULL);
-+ }
-+ }
-+ }
-+ /* Test for cancellation */
-+ if (sigsetjmp(jmpbuf, 1) == 0) {
-+ THREAD_SETMEM(self, p_cancel_jmp, &jmpbuf);
-+ if (! (THREAD_GETMEM(self, p_canceled)
-+ && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) {
-+ /* Reset the signal count */
-+ THREAD_SETMEM(self, p_signal, 0);
-+ /* Say we're in sigwait */
-+ THREAD_SETMEM(self, p_sigwaiting, 1);
-+ /* Unblock the signals and wait for them */
-+ sigsuspend(&mask);
-+ }
-+ }
-+ THREAD_SETMEM(self, p_cancel_jmp, NULL);
-+ /* The signals are now reblocked. Check for cancellation */
-+ pthread_testcancel();
-+ /* We should have self->p_signal != 0 and equal to the signal received */
-+ *sig = THREAD_GETMEM(self, p_signal);
-+ return 0;
-+}
-+
-+/* Redefine raise() to send signal to calling thread only,
-+ as per POSIX 1003.1c */
-+int raise (int sig)
-+{
-+ int retcode = pthread_kill(pthread_self(), sig);
-+ if (retcode == 0)
-+ return 0;
-+ else {
-+ errno = retcode;
-+ return -1;
-+ }
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/specific.c glibc-2.1.3/linuxthreads/specific.c
---- ../glibc-2.1.3/linuxthreads/specific.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/specific.c 1999-09-28 08:29:01.000000000 -0700
-@@ -0,0 +1,177 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Thread-specific data */
-+
-+#include <errno.h>
-+#include <stddef.h>
-+#include <stdlib.h>
-+#include "pthread.h"
-+#include "internals.h"
-+
-+/* Table of keys. */
-+
-+static struct pthread_key_struct pthread_keys[PTHREAD_KEYS_MAX] =
-+ { { 0, NULL } };
-+
-+/* Mutex to protect access to pthread_keys */
-+
-+static pthread_mutex_t pthread_keys_mutex = PTHREAD_MUTEX_INITIALIZER;
-+
-+/* Create a new key */
-+
-+int __pthread_key_create(pthread_key_t * key, destr_function destr)
-+{
-+ int i;
-+
-+ pthread_mutex_lock(&pthread_keys_mutex);
-+ for (i = 0; i < PTHREAD_KEYS_MAX; i++) {
-+ if (! pthread_keys[i].in_use) {
-+ /* Mark key in use */
-+ pthread_keys[i].in_use = 1;
-+ pthread_keys[i].destr = destr;
-+ pthread_mutex_unlock(&pthread_keys_mutex);
-+ *key = i;
-+ return 0;
-+ }
-+ }
-+ pthread_mutex_unlock(&pthread_keys_mutex);
-+ return EAGAIN;
-+}
-+strong_alias (__pthread_key_create, pthread_key_create)
-+
-+/* Delete a key */
-+
-+int pthread_key_delete(pthread_key_t key)
-+{
-+ pthread_descr self = thread_self();
-+ pthread_descr th;
-+ unsigned int idx1st, idx2nd;
-+
-+ pthread_mutex_lock(&pthread_keys_mutex);
-+ if (key >= PTHREAD_KEYS_MAX || !pthread_keys[key].in_use) {
-+ pthread_mutex_unlock(&pthread_keys_mutex);
-+ return EINVAL;
-+ }
-+ pthread_keys[key].in_use = 0;
-+ pthread_keys[key].destr = NULL;
-+ /* Set the value of the key to NULL in all running threads, so
-+ that if the key is reallocated later by pthread_key_create, its
-+ associated values will be NULL in all threads. */
-+ idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
-+ idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
-+ th = self;
-+ do {
-+ /* If the thread already is terminated don't modify the memory. */
-+ if (!th->p_terminated && th->p_specific[idx1st] != NULL)
-+ th->p_specific[idx1st][idx2nd] = NULL;
-+ th = th->p_nextlive;
-+ } while (th != self);
-+ pthread_mutex_unlock(&pthread_keys_mutex);
-+ return 0;
-+}
-+
-+/* Set the value of a key */
-+
-+int __pthread_setspecific(pthread_key_t key, const void * pointer)
-+{
-+ pthread_descr self = thread_self();
-+ unsigned int idx1st, idx2nd;
-+
-+ if (key >= PTHREAD_KEYS_MAX || !pthread_keys[key].in_use)
-+ return EINVAL;
-+ idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
-+ idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
-+ if (THREAD_GETMEM_NC(self, p_specific[idx1st]) == NULL) {
-+ void *newp = calloc(PTHREAD_KEY_2NDLEVEL_SIZE, sizeof (void *));
-+ if (newp == NULL)
-+ return ENOMEM;
-+ THREAD_SETMEM_NC(self, p_specific[idx1st], newp);
-+ }
-+ THREAD_GETMEM_NC(self, p_specific[idx1st])[idx2nd] = (void *) pointer;
-+ return 0;
-+}
-+strong_alias (__pthread_setspecific, pthread_setspecific)
-+
-+/* Get the value of a key */
-+
-+void * __pthread_getspecific(pthread_key_t key)
-+{
-+ pthread_descr self = thread_self();
-+ unsigned int idx1st, idx2nd;
-+
-+ if (key >= PTHREAD_KEYS_MAX)
-+ return NULL;
-+ idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
-+ idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
-+ if (THREAD_GETMEM_NC(self, p_specific[idx1st]) == NULL
-+ || !pthread_keys[key].in_use)
-+ return NULL;
-+ return THREAD_GETMEM_NC(self, p_specific[idx1st])[idx2nd];
-+}
-+strong_alias (__pthread_getspecific, pthread_getspecific)
-+
-+/* Call the destruction routines on all keys */
-+
-+void __pthread_destroy_specifics()
-+{
-+ pthread_descr self = thread_self();
-+ int i, j, round, found_nonzero;
-+ destr_function destr;
-+ void * data;
-+
-+ for (round = 0, found_nonzero = 1;
-+ found_nonzero && round < PTHREAD_DESTRUCTOR_ITERATIONS;
-+ round++) {
-+ found_nonzero = 0;
-+ for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++)
-+ if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL)
-+ for (j = 0; j < PTHREAD_KEY_2NDLEVEL_SIZE; j++) {
-+ destr = pthread_keys[i * PTHREAD_KEY_2NDLEVEL_SIZE + j].destr;
-+ data = THREAD_GETMEM_NC(self, p_specific[i])[j];
-+ if (destr != NULL && data != NULL) {
-+ THREAD_GETMEM_NC(self, p_specific[i])[j] = NULL;
-+ destr(data);
-+ found_nonzero = 1;
-+ }
-+ }
-+ }
-+ for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++) {
-+ if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL)
-+ free(THREAD_GETMEM_NC(self, p_specific[i]));
-+ }
-+}
-+
-+/* Thread-specific data for libc. */
-+
-+static int
-+libc_internal_tsd_set(enum __libc_tsd_key_t key, const void * pointer)
-+{
-+ pthread_descr self = thread_self();
-+
-+ THREAD_SETMEM_NC(self, p_libc_specific[key], (void *) pointer);
-+ return 0;
-+}
-+int (*__libc_internal_tsd_set)(enum __libc_tsd_key_t key, const void * pointer)
-+ = libc_internal_tsd_set;
-+
-+static void *
-+libc_internal_tsd_get(enum __libc_tsd_key_t key)
-+{
-+ pthread_descr self = thread_self();
-+
-+ return THREAD_GETMEM_NC(self, p_libc_specific[key]);
-+}
-+void * (*__libc_internal_tsd_get)(enum __libc_tsd_key_t key)
-+ = libc_internal_tsd_get;
-diff -Naur ../glibc-2.1.3/linuxthreads/spinlock.c glibc-2.1.3/linuxthreads/spinlock.c
---- ../glibc-2.1.3/linuxthreads/spinlock.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/spinlock.c 2000-01-06 15:40:57.000000000 -0800
-@@ -0,0 +1,195 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+/* Internal locks */
-+
-+#include <errno.h>
-+#include <sched.h>
-+#include <time.h>
-+#include "pthread.h"
-+#include "internals.h"
-+#include "spinlock.h"
-+#include "restart.h"
-+
-+/* The status field of a fastlock has the following meaning:
-+ 0: fastlock is free
-+ 1: fastlock is taken, no thread is waiting on it
-+ ADDR: fastlock is taken, ADDR is address of thread descriptor for
-+ first waiting thread, other waiting threads are linked via
-+ their p_nextlock field.
-+ The waiting list is not sorted by priority order.
-+ Actually, we always insert at top of list (sole insertion mode
-+ that can be performed without locking).
-+ For __pthread_unlock, we perform a linear search in the list
-+ to find the highest-priority, oldest waiting thread.
-+ This is safe because there are no concurrent __pthread_unlock
-+ operations -- only the thread that locked the mutex can unlock it. */
-+
-+void internal_function __pthread_lock(struct _pthread_fastlock * lock,
-+ pthread_descr self)
-+{
-+ long oldstatus, newstatus;
-+ int spurious_wakeup_count = 0;
-+
-+ do {
-+ oldstatus = lock->__status;
-+ if (oldstatus == 0) {
-+ newstatus = 1;
-+ } else {
-+ if (self == NULL)
-+ self = thread_self();
-+ newstatus = (long) self;
-+ }
-+ if (self != NULL) {
-+ ASSERT(self->p_nextlock == NULL);
-+ THREAD_SETMEM(self, p_nextlock, (pthread_descr) oldstatus);
-+ }
-+ } while(! compare_and_swap(&lock->__status, oldstatus, newstatus,
-+ &lock->__spinlock));
-+
-+ /* Suspend with guard against spurious wakeup.
-+ This can happen in pthread_cond_timedwait_relative, when the thread
-+ wakes up due to timeout and is still on the condvar queue, and then
-+ locks the queue to remove itself. At that point it may still be on the
-+ queue, and may be resumed by a condition signal. */
-+
-+ if (oldstatus != 0) {
-+ for (;;) {
-+ suspend(self);
-+ if (self->p_nextlock != NULL) {
-+ /* Count resumes that don't belong to us. */
-+ spurious_wakeup_count++;
-+ continue;
-+ }
-+ break;
-+ }
-+ }
-+
-+ /* Put back any resumes we caught that don't belong to us. */
-+ while (spurious_wakeup_count--)
-+ restart(self);
-+}
-+
-+void internal_function __pthread_unlock(struct _pthread_fastlock * lock)
-+{
-+ long oldstatus;
-+ pthread_descr thr, * ptr, * maxptr;
-+ int maxprio;
-+
-+again:
-+ oldstatus = lock->__status;
-+ if (oldstatus == 0 || oldstatus == 1) {
-+ /* No threads are waiting for this lock. Please note that we also
-+ enter this case if the lock is not taken at all. If this wouldn't
-+ be done here we would crash further down. */
-+ if (! compare_and_swap(&lock->__status, oldstatus, 0, &lock->__spinlock))
-+ goto again;
-+ return;
-+ }
-+ /* Find thread in waiting queue with maximal priority */
-+ ptr = (pthread_descr *) &lock->__status;
-+ thr = (pthread_descr) oldstatus;
-+ maxprio = 0;
-+ maxptr = ptr;
-+ while (thr != (pthread_descr) 1) {
-+ if (thr->p_priority >= maxprio) {
-+ maxptr = ptr;
-+ maxprio = thr->p_priority;
-+ }
-+ ptr = &(thr->p_nextlock);
-+ thr = *ptr;
-+ }
-+ /* Remove max prio thread from waiting list. */
-+ if (maxptr == (pthread_descr *) &lock->__status) {
-+ /* If max prio thread is at head, remove it with compare-and-swap
-+ to guard against concurrent lock operation */
-+ thr = (pthread_descr) oldstatus;
-+ if (! compare_and_swap(&lock->__status,
-+ oldstatus, (long)(thr->p_nextlock),
-+ &lock->__spinlock))
-+ goto again;
-+ } else {
-+ /* No risk of concurrent access, remove max prio thread normally */
-+ thr = *maxptr;
-+ *maxptr = thr->p_nextlock;
-+ }
-+ /* Wake up the selected waiting thread */
-+ thr->p_nextlock = NULL;
-+ restart(thr);
-+}
-+
-+/* Compare-and-swap emulation with a spinlock */
-+
-+#ifdef TEST_FOR_COMPARE_AND_SWAP
-+int __pthread_has_cas = 0;
-+#endif
-+
-+#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP
-+
-+static void __pthread_acquire(int * spinlock);
-+
-+int __pthread_compare_and_swap(long * ptr, long oldval, long newval,
-+ int * spinlock)
-+{
-+ int res;
-+ if (testandset(spinlock)) __pthread_acquire(spinlock);
-+ if (*ptr == oldval) {
-+ *ptr = newval; res = 1;
-+ } else {
-+ res = 0;
-+ }
-+ *spinlock = 0;
-+ return res;
-+}
-+
-+/* This function is called if the inlined test-and-set
-+ in __pthread_compare_and_swap() failed */
-+
-+/* The retry strategy is as follows:
-+ - We test and set the spinlock MAX_SPIN_COUNT times, calling
-+ sched_yield() each time. This gives ample opportunity for other
-+ threads with priority >= our priority to make progress and
-+ release the spinlock.
-+ - If a thread with priority < our priority owns the spinlock,
-+ calling sched_yield() repeatedly is useless, since we're preventing
-+ the owning thread from making progress and releasing the spinlock.
-+ So, after MAX_SPIN_LOCK attemps, we suspend the calling thread
-+ using nanosleep(). This again should give time to the owning thread
-+ for releasing the spinlock.
-+ Notice that the nanosleep() interval must not be too small,
-+ since the kernel does busy-waiting for short intervals in a realtime
-+ process (!). The smallest duration that guarantees thread
-+ suspension is currently 2ms.
-+ - When nanosleep() returns, we try again, doing MAX_SPIN_COUNT
-+ sched_yield(), then sleeping again if needed. */
-+
-+static void __pthread_acquire(int * spinlock)
-+{
-+ int cnt = 0;
-+ struct timespec tm;
-+
-+ while (testandset(spinlock)) {
-+ if (cnt < MAX_SPIN_COUNT) {
-+ sched_yield();
-+ cnt++;
-+ } else {
-+ tm.tv_sec = 0;
-+ tm.tv_nsec = SPIN_SLEEP_DURATION;
-+ nanosleep(&tm, NULL);
-+ cnt = 0;
-+ }
-+ }
-+}
-+
-+#endif
-diff -Naur ../glibc-2.1.3/linuxthreads/spinlock.h glibc-2.1.3/linuxthreads/spinlock.h
---- ../glibc-2.1.3/linuxthreads/spinlock.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/spinlock.h 2000-01-06 15:40:57.000000000 -0800
-@@ -0,0 +1,102 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+#if defined(TEST_FOR_COMPARE_AND_SWAP)
-+
-+extern int __pthread_has_cas;
-+extern int __pthread_compare_and_swap(long * ptr, long oldval, long newval,
-+ int * spinlock);
-+
-+static inline int compare_and_swap(long * ptr, long oldval, long newval,
-+ int * spinlock)
-+{
-+ if (__builtin_expect (__pthread_has_cas, 1))
-+ return __compare_and_swap(ptr, oldval, newval);
-+ else
-+ return __pthread_compare_and_swap(ptr, oldval, newval, spinlock);
-+}
-+
-+#elif defined(HAS_COMPARE_AND_SWAP)
-+
-+static inline int compare_and_swap(long * ptr, long oldval, long newval,
-+ int * spinlock)
-+{
-+ return __compare_and_swap(ptr, oldval, newval);
-+}
-+
-+#else
-+
-+extern int __pthread_compare_and_swap(long * ptr, long oldval, long newval,
-+ int * spinlock);
-+
-+static inline int compare_and_swap(long * ptr, long oldval, long newval,
-+ int * spinlock)
-+{
-+ return __pthread_compare_and_swap(ptr, oldval, newval, spinlock);
-+}
-+
-+#endif
-+
-+/* Internal locks */
-+
-+extern void internal_function __pthread_lock(struct _pthread_fastlock * lock,
-+ pthread_descr self);
-+extern void internal_function __pthread_unlock(struct _pthread_fastlock *lock);
-+
-+static inline void __pthread_init_lock(struct _pthread_fastlock * lock)
-+{
-+ lock->__status = 0;
-+ lock->__spinlock = 0;
-+}
-+
-+static inline int __pthread_trylock (struct _pthread_fastlock * lock)
-+{
-+ long oldstatus;
-+
-+ do {
-+ oldstatus = lock->__status;
-+ if (oldstatus != 0) return EBUSY;
-+ } while(! compare_and_swap(&lock->__status, 0, 1, &lock->__spinlock));
-+ return 0;
-+}
-+
-+#define LOCK_INITIALIZER {0, 0}
-+
-+/* Operations on pthread_atomic, which is defined in internals.h */
-+
-+static inline long atomic_increment(struct pthread_atomic *pa)
-+{
-+ long oldval;
-+
-+ do {
-+ oldval = pa->p_count;
-+ } while (!compare_and_swap(&pa->p_count, oldval, oldval + 1, &pa->p_spinlock));
-+
-+ return oldval;
-+}
-+
-+
-+static inline long atomic_decrement(struct pthread_atomic *pa)
-+{
-+ long oldval;
-+
-+ do {
-+ oldval = pa->p_count;
-+ } while (!compare_and_swap(&pa->p_count, oldval, oldval - 1, &pa->p_spinlock));
-+
-+ return oldval;
-+}
-+
-+#define ATOMIC_INITIALIZER { 0, 0 }
-+
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/alpha/pt-machine.h glibc-2.1.3/linuxthreads/sysdeps/alpha/pt-machine.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/alpha/pt-machine.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/alpha/pt-machine.h 2000-01-03 16:06:52.000000000 -0800
-@@ -0,0 +1,108 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ Alpha version.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Richard Henderson <rth@tamu.edu>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+#include <asm/pal.h>
-+
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#define CURRENT_STACK_FRAME stack_pointer
-+register char *stack_pointer __asm__("$30");
-+
-+
-+/* Spinlock implementation; required. */
-+PT_EI long int
-+testandset (int *spinlock)
-+{
-+ long int ret, temp;
-+
-+ __asm__ __volatile__(
-+ "/* Inline spinlock test & set */\n"
-+ "1:\t"
-+ "ldl_l %0,%3\n\t"
-+ "bne %0,2f\n\t"
-+ "or $31,1,%1\n\t"
-+ "stl_c %1,%2\n\t"
-+ "beq %1,1b\n"
-+ "2:\tmb\n"
-+ "/* End spinlock test & set */"
-+ : "=&r"(ret), "=&r"(temp), "=m"(*spinlock)
-+ : "m"(*spinlock)
-+ : "memory");
-+
-+ return ret;
-+}
-+
-+/* Spinlock release; default is just set to zero. */
-+#define RELEASE(spinlock) \
-+ __asm__ __volatile__("mb" : : : "memory"); \
-+ *spinlock = 0
-+
-+
-+/* Begin allocating thread stacks at this address. Default is to allocate
-+ them just below the initial program stack. */
-+#define THREAD_STACK_START_ADDRESS 0x40000000000
-+
-+
-+/* Return the thread descriptor for the current thread. */
-+#define THREAD_SELF \
-+({ \
-+ register pthread_descr __self __asm__("$0"); \
-+ __asm__ ("call_pal %1" : "=r"(__self) : "i"(PAL_rduniq) : "$0"); \
-+ __self; \
-+})
-+
-+/* Initialize the thread-unique value. */
-+#define INIT_THREAD_SELF(descr, nr) \
-+{ \
-+ register pthread_descr __self __asm__("$16") = (descr); \
-+ __asm__ __volatile__ ("call_pal %1" : : "r"(__self), "i"(PAL_wruniq)); \
-+}
-+
-+
-+/* Compare-and-swap for semaphores. */
-+
-+#define HAS_COMPARE_AND_SWAP
-+PT_EI int
-+__compare_and_swap (long int *p, long int oldval, long int newval)
-+{
-+ long int ret;
-+
-+ __asm__ __volatile__ (
-+ "/* Inline compare & swap */\n"
-+ "1:\t"
-+ "ldq_l %0,%4\n\t"
-+ "cmpeq %0,%2,%0\n\t"
-+ "beq %0,2f\n\t"
-+ "mov %3,%0\n\t"
-+ "stq_c %0,%1\n\t"
-+ "beq %0,1b\n\t"
-+ "2:\tmb\n"
-+ "/* End compare & swap */"
-+ : "=&r"(ret), "=m"(*p)
-+ : "r"(oldval), "r"(newval), "m"(*p));
-+
-+ return ret;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/arm/pt-machine.h glibc-2.1.3/linuxthreads/sysdeps/arm/pt-machine.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/arm/pt-machine.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/arm/pt-machine.h 1998-10-09 11:34:00.000000000 -0700
-@@ -0,0 +1,48 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ ARM version.
-+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Philip Blundell <philb@gnu.org>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+
-+/* This will not work on ARM1 or ARM2 because SWP is lacking on those
-+ machines. Unfortunately we have no way to detect this at compile
-+ time; let's hope nobody tries to use one. */
-+
-+/* Spinlock implementation; required. */
-+PT_EI int
-+testandset (int *spinlock)
-+{
-+ register unsigned int ret;
-+
-+ __asm__ __volatile__("swp %0, %1, [%2]"
-+ : "=r"(ret)
-+ : "0"(1), "r"(spinlock));
-+
-+ return ret;
-+}
-+
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#define CURRENT_STACK_FRAME stack_pointer
-+register char * stack_pointer __asm__ ("sp");
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/i386/i686/pt-machine.h glibc-2.1.3/linuxthreads/sysdeps/i386/i686/pt-machine.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/i386/i686/pt-machine.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/i386/i686/pt-machine.h 1999-12-07 08:50:25.000000000 -0800
-@@ -0,0 +1,67 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ i686 version.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Richard Henderson <rth@tamu.edu>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#define CURRENT_STACK_FRAME stack_pointer
-+register char * stack_pointer __asm__ ("%esp");
-+
-+
-+/* Spinlock implementation; required. */
-+PT_EI int
-+testandset (int *spinlock)
-+{
-+ int ret;
-+
-+ __asm__ __volatile__ (
-+ "xchgl %0, %1"
-+ : "=r"(ret), "=m"(*spinlock)
-+ : "0"(1), "m"(*spinlock)
-+ : "memory");
-+
-+ return ret;
-+}
-+
-+
-+/* Compare-and-swap for semaphores. It's always available on i686. */
-+#define HAS_COMPARE_AND_SWAP
-+
-+PT_EI int
-+__compare_and_swap (long int *p, long int oldval, long int newval)
-+{
-+ char ret;
-+ long int readval;
-+
-+ __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
-+ : "=q" (ret), "=m" (*p), "=a" (readval)
-+ : "r" (newval), "m" (*p), "a" (oldval)
-+ : "memory");
-+ return ret;
-+}
-+
-+
-+/* Use the LDT implementation only if the kernel is fixed. */
-+//#include "../useldt.h"
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/i386/pt-machine.h glibc-2.1.3/linuxthreads/sysdeps/i386/pt-machine.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/i386/pt-machine.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/i386/pt-machine.h 1999-12-07 08:50:25.000000000 -0800
-@@ -0,0 +1,99 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ i386 version.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Richard Henderson <rth@tamu.edu>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#define CURRENT_STACK_FRAME stack_pointer
-+register char * stack_pointer __asm__ ("%esp");
-+
-+
-+/* Spinlock implementation; required. */
-+PT_EI int
-+testandset (int *spinlock)
-+{
-+ int ret;
-+
-+ __asm__ __volatile__(
-+ "xchgl %0, %1"
-+ : "=r"(ret), "=m"(*spinlock)
-+ : "0"(1), "m"(*spinlock)
-+ : "memory");
-+
-+ return ret;
-+}
-+
-+
-+/* Compare-and-swap for semaphores.
-+ Available on the 486 and above, but not on the 386.
-+ We test dynamically whether it's available or not. */
-+
-+#define HAS_COMPARE_AND_SWAP
-+#define TEST_FOR_COMPARE_AND_SWAP
-+
-+PT_EI int
-+__compare_and_swap (long int *p, long int oldval, long int newval)
-+{
-+ char ret;
-+ long int readval;
-+
-+ __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
-+ : "=q" (ret), "=m" (*p), "=a" (readval)
-+ : "r" (newval), "m" (*p), "a" (oldval)
-+ : "memory");
-+ return ret;
-+}
-+
-+
-+PT_EI int
-+get_eflags (void)
-+{
-+ int res;
-+ __asm__ __volatile__ ("pushfl; popl %0" : "=r" (res) : );
-+ return res;
-+}
-+
-+
-+PT_EI void
-+set_eflags (int newflags)
-+{
-+ __asm__ __volatile__ ("pushl %0; popfl" : : "r" (newflags) : "cc");
-+}
-+
-+
-+PT_EI int
-+compare_and_swap_is_available (void)
-+{
-+ int oldflags = get_eflags ();
-+ int changed;
-+ /* Flip AC bit in EFLAGS. */
-+ set_eflags (oldflags ^ 0x40000);
-+ /* See if bit changed. */
-+ changed = (get_eflags () ^ oldflags) & 0x40000;
-+ /* Restore EFLAGS. */
-+ set_eflags (oldflags);
-+ /* If the AC flag did not change, it's a 386 and it lacks cmpxchg.
-+ Otherwise, it's a 486 or above and it has cmpxchg. */
-+ return changed != 0;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/i386/useldt.h glibc-2.1.3/linuxthreads/sysdeps/i386/useldt.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/i386/useldt.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/i386/useldt.h 1998-08-31 11:34:00.000000000 -0700
-@@ -0,0 +1,170 @@
-+/* Special definitions for ix86 machine using segment register based
-+ thread descriptor.
-+ Copyright (C) 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stddef.h> /* For offsetof. */
-+
-+
-+/* We don't want to include the kernel header. So duplicate the
-+ information. */
-+
-+/* Structure passed on `modify_ldt' call. */
-+struct modify_ldt_ldt_s
-+{
-+ unsigned int entry_number;
-+ unsigned long int base_addr;
-+ unsigned int limit;
-+ unsigned int seg_32bit:1;
-+ unsigned int contents:2;
-+ unsigned int read_exec_only:1;
-+ unsigned int limit_in_pages:1;
-+ unsigned int seg_not_present:1;
-+ unsigned int useable:1;
-+ unsigned int empty:25;
-+};
-+
-+/* System call to set LDT entry. */
-+extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
-+
-+
-+/* Return the thread descriptor for the current thread.
-+
-+ The contained asm must *not* be marked volatile since otherwise
-+ assignments like
-+ pthread_descr self = thread_self();
-+ do not get optimized away. */
-+#define THREAD_SELF \
-+({ \
-+ register pthread_descr __self; \
-+ __asm__ ("movl %%gs:%c1,%0" : "=r" (__self) \
-+ : "i" (offsetof (struct _pthread_descr_struct, p_self))); \
-+ __self; \
-+})
-+
-+/* Initialize the thread-unique value. */
-+#define INIT_THREAD_SELF(descr, nr) \
-+{ \
-+ struct modify_ldt_ldt_s ldt_entry = \
-+ { nr, (unsigned long int) descr, sizeof (*descr), 1, 0, 0, 0, 0, 1, 0 }; \
-+ if (__modify_ldt (1, &ldt_entry, sizeof (ldt_entry)) != 0) \
-+ abort (); \
-+ __asm__ __volatile__ ("movw %w0, %%gs" : : "r" (nr * 8 + 7)); \
-+}
-+
-+/* Free resources associated with thread descriptor. */
-+#define FREE_THREAD_SELF(descr, nr) \
-+{ \
-+ struct modify_ldt_ldt_s ldt_entry = \
-+ { nr, 0, 0, 0, 0, 1, 0, 1, 0, 0 }; \
-+ __asm__ __volatile__ ("movw %w0,%%gs" : : "r" (0)); \
-+ __modify_ldt (1, &ldt_entry, sizeof (ldt_entry)); \
-+}
-+
-+/* Read member of the thread descriptor directly. */
-+#define THREAD_GETMEM(descr, member) \
-+({ \
-+ __typeof__ (descr->member) __value; \
-+ if (sizeof (__value) == 1) \
-+ __asm__ __volatile__ ("movb %%gs:%P2,%b0" \
-+ : "=r" (__value) \
-+ : "0" (0), \
-+ "i" (offsetof (struct _pthread_descr_struct, \
-+ member))); \
-+ else \
-+ { \
-+ if (sizeof (__value) != 4) \
-+ /* There should not be any value with a size other than 1 or 4. */ \
-+ abort (); \
-+ \
-+ __asm__ __volatile__ ("movl %%gs:%P1,%0" \
-+ : "=r" (__value) \
-+ : "i" (offsetof (struct _pthread_descr_struct, \
-+ member))); \
-+ } \
-+ __value; \
-+})
-+
-+/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
-+#define THREAD_GETMEM_NC(descr, member) \
-+({ \
-+ __typeof__ (descr->member) __value; \
-+ if (sizeof (__value) == 1) \
-+ __asm__ __volatile__ ("movb %%gs:(%2),%b0" \
-+ : "=r" (__value) \
-+ : "0" (0), \
-+ "r" (offsetof (struct _pthread_descr_struct, \
-+ member))); \
-+ else \
-+ { \
-+ if (sizeof (__value) != 4) \
-+ /* There should not be any value with a size other than 1 or 4. */ \
-+ abort (); \
-+ \
-+ __asm__ __volatile__ ("movl %%gs:(%1),%0" \
-+ : "=r" (__value) \
-+ : "r" (offsetof (struct _pthread_descr_struct, \
-+ member))); \
-+ } \
-+ __value; \
-+})
-+
-+/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
-+#define THREAD_SETMEM(descr, member, value) \
-+({ \
-+ __typeof__ (descr->member) __value = (value); \
-+ if (sizeof (__value) == 1) \
-+ __asm__ __volatile__ ("movb %0,%%gs:%P1" : \
-+ : "r" (__value), \
-+ "i" (offsetof (struct _pthread_descr_struct, \
-+ member))); \
-+ else \
-+ { \
-+ if (sizeof (__value) != 4) \
-+ /* There should not be any value with a size other than 1 or 4. */ \
-+ abort (); \
-+ \
-+ __asm__ __volatile__ ("movl %0,%%gs:%P1" : \
-+ : "r" (__value), \
-+ "i" (offsetof (struct _pthread_descr_struct, \
-+ member))); \
-+ } \
-+})
-+
-+/* Set member of the thread descriptor directly. */
-+#define THREAD_SETMEM_NC(descr, member, value) \
-+({ \
-+ __typeof__ (descr->member) __value = (value); \
-+ if (sizeof (__value) == 1) \
-+ __asm__ __volatile__ ("movb %0,%%gs:(%1)" : \
-+ : "r" (__value), \
-+ "r" (offsetof (struct _pthread_descr_struct, \
-+ member))); \
-+ else \
-+ { \
-+ if (sizeof (__value) != 4) \
-+ /* There should not be any value with a size other than 1 or 4. */ \
-+ abort (); \
-+ \
-+ __asm__ __volatile__ ("movl %0,%%gs:(%1)" : \
-+ : "r" (__value), \
-+ "r" (offsetof (struct _pthread_descr_struct, \
-+ member))); \
-+ } \
-+})
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/m68k/pt-machine.h glibc-2.1.3/linuxthreads/sysdeps/m68k/pt-machine.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/m68k/pt-machine.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/m68k/pt-machine.h 1998-10-09 11:34:04.000000000 -0700
-@@ -0,0 +1,62 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ m68k version.
-+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Richard Henderson <rth@tamu.edu>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If
-+ not, write to the Free Software Foundation, Inc.,
-+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+
-+/* Spinlock implementation; required. */
-+PT_EI int
-+testandset (int *spinlock)
-+{
-+ char ret;
-+
-+ __asm__ __volatile__("tas %1; sne %0"
-+ : "=dm"(ret), "=m"(*spinlock)
-+ : "m"(*spinlock)
-+ : "cc");
-+
-+ return ret;
-+}
-+
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#define CURRENT_STACK_FRAME stack_pointer
-+register char * stack_pointer __asm__ ("%sp");
-+
-+
-+/* Compare-and-swap for semaphores. */
-+
-+#define HAS_COMPARE_AND_SWAP
-+PT_EI int
-+__compare_and_swap (long int *p, long int oldval, long int newval)
-+{
-+ char ret;
-+ long int readval;
-+
-+ __asm__ __volatile__ ("casl %2, %3, %1; seq %0"
-+ : "=dm" (ret), "=m" (*p), "=d" (readval)
-+ : "d" (newval), "m" (*p), "2" (oldval));
-+
-+ return ret;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/mips/pt-machine.h glibc-2.1.3/linuxthreads/sysdeps/mips/pt-machine.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/mips/pt-machine.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/mips/pt-machine.h 1998-10-09 11:34:05.000000000 -0700
-@@ -0,0 +1,90 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>.
-+ Based on the Alpha version by Richard Henderson <rth@tamu.edu>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If
-+ not, write to the Free Software Foundation, Inc.,
-+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+ TODO: This version makes use of MIPS ISA 2 features. It won't
-+ work on ISA 1. These machines will have to take the overhead of
-+ a sysmips(MIPS_ATOMIC_SET, ...) syscall which isn't implemented
-+ yet correctly. There is however a better solution for R3000
-+ uniprocessor machines possible. */
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+
-+/* Spinlock implementation; required. */
-+PT_EI long int
-+testandset (int *spinlock)
-+{
-+ long int ret, temp;
-+
-+ __asm__ __volatile__(
-+ "# Inline spinlock test & set\n\t"
-+ ".set\tmips2\n"
-+ "1:\tll\t%0,%3\n\t"
-+ "bnez\t%0,2f\n\t"
-+ ".set\tnoreorder\n\t"
-+ "li\t%1,1\n\t"
-+ ".set\treorder\n\t"
-+ "sc\t%1,%2\n\t"
-+ "beqz\t%1,1b\n"
-+ "2:\t.set\tmips0\n\t"
-+ "/* End spinlock test & set */"
-+ : "=&r"(ret), "=&r" (temp), "=m"(*spinlock)
-+ : "m"(*spinlock)
-+ : "memory");
-+
-+ return ret;
-+}
-+
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#define CURRENT_STACK_FRAME stack_pointer
-+register char * stack_pointer __asm__ ("$29");
-+
-+
-+/* Compare-and-swap for semaphores. */
-+
-+#define HAS_COMPARE_AND_SWAP
-+PT_EI int
-+__compare_and_swap (long int *p, long int oldval, long int newval)
-+{
-+ long ret;
-+
-+ __asm__ __volatile__ (
-+ "/* Inline compare & swap */\n\t"
-+ ".set\tmips2\n"
-+ "1:\tll\t%0,%4\n\t"
-+ ".set\tnoreorder\n\t"
-+ "bne\t%0,%2,2f\n\t"
-+ "move\t%0,%3\n\t"
-+ ".set\treorder\n\t"
-+ "sc\t%0,%1\n\t"
-+ "beqz\t%0,1b\n"
-+ "2:\t.set\tmips0\n\t"
-+ "/* End compare & swap */"
-+ : "=&r"(ret), "=m"(*p)
-+ : "r"(oldval), "r"(newval), "m"(*p));
-+
-+ return ret;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/powerpc/pt-machine.h glibc-2.1.3/linuxthreads/sysdeps/powerpc/pt-machine.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/powerpc/pt-machine.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/powerpc/pt-machine.h 1998-10-09 11:34:06.000000000 -0700
-@@ -0,0 +1,69 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ powerpc version.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If
-+ not, write to the Free Software Foundation, Inc.,
-+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+/* These routines are from Appendix G of the 'PowerPC 601 RISC Microprocessor
-+ User's Manual', by IBM and Motorola. */
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+/* For multiprocessor systems, we want to ensure all memory accesses
-+ are completed before we reset a lock. */
-+#if 0
-+/* on non multiprocessor systems, you can just: */
-+#define sync() /* nothing */
-+#else
-+#define sync() __asm__ __volatile__ ("sync")
-+#endif
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#define CURRENT_STACK_FRAME stack_pointer
-+register char * stack_pointer __asm__ ("r1");
-+
-+/* Compare-and-swap for semaphores. */
-+/* note that test-and-set(x) is the same as compare-and-swap(x, 0, 1) */
-+
-+#define HAS_COMPARE_AND_SWAP
-+#if BROKEN_PPC_ASM_CR0
-+static
-+#else
-+PT_EI
-+#endif
-+int
-+__compare_and_swap (long int *p, long int oldval, long int newval)
-+{
-+ int ret;
-+
-+ sync();
-+ __asm__ __volatile__(
-+ "0: lwarx %0,0,%1 ;"
-+ " xor. %0,%3,%0;"
-+ " bne 1f;"
-+ " stwcx. %2,0,%1;"
-+ " bne- 0b;"
-+ "1: "
-+ : "=&r"(ret)
-+ : "r"(p), "r"(newval), "r"(oldval)
-+ : "cr0", "memory");
-+ sync();
-+ return ret == 0;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/pthread/Makefile glibc-2.1.3/linuxthreads/sysdeps/pthread/Makefile
---- ../glibc-2.1.3/linuxthreads/sysdeps/pthread/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/pthread/Makefile 1998-08-28 03:07:20.000000000 -0700
-@@ -0,0 +1,3 @@
-+ifeq ($(subdir),libio)
-+sysdep_headers += bits/stdio-lock.h
-+endif
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/pthread/Subdirs glibc-2.1.3/linuxthreads/sysdeps/pthread/Subdirs
---- ../glibc-2.1.3/linuxthreads/sysdeps/pthread/Subdirs 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/pthread/Subdirs 1999-11-09 23:02:08.000000000 -0800
-@@ -0,0 +1 @@
-+linuxthreads_db
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/libc-lock.h glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/libc-lock.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/libc-lock.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/libc-lock.h 1999-05-07 07:34:29.000000000 -0700
-@@ -0,0 +1,214 @@
-+/* libc-internal interface for mutex locks. LinuxThreads version.
-+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef _BITS_LIBC_LOCK_H
-+#define _BITS_LIBC_LOCK_H 1
-+
-+#include <pthread.h>
-+
-+/* Mutex type. */
-+#ifdef _LIBC
-+typedef pthread_mutex_t __libc_lock_t;
-+#else
-+typedef struct __libc_lock_opaque__ __libc_lock_t;
-+#endif
-+
-+/* Type for key to thread-specific data. */
-+typedef pthread_key_t __libc_key_t;
-+
-+/* Define a lock variable NAME with storage class CLASS. The lock must be
-+ initialized with __libc_lock_init before it can be used (or define it
-+ with __libc_lock_define_initialized, below). Use `extern' for CLASS to
-+ declare a lock defined in another module. In public structure
-+ definitions you must use a pointer to the lock structure (i.e., NAME
-+ begins with a `*'), because its storage size will not be known outside
-+ of libc. */
-+#define __libc_lock_define(CLASS,NAME) \
-+ CLASS __libc_lock_t NAME;
-+
-+/* Define an initialized lock variable NAME with storage class CLASS.
-+
-+ For the C library we take a deeper look at the initializer. For this
-+ implementation all fields are initialized to zero. Therefore we
-+ don't initialize the variable which allows putting it into the BSS
-+ section. */
-+#define __libc_lock_define_initialized(CLASS,NAME) \
-+ CLASS __libc_lock_t NAME;
-+
-+/* Define an initialized recursive lock variable NAME with storage
-+ class CLASS. */
-+#define __libc_lock_define_initialized_recursive(CLASS,NAME) \
-+ CLASS __libc_lock_t NAME = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-+
-+/* Initialize the named lock variable, leaving it in a consistent, unlocked
-+ state. */
-+#define __libc_lock_init(NAME) \
-+ (__pthread_mutex_init != NULL ? __pthread_mutex_init (&(NAME), NULL) : 0);
-+
-+/* Same as last but this time we initialize a recursive mutex. */
-+#define __libc_lock_init_recursive(NAME) \
-+ do { \
-+ if (__pthread_mutex_init != NULL) \
-+ { \
-+ pthread_mutexattr_t __attr; \
-+ __pthread_mutexattr_init (&__attr); \
-+ __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP); \
-+ __pthread_mutex_init (&(NAME), &__attr); \
-+ __pthread_mutexattr_destroy (&__attr); \
-+ } \
-+ } while (0);
-+
-+/* Finalize the named lock variable, which must be locked. It cannot be
-+ used again until __libc_lock_init is called again on it. This must be
-+ called on a lock variable before the containing storage is reused. */
-+#define __libc_lock_fini(NAME) \
-+ (__pthread_mutex_destroy != NULL ? __pthread_mutex_destroy (&(NAME)) : 0);
-+
-+/* Finalize recursive named lock. */
-+#define __libc_lock_fini_recursive(NAME) __libc_lock_fini (NAME)
-+
-+/* Lock the named lock variable. */
-+#define __libc_lock_lock(NAME) \
-+ (__pthread_mutex_lock != NULL ? __pthread_mutex_lock (&(NAME)) : 0);
-+
-+/* Lock the recursive named lock variable. */
-+#define __libc_lock_lock_recursive(NAME) __libc_lock_lock (NAME)
-+
-+/* Try to lock the named lock variable. */
-+#define __libc_lock_trylock(NAME) \
-+ (__pthread_mutex_trylock != NULL ? __pthread_mutex_trylock (&(NAME)) : 0)
-+
-+/* Try to lock the recursive named lock variable. */
-+#define __libc_lock_trylock_recursive(NAME) __libc_lock_trylock (NAME)
-+
-+/* Unlock the named lock variable. */
-+#define __libc_lock_unlock(NAME) \
-+ (__pthread_mutex_unlock != NULL ? __pthread_mutex_unlock (&(NAME)) : 0);
-+
-+/* Unlock the recursive named lock variable. */
-+#define __libc_lock_unlock_recursive(NAME) __libc_lock_unlock (NAME)
-+
-+
-+/* Define once control variable. */
-+#if PTHREAD_ONCE_INIT == 0
-+/* Special case for static variables where we can avoid the initialization
-+ if it is zero. */
-+# define __libc_once_define(CLASS, NAME) \
-+ CLASS pthread_once_t NAME
-+#else
-+# define __libc_once_define(CLASS, NAME) \
-+ CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT
-+#endif
-+
-+/* Call handler iff the first call. */
-+#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
-+ do { \
-+ if (__pthread_once != NULL) \
-+ __pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION)); \
-+ else if ((ONCE_CONTROL) == 0) { \
-+ INIT_FUNCTION (); \
-+ (ONCE_CONTROL) = 1; \
-+ } \
-+ } while (0)
-+
-+
-+/* Start critical region with cleanup. */
-+#define __libc_cleanup_region_start(FCT, ARG) \
-+ { struct _pthread_cleanup_buffer _buffer; \
-+ int _avail = _pthread_cleanup_push_defer != NULL; \
-+ if (_avail) { \
-+ _pthread_cleanup_push_defer (&_buffer, (FCT), (ARG)); \
-+ }
-+
-+/* End critical region with cleanup. */
-+#define __libc_cleanup_region_end(DOIT) \
-+ if (_avail) { \
-+ _pthread_cleanup_pop_restore (&_buffer, (DOIT)); \
-+ } \
-+ }
-+
-+/* Sometimes we have to exit the block in the middle. */
-+#define __libc_cleanup_end(DOIT) \
-+ if (_avail) { \
-+ _pthread_cleanup_pop_restore (&_buffer, (DOIT)); \
-+ }
-+
-+/* Create thread-specific key. */
-+#define __libc_key_create(KEY, DESTRUCTOR) \
-+ (__pthread_key_create != NULL ? __pthread_key_create (KEY, DESTRUCTOR) : 1)
-+
-+/* Get thread-specific data. */
-+#define __libc_getspecific(KEY) \
-+ (__pthread_getspecific != NULL ? __pthread_getspecific (KEY) : NULL)
-+
-+/* Set thread-specific data. */
-+#define __libc_setspecific(KEY, VALUE) \
-+ (__pthread_setspecific != NULL ? __pthread_setspecific (KEY, VALUE) : 0)
-+
-+
-+/* Register handlers to execute before and after `fork'. */
-+#define __libc_atfork(PREPARE, PARENT, CHILD) \
-+ (__pthread_atfork != NULL ? __pthread_atfork (PREPARE, PARENT, CHILD) : 0)
-+
-+
-+/* Make the pthread functions weak so that we can elide them from
-+ single-threaded processes. */
-+#ifndef __NO_WEAK_PTHREAD_ALIASES
-+# ifdef weak_extern
-+weak_extern (__pthread_mutex_init)
-+weak_extern (__pthread_mutex_destroy)
-+weak_extern (__pthread_mutex_lock)
-+weak_extern (__pthread_mutex_trylock)
-+weak_extern (__pthread_mutex_unlock)
-+weak_extern (__pthread_mutexattr_init)
-+weak_extern (__pthread_mutexattr_destroy)
-+weak_extern (__pthread_mutexattr_settype)
-+weak_extern (__pthread_key_create)
-+weak_extern (__pthread_setspecific)
-+weak_extern (__pthread_getspecific)
-+weak_extern (__pthread_once)
-+weak_extern (__pthread_initialize)
-+weak_extern (__pthread_atfork)
-+weak_extern (_pthread_cleanup_push_defer)
-+weak_extern (_pthread_cleanup_pop_restore)
-+# else
-+# pragma weak __pthread_mutex_init
-+# pragma weak __pthread_mutex_destroy
-+# pragma weak __pthread_mutex_lock
-+# pragma weak __pthread_mutex_trylock
-+# pragma weak __pthread_mutex_unlock
-+# pragma weak __pthread_mutexattr_init
-+# pragma weak __pthread_mutexattr_destroy
-+# pragma weak __pthread_mutexattr_settype
-+# pragma weak __pthread_key_create
-+# pragma weak __pthread_setspecific
-+# pragma weak __pthread_getspecific
-+# pragma weak __pthread_once
-+# pragma weak __pthread_initialize
-+# pragma weak __pthread_atfork
-+# pragma weak _pthread_cleanup_push_defer
-+# pragma weak _pthread_cleanup_pop_restore
-+# endif
-+#endif
-+
-+/* We need portable names for some functions. E.g., when they are
-+ used as argument to __libc_cleanup_region_start. */
-+#define __libc_mutex_unlock __pthread_mutex_unlock
-+
-+#endif /* bits/libc-lock.h */
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/libc-tsd.h glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/libc-tsd.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/libc-tsd.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/libc-tsd.h 1998-11-30 06:18:52.000000000 -0800
-@@ -0,0 +1,43 @@
-+/* libc-internal interface for thread-specific data. LinuxThreads version.
-+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef _BITS_LIBC_TSD_H
-+#define _BITS_LIBC_TSD_H 1
-+
-+
-+/* Fast thread-specific data internal to libc. */
-+enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0,
-+ _LIBC_TSD_KEY_DL_ERROR,
-+ _LIBC_TSD_KEY_N };
-+
-+extern void *(*__libc_internal_tsd_get) __P ((enum __libc_tsd_key_t));
-+extern int (*__libc_internal_tsd_set) __P ((enum __libc_tsd_key_t,
-+ __const void *));
-+
-+#define __libc_tsd_define(CLASS, KEY) CLASS void *__libc_tsd_##KEY##_data;
-+#define __libc_tsd_get(KEY) \
-+ (__libc_internal_tsd_get != NULL \
-+ ? __libc_internal_tsd_get (_LIBC_TSD_KEY_##KEY) \
-+ : __libc_tsd_##KEY##_data)
-+#define __libc_tsd_set(KEY, VALUE) \
-+ (__libc_internal_tsd_set != NULL \
-+ ? __libc_internal_tsd_set (_LIBC_TSD_KEY_##KEY, (VALUE)) \
-+ : ((__libc_tsd_##KEY##_data = (VALUE)), 0))
-+
-+#endif /* bits/libc-tsd.h */
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h 2000-01-20 18:32:38.000000000 -0800
-@@ -0,0 +1,122 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+#if !defined _BITS_TYPES_H && !defined _PTHREAD_H
-+# error "Never include <bits/pthreadtypes.h> directly; use <sys/types.h> instead."
-+#endif
-+
-+#ifndef _BITS_PTHREADTYPES_H
-+#define _BITS_PTHREADTYPES_H 1
-+
-+#define __need_schedparam
-+#include <bits/sched.h>
-+
-+/* Fast locks (not abstract because mutexes and conditions aren't abstract). */
-+struct _pthread_fastlock
-+{
-+ long int __status; /* "Free" or "taken" or head of waiting list */
-+ int __spinlock; /* For compare-and-swap emulation */
-+};
-+
-+#ifndef _PTHREAD_DESCR_DEFINED
-+/* Thread descriptors */
-+typedef struct _pthread_descr_struct *_pthread_descr;
-+# define _PTHREAD_DESCR_DEFINED
-+#endif
-+
-+
-+/* Attributes for threads. */
-+typedef struct
-+{
-+ int __detachstate;
-+ int __schedpolicy;
-+ struct __sched_param __schedparam;
-+ int __inheritsched;
-+ int __scope;
-+ size_t __guardsize;
-+ int __stackaddr_set;
-+ void *__stackaddr;
-+ size_t __stacksize;
-+} pthread_attr_t;
-+
-+
-+/* Conditions (not abstract because of PTHREAD_COND_INITIALIZER */
-+typedef struct
-+{
-+ struct _pthread_fastlock __c_lock; /* Protect against concurrent access */
-+ _pthread_descr __c_waiting; /* Threads waiting on this condition */
-+} pthread_cond_t;
-+
-+
-+/* Attribute for conditionally variables. */
-+typedef struct
-+{
-+ int __dummy;
-+} pthread_condattr_t;
-+
-+/* Keys for thread-specific data */
-+typedef unsigned int pthread_key_t;
-+
-+
-+/* Mutexes (not abstract because of PTHREAD_MUTEX_INITIALIZER). */
-+/* (The layout is unnatural to maintain binary compatibility
-+ with earlier releases of LinuxThreads.) */
-+typedef struct
-+{
-+ int __m_reserved; /* Reserved for future use */
-+ int __m_count; /* Depth of recursive locking */
-+ _pthread_descr __m_owner; /* Owner thread (if recursive or errcheck) */
-+ int __m_kind; /* Mutex kind: fast, recursive or errcheck */
-+ struct _pthread_fastlock __m_lock; /* Underlying fast lock */
-+} pthread_mutex_t;
-+
-+
-+/* Attribute for mutex. */
-+typedef struct
-+{
-+ int __mutexkind;
-+} pthread_mutexattr_t;
-+
-+
-+/* Once-only execution */
-+typedef int pthread_once_t;
-+
-+
-+#ifdef __USE_UNIX98
-+/* Read-write locks. */
-+typedef struct _pthread_rwlock_t
-+{
-+ struct _pthread_fastlock __rw_lock; /* Lock to guarantee mutual exclusion */
-+ int __rw_readers; /* Number of readers */
-+ _pthread_descr __rw_writer; /* Identity of writer, or NULL if none */
-+ _pthread_descr __rw_read_waiting; /* Threads waiting for reading */
-+ _pthread_descr __rw_write_waiting; /* Threads waiting for writing */
-+ int __rw_kind; /* Reader/Writer preference selection */
-+ int __rw_pshared; /* Shared between processes or not */
-+} pthread_rwlock_t;
-+
-+
-+/* Attribute for read-write locks. */
-+typedef struct
-+{
-+ int __lockkind;
-+ int __pshared;
-+} pthread_rwlockattr_t;
-+#endif
-+
-+
-+/* Thread identifiers */
-+typedef unsigned long int pthread_t;
-+
-+#endif /* bits/pthreadtypes.h */
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/stdio-lock.h glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/stdio-lock.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/stdio-lock.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/pthread/bits/stdio-lock.h 1999-01-04 07:42:03.000000000 -0800
-@@ -0,0 +1,39 @@
-+/* Thread package specific definitions of stream lock type.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <pthread.h>
-+
-+typedef pthread_mutex_t _IO_lock_t;
-+
-+/* We need recursive (counting) mutexes. */
-+#define _IO_lock_initializer PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
-+
-+
-+#define _IO_cleanup_region_start(_fct, _fp) \
-+ __libc_cleanup_region_start (_fct, _fp)
-+#define _IO_cleanup_region_end(_doit) \
-+ __libc_cleanup_region_end (_doit)
-+#define _IO_lock_init(_name) \
-+ __libc_lock_init_recursive (_name)
-+#define _IO_lock_fini(_name) \
-+ __libc_lock_fini_recursive (_name)
-+#define _IO_lock_lock(_name) \
-+ __libc_lock_lock (_name)
-+#define _IO_lock_unlock(_name) \
-+ __libc_lock_unlock (_name)
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/pthread/pthread.h glibc-2.1.3/linuxthreads/sysdeps/pthread/pthread.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/pthread/pthread.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/pthread/pthread.h 2000-01-20 18:32:38.000000000 -0800
-@@ -0,0 +1,552 @@
-+/* Linuxthreads - a simple clone()-based implementation of Posix */
-+/* threads for Linux. */
-+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
-+/* */
-+/* This program is free software; you can redistribute it and/or */
-+/* modify it under the terms of the GNU Library General Public License */
-+/* as published by the Free Software Foundation; either version 2 */
-+/* of the License, or (at your option) any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, */
-+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-+/* GNU Library General Public License for more details. */
-+
-+#ifndef _PTHREAD_H
-+#define _PTHREAD_H 1
-+
-+#include <features.h>
-+
-+#include <sched.h>
-+#include <time.h>
-+
-+#define __need_sigset_t
-+#include <signal.h>
-+#include <bits/pthreadtypes.h>
-+
-+
-+__BEGIN_DECLS
-+
-+/* Initializers. */
-+
-+#define PTHREAD_MUTEX_INITIALIZER \
-+ {0, 0, 0, PTHREAD_MUTEX_FAST_NP, {0, 0}}
-+#ifdef __USE_GNU
-+# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
-+ {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}}
-+#endif
-+
-+#define PTHREAD_COND_INITIALIZER {{0, 0}, 0}
-+
-+#ifdef __USE_UNIX98
-+# define PTHREAD_RWLOCK_INITIALIZER \
-+ { {0, 0}, 0, NULL, NULL, NULL, \
-+ PTHREAD_RWLOCK_DEFAULT_NP, PTHREAD_PROCESS_PRIVATE }
-+#endif
-+
-+/* Values for attributes. */
-+
-+enum
-+{
-+ PTHREAD_CREATE_JOINABLE,
-+#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
-+ PTHREAD_CREATE_DETACHED
-+#define PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
-+};
-+
-+enum
-+{
-+ PTHREAD_INHERIT_SCHED,
-+#define PTHREAD_INHERIT_SCHED PTHREAD_INHERIT_SCHED
-+ PTHREAD_EXPLICIT_SCHED
-+#define PTHREAD_EXPLICIT_SCHED PTHREAD_EXPLICIT_SCHED
-+};
-+
-+enum
-+{
-+ PTHREAD_SCOPE_SYSTEM,
-+#define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM
-+ PTHREAD_SCOPE_PROCESS
-+#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS
-+};
-+
-+enum
-+{
-+ PTHREAD_MUTEX_FAST_NP,
-+ PTHREAD_MUTEX_RECURSIVE_NP,
-+ PTHREAD_MUTEX_ERRORCHECK_NP
-+#ifdef __USE_UNIX98
-+ ,
-+ PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
-+ PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
-+ PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
-+ PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
-+#endif
-+};
-+
-+enum
-+{
-+ PTHREAD_PROCESS_PRIVATE,
-+#define PTHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
-+ PTHREAD_PROCESS_SHARED
-+#define PTHREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
-+};
-+
-+#ifdef __USE_UNIX98
-+enum
-+{
-+ PTHREAD_RWLOCK_PREFER_READER_NP,
-+ PTHREAD_RWLOCK_PREFER_WRITER_NP,
-+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
-+ PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_WRITER_NP
-+};
-+#endif /* Unix98 */
-+
-+#define PTHREAD_ONCE_INIT 0
-+
-+/* Cleanup buffers */
-+
-+struct _pthread_cleanup_buffer
-+{
-+ void (*__routine) __PMT ((void *)); /* Function to call. */
-+ void *__arg; /* Its argument. */
-+ int __canceltype; /* Saved cancellation type. */
-+ struct _pthread_cleanup_buffer *__prev; /* Chaining of cleanup functions. */
-+};
-+
-+/* Cancellation */
-+
-+enum
-+{
-+ PTHREAD_CANCEL_ENABLE,
-+#define PTHREAD_CANCEL_ENABLE PTHREAD_CANCEL_ENABLE
-+ PTHREAD_CANCEL_DISABLE
-+#define PTHREAD_CANCEL_DISABLE PTHREAD_CANCEL_DISABLE
-+};
-+enum
-+{
-+ PTHREAD_CANCEL_DEFERRED,
-+#define PTHREAD_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED
-+ PTHREAD_CANCEL_ASYNCHRONOUS
-+#define PTHREAD_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_ASYNCHRONOUS
-+};
-+#define PTHREAD_CANCELED ((void *) -1)
-+
-+
-+/* Function for handling threads. */
-+
-+/* Create a thread with given attributes ATTR (or default attributes
-+ if ATTR is NULL), and call function START_ROUTINE with given
-+ arguments ARG. */
-+extern int pthread_create __P ((pthread_t *__thread,
-+ __const pthread_attr_t *__attr,
-+ void *(*__start_routine) (void *),
-+ void *__arg));
-+
-+/* Obtain the identifier of the current thread. */
-+extern pthread_t pthread_self __P ((void));
-+
-+/* Compare two thread identifiers. */
-+extern int pthread_equal __P ((pthread_t __thread1, pthread_t __thread2));
-+
-+/* Terminate calling thread. */
-+extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));
-+
-+/* Make calling thread wait for termination of the thread TH. The
-+ exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN
-+ is not NULL. */
-+extern int pthread_join __P ((pthread_t __th, void **__thread_return));
-+
-+/* Indicate that the thread TH is never to be joined with PTHREAD_JOIN.
-+ The resources of TH will therefore be freed immediately when it
-+ terminates, instead of waiting for another thread to perform PTHREAD_JOIN
-+ on it. */
-+extern int pthread_detach __P ((pthread_t __th));
-+
-+
-+/* Functions for handling attributes. */
-+
-+/* Initialize thread attribute *ATTR with default attributes
-+ (detachstate is PTHREAD_JOINABLE, scheduling policy is SCHED_OTHER,
-+ no user-provided stack). */
-+extern int pthread_attr_init __P ((pthread_attr_t *__attr));
-+
-+/* Destroy thread attribute *ATTR. */
-+extern int pthread_attr_destroy __P ((pthread_attr_t *__attr));
-+
-+/* Set the `detachstate' attribute in *ATTR according to DETACHSTATE. */
-+extern int pthread_attr_setdetachstate __P ((pthread_attr_t *__attr,
-+ int __detachstate));
-+
-+/* Return in *DETACHSTATE the `detachstate' attribute in *ATTR. */
-+extern int pthread_attr_getdetachstate __P ((__const pthread_attr_t *__attr,
-+ int *__detachstate));
-+
-+/* Set scheduling parameters (priority, etc) in *ATTR according to PARAM. */
-+extern int pthread_attr_setschedparam __P ((pthread_attr_t *__attr,
-+ __const struct sched_param *__param));
-+
-+/* Return in *PARAM the scheduling parameters of *ATTR. */
-+extern int pthread_attr_getschedparam __P ((__const pthread_attr_t *__attr,
-+ struct sched_param *__param));
-+
-+/* Set scheduling policy in *ATTR according to POLICY. */
-+extern int pthread_attr_setschedpolicy __P ((pthread_attr_t *__attr,
-+ int __policy));
-+
-+/* Return in *POLICY the scheduling policy of *ATTR. */
-+extern int pthread_attr_getschedpolicy __P ((__const pthread_attr_t *__attr,
-+ int *__policy));
-+
-+/* Set scheduling inheritance mode in *ATTR according to INHERIT. */
-+extern int pthread_attr_setinheritsched __P ((pthread_attr_t *__attr,
-+ int __inherit));
-+
-+/* Return in *INHERIT the scheduling inheritance mode of *ATTR. */
-+extern int pthread_attr_getinheritsched __P ((__const pthread_attr_t *__attr,
-+ int *__inherit));
-+
-+/* Set scheduling contention scope in *ATTR according to SCOPE. */
-+extern int pthread_attr_setscope __P ((pthread_attr_t *__attr, int __scope));
-+
-+/* Return in *SCOPE the scheduling contention scope of *ATTR. */
-+extern int pthread_attr_getscope __P ((__const pthread_attr_t *__attr,
-+ int *__scope));
-+
-+#ifdef __USE_UNIX98
-+/* Set the size of the guard area at the bottom of the thread. */
-+extern int pthread_attr_setguardsize __P ((pthread_attr_t *__attr,
-+ size_t __guardsize));
-+
-+/* Get the size of the guard area at the bottom of the thread. */
-+extern int pthread_attr_getguardsize __P ((__const pthread_attr_t *__attr,
-+ size_t *__guardsize));
-+#endif
-+
-+/* Set the starting address of the stack of the thread to be created.
-+ Depending on whether the stack grows up or doen the value must either
-+ be higher or lower than all the address in the memory block. The
-+ minimal size of the block must be PTHREAD_STACK_SIZE. */
-+extern int pthread_attr_setstackaddr __P ((pthread_attr_t *__attr,
-+ void *__stackaddr));
-+
-+/* Return the previously set address for the stack. */
-+extern int pthread_attr_getstackaddr __P ((__const pthread_attr_t *__attr,
-+ void **__stackaddr));
-+
-+/* Add information about the minimum stack size needed for the thread
-+ to be started. This size must never be less than PTHREAD_STACK_SIZE
-+ and must also not exceed the system limits. */
-+extern int pthread_attr_setstacksize __P ((pthread_attr_t *__attr,
-+ size_t __stacksize));
-+
-+/* Return the currently used minimal stack size. */
-+extern int pthread_attr_getstacksize __P ((__const pthread_attr_t *__attr,
-+ size_t *__stacksize));
-+
-+/* Functions for scheduling control. */
-+
-+/* Set the scheduling parameters for TARGET_THREAD according to POLICY
-+ and *PARAM. */
-+extern int pthread_setschedparam __P ((pthread_t __target_thread, int __policy,
-+ __const struct sched_param *__param));
-+
-+/* Return in *POLICY and *PARAM the scheduling parameters for TARGET_THREAD. */
-+extern int pthread_getschedparam __P ((pthread_t __target_thread,
-+ int *__policy,
-+ struct sched_param *__param));
-+
-+#ifdef __USE_UNIX98
-+/* Determine level of concurrency. */
-+extern int pthread_getconcurrency __P ((void));
-+
-+/* Set new concurrency level to LEVEL. */
-+extern int pthread_setconcurrency __P ((int __level));
-+#endif
-+
-+/* Functions for mutex handling. */
-+
-+/* Initialize MUTEX using attributes in *MUTEX_ATTR, or use the
-+ default values if later is NULL. */
-+extern int __pthread_mutex_init __P ((pthread_mutex_t *__mutex,
-+ __const pthread_mutexattr_t *__mutex_attr));
-+extern int pthread_mutex_init __P ((pthread_mutex_t *__mutex,
-+ __const pthread_mutexattr_t *__mutex_attr));
-+
-+/* Destroy MUTEX. */
-+extern int __pthread_mutex_destroy __P ((pthread_mutex_t *__mutex));
-+extern int pthread_mutex_destroy __P ((pthread_mutex_t *__mutex));
-+
-+/* Try to lock MUTEX. */
-+extern int __pthread_mutex_trylock __P ((pthread_mutex_t *__mutex));
-+extern int pthread_mutex_trylock __P ((pthread_mutex_t *__mutex));
-+
-+/* Wait until lock for MUTEX becomes available and lock it. */
-+extern int __pthread_mutex_lock __P ((pthread_mutex_t *__mutex));
-+extern int pthread_mutex_lock __P ((pthread_mutex_t *__mutex));
-+
-+/* Unlock MUTEX. */
-+extern int __pthread_mutex_unlock __P ((pthread_mutex_t *__mutex));
-+extern int pthread_mutex_unlock __P ((pthread_mutex_t *__mutex));
-+
-+
-+/* Functions for handling mutex attributes. */
-+
-+/* Initialize mutex attribute object ATTR with default attributes
-+ (kind is PTHREAD_MUTEX_FAST_NP). */
-+extern int __pthread_mutexattr_init __P ((pthread_mutexattr_t *__attr));
-+extern int pthread_mutexattr_init __P ((pthread_mutexattr_t *__attr));
-+
-+/* Destroy mutex attribute object ATTR. */
-+extern int __pthread_mutexattr_destroy __P ((pthread_mutexattr_t *__attr));
-+extern int pthread_mutexattr_destroy __P ((pthread_mutexattr_t *__attr));
-+
-+#ifdef __USE_UNIX98
-+/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
-+ PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
-+ PTHREAD_MUTEX_DEFAULT). */
-+extern int __pthread_mutexattr_settype __P ((pthread_mutexattr_t *__attr,
-+ int __kind));
-+extern int pthread_mutexattr_settype __P ((pthread_mutexattr_t *__attr,
-+ int __kind));
-+
-+/* Return in *KIND the mutex kind attribute in *ATTR. */
-+extern int pthread_mutexattr_gettype __P ((__const pthread_mutexattr_t *__attr,
-+ int *__kind));
-+#endif
-+
-+
-+/* Functions for handling conditional variables. */
-+
-+/* Initialize condition variable COND using attributes ATTR, or use
-+ the default values if later is NULL. */
-+extern int pthread_cond_init __P ((pthread_cond_t *__cond,
-+ __const pthread_condattr_t *__cond_attr));
-+
-+/* Destroy condition variable COND. */
-+extern int pthread_cond_destroy __P ((pthread_cond_t *__cond));
-+
-+/* Wake up one thread waiting for condition variable COND. */
-+extern int pthread_cond_signal __P ((pthread_cond_t *__cond));
-+
-+/* Wake up all threads waiting for condition variables COND. */
-+extern int pthread_cond_broadcast __P ((pthread_cond_t *__cond));
-+
-+/* Wait for condition variable COND to be signaled or broadcast.
-+ MUTEX is assumed to be locked before. */
-+extern int pthread_cond_wait __P ((pthread_cond_t *__cond,
-+ pthread_mutex_t *__mutex));
-+
-+/* Wait for condition variable COND to be signaled or broadcast until
-+ ABSTIME. MUTEX is assumed to be locked before. ABSTIME is an
-+ absolute time specification; zero is the beginning of the epoch
-+ (00:00:00 GMT, January 1, 1970). */
-+extern int pthread_cond_timedwait __P ((pthread_cond_t *__cond,
-+ pthread_mutex_t *__mutex,
-+ __const struct timespec *__abstime));
-+
-+/* Functions for handling condition variable attributes. */
-+
-+/* Initialize condition variable attribute ATTR. */
-+extern int pthread_condattr_init __P ((pthread_condattr_t *__attr));
-+
-+/* Destroy condition variable attribute ATTR. */
-+extern int pthread_condattr_destroy __P ((pthread_condattr_t *__attr));
-+
-+
-+#ifdef __USE_UNIX98
-+/* Functions for handling read-write locks. */
-+
-+/* Initialize read-write lock RWLOCK using attributes ATTR, or use
-+ the default values if later is NULL. */
-+extern int pthread_rwlock_init __P ((pthread_rwlock_t *__rwlock,
-+ __const pthread_rwlockattr_t *__attr));
-+
-+/* Destroy read-write lock RWLOCK. */
-+extern int pthread_rwlock_destroy __P ((pthread_rwlock_t *__rwlock));
-+
-+/* Acquire read lock for RWLOCK. */
-+extern int pthread_rwlock_rdlock __P ((pthread_rwlock_t *__rwlock));
-+
-+/* Try to acquire read lock for RWLOCK. */
-+extern int pthread_rwlock_tryrdlock __P ((pthread_rwlock_t *__rwlock));
-+
-+/* Acquire write lock for RWLOCK. */
-+extern int pthread_rwlock_wrlock __P ((pthread_rwlock_t *__rwlock));
-+
-+/* Try to acquire writelock for RWLOCK. */
-+extern int pthread_rwlock_trywrlock __P ((pthread_rwlock_t *__rwlock));
-+
-+/* Unlock RWLOCK. */
-+extern int pthread_rwlock_unlock __P ((pthread_rwlock_t *__rwlock));
-+
-+
-+/* Functions for handling read-write lock attributes. */
-+
-+/* Initialize attribute object ATTR with default values. */
-+extern int pthread_rwlockattr_init __P ((pthread_rwlockattr_t *__attr));
-+
-+/* Destroy attribute object ATTR. */
-+extern int pthread_rwlockattr_destroy __P ((pthread_rwlockattr_t *__attr));
-+
-+/* Return current setting of process-shared attribute of ATTR in PSHARED. */
-+extern int pthread_rwlockattr_getpshared __P ((__const
-+ pthread_rwlockattr_t *__attr,
-+ int *__pshared));
-+
-+/* Set process-shared attribute of ATTR to PSHARED. */
-+extern int pthread_rwlockattr_setpshared __P ((pthread_rwlockattr_t *__attr,
-+ int __pshared));
-+
-+/* Return current setting of reader/writer preference. */
-+extern int pthread_rwlockattr_getkind_np __P ((__const
-+ pthread_rwlockattr_t *__attr,
-+ int *__pref));
-+
-+/* Set reader/write preference. */
-+extern int pthread_rwlockattr_setkind_np __P ((pthread_rwlockattr_t *__attr,
-+ int __pref));
-+#endif
-+
-+
-+/* Functions for handling thread-specific data */
-+
-+/* Create a key value identifying a location in the thread-specific data
-+ area. Each thread maintains a distinct thread-specific data area.
-+ DESTR_FUNCTION, if non-NULL, is called with
-+ the value associated to that key when the key is destroyed.
-+ DESTR_FUNCTION is not called if the value associated is NULL
-+ when the key is destroyed. */
-+extern int __pthread_key_create __P ((pthread_key_t *__key,
-+ void (*__destr_function) (void *)));
-+extern int pthread_key_create __P ((pthread_key_t *__key,
-+ void (*__destr_function) (void *)));
-+
-+/* Destroy KEY. */
-+extern int pthread_key_delete __P ((pthread_key_t __key));
-+
-+/* Store POINTER in the thread-specific data slot identified by KEY. */
-+extern int __pthread_setspecific __P ((pthread_key_t __key,
-+ __const void *__pointer));
-+extern int pthread_setspecific __P ((pthread_key_t __key,
-+ __const void *__pointer));
-+
-+/* Return current value of the thread-specific data slot identified by KEY. */
-+extern void *__pthread_getspecific __P ((pthread_key_t __key));
-+extern void *pthread_getspecific __P ((pthread_key_t __key));
-+
-+
-+/* Functions for handling initialization */
-+
-+/* Guarantee that the initialization function INIT_ROUTINE will be called
-+ only once, even if pthread_once is executed several times with the
-+ same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or
-+ extern variable initialized to PTHREAD_ONCE_INIT. */
-+extern int __pthread_once __P ((pthread_once_t *__once_control,
-+ void (*__init_routine) (void)));
-+extern int pthread_once __P ((pthread_once_t *__once_control,
-+ void (*__init_routine) (void)));
-+
-+
-+/* Functions for handling cancellation. */
-+
-+/* Set cancelability state of current thread to STATE, returning old
-+ state in *OLDSTATE if OLDSTATE is not NULL. */
-+extern int pthread_setcancelstate __P ((int __state, int *__oldstate));
-+
-+/* Set cancellation state of current thread to TYPE, returning the old
-+ type in *OLDTYPE if OLDTYPE is not NULL. */
-+extern int pthread_setcanceltype __P ((int __type, int *__oldtype));
-+
-+/* Cancel THREAD immediately or at the next possibility. */
-+extern int pthread_cancel __P ((pthread_t __thread));
-+
-+/* Test for pending cancellation for the current thread and terminate
-+ the thread as per pthread_exit(PTHREAD_CANCELED) if it has been
-+ cancelled. */
-+extern void pthread_testcancel __P ((void));
-+
-+
-+/* Install a cleanup handler: ROUTINE will be called with arguments ARG
-+ when the thread is cancelled or calls pthread_exit. ROUTINE will also
-+ be called with arguments ARG when the matching pthread_cleanup_pop
-+ is executed with non-zero EXECUTE argument.
-+ pthread_cleanup_push and pthread_cleanup_pop are macros and must always
-+ be used in matching pairs at the same nesting level of braces. */
-+
-+#define pthread_cleanup_push(routine,arg) \
-+ { struct _pthread_cleanup_buffer _buffer; \
-+ _pthread_cleanup_push (&_buffer, (routine), (arg));
-+
-+extern void _pthread_cleanup_push __P ((struct _pthread_cleanup_buffer *__buffer,
-+ void (*__routine) (void *),
-+ void *__arg));
-+
-+/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
-+ If EXECUTE is non-zero, the handler function is called. */
-+
-+#define pthread_cleanup_pop(execute) \
-+ _pthread_cleanup_pop (&_buffer, (execute)); }
-+
-+extern void _pthread_cleanup_pop __P ((struct _pthread_cleanup_buffer *__buffer,
-+ int __execute));
-+
-+/* Install a cleanup handler as pthread_cleanup_push does, but also
-+ saves the current cancellation type and set it to deferred cancellation. */
-+
-+#ifdef __USE_GNU
-+# define pthread_cleanup_push_defer_np(routine,arg) \
-+ { struct _pthread_cleanup_buffer _buffer; \
-+ _pthread_cleanup_push_defer (&_buffer, (routine), (arg));
-+
-+extern void _pthread_cleanup_push_defer __P ((struct _pthread_cleanup_buffer *__buffer,
-+ void (*__routine) (void *),
-+ void *__arg));
-+
-+/* Remove a cleanup handler as pthread_cleanup_pop does, but also
-+ restores the cancellation type that was in effect when the matching
-+ pthread_cleanup_push_defer was called. */
-+
-+# define pthread_cleanup_pop_restore_np(execute) \
-+ _pthread_cleanup_pop_restore (&_buffer, (execute)); }
-+
-+extern void _pthread_cleanup_pop_restore __P ((struct _pthread_cleanup_buffer *__buffer,
-+ int __execute));
-+#endif
-+
-+/* Functions for handling signals. */
-+#include <bits/sigthread.h>
-+
-+
-+/* Functions for handling process creation and process execution. */
-+
-+/* Install handlers to be called when a new process is created with FORK.
-+ The PREPARE handler is called in the parent process just before performing
-+ FORK. The PARENT handler is called in the parent process just after FORK.
-+ The CHILD handler is called in the child process. Each of the three
-+ handlers can be NULL, meaning that no handler needs to be called at that
-+ point.
-+ PTHREAD_ATFORK can be called several times, in which case the PREPARE
-+ handlers are called in LIFO order (last added with PTHREAD_ATFORK,
-+ first called before FORK), and the PARENT and CHILD handlers are called
-+ in FIFO (first added, first called). */
-+
-+extern int __pthread_atfork __P ((void (*__prepare) (void),
-+ void (*__parent) (void),
-+ void (*__child) (void)));
-+extern int pthread_atfork __P ((void (*__prepare) (void),
-+ void (*__parent) (void),
-+ void (*__child) (void)));
-+
-+/* Terminate all threads in the program except the calling process.
-+ Should be called just before invoking one of the exec*() functions. */
-+
-+extern void pthread_kill_other_threads_np __P ((void));
-+
-+
-+/* This function is called to initialize the pthread library. */
-+extern void __pthread_initialize __P ((void));
-+
-+__END_DECLS
-+
-+#endif /* pthread.h */
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/pthread/semaphore.h glibc-2.1.3/linuxthreads/sysdeps/pthread/semaphore.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/pthread/semaphore.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/pthread/semaphore.h 1998-09-10 21:32:08.000000000 -0700
-@@ -0,0 +1 @@
-+#include <linuxthreads/semaphore.h>
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h glibc-2.1.3/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h 1998-10-09 11:34:08.000000000 -0700
-@@ -0,0 +1,66 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ sparc version.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Richard Henderson <rth@tamu.edu>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+/* Spinlock implementation; required. */
-+PT_EI int
-+testandset (int *spinlock)
-+{
-+ int ret;
-+
-+ __asm__ __volatile__("ldstub %1,%0"
-+ : "=r"(ret), "=m"(*spinlock)
-+ : "m"(*spinlock));
-+
-+ return ret;
-+}
-+
-+
-+/* Spinlock release; default is just set to zero. */
-+#define RELEASE(spinlock) \
-+ __asm__ __volatile__("stbar; stb %1,%0" : "=m"(*(spinlock)) : "r"(0));
-+
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#define CURRENT_STACK_FRAME stack_pointer
-+register char * stack_pointer __asm__("%sp");
-+
-+
-+/* Registers %g6 and %g7 are reserved by the ABI for "system use". It
-+ happens that Solaris uses %g6 for the thread pointer -- we do the same. */
-+struct _pthread_descr_struct;
-+register struct _pthread_descr_struct *__thread_self __asm__("%g6");
-+
-+/* Return the thread descriptor for the current thread. */
-+#define THREAD_SELF __thread_self
-+
-+/* Initialize the thread-unique value. */
-+#define INIT_THREAD_SELF(descr, nr) (__thread_self = (descr))
-+
-+/* Access to data in the thread descriptor is easy. */
-+#define THREAD_GETMEM(descr, member) __thread_self->member
-+#define THREAD_GETMEM_NC(descr, member) __thread_self->member
-+#define THREAD_SETMEM(descr, member, value) __thread_self->member = (value)
-+#define THREAD_SETMEM_NC(descr, member, value) __thread_self->member = (value)
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h glibc-2.1.3/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h 1999-06-16 15:34:10.000000000 -0700
-@@ -0,0 +1,77 @@
-+/* Machine-dependent pthreads configuration and inline functions.
-+ Sparc v9 version.
-+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Richard Henderson <rth@tamu.edu>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If
-+ not, write to the Free Software Foundation, Inc.,
-+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+#ifndef PT_EI
-+# define PT_EI extern inline
-+#endif
-+
-+
-+/* Spinlock implementation; required. */
-+PT_EI int
-+testandset (int *spinlock)
-+{
-+ int ret;
-+
-+ __asm__ __volatile__("ldstub %1,%0"
-+ : "=r"(ret), "=m"(*spinlock) : "m"(*spinlock));
-+
-+ return ret;
-+}
-+
-+
-+/* Get some notion of the current stack. Need not be exactly the top
-+ of the stack, just something somewhere in the current frame. */
-+#define CURRENT_STACK_FRAME stack_pointer
-+register char *stack_pointer __asm__ ("%sp");
-+
-+
-+/* Registers %g6 and %g7 are reserved by the ABI for "system use". It
-+ happens that Solaris uses %g6 for the thread pointer -- we do the same. */
-+struct _pthread_descr_struct;
-+register struct _pthread_descr_struct *__thread_self __asm__("%g6");
-+
-+/* Return the thread descriptor for the current thread. */
-+#define THREAD_SELF __thread_self
-+
-+/* Initialize the thread-unique value. */
-+#define INIT_THREAD_SELF(descr, nr) (__thread_self = (descr))
-+
-+
-+/* Compare-and-swap for semaphores. */
-+
-+#define HAS_COMPARE_AND_SWAP
-+PT_EI int
-+__compare_and_swap (long int *p, long int oldval, long int newval)
-+{
-+ long int readval;
-+
-+ __asm__ __volatile__ ("casx [%4], %2, %0"
-+ : "=r"(readval), "=m"(*p)
-+ : "r"(oldval), "m"(*p), "r"(p), "0"(newval));
-+
-+ return readval == oldval;
-+}
-+
-+/* Access to data in the thread descriptor is easy. */
-+#define THREAD_GETMEM(descr, member) __thread_self->member
-+#define THREAD_GETMEM_NC(descr, member) __thread_self->member
-+#define THREAD_SETMEM(descr, member, value) __thread_self->member = (value)
-+#define THREAD_SETMEM_NC(descr, member, value) __thread_self->member = (value)
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/Implies glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/Implies
---- ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/Implies 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/Implies 1998-08-28 03:07:20.000000000 -0700
-@@ -0,0 +1 @@
-+pthread
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h 1998-11-13 10:10:46.000000000 -0800
-@@ -0,0 +1,55 @@
-+/* Minimum guaranteed maximum values for system limits. Linux version.
-+ Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+/* The kernel header pollutes the namespace with the NR_OPEN symbol.
-+ Remove this after including the header if necessary. */
-+#ifndef NR_OPEN
-+# define __undef_NR_OPEN
-+#endif
-+
-+/* The kernel sources contain a file with all the needed information. */
-+#include <linux/limits.h>
-+
-+/* Have to remove NR_OPEN? */
-+#ifdef __undef_NR_OPEN
-+# undef NR_OPEN
-+# undef __undef_NR_OPEN
-+#endif
-+
-+/* The number of data keys per process. */
-+#define _POSIX_THREAD_KEYS_MAX 128
-+/* This is the value this implementation supports. */
-+#define PTHREAD_KEYS_MAX 1024
-+
-+/* Controlling the iterations of destructors for thread-specific data. */
-+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
-+/* Number of iterations this implementation does. */
-+#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
-+
-+/* The number of threads per process. */
-+#define _POSIX_THREAD_THREADS_MAX 64
-+/* This is the value this implementation supports. */
-+#define PTHREAD_THREADS_MAX 1024
-+
-+/* Maximum amount by which a process can descrease its asynchronous I/O
-+ priority level. */
-+#define AIO_PRIO_DELTA_MAX 20
-+
-+/* Minimum size for a thread. We are free to choose a reasonable value. */
-+#define PTHREAD_STACK_MIN 16384
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h 1999-01-18 13:32:42.000000000 -0800
-@@ -0,0 +1,110 @@
-+/* Define POSIX options for Linux.
-+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef _POSIX_OPT_H
-+#define _POSIX_OPT_H 1
-+
-+/* Job control is supported. */
-+#define _POSIX_JOB_CONTROL 1
-+
-+/* Processes have a saved set-user-ID and a saved set-group-ID. */
-+#define _POSIX_SAVED_IDS 1
-+
-+/* Priority scheduling is supported. */
-+#define _POSIX_PRIORITY_SCHEDULING 1
-+
-+/* Synchronizing file data is supported. */
-+#define _POSIX_SYNCHRONIZED_IO 1
-+
-+/* The fsync function is present. */
-+#define _POSIX_FSYNC 1
-+
-+/* Mapping of files to memory is supported. */
-+#define _POSIX_MAPPED_FILES 1
-+
-+/* Locking of all memory is supported. */
-+#define _POSIX_MEMLOCK 1
-+
-+/* Locking of ranges of memory is supported. */
-+#define _POSIX_MEMLOCK_RANGE 1
-+
-+/* Setting of memory protections is supported. */
-+#define _POSIX_MEMORY_PROTECTION 1
-+
-+/* Implementation supports `poll' function. */
-+#define _POSIX_POLL 1
-+
-+/* Implementation supports `select' and `pselect' functions. */
-+#define _POSIX_SELECT 1
-+
-+/* Only root can change owner of file. */
-+#define _POSIX_CHOWN_RESTRICTED 1
-+
-+/* `c_cc' member of 'struct termios' structure can be disabled by
-+ using the value _POSIX_VDISABLE. */
-+#define _POSIX_VDISABLE '\0'
-+
-+/* Filenames are not silently truncated. */
-+#define _POSIX_NO_TRUNC 1
-+
-+/* X/Open realtime support is available. */
-+#define _XOPEN_REALTIME 1
-+
-+/* X/Open realtime thread support is available. */
-+#define _XOPEN_REALTIME_THREADS 1
-+
-+/* XPG4.2 shared memory is supported. */
-+#define _XOPEN_SHM 1
-+
-+/* Tell we have POSIX threads. */
-+#define _POSIX_THREADS 1
-+
-+/* We have the reentrant functions described in POSIX. */
-+#define _POSIX_REENTRANT_FUNCTIONS 1
-+#define _POSIX_THREAD_SAFE_FUNCTIONS 1
-+
-+/* We provide priority scheduling for threads. */
-+#define _POSIX_THREAD_PRIORITY_SCHEDULING 1
-+
-+/* We support user-defined stack sizes. */
-+#define _POSIX_THREAD_ATTR_STACKSIZE 1
-+
-+/* We support user-defined stacks. */
-+#define _POSIX_THREAD_ATTR_STACKADDR 1
-+
-+/* We support POSIX.1b semaphores, but only the non-shared form for now. */
-+/*#define _POSIX_SEMAPHORES 1 XXX We are not quite there now. */
-+
-+/* Real-time signals are supported. */
-+#define _POSIX_REALTIME_SIGNALS 1
-+
-+/* We support asynchronous I/O. */
-+#define _POSIX_ASYNCHRONOUS_IO 1
-+/* Alternative name for Unix98. */
-+#define _LFS_ASYNCHRONOUS_IO 1
-+
-+/* The LFS support in asynchronous I/O is also available. */
-+#define _LFS64_ASYNCHRONOUS_IO 1
-+
-+/* The rest of the LFS is also available. */
-+#define _LFS_LARGEFILE 1
-+#define _LFS64_LARGEFILE 1
-+#define _LFS64_STDIO 1
-+
-+#endif /* posix_opt.h */
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h
---- ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h 1998-09-13 09:25:31.000000000 -0700
-@@ -0,0 +1,37 @@
-+/* Signal handling function for threaded programs.
-+ Copyright (C) 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef _BITS_SIGTHREAD_H
-+#define _BITS_SIGTHREAD_H 1
-+
-+#if !defined _SIGNAL_H && !defined _PTHREAD_H
-+# error "Never include this file directly. Use <pthread.h> instead"
-+#endif
-+
-+/* Functions for handling signals. */
-+
-+/* Modify the signal mask for the calling thread. The arguments have
-+ the same meaning as for sigprocmask(2). */
-+extern int pthread_sigmask __P ((int __how, __const __sigset_t *__newmask,
-+ __sigset_t *__oldmask));
-+
-+/* Send signal SIGNO to the given thread. */
-+extern int pthread_kill __P ((pthread_t __thread, int __signo));
-+
-+#endif /* bits/sigthread.h */
-diff -Naur ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/configure glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/configure
---- ../glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/configure 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/sysdeps/unix/sysv/linux/configure 1998-08-28 03:07:20.000000000 -0700
-@@ -0,0 +1,3 @@
-+# Local configure fragment for sysdeps/unix/sysv/linux.
-+
-+DEFINES="$DEFINES -D_LIBC_REENTRANT"
-diff -Naur ../glibc-2.1.3/linuxthreads/weaks.c glibc-2.1.3/linuxthreads/weaks.c
---- ../glibc-2.1.3/linuxthreads/weaks.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/weaks.c 1998-08-28 03:07:19.000000000 -0700
-@@ -0,0 +1,117 @@
-+/* The weak pthread functions for Linux.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <errno.h>
-+#include <limits.h>
-+#include <stdlib.h>
-+
-+extern int __pthread_return_0 __P ((void));
-+extern int __pthread_return_1 __P ((void));
-+extern void __pthread_return_void __P ((void));
-+
-+/* Those are pthread functions which return 0 if successful. */
-+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
-+weak_alias (__pthread_return_0, __libc_pthread_attr_init_2_0)
-+symbol_version (__libc_pthread_attr_init_2_0, pthread_attr_init, GLIBC_2.0);
-+weak_alias (__pthread_return_0, __libc_pthread_attr_init_2_1)
-+default_symbol_version (__libc_pthread_attr_init_2_1, pthread_attr_init,
-+ GLIBC_2.1);
-+#else
-+weak_alias (__pthread_return_0, pthread_attr_init)
-+#endif
-+weak_alias (__pthread_return_0, pthread_attr_destroy)
-+weak_alias (__pthread_return_0, pthread_attr_setdetachstate)
-+weak_alias (__pthread_return_0, pthread_attr_getdetachstate)
-+weak_alias (__pthread_return_0, pthread_attr_setschedparam)
-+weak_alias (__pthread_return_0, pthread_attr_getschedparam)
-+weak_alias (__pthread_return_0, pthread_attr_setschedpolicy)
-+weak_alias (__pthread_return_0, pthread_attr_getschedpolicy)
-+weak_alias (__pthread_return_0, pthread_attr_setinheritsched)
-+weak_alias (__pthread_return_0, pthread_attr_getinheritsched)
-+weak_alias (__pthread_return_0, pthread_attr_setscope)
-+weak_alias (__pthread_return_0, pthread_attr_getscope)
-+weak_alias (__pthread_return_0, pthread_attr_setstackaddr)
-+weak_alias (__pthread_return_0, pthread_attr_getstackaddr)
-+weak_alias (__pthread_return_0, pthread_attr_setstacksize)
-+weak_alias (__pthread_return_0, pthread_attr_getstacksize)
-+weak_alias (__pthread_return_0, pthread_mutex_init)
-+weak_alias (__pthread_return_0, pthread_mutex_destroy)
-+weak_alias (__pthread_return_0, pthread_mutex_lock)
-+weak_alias (__pthread_return_0, pthread_mutex_trylock)
-+weak_alias (__pthread_return_0, pthread_mutex_unlock)
-+weak_alias (__pthread_return_0, pthread_mutexattr_init)
-+weak_alias (__pthread_return_0, pthread_mutexattr_destroy)
-+weak_alias (__pthread_return_0, pthread_mutexattr_settype)
-+weak_alias (__pthread_return_0, pthread_mutexattr_gettype)
-+weak_alias (__pthread_return_0, pthread_condattr_init)
-+weak_alias (__pthread_return_0, pthread_condattr_destroy)
-+weak_alias (__pthread_return_0, pthread_setschedparam)
-+weak_alias (__pthread_return_0, pthread_getschedparam)
-+weak_alias (__pthread_return_0, pthread_getcancelstate)
-+weak_alias (__pthread_return_0, pthread_setcancelstate)
-+weak_alias (__pthread_return_0, pthread_setcanceltype)
-+weak_alias (__pthread_return_0, pthread_setconcurrency)
-+weak_alias (__pthread_return_0, pthread_getconcurrency)
-+weak_alias (__pthread_return_0, pthread_self)
-+weak_alias (__pthread_return_0, pthread_cond_init)
-+weak_alias (__pthread_return_0, pthread_cond_destroy)
-+weak_alias (__pthread_return_0, pthread_cond_wait)
-+weak_alias (__pthread_return_0, pthread_cond_timedwait)
-+weak_alias (__pthread_return_0, pthread_cond_signal)
-+weak_alias (__pthread_return_0, pthread_cond_broadcast)
-+weak_alias (__pthread_return_0, pthread_rwlock_init)
-+weak_alias (__pthread_return_0, pthread_rwlock_destroy)
-+weak_alias (__pthread_return_0, pthread_rwlock_rdlock)
-+weak_alias (__pthread_return_0, pthread_rwlock_wrlock)
-+weak_alias (__pthread_return_0, pthread_rwlock_tryrdlock)
-+weak_alias (__pthread_return_0, pthread_rwlock_trywrlock)
-+weak_alias (__pthread_return_0, pthread_rwlock_unlock)
-+weak_alias (__pthread_return_0, pthread_rwlockattr_init)
-+weak_alias (__pthread_return_0, pthread_rwlockattr_destroy)
-+weak_alias (__pthread_return_0, pthread_rwlockattr_setpshared)
-+weak_alias (__pthread_return_0, pthread_rwlockattr_getpshared)
-+
-+
-+/* Those are pthread functions which return 1 if successful. */
-+weak_alias (__pthread_return_1, pthread_equal)
-+
-+/* pthread_exit () is a special case. */
-+void
-+weak_function
-+pthread_exit (void *retval)
-+{
-+ exit (EXIT_SUCCESS);
-+}
-+
-+int
-+__pthread_return_0 (void)
-+{
-+ return 0;
-+}
-+
-+int
-+__pthread_return_1 (void)
-+{
-+ return 1;
-+}
-+
-+void
-+__pthread_return_void (void)
-+{
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads/wrapsyscall.c glibc-2.1.3/linuxthreads/wrapsyscall.c
---- ../glibc-2.1.3/linuxthreads/wrapsyscall.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads/wrapsyscall.c 1998-12-02 11:03:25.000000000 -0800
-@@ -0,0 +1,186 @@
-+/* Wrapper arpund system calls to provide cancelation points.
-+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <fcntl.h>
-+#include <sys/mman.h>
-+#include <pthread.h>
-+#include <unistd.h>
-+#include <stdarg.h>
-+#include <stddef.h>
-+#include <stdlib.h>
-+#include <termios.h>
-+#include <sys/resource.h>
-+#include <sys/wait.h>
-+#include <sys/socket.h>
-+
-+
-+#ifndef PIC
-+/* We need a hook to force this file to be linked in when static
-+ libpthread is used. */
-+const int __pthread_provide_wrappers = 0;
-+#endif
-+
-+
-+#define CANCELABLE_SYSCALL(res_type, name, param_list, params) \
-+res_type __libc_##name param_list; \
-+res_type \
-+name param_list \
-+{ \
-+ res_type result; \
-+ int oldtype; \
-+ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \
-+ result = __libc_##name params; \
-+ pthread_setcanceltype (oldtype, NULL); \
-+ return result; \
-+}
-+
-+#define CANCELABLE_SYSCALL_VA(res_type, name, param_list, params, last_arg) \
-+res_type __libc_##name param_list; \
-+res_type \
-+name param_list \
-+{ \
-+ res_type result; \
-+ int oldtype; \
-+ va_list ap; \
-+ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \
-+ va_start (ap, last_arg); \
-+ result = __libc_##name params; \
-+ va_end (ap); \
-+ pthread_setcanceltype (oldtype, NULL); \
-+ return result; \
-+}
-+
-+
-+/* close(2). */
-+CANCELABLE_SYSCALL (int, close, (int fd), (fd))
-+strong_alias (close, __close)
-+
-+
-+/* fcntl(2). */
-+CANCELABLE_SYSCALL_VA (int, fcntl, (int fd, int cmd, ...),
-+ (fd, cmd, va_arg (ap, long int)), cmd)
-+strong_alias (fcntl, __fcntl)
-+
-+
-+/* fsync(2). */
-+CANCELABLE_SYSCALL (int, fsync, (int fd), (fd))
-+
-+
-+/* lseek(2). */
-+CANCELABLE_SYSCALL (off_t, lseek, (int fd, off_t offset, int whence),
-+ (fd, offset, whence))
-+strong_alias (lseek, __lseek)
-+
-+
-+/* msync(2). */
-+CANCELABLE_SYSCALL (int, msync, (__ptr_t addr, size_t length, int flags),
-+ (addr, length, flags))
-+
-+
-+/* nanosleep(2). */
-+CANCELABLE_SYSCALL (int, nanosleep, (const struct timespec *requested_time,
-+ struct timespec *remaining),
-+ (requested_time, remaining))
-+
-+
-+/* open(2). */
-+CANCELABLE_SYSCALL_VA (int, open, (const char *pathname, int flags, ...),
-+ (pathname, flags, va_arg (ap, mode_t)), flags)
-+strong_alias (open, __open)
-+
-+
-+/* pause(2). */
-+CANCELABLE_SYSCALL (int, pause, (void), ())
-+
-+
-+/* read(2). */
-+CANCELABLE_SYSCALL (ssize_t, read, (int fd, void *buf, size_t count),
-+ (fd, buf, count))
-+strong_alias (read, __read)
-+
-+
-+/* system(3). */
-+CANCELABLE_SYSCALL (int, system, (const char *line), (line))
-+
-+
-+/* tcdrain(2). */
-+CANCELABLE_SYSCALL (int, tcdrain, (int fd), (fd))
-+
-+
-+/* wait(2). */
-+CANCELABLE_SYSCALL (__pid_t, wait, (__WAIT_STATUS_DEFN stat_loc), (stat_loc))
-+strong_alias (wait, __wait)
-+
-+
-+/* waitpid(2). */
-+CANCELABLE_SYSCALL (__pid_t, waitpid, (__pid_t pid, int *stat_loc,
-+ int options),
-+ (pid, stat_loc, options))
-+
-+
-+/* write(2). */
-+CANCELABLE_SYSCALL (ssize_t, write, (int fd, const void *buf, size_t n),
-+ (fd, buf, n))
-+strong_alias (write, __write)
-+
-+
-+/* The following system calls are thread cancellation points specified
-+ in XNS. */
-+
-+/* accept(2). */
-+CANCELABLE_SYSCALL (int, accept, (int fd, __SOCKADDR_ARG addr,
-+ socklen_t *addr_len),
-+ (fd, addr, addr_len))
-+
-+/* connect(2). */
-+CANCELABLE_SYSCALL (int, connect, (int fd, __CONST_SOCKADDR_ARG addr,
-+ socklen_t len),
-+ (fd, addr, len))
-+strong_alias (connect, __connect)
-+
-+/* recv(2). */
-+CANCELABLE_SYSCALL (int, recv, (int fd, __ptr_t buf, size_t n, int flags),
-+ (fd, buf, n, flags))
-+
-+/* recvfrom(2). */
-+CANCELABLE_SYSCALL (int, recvfrom, (int fd, __ptr_t buf, size_t n, int flags,
-+ __SOCKADDR_ARG addr, socklen_t *addr_len),
-+ (fd, buf, n, flags, addr, addr_len))
-+
-+/* recvmsg(2). */
-+CANCELABLE_SYSCALL (int, recvmsg, (int fd, struct msghdr *message, int flags),
-+ (fd, message, flags))
-+
-+/* send(2). */
-+CANCELABLE_SYSCALL (int, send, (int fd, const __ptr_t buf, size_t n,
-+ int flags),
-+ (fd, buf, n, flags))
-+strong_alias (send, __send)
-+
-+/* sendmsg(2). */
-+CANCELABLE_SYSCALL (int, sendmsg, (int fd, const struct msghdr *message,
-+ int flags),
-+ (fd, message, flags))
-+
-+/* sendto(2). */
-+CANCELABLE_SYSCALL (int, sendto, (int fd, const __ptr_t buf, size_t n,
-+ int flags, __CONST_SOCKADDR_ARG addr,
-+ socklen_t addr_len),
-+ (fd, buf, n, flags, addr, addr_len))
-diff -Naur ../glibc-2.1.3/linuxthreads_db/Banner glibc-2.1.3/linuxthreads_db/Banner
---- ../glibc-2.1.3/linuxthreads_db/Banner 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/Banner 1999-11-12 10:51:03.000000000 -0800
-@@ -0,0 +1 @@
-+libthread_db work sponsored by Alpha Processor Inc
-diff -Naur ../glibc-2.1.3/linuxthreads_db/ChangeLog glibc-2.1.3/linuxthreads_db/ChangeLog
---- ../glibc-2.1.3/linuxthreads_db/ChangeLog 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/ChangeLog 2000-01-20 18:16:37.000000000 -0800
-@@ -0,0 +1,208 @@
-+2000-01-19 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * td_thr_getgregs.c: Correct size parameter of memset call.
-+
-+1999-12-02 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * proc_service.h: Fix typoes in last added declaractions.
-+
-+1999-12-01 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * proc_service.h: Add ps_pstop, ps_pcontinue, ps_lstop, and
-+ ps_lcontinue prototypes.
-+
-+1999-11-23 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Makefile: Correct dependency for shared object.
-+
-+1999-11-22 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * td_ta_map_lwp2thr.c: Add missing brace in comparison.
-+
-+ * thread_dbP.h (LOG): Only print message if __td_debug is nonzero.
-+ * td_init.c: Add __td_debug.
-+
-+1999-11-12 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * td_ta_thr_iter.c: Start copying list of descriptors from right
-+ position in target process.
-+
-+ * td_ta_thr_iter.c: Fix loop starting point over all but main and
-+ manager thread.
-+
-+ * td_ta_thr_iter.c: Read descriptors for main and manager thread
-+ special since after this we can assume that no new threads will be
-+ created anymore (at least in the gdb implementation).
-+
-+ * Makefile: Define version correctly.
-+
-+1999-11-10 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * td_ta_map_lwp2thr.c: If p_pid field is zero, this is before the
-+ thread library is initialized and we get the PID from the
-+ debugger.
-+
-+1999-11-08 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * td_thr_get_info.c: Make sure ti_lid is never zero.
-+
-+ * proc_service.h: Add ps_getpid prototype.
-+
-+1999-11-03 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * thread_dbP.h (ta_ok): New function.
-+ * td_ta_new.c: Add new handle to list.
-+ * td_ta_delete.c: Remove handle from list.
-+ * td_ta_clear_event.c: Use ta_ok to check for correct ta parameter.
-+ * td_ta_enable_stats.c: Likewise.
-+ * td_ta_event_addr.c: Likewise.
-+ * td_ta_event_getmsg.c: Likewise.
-+ * td_ta_get_nthreads.c: Likewise.
-+ * td_ta_get_ph.c: Likewise.
-+ * td_ta_get_stats.c: Likewise.
-+ * td_ta_map_id2thr.c: Likewise.
-+ * td_ta_map_lwp2thr.c: Likewise.
-+ * td_ta_reset_stats.c: Likewise.
-+ * td_ta_set_event.c: Likewise.
-+ * td_ta_setconcurrency.c: Likewise.
-+ * td_ta_thr_iter.c: Likewise.
-+
-+ * td_ta_tsd_iter.c: Optimize memory retrieving.
-+
-+ * Versions: New file.
-+
-+ * td_thr_get_info.c (td_thr_get_info): Initialize ti_traceme.
-+
-+1999-11-02 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * td_ta_thr_iter.c (td_ta_thr_iter): Optimize a bit. Read all
-+ handles at once.
-+
-+ * thread_dbP.h (struct th_thragent): Add pthread_handle_num.
-+ * td_ta_new.c: Initialize pthread_handle_num.
-+ * td_ta_event_getmsg.c: If last event was already reported search
-+ for another unreported event.
-+
-+ * td_thr_get_info.c (td_thr_get_info): Initialize ti_events.
-+
-+ * Makefile (libthread_db-routines): Add td_ta_set_event,
-+ td_ta_event_getmsg, and td_ta_clear_event.
-+ * td_ta_clear_event.c: New file.
-+ * td_ta_event_getmsg.c: New file.
-+ * td_ta_new.c: Get address of __pthread_last_event in target.
-+ * td_ta_set_event.c: Don't overwrite old mask, set additional bits.
-+ * td_thr_set_event.c: Likewise.
-+ * td_thr_clear_event.c: Implement.
-+ * thread_db.h: Declare td_ta_clear_event and td_ta_event_getmsg.
-+ * thread_dbP.h (struct td_thragent): Add pthread_last_event.
-+
-+ * td_ta_new.c: Don't test for __pthread_threads_debug. Get address
-+ of __pthread_threads_events and fail if this is not possible.
-+ * td_ta_event_addr.c: Implement.
-+ * td_thr_event_enable.c: Implement.
-+ * td_thr_event_getmsg.c: Implement.
-+ * td_thr_set_event.c: Implement.
-+ * td_ta_set_event.c: New file.
-+ * thread_db.h (td_eventbuf_t): Define.
-+ Declare td_ta_set_event.
-+ * thread_dbP.h (struct td_thragent): Add pthread_threads_eventsp.
-+
-+ * td_thr_getfpregs.c: For terminated threads return empty structure.
-+ * td_thr_getgregs.c: Likewise.
-+ * td_thr_setfpregs.c: Likewise.
-+ * td_thr_setgregs.c: Likewise.
-+
-+1999-11-01 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * thread_db.h: Shuffle types around to make things work for gdb.
-+ * thread_dbP.h: Include proc_service.h before thread_db.h.
-+
-+ * thread_db.h: It's TD_NOLIBTHREAD, not TD_LIBTHREAD.
-+ * td_ta_new.c: Likewise.
-+
-+1999-10-14 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * td_ta_new.c: p_startfct does not exist anymore.
-+
-+ * td_thr_get_info.c: Always initialize start function.
-+
-+ * td_ta_thr_iter.c: Don't return threads which exited (but are not
-+ joined).
-+
-+ * td_thr_validate.c: Don't skip manager thread.
-+
-+1999-10-13 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * td_ta_thr_iter.c: Use size of descriptor from *TA.
-+ Don't return manager thread before it's actually running.
-+ Actually use state parameter to distingusih at least a few states.
-+
-+ * td_thr_get_info.c: Handle manager thread special. Fill in ti_lid,
-+ ti_state, and ti_startfunc fields.
-+
-+1999-10-12 Andreas Jaeger <aj@suse.de>
-+
-+ * thread_dbP.h: Include <string.h> for strlen declaration. Remove
-+ __libc_write prototype since this is already declared in
-+ linuxthreads/internals.h.
-+
-+1999-10-11 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * thread_db.h: Fix comment for ti_type.
-+
-+ * td_thr_get_info.c: Initialize ti_type field.
-+
-+ * td_ta_thr_iter.c: Also report the manager thread.
-+
-+1999-10-08 Andreas Jaeger <aj@suse.de>
-+
-+ * thread_db.h: Fix typos in comments.
-+
-+ * td_ta_get_nthreads.c (td_ta_get_nthreads): Don't hardcode
-+ libpthread library name, get it from <gnu/lib-names.h> instead.
-+ * td_ta_new.c (td_ta_new): Likewise.
-+
-+1999-10-08 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * shlib-versions: New file.
-+
-+1999-10-07 Ulrich Drepper <drepper@cygnus.com>
-+
-+ * Makefile: New file.
-+ * proc_service.h: New file.
-+ * td_init.c: New file.
-+ * td_log.c: New file.
-+ * td_ta_delete.c: New file.
-+ * td_ta_enable_stats.c: New file.
-+ * td_ta_event_addr.c: New file.
-+ * td_ta_get_nthreads.c: New file.
-+ * td_ta_get_ph.c: New file.
-+ * td_ta_get_stats.c: New file.
-+ * td_ta_map_id2thr.c: New file.
-+ * td_ta_map_lwp2thr.c: New file.
-+ * td_ta_new.c: New file.
-+ * td_ta_reset_stats.c: New file.
-+ * td_ta_setconcurrency.c: New file.
-+ * td_ta_thr_iter.c: New file.
-+ * td_ta_tsd_iter.c: New file.
-+ * td_thr_clear_event.c: New file.
-+ * td_thr_dbresume.c: New file.
-+ * td_thr_dbsuspend.c: New file.
-+ * td_thr_event_enable.c: New file.
-+ * td_thr_event_getmsg.c: New file.
-+ * td_thr_get_info.c: New file.
-+ * td_thr_getfpregs.c: New file.
-+ * td_thr_getgregs.c: New file.
-+ * td_thr_getxregs.c: New file.
-+ * td_thr_getxregsize.c: New file.
-+ * td_thr_set_event.c: New file.
-+ * td_thr_setfpregs.c: New file.
-+ * td_thr_setgregs.c: New file.
-+ * td_thr_setprio.c: New file.
-+ * td_thr_setsigpending.c: New file.
-+ * td_thr_setxregs.c: New file.
-+ * td_thr_sigsetmask.c: New file.
-+ * td_thr_tsd.c: New file.
-+ * td_thr_validate.c: New file.
-+ * thread_db.h: New file.
-+ * thread_dbP.h: New file.
-diff -Naur ../glibc-2.1.3/linuxthreads_db/Makefile glibc-2.1.3/linuxthreads_db/Makefile
---- ../glibc-2.1.3/linuxthreads_db/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/Makefile 1999-11-23 09:46:56.000000000 -0800
-@@ -0,0 +1,51 @@
-+# Copyright (C) 1999 Free Software Foundation, Inc.
-+# This file is part of the GNU C Library.
-+
-+# The GNU C Library is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU Library General Public License as
-+# published by the Free Software Foundation; either version 2 of the
-+# License, or (at your option) any later version.
-+
-+# The GNU C Library is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# Library General Public License for more details.
-+
-+# You should have received a copy of the GNU Library General Public
-+# License along with the GNU C Library; see the file COPYING.LIB. If not,
-+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+# Boston, MA 02111-1307, USA.
-+
-+# Makefile for linuxthreads debug library subdirectory of GNU C Library.
-+
-+subdir := linuxthreads_db
-+
-+linuxthreads_db-version = 1.0
-+
-+extra-libs = libthread_db
-+extra-libs-others := $(extra-libs)
-+
-+headers = thread_db.h
-+libthread_db-routines = td_init td_log td_ta_delete td_ta_get_nthreads \
-+ td_ta_get_ph td_ta_map_id2thr td_ta_map_lwp2thr \
-+ td_ta_new td_ta_thr_iter td_ta_tsd_iter \
-+ td_thr_get_info td_thr_getfpregs td_thr_getgregs \
-+ td_thr_getxregs td_thr_getxregsize td_thr_setfpregs \
-+ td_thr_setgregs td_thr_setprio td_thr_setsigpending \
-+ td_thr_setxregs td_thr_sigsetmask td_thr_tsd \
-+ td_thr_validate td_thr_dbsuspend td_thr_dbresume \
-+ td_ta_setconcurrency td_ta_enable_stats \
-+ td_ta_reset_stats td_ta_get_stats td_ta_event_addr \
-+ td_thr_event_enable td_thr_set_event \
-+ td_thr_clear_event td_thr_event_getmsg \
-+ td_ta_set_event td_ta_event_getmsg \
-+ td_ta_clear_event
-+
-+libthread_db-inhibit-o = $(filter-out .os,$(object-suffixes))
-+
-+include ../Rules
-+
-+# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
-+# This ensures they will load libc.so for needed symbols if loaded by
-+# a statically-linked program that hasn't already loaded it.
-+$(objpfx)libthread_db.so: $(common-objpfx)libc.so
-diff -Naur ../glibc-2.1.3/linuxthreads_db/Versions glibc-2.1.3/linuxthreads_db/Versions
---- ../glibc-2.1.3/linuxthreads_db/Versions 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/Versions 1999-11-09 23:03:06.000000000 -0800
-@@ -0,0 +1,15 @@
-+libthread_db {
-+ GLIBC_2.1.3 {
-+ # t*
-+ td_init; td_log; td_ta_clear_event; td_ta_delete; td_ta_enable_stats;
-+ td_ta_event_addr; td_ta_event_getmsg; td_ta_get_nthreads; td_ta_get_ph;
-+ td_ta_get_stats; td_ta_map_id2thr; td_ta_map_lwp2thr; td_ta_new;
-+ td_ta_reset_stats; td_ta_set_event; td_ta_setconcurrency;
-+ td_ta_thr_iter; td_ta_tsd_iter; td_thr_clear_event; td_thr_dbresume;
-+ td_thr_dbsuspend; td_thr_event_enable; td_thr_event_getmsg;
-+ td_thr_get_info; td_thr_getfpregs; td_thr_getgregs; td_thr_getxregs;
-+ td_thr_getxregsize; td_thr_set_event; td_thr_setfpregs; td_thr_setgregs;
-+ td_thr_setprio; td_thr_setsigpending; td_thr_setxregs; td_thr_sigsetmask;
-+ td_thr_tsd; td_thr_validate;
-+ }
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/proc_service.h glibc-2.1.3/linuxthreads_db/proc_service.h
---- ../glibc-2.1.3/linuxthreads_db/proc_service.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/proc_service.h 1999-12-02 00:07:56.000000000 -0800
-@@ -0,0 +1,70 @@
-+/* Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+/* The definitions in this file must correspond to those in the debugger. */
-+#include <sys/procfs.h>
-+
-+typedef enum
-+{
-+ PS_OK, /* generic "call succeeded" */
-+ PS_ERR, /* generic. */
-+ PS_BADPID, /* bad process handle */
-+ PS_BADLID, /* bad lwp identifier */
-+ PS_BADADDR, /* bad address */
-+ PS_NOSYM, /* p_lookup() could not find given symbol */
-+ PS_NOFREGS
-+ /*
-+ * FPU register set not available for given
-+ * lwp
-+ */
-+} ps_err_e;
-+
-+
-+struct ps_prochandle; /* user defined. */
-+
-+
-+extern ps_err_e ps_pdread(struct ps_prochandle *,
-+ psaddr_t, void *, size_t);
-+extern ps_err_e ps_pdwrite(struct ps_prochandle *,
-+ psaddr_t, const void *, size_t);
-+extern ps_err_e ps_ptread(struct ps_prochandle *,
-+ psaddr_t, void *, size_t);
-+extern ps_err_e ps_ptwrite(struct ps_prochandle *,
-+ psaddr_t, const void *, size_t);
-+
-+extern ps_err_e ps_pglobal_lookup(struct ps_prochandle *,
-+ const char *object_name, const char *sym_name, psaddr_t *sym_addr);
-+
-+
-+extern ps_err_e ps_lgetregs(struct ps_prochandle *,
-+ lwpid_t, prgregset_t);
-+extern ps_err_e ps_lsetregs(struct ps_prochandle *,
-+ lwpid_t, const prgregset_t);
-+extern ps_err_e ps_lgetfpregs(struct ps_prochandle *,
-+ lwpid_t, prfpregset_t *);
-+extern ps_err_e ps_lsetfpregs(struct ps_prochandle *,
-+ lwpid_t, const prfpregset_t *);
-+
-+extern pid_t ps_getpid (struct ps_prochandle *);
-+
-+
-+extern ps_err_e ps_pstop (const struct ps_prochandle *);
-+extern ps_err_e ps_pcontinue (const struct ps_prochandle *);
-+
-+extern ps_err_e ps_lstop (const struct ps_prochandle *, lwpid_t);
-+extern ps_err_e ps_lcontinue (const struct ps_prochandle *, lwpid_t);
-diff -Naur ../glibc-2.1.3/linuxthreads_db/shlib-versions glibc-2.1.3/linuxthreads_db/shlib-versions
---- ../glibc-2.1.3/linuxthreads_db/shlib-versions 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/shlib-versions 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,2 @@
-+# The thread debug library
-+.*-.*-linux.* libthread_db=1
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_init.c glibc-2.1.3/linuxthreads_db/td_init.c
---- ../glibc-2.1.3/linuxthreads_db/td_init.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_init.c 1999-11-22 12:50:11.000000000 -0800
-@@ -0,0 +1,32 @@
-+/* Initialization function of thread debugger support library.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+int __td_debug;
-+
-+
-+td_err_e
-+td_init (void)
-+{
-+ /* XXX We have to figure out what has to be done. */
-+ LOG (__FUNCTION__);
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_log.c glibc-2.1.3/linuxthreads_db/td_log.c
---- ../glibc-2.1.3/linuxthreads_db/td_log.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_log.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,32 @@
-+/* Noop, left for historical reasons.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_log (void)
-+{
-+ /* This interface is deprecated in the Sun interface. We provide it
-+ for compatibility but don't do anyhting ourself. We might in
-+ future do some logging if this seems reasonable. */
-+ LOG (__FUNCTION__);
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_clear_event.c glibc-2.1.3/linuxthreads_db/td_ta_clear_event.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_clear_event.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_clear_event.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,53 @@
-+/* Globally disable events.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_clear_event (ta, event)
-+ const td_thragent_t *ta;
-+ td_thr_events_t *event;
-+{
-+ td_thr_events_t old_event;
-+ int i;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ /* Write the new value into the thread data structure. */
-+ if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
-+ &old_event, sizeof (td_thrhandle_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Remove the set bits in. */
-+ for (i = 0; i < TD_EVENTSIZE; ++i)
-+ old_event.event_bits[i] &= ~event->event_bits[i];
-+
-+ /* Write the new value into the thread data structure. */
-+ if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp,
-+ &old_event, sizeof (td_thrhandle_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_delete.c glibc-2.1.3/linuxthreads_db/td_ta_delete.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_delete.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_delete.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,58 @@
-+/* Detach to target process.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stdlib.h>
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_delete (td_thragent_t *ta)
-+{
-+ LOG (__FUNCTION__);
-+
-+ /* Safety check. */
-+ if (ta == NULL || __td_agent_list == NULL)
-+ return TD_BADTA;
-+
-+ /* Remove the handle from the list. */
-+ if (ta == __td_agent_list->ta)
-+ /* It's the first element of the list. */
-+ __td_agent_list = __td_agent_list->next;
-+ else
-+ {
-+ /* We have to search for it. */
-+ struct agent_list *runp = __td_agent_list;
-+
-+ while (runp->next != NULL && runp->next->ta != ta)
-+ runp = runp->next;
-+
-+ if (runp->next == NULL)
-+ /* It's not a valid decriptor since it is not in the list. */
-+ return TD_BADTA;
-+
-+ runp->next = runp->next->next;
-+ }
-+
-+ /* The handle was allocated in `td_ta_new'. */
-+ free (ta);
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_enable_stats.c glibc-2.1.3/linuxthreads_db/td_ta_enable_stats.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_enable_stats.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_enable_stats.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,35 @@
-+/* Enable collection of statistics for process.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_enable_stats (const td_thragent_t *ta, int enable)
-+{
-+ /* XXX We have to figure out what has to be done. */
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_event_addr.c glibc-2.1.3/linuxthreads_db/td_ta_event_addr.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_event_addr.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_event_addr.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,75 @@
-+/* Get event address.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <gnu/lib-names.h>
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_event_addr (const td_thragent_t *ta, td_event_e event, td_notify_t *addr)
-+{
-+ td_err_e res = TD_NOEVENT;
-+ const char *symbol = NULL;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ switch (event)
-+ {
-+ case TD_CREATE:
-+ symbol = "__linuxthreads_create_event";
-+ break;
-+
-+ case TD_DEATH:
-+ symbol = "__linuxthreads_death_event";
-+ break;
-+
-+ case TD_REAP:
-+ symbol = "__linuxthreads_reap_event";
-+ break;
-+
-+ default:
-+ /* Event cannot be handled. */
-+ break;
-+ }
-+
-+ /* Now get the address. */
-+ if (symbol != NULL)
-+ {
-+ psaddr_t taddr;
-+
-+ if (ps_pglobal_lookup (ta->ph, LIBPTHREAD_SO, symbol, &taddr) == PS_OK)
-+ {
-+ /* Success, we got the address. */
-+ addr->type = NOTIFY_BPT;
-+ addr->u.bptaddr = taddr;
-+
-+ res = TD_OK;
-+ }
-+ else
-+ res = TD_ERR;
-+ }
-+
-+ return res;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_event_getmsg.c glibc-2.1.3/linuxthreads_db/td_ta_event_getmsg.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_event_getmsg.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_event_getmsg.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,128 @@
-+/* Retrieve event.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stddef.h>
-+#include <string.h>
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_event_getmsg (const td_thragent_t *ta, td_event_msg_t *msg)
-+{
-+ /* XXX I cannot think of another way but using a static variable. */
-+ static td_thrhandle_t th;
-+ td_eventbuf_t event;
-+ psaddr_t addr;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ /* Get the pointer to the thread descriptor with the last event. */
-+ if (ps_pdread (ta->ph, ta->pthread_last_event,
-+ &addr, sizeof (void *)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* If the pointer is NULL no event occurred. */
-+ if (addr == 0)
-+ return TD_NOMSG;
-+
-+ /* Read the even structure from the target. */
-+ if (ps_pdread (ta->ph,
-+ ((char *) addr
-+ + offsetof (struct _pthread_descr_struct, p_eventbuf)),
-+ &event, sizeof (td_eventbuf_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Check whether an event occurred. */
-+ if (event.eventnum == TD_EVENT_NONE)
-+ {
-+ /* Oh well, this means the last event was already read. So
-+ we have to look for any other event. */
-+ struct pthread_handle_struct handles[ta->pthread_threads_max];
-+ int num;
-+ int i;
-+
-+ /* Read the number of currently active threads. */
-+ if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int))
-+ != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Now read the handles. */
-+ if (ps_pdread (ta->ph, ta->handles, handles,
-+ ta->pthread_threads_max * sizeof (handles[0])) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ for (i = 0; i < ta->pthread_threads_max && num > 0; ++i)
-+ {
-+ if (handles[i].h_descr == NULL)
-+ /* No entry here. */
-+ continue;
-+
-+ /* First count this active thread. */
-+ --num;
-+
-+ if (handles[i].h_descr == addr)
-+ /* We already handled this. */
-+ continue;
-+
-+ /* Read the event data for this thread. */
-+ if (ps_pdread (ta->ph,
-+ ((char *) handles[i].h_descr
-+ + offsetof (struct _pthread_descr_struct,
-+ p_eventbuf)),
-+ &event, sizeof (td_eventbuf_t)) != PS_OK)
-+ return TD_ERR;
-+
-+ if (event.eventnum != TD_EVENT_NONE)
-+ {
-+ /* We found a thread with an unreported event. */
-+ addr = handles[i].h_descr;
-+ break;
-+ }
-+ }
-+
-+ /* If we haven't found any other event signal this to the user. */
-+ if (event.eventnum == TD_EVENT_NONE)
-+ return TD_NOMSG;
-+ }
-+
-+ /* Generate the thread descriptor. */
-+ th.th_ta_p = (td_thragent_t *) ta;
-+ th.th_unique = addr;
-+
-+ /* Fill the user's data structure. */
-+ msg->event = event.eventnum;
-+ msg->th_p = &th;
-+ msg->msg.data = (uintptr_t) event.eventdata;
-+
-+ /* And clear the event message in the target. */
-+ memset (&event, '\0', sizeof (td_eventbuf_t));
-+ if (ps_pdwrite (ta->ph,
-+ ((char *) addr
-+ + offsetof (struct _pthread_descr_struct, p_eventbuf)),
-+ &event, sizeof (td_eventbuf_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_get_nthreads.c glibc-2.1.3/linuxthreads_db/td_ta_get_nthreads.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_get_nthreads.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_get_nthreads.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,44 @@
-+/* Get the number of threads in the process.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+#include <gnu/lib-names.h>
-+
-+td_err_e
-+td_ta_get_nthreads (const td_thragent_t *ta, int *np)
-+{
-+ psaddr_t addr;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ /* Access the variable `__pthread_handles_num'. */
-+ if (ps_pglobal_lookup (ta->ph, LIBPTHREAD_SO, "__pthread_handles_num",
-+ &addr) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ if (ps_pdread (ta->ph, addr, np, sizeof (int)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_get_ph.c glibc-2.1.3/linuxthreads_db/td_ta_get_ph.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_get_ph.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_get_ph.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,36 @@
-+/* Get external process handle.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_get_ph (const td_thragent_t *ta, struct ps_prochandle **ph)
-+{
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ *ph = ta->ph;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_get_stats.c glibc-2.1.3/linuxthreads_db/td_ta_get_stats.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_get_stats.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_get_stats.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,35 @@
-+/* Retrieve statistics for process.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_get_stats (const td_thragent_t *ta, td_ta_stats_t *statsp)
-+{
-+ /* XXX We have to figure out what has to be done. */
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_map_id2thr.c glibc-2.1.3/linuxthreads_db/td_ta_map_id2thr.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_map_id2thr.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_map_id2thr.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,63 @@
-+/* Map thread ID to thread handle.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th)
-+{
-+ struct pthread_handle_struct phc;
-+ struct _pthread_descr_struct pds;
-+ int pthread_threads_max;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ /* Make the following expression a bit smaller. */
-+ pthread_threads_max = ta->pthread_threads_max;
-+
-+ /* We can compute the entry in the handle array we want. */
-+ if (ps_pdread (ta->ph, ta->handles + pt % pthread_threads_max, &phc,
-+ sizeof (struct pthread_handle_struct)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Test whether this entry is in use. */
-+ if (phc.h_descr == NULL)
-+ return TD_BADTH;
-+
-+ /* Next test: get the descriptor to see whether this is not an old
-+ thread handle. */
-+ if (ps_pdread (ta->ph, phc.h_descr, &pds,
-+ sizeof (struct _pthread_descr_struct)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ if (pds.p_tid != pt)
-+ return TD_BADTH;
-+
-+ /* Create the `td_thrhandle_t' object. */
-+ th->th_ta_p = (td_thragent_t *) ta;
-+ th->th_unique = phc.h_descr;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_map_lwp2thr.c glibc-2.1.3/linuxthreads_db/td_ta_map_lwp2thr.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_map_lwp2thr.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_map_lwp2thr.c 1999-11-22 18:24:56.000000000 -0800
-@@ -0,0 +1,81 @@
-+/* Which thread is running on an lwp?
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
-+{
-+ int pthread_threads_max = ta->pthread_threads_max;
-+ size_t sizeof_descr = ta->sizeof_descr;
-+ struct pthread_handle_struct phc[pthread_threads_max];
-+ size_t cnt;
-+#ifdef ALL_THREADS_STOPPED
-+ int num;
-+#else
-+# define num 1
-+#endif
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ /* Read all the descriptors. */
-+ if (ps_pdread (ta->ph, ta->handles, phc,
-+ sizeof (struct pthread_handle_struct) * pthread_threads_max)
-+ != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+#ifdef ALL_THREADS_STOPPED
-+ /* Read the number of currently active threads. */
-+ if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+#endif
-+
-+ /* Get the entries one after the other and find out whether the ID
-+ matches. */
-+ for (cnt = 0; cnt < pthread_threads_max && num > 0; ++cnt)
-+ if (phc[cnt].h_descr != NULL)
-+ {
-+ struct _pthread_descr_struct pds;
-+
-+#ifdef ALL_THREADS_STOPPED
-+ /* First count this active thread. */
-+ --num;
-+#endif
-+
-+ if (ps_pdread (ta->ph, phc[cnt].h_descr, &pds, sizeof_descr) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ if ((pds.p_pid ?: ps_getpid (ta->ph)) == lwpid)
-+ {
-+ /* Found it. Now fill in the `td_thrhandle_t' object. */
-+ th->th_ta_p = (td_thragent_t *) ta;
-+ th->th_unique = phc[cnt].h_descr;
-+
-+ return TD_OK;
-+ }
-+ }
-+
-+ return TD_NOLWP;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_new.c glibc-2.1.3/linuxthreads_db/td_ta_new.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_new.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_new.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,154 @@
-+/* Attach to target process.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stddef.h>
-+#include <stdlib.h>
-+#include <gnu/lib-names.h>
-+
-+#include "thread_dbP.h"
-+
-+
-+/* Datatype for the list of known thread agents. Normally there will
-+ be exactly one so we don't spend much though on making it fast. */
-+struct agent_list *__td_agent_list;
-+
-+
-+td_err_e
-+td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
-+{
-+ psaddr_t addr;
-+ struct agent_list *elemp;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Get the global event mask. This is one of the variables which
-+ are new in the thread library to enable debugging. If it is
-+ not available we cannot debug. */
-+ if (ps_pglobal_lookup (ps, LIBPTHREAD_SO,
-+ "__pthread_threads_events", &addr) != PS_OK)
-+ return TD_NOLIBTHREAD;
-+
-+ /* Fill in the appropriate information. */
-+ *ta = (td_thragent_t *) malloc (sizeof (td_thragent_t));
-+ if (*ta == NULL)
-+ return TD_MALLOC;
-+
-+ /* Store the proc handle which we will pass to the callback functions
-+ back into the debugger. */
-+ (*ta)->ph = ps;
-+
-+ /* Remember the address. */
-+ (*ta)->pthread_threads_eventsp = (td_thr_events_t *) addr;
-+
-+ /* Get the pointer to the variable pointing to the thread descriptor
-+ with the last event. */
-+ if (ps_pglobal_lookup (ps, LIBPTHREAD_SO,
-+ "__pthread_last_event",
-+ &(*ta)->pthread_last_event) != PS_OK)
-+ {
-+ free_return:
-+ free (*ta);
-+ return TD_ERR;
-+ }
-+
-+ /* Get the pointer to the variable containing the number of active
-+ threads. */
-+ if (ps_pglobal_lookup (ps, LIBPTHREAD_SO,
-+ "__pthread_handles_num",
-+ &(*ta)->pthread_handles_num) != PS_OK)
-+ goto free_return;
-+
-+ /* See whether the library contains the necessary symbols. */
-+ if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, "__pthread_handles",
-+ &addr) != PS_OK)
-+ goto free_return;
-+
-+ (*ta)->handles = (struct pthread_handle_struct *) addr;
-+
-+
-+ if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, "pthread_keys",
-+ &addr) != PS_OK)
-+ goto free_return;
-+
-+ /* Cast to the right type. */
-+ (*ta)->keys = (struct pthread_key_struct *) addr;
-+
-+ /* Find out about the maximum number of threads. Old implementations
-+ don't provide this information. In this case we assume that the
-+ debug library is compiled with the same values. */
-+ if (ps_pglobal_lookup (ps, LIBPTHREAD_SO,
-+ "__linuxthreads_pthread_threads_max", &addr) != PS_OK)
-+ (*ta)->pthread_threads_max = PTHREAD_THREADS_MAX;
-+ else
-+ {
-+ if (ps_pdread (ps, addr, &(*ta)->pthread_threads_max, sizeof (int))
-+ != PS_OK)
-+ goto free_return;
-+ }
-+
-+ /* Similar for the maximum number of thread local data keys. */
-+ if (ps_pglobal_lookup (ps, LIBPTHREAD_SO,
-+ "__linuxthreads_pthread_keys_max", &addr) != PS_OK)
-+ (*ta)->pthread_keys_max = PTHREAD_KEYS_MAX;
-+ else
-+ {
-+ if (ps_pdread (ps, addr, &(*ta)->pthread_keys_max, sizeof (int))
-+ != PS_OK)
-+ goto free_return;
-+ }
-+
-+ /* And for the size of the second level arrays for the keys. */
-+ if (ps_pglobal_lookup (ps, LIBPTHREAD_SO,
-+ "__linuxthreads_pthread_sizeof_descr", &addr)
-+ != PS_OK)
-+ (*ta)->sizeof_descr = sizeof (struct _pthread_descr_struct);
-+ else
-+ {
-+ if (ps_pdread (ps, addr, &(*ta)->sizeof_descr, sizeof (int)) != PS_OK)
-+ goto free_return;
-+ }
-+
-+ /* Similar for the maximum number of thread local data keys. */
-+ if (ps_pglobal_lookup (ps, LIBPTHREAD_SO,
-+ "__linuxthreads_pthread_keys_max", &addr) != PS_OK)
-+ (*ta)->pthread_keys_max = PTHREAD_KEYS_MAX;
-+ else
-+ {
-+ if (ps_pdread (ps, addr, &(*ta)->pthread_keys_max, sizeof (int))
-+ != PS_OK)
-+ goto free_return;
-+ }
-+
-+ /* Now add the new agent descriptor to the list. */
-+ elemp = (struct agent_list *) malloc (sizeof (struct agent_list));
-+ if (elemp == NULL)
-+ {
-+ /* Argh, now that everything else worked... */
-+ free (*ta);
-+ return TD_MALLOC;
-+ }
-+
-+ /* We don't care for thread-safety here. */
-+ elemp->ta = *ta;
-+ elemp->next = __td_agent_list;
-+ __td_agent_list = elemp;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_reset_stats.c glibc-2.1.3/linuxthreads_db/td_ta_reset_stats.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_reset_stats.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_reset_stats.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,35 @@
-+/* Reset statistics.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_reset_stats (const td_thragent_t *ta)
-+{
-+ /* XXX We have to figure out what has to be done. */
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_set_event.c glibc-2.1.3/linuxthreads_db/td_ta_set_event.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_set_event.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_set_event.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,53 @@
-+/* Globally enable events.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_set_event (ta, event)
-+ const td_thragent_t *ta;
-+ td_thr_events_t *event;
-+{
-+ td_thr_events_t old_event;
-+ int i;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ /* Write the new value into the thread data structure. */
-+ if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
-+ &old_event, sizeof (td_thrhandle_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Or the new bits in. */
-+ for (i = 0; i < TD_EVENTSIZE; ++i)
-+ old_event.event_bits[i] |= event->event_bits[i];
-+
-+ /* Write the new value into the thread data structure. */
-+ if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp,
-+ &old_event, sizeof (td_thrhandle_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_setconcurrency.c glibc-2.1.3/linuxthreads_db/td_ta_setconcurrency.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_setconcurrency.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_setconcurrency.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,35 @@
-+/* Set suggested concurrency level for process.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_setconcurrency (const td_thragent_t *ta, int level)
-+{
-+ /* This is something LinuxThreads does not support. */
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ return TD_NOCAPAB;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_thr_iter.c glibc-2.1.3/linuxthreads_db/td_ta_thr_iter.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_thr_iter.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_thr_iter.c 1999-11-12 15:26:24.000000000 -0800
-@@ -0,0 +1,142 @@
-+/* Iterate over a process's threads.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+static int
-+handle_descr (const td_thragent_t *ta, td_thr_iter_f *callback,
-+ void *cbdata_p, td_thr_state_e state, int ti_pri,
-+ size_t cnt, pthread_descr descr)
-+{
-+ struct _pthread_descr_struct pds;
-+ size_t sizeof_descr = ta->sizeof_descr;
-+ td_thrhandle_t th;
-+
-+ if (ps_pdread (ta->ph, descr, &pds, sizeof_descr) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* The manager thread must be handled special. The descriptor
-+ exists but the thread only gets created when the first
-+ `pthread_create' call is issued. A clear indication that this
-+ happened is when the p_pid field is non-zero. */
-+ if (cnt == 1 && pds.p_pid == 0)
-+ return TD_OK;
-+
-+ /* Now test whether this thread matches the specified
-+ conditions. */
-+
-+ /* Only if the priority level is as high or higher. */
-+ if (pds.p_priority < ti_pri)
-+ return TD_OK;
-+
-+ /* Test the state.
-+ XXX This is incomplete. */
-+ if (state != TD_THR_ANY_STATE)
-+ return TD_OK;
-+
-+ /* XXX For now we ignore threads which are not running anymore.
-+ The reason is that gdb tries to get the registers and fails.
-+ In future we should have a special mode of the thread library
-+ in which we keep the process around until the actual join
-+ operation happened. */
-+ if (pds.p_exited != 0)
-+ return TD_OK;
-+
-+ /* Yep, it matches. Call the callback function. */
-+ th.th_ta_p = (td_thragent_t *) ta;
-+ th.th_unique = descr;
-+ if (callback (&th, cbdata_p) != 0)
-+ return TD_DBERR;
-+
-+ /* All done successfully. */
-+ return TD_OK;
-+}
-+
-+
-+td_err_e
-+td_ta_thr_iter (const td_thragent_t *ta, td_thr_iter_f *callback,
-+ void *cbdata_p, td_thr_state_e state, int ti_pri,
-+ sigset_t *ti_sigmask_p, unsigned int ti_user_flags)
-+{
-+ int pthread_threads_max;
-+ struct pthread_handle_struct *phc;
-+ td_err_e result = TD_OK;
-+ int cnt;
-+#ifdef ALL_THREADS_STOPPED
-+ int num;
-+#else
-+# define num 1
-+#endif
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ pthread_threads_max = ta->pthread_threads_max;
-+ phc = (struct pthread_handle_struct *) alloca (sizeof (phc[0])
-+ * pthread_threads_max);
-+
-+ /* First read only the main thread and manager thread information. */
-+ if (ps_pdread (ta->ph, ta->handles, phc,
-+ sizeof (struct pthread_handle_struct) * 2) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Now handle these descriptors. */
-+ result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 0,
-+ phc[0].h_descr);
-+ if (result != TD_OK)
-+ return result;
-+ result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 1,
-+ phc[1].h_descr);
-+ if (result != TD_OK)
-+ return result;
-+
-+ /* Read all the descriptors. */
-+ if (ps_pdread (ta->ph, ta->handles + 2, &phc[2],
-+ (sizeof (struct pthread_handle_struct)
-+ * (pthread_threads_max - 2))) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+#ifdef ALL_THREADS_STOPPED
-+ /* Read the number of currently active threads. */
-+ if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+#endif
-+
-+ /* Now get all descriptors, one after the other. */
-+ for (cnt = 2; cnt < pthread_threads_max && num > 0; ++cnt)
-+ if (phc[cnt].h_descr != NULL)
-+ {
-+#ifdef ALL_THREADS_STOPPED
-+ /* First count this active thread. */
-+ --num;
-+#endif
-+
-+ result = handle_descr (ta, callback, cbdata_p, state, ti_pri, cnt,
-+ phc[cnt].h_descr);
-+ if (result != TD_OK)
-+ break;
-+ }
-+
-+ return result;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_ta_tsd_iter.c glibc-2.1.3/linuxthreads_db/td_ta_tsd_iter.c
---- ../glibc-2.1.3/linuxthreads_db/td_ta_tsd_iter.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_ta_tsd_iter.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,55 @@
-+/* Iterate over a process's thread-specific data.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_ta_tsd_iter (const td_thragent_t *ta, td_key_iter_f *callback,
-+ void *cbdata_p)
-+{
-+ struct pthread_key_struct *keys;
-+ int pthread_keys_max;
-+ int cnt;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Test whether the TA parameter is ok. */
-+ if (! ta_ok (ta))
-+ return TD_BADTA;
-+
-+ pthread_keys_max = ta->pthread_keys_max;
-+ keys = (struct pthread_key_struct *) alloca (sizeof (keys[0])
-+ * pthread_keys_max);
-+
-+ /* Read all the information about the keys. */
-+ if (ps_pdread (ta->ph, ta->keys, keys,
-+ sizeof (keys[0]) * pthread_keys_max) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Now get all descriptors, one after the other. */
-+ for (cnt = 0; cnt < pthread_keys_max; ++cnt)
-+ if (keys[cnt].in_use
-+ /* Return with an error if the callback returns a nonzero value. */
-+ && callback (cnt, keys[cnt].destr, cbdata_p) != 0)
-+ return TD_DBERR;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_clear_event.c glibc-2.1.3/linuxthreads_db/td_thr_clear_event.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_clear_event.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_clear_event.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,57 @@
-+/* Disable specific event for thread.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stddef.h>
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_clear_event (th, event)
-+ const td_thrhandle_t *th;
-+ td_thr_events_t *event;
-+{
-+ td_thr_events_t old_event;
-+ int i;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Write the new value into the thread data structure. */
-+ if (ps_pdread (th->th_ta_p->ph,
-+ ((char *) th->th_unique
-+ + offsetof (struct _pthread_descr_struct,
-+ p_eventbuf.eventmask)),
-+ &old_event, sizeof (td_thrhandle_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Remove the set bits in. */
-+ for (i = 0; i < TD_EVENTSIZE; ++i)
-+ old_event.event_bits[i] &= ~event->event_bits[i];
-+
-+ /* Write the new value into the thread data structure. */
-+ if (ps_pdwrite (th->th_ta_p->ph,
-+ ((char *) th->th_unique
-+ + offsetof (struct _pthread_descr_struct,
-+ p_eventbuf.eventmask)),
-+ &old_event, sizeof (td_thrhandle_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_dbresume.c glibc-2.1.3/linuxthreads_db/td_thr_dbresume.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_dbresume.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_dbresume.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,30 @@
-+/* Resume execution of given thread.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_dbresume (const td_thrhandle_t *th)
-+{
-+ /* XXX We have to figure out what has to be done. */
-+ LOG (__FUNCTION__);
-+ return TD_NOCAPAB;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_dbsuspend.c glibc-2.1.3/linuxthreads_db/td_thr_dbsuspend.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_dbsuspend.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_dbsuspend.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,30 @@
-+/* Suspend execution of given thread.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_dbsuspend (const td_thrhandle_t *th)
-+{
-+ /* XXX We have to figure out what has to be done. */
-+ LOG (__FUNCTION__);
-+ return TD_NOCAPAB;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_event_enable.c glibc-2.1.3/linuxthreads_db/td_thr_event_enable.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_event_enable.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_event_enable.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,41 @@
-+/* Enable event process-wide.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stddef.h>
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_event_enable (th, onoff)
-+ const td_thrhandle_t *th;
-+ int onoff;
-+{
-+ LOG (__FUNCTION__);
-+
-+ /* Write the new value into the thread data structure. */
-+ if (ps_pdwrite (th->th_ta_p->ph,
-+ ((char *) th->th_unique
-+ + offsetof (struct _pthread_descr_struct, p_report_events)),
-+ &onoff, sizeof (int)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_event_getmsg.c glibc-2.1.3/linuxthreads_db/td_thr_event_getmsg.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_event_getmsg.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_event_getmsg.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,60 @@
-+/* Retrieve event.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stddef.h>
-+#include <string.h>
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_event_getmsg (const td_thrhandle_t *th, td_event_msg_t *msg)
-+{
-+ td_eventbuf_t event;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Read the even structure from the target. */
-+ if (ps_pdread (th->th_ta_p->ph,
-+ ((char *) th->th_unique
-+ + offsetof (struct _pthread_descr_struct, p_eventbuf)),
-+ &event, sizeof (td_eventbuf_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Check whether an event occurred. */
-+ if (event.eventnum == TD_EVENT_NONE)
-+ /* Nothing. */
-+ return TD_NOMSG;
-+
-+ /* Fill the user's data structure. */
-+ msg->event = event.eventnum;
-+ msg->th_p = th;
-+ msg->msg.data = (uintptr_t) event.eventdata;
-+
-+ /* And clear the event message in the target. */
-+ memset (&event, '\0', sizeof (td_eventbuf_t));
-+ if (ps_pdwrite (th->th_ta_p->ph,
-+ ((char *) th->th_unique
-+ + offsetof (struct _pthread_descr_struct, p_eventbuf)),
-+ &event, sizeof (td_eventbuf_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_get_info.c glibc-2.1.3/linuxthreads_db/td_thr_get_info.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_get_info.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_get_info.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,75 @@
-+/* Get thread information.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stddef.h>
-+#include <string.h>
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop)
-+{
-+ struct _pthread_descr_struct pds;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Get the thread descriptor. */
-+ if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
-+ th->th_ta_p->sizeof_descr) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Fill in information. Clear first to provide reproducable
-+ results for the fields we do not fill in. */
-+ memset (infop, '\0', sizeof (td_thrinfo_t));
-+
-+ /* We have to handle the manager thread special since the thread
-+ descriptor in older versions is not fully initialized. */
-+ if (pds.p_nr == 1)
-+ {
-+ infop->ti_tid = th->th_ta_p->pthread_threads_max * 2 + 1;
-+ infop->ti_type = TD_THR_SYSTEM;
-+ infop->ti_state = TD_THR_RUN;
-+ }
-+ else
-+ {
-+ infop->ti_tid = pds.p_tid;
-+ infop->ti_tls = (char *) pds.p_specific;
-+ infop->ti_pri = pds.p_priority;
-+ infop->ti_type = TD_THR_USER;
-+
-+ if (pds.p_exited)
-+ /* This should not happen. */
-+ infop->ti_state = TD_THR_ZOMBIE;
-+ else
-+ /* XXX For now there is no way to get more information. */
-+ infop->ti_state = TD_THR_RUN;
-+ }
-+
-+ /* Initialization which are the same in both cases. */
-+ infop->ti_lid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph);
-+ infop->ti_ta_p = th->th_ta_p;
-+ infop->ti_startfunc = pds.p_start_args.start_routine;
-+ memcpy (&infop->ti_events, &pds.p_eventbuf.eventmask,
-+ sizeof (td_thr_events_t));
-+ infop->ti_traceme = pds.p_report_events != 0;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_getfpregs.c glibc-2.1.3/linuxthreads_db/td_thr_getfpregs.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_getfpregs.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_getfpregs.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,44 @@
-+/* Get a thread's floating-point register set.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_getfpregs (const td_thrhandle_t *th, prfpregset_t *regset)
-+{
-+ struct _pthread_descr_struct pds;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* We have to get the state and the PID for this thread. */
-+ if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
-+ sizeof (struct _pthread_descr_struct)) != PS_OK)
-+ return TD_ERR;
-+
-+ /* If the thread already terminated we return all zeroes. */
-+ if (pds.p_terminated)
-+ memset (regset, '\0', sizeof (*regset));
-+ /* Otherwise get the register content through the callback. */
-+ else if (ps_lgetfpregs (th->th_ta_p->ph, pds.p_pid, regset) != PS_OK)
-+ return TD_ERR;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_getgregs.c glibc-2.1.3/linuxthreads_db/td_thr_getgregs.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_getgregs.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_getgregs.c 2000-01-20 18:16:37.000000000 -0800
-@@ -0,0 +1,44 @@
-+/* Get a thread's general register set.
-+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_getgregs (const td_thrhandle_t *th, prgregset_t gregs)
-+{
-+ struct _pthread_descr_struct pds;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* We have to get the state and the PID for this thread. */
-+ if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
-+ sizeof (struct _pthread_descr_struct)) != PS_OK)
-+ return TD_ERR;
-+
-+ /* If the thread already terminated we return all zeroes. */
-+ if (pds.p_terminated)
-+ memset (gregs, '\0', sizeof (prgregset_t));
-+ /* Otherwise get the register content through the callback. */
-+ else if (ps_lgetregs (th->th_ta_p->ph, pds.p_pid, gregs) != PS_OK)
-+ return TD_ERR;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_getxregs.c glibc-2.1.3/linuxthreads_db/td_thr_getxregs.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_getxregs.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_getxregs.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,30 @@
-+/* Get a thread's extra state register set.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_getxregs (const td_thrhandle_t *th, void *xregs)
-+{
-+ /* XXX This might be platform specific. */
-+ LOG (__FUNCTION__);
-+ return TD_NOXREGS;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_getxregsize.c glibc-2.1.3/linuxthreads_db/td_thr_getxregsize.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_getxregsize.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_getxregsize.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,30 @@
-+/* Get the size of the extra state register set for this architecture.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_getxregsize (const td_thrhandle_t *th, int *sizep)
-+{
-+ /* XXX This might be platform specific. */
-+ LOG (__FUNCTION__);
-+ return TD_NOXREGS;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_set_event.c glibc-2.1.3/linuxthreads_db/td_thr_set_event.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_set_event.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_set_event.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,57 @@
-+/* Enable specific event for thread.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stddef.h>
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_set_event (th, event)
-+ const td_thrhandle_t *th;
-+ td_thr_events_t *event;
-+{
-+ td_thr_events_t old_event;
-+ int i;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Write the new value into the thread data structure. */
-+ if (ps_pdread (th->th_ta_p->ph,
-+ ((char *) th->th_unique
-+ + offsetof (struct _pthread_descr_struct,
-+ p_eventbuf.eventmask)),
-+ &old_event, sizeof (td_thrhandle_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Or the new bits in. */
-+ for (i = 0; i < TD_EVENTSIZE; ++i)
-+ old_event.event_bits[i] |= event->event_bits[i];
-+
-+ /* Write the new value into the thread data structure. */
-+ if (ps_pdwrite (th->th_ta_p->ph,
-+ ((char *) th->th_unique
-+ + offsetof (struct _pthread_descr_struct,
-+ p_eventbuf.eventmask)),
-+ &old_event, sizeof (td_thrhandle_t)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_setfpregs.c glibc-2.1.3/linuxthreads_db/td_thr_setfpregs.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_setfpregs.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_setfpregs.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,42 @@
-+/* Set a thread's floating-point register set.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_setfpregs (const td_thrhandle_t *th, const prfpregset_t *fpregs)
-+{
-+ struct _pthread_descr_struct pds;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* We have to get the state and the PID for this thread. */
-+ if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
-+ sizeof (struct _pthread_descr_struct)) != PS_OK)
-+ return TD_ERR;
-+
-+ /* Only set the registers if the thread hasn't yet terminated. */
-+ if (pds.p_terminated == 0
-+ && ps_lsetfpregs (th->th_ta_p->ph, pds.p_pid, fpregs) != PS_OK)
-+ return TD_ERR;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_setgregs.c glibc-2.1.3/linuxthreads_db/td_thr_setgregs.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_setgregs.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_setgregs.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,42 @@
-+/* Set a thread's general register set.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_setgregs (const td_thrhandle_t *th, prgregset_t gregs)
-+{
-+ struct _pthread_descr_struct pds;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* We have to get the state and the PID for this thread. */
-+ if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
-+ sizeof (struct _pthread_descr_struct)) != PS_OK)
-+ return TD_ERR;
-+
-+ /* Only set the registers if the thread hasn't yet terminated. */
-+ if (pds.p_terminated == 0
-+ && ps_lsetregs (th->th_ta_p->ph, pds.p_pid, gregs) != PS_OK)
-+ return TD_ERR;
-+
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_setprio.c glibc-2.1.3/linuxthreads_db/td_thr_setprio.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_setprio.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_setprio.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,30 @@
-+/* Set a thread's priority.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_setprio (const td_thrhandle_t *th, int prio)
-+{
-+ /* XXX We have to figure out what has to be done. */
-+ LOG (__FUNCTION__);
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_setsigpending.c glibc-2.1.3/linuxthreads_db/td_thr_setsigpending.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_setsigpending.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_setsigpending.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,31 @@
-+/* Raise a signal for a thread.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_setsigpending (const td_thrhandle_t *th, unsigned char n,
-+ const sigset_t *ss)
-+{
-+ /* XXX We have to figure out what has to be done. */
-+ LOG (__FUNCTION__);
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_setxregs.c glibc-2.1.3/linuxthreads_db/td_thr_setxregs.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_setxregs.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_setxregs.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,30 @@
-+/* Set a thread's extra state register set.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_setxregs (const td_thrhandle_t *ta, const void *addr)
-+{
-+ /* XXX This might have to be platform specific. */
-+ LOG (__FUNCTION__);
-+ return TD_NOXREGS;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_sigsetmask.c glibc-2.1.3/linuxthreads_db/td_thr_sigsetmask.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_sigsetmask.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_sigsetmask.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,30 @@
-+/* Set a thread's signal mask.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_sigsetmask (const td_thrhandle_t *th, const sigset_t *ss)
-+{
-+ /* XXX We have to figure out what has to be done. */
-+ LOG (__FUNCTION__);
-+ return TD_OK;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_tsd.c glibc-2.1.3/linuxthreads_db/td_thr_tsd.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_tsd.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_tsd.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,76 @@
-+/* Get a thread-specific data pointer for a thread.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_tsd (const td_thrhandle_t *th, const thread_key_t tk, void **data)
-+{
-+ struct _pthread_descr_struct pds;
-+ struct pthread_key_struct *keys = th->th_ta_p->keys;
-+ struct pthread_key_struct key;
-+ int pthread_keys_max = th->th_ta_p->pthread_keys_max;
-+ int pthread_key_2ndlevel_size = th->th_ta_p->pthread_key_2ndlevel_size;
-+ unsigned int idx1st;
-+ unsigned int idx2nd;
-+ void *p;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Get the thread descriptor. */
-+ if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
-+ sizeof (struct _pthread_descr_struct)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Check correct value of key. */
-+ if (tk >= pthread_keys_max)
-+ return TD_BADKEY;
-+
-+ /* Get the key entry. */
-+ if (ps_pdread (th->th_ta_p->ph, keys, &key,
-+ sizeof (struct pthread_key_struct)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ /* Fail if this key is not at all used. */
-+ if (! key.in_use)
-+ return TD_BADKEY;
-+
-+ /* Compute the indeces. */
-+ idx1st = tk / pthread_key_2ndlevel_size;
-+ idx2nd = tk % pthread_key_2ndlevel_size;
-+
-+ /* Check the pointer to the second level array. */
-+ if (pds.p_specific[idx1st] == NULL)
-+ return TD_NOTSD;
-+
-+ /* Now get the real key.
-+ XXX I don't know whether it's correct but there is currently no
-+ easy way to determine whether a key was never set or the value
-+ is NULL. We return an error whenever the value is NULL. */
-+ if (ps_pdread (th->th_ta_p->ph, &pds.p_specific[idx1st][idx2nd], &p,
-+ sizeof (void *)) != PS_OK)
-+ return TD_ERR;
-+
-+ if (p != NULL)
-+ *data = p;
-+
-+ return p != NULL ? TD_OK : TD_NOTSD;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/td_thr_validate.c glibc-2.1.3/linuxthreads_db/td_thr_validate.c
---- ../glibc-2.1.3/linuxthreads_db/td_thr_validate.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/td_thr_validate.c 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,51 @@
-+/* Validate a thread handle.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include "thread_dbP.h"
-+
-+
-+td_err_e
-+td_thr_validate (const td_thrhandle_t *th)
-+{
-+ struct pthread_handle_struct *handles = th->th_ta_p->handles;
-+ int pthread_threads_max = th->th_ta_p->pthread_threads_max;
-+ int cnt;
-+
-+ LOG (__FUNCTION__);
-+
-+ /* Now get all descriptors, one after the other. */
-+ for (cnt = 0; cnt < pthread_threads_max; ++cnt, ++handles)
-+ {
-+ struct pthread_handle_struct phc;
-+
-+ if (ps_pdread (th->th_ta_p->ph, handles, &phc,
-+ sizeof (struct pthread_handle_struct)) != PS_OK)
-+ return TD_ERR; /* XXX Other error value? */
-+
-+ if (phc.h_descr != NULL && phc.h_descr == th->th_unique)
-+ {
-+ /* XXX There should be another test using the TID but this is
-+ currently not available. */
-+ return TD_OK;
-+ }
-+ }
-+
-+ return TD_ERR;
-+}
-diff -Naur ../glibc-2.1.3/linuxthreads_db/thread_db.h glibc-2.1.3/linuxthreads_db/thread_db.h
---- ../glibc-2.1.3/linuxthreads_db/thread_db.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/thread_db.h 1999-11-09 21:05:07.000000000 -0800
-@@ -0,0 +1,436 @@
-+/* Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef _THREAD_DB_H
-+#define _THREAD_DB_H 1
-+
-+/* This is the debugger interface for the LinuxThreads library. It is
-+ modelled closely after the interface with same names in Solaris with
-+ the goal to share the same code in the debugger. */
-+#include <pthread.h>
-+#include <stdint.h>
-+#include <sys/types.h>
-+#include <sys/procfs.h>
-+
-+
-+/* Error codes of the library. */
-+typedef enum
-+{
-+ TD_OK, /* No error. */
-+ TD_ERR, /* No further specified error. */
-+ TD_NOTHR, /* No matching thread found. */
-+ TD_NOSV, /* No matching synchronization handle found. */
-+ TD_NOLWP, /* No matching light-weighted process found. */
-+ TD_BADPH, /* Invalid process handle. */
-+ TD_BADTH, /* Invalid thread handle. */
-+ TD_BADSH, /* Invalid synchronization handle. */
-+ TD_BADTA, /* Invalid thread agent. */
-+ TD_BADKEY, /* Invalid key. */
-+ TD_NOMSG, /* No event available. */
-+ TD_NOFPREGS, /* No floating-point register content available. */
-+ TD_NOLIBTHREAD, /* Application not linked with thread library. */
-+ TD_NOEVENT, /* Requested event is not supported. */
-+ TD_NOCAPAB, /* Capability not available. */
-+ TD_DBERR, /* Internal debug library error. */
-+ TD_NOAPLIC, /* Operation is not applicable. */
-+ TD_NOTSD, /* No thread-specific data available. */
-+ TD_MALLOC, /* Out of memory. */
-+ TD_PARTIALREG, /* Not entire register set was read or written. */
-+ TD_NOXREGS /* X register set not available for given thread. */
-+} td_err_e;
-+
-+
-+/* Possible thread states. TD_THR_ANY_STATE is a pseudo-state used to
-+ select threads regardless of state in td_ta_thr_iter(). */
-+typedef enum
-+{
-+ TD_THR_ANY_STATE,
-+ TD_THR_UNKNOWN,
-+ TD_THR_STOPPED,
-+ TD_THR_RUN,
-+ TD_THR_ACTIVE,
-+ TD_THR_ZOMBIE,
-+ TD_THR_SLEEP,
-+ TD_THR_STOPPED_ASLEEP
-+} td_thr_state_e;
-+
-+/* Thread type: user or system. TD_THR_ANY_TYPE is a pseudo-type used
-+ to select threads regardless of type in td_ta_thr_iter(). */
-+typedef enum
-+{
-+ TD_THR_ANY_TYPE,
-+ TD_THR_USER,
-+ TD_THR_SYSTEM
-+} td_thr_type_e;
-+
-+
-+/* Types of the debugging library. */
-+
-+/* Handle for a process. This type is opaque. */
-+typedef struct td_thragent td_thragent_t;
-+
-+/* The actual thread handle type. This is also opaque. */
-+typedef struct td_thrhandle
-+{
-+ td_thragent_t *th_ta_p;
-+ psaddr_t th_unique;
-+} td_thrhandle_t;
-+
-+
-+/* Flags for `td_ta_thr_iter'. */
-+#define TD_THR_ANY_USER_FLAGS 0xffffffff
-+#define TD_THR_LOWEST_PRIORITY -20
-+#define TD_SIGNO_MASK NULL
-+
-+
-+#define TD_EVENTSIZE 2
-+#define BT_UISHIFT 5 /* log base 2 of BT_NBIPUI, to extract word index */
-+#define BT_NBIPUI (1 << BT_UISHIFT) /* n bits per uint */
-+#define BT_UIMASK (BT_NBIPUI - 1) /* to extract bit index */
-+
-+/* Bitmask of enabled events. */
-+typedef struct td_thr_events
-+{
-+ uint32_t event_bits[TD_EVENTSIZE];
-+} td_thr_events_t;
-+
-+/* Event set manipulation macros. */
-+#define __td_eventmask(n) \
-+ (UINT32_C (1) << (((n) - 1) & BT_UIMASK))
-+#define __td_eventword(n) \
-+ ((UINT32_C ((n) - 1)) >> BT_UISHIFT)
-+
-+#define td_event_emptyset(setp) \
-+ do { \
-+ int __i; \
-+ for (__i = TD_EVENTSIZE; __i > 0; --__i) \
-+ (setp)->event_bits[__i - 1] = 0; \
-+ } while (0)
-+
-+#define td_event_fillset(setp) \
-+ do { \
-+ int __i; \
-+ for (__i = TD_EVENTSIZE; __i > 0; --__i) \
-+ (setp)->event_bits[__i - 1] = UINT32_C (0xffffffff); \
-+ } while (0)
-+
-+#define td_event_addset(setp, n) \
-+ (((setp)->event_bits[__td_eventword (n)]) |= __td_eventmask (n))
-+#define td_event_delset(setp, n) \
-+ (((setp)->event_bits[__td_eventword (n)]) &= ~__td_eventmask (n))
-+#define td_eventismember(setp, n) \
-+ (__td_eventmask (n) & ((setp)->event_bits[__td_eventword (n)]))
-+#if TD_EVENTSIZE == 2
-+# define td_eventisempty(setp) \
-+ (!((setp)->event_bits[0]) && !((setp)->event_bits[1]))
-+#else
-+# error "td_eventisempty must be changed to match TD_EVENTSIZE"
-+#endif
-+
-+/* Events reportable by the thread implementation. */
-+typedef enum
-+{
-+ TD_ALL_EVENTS, /* Pseudo-event number. */
-+ TD_EVENT_NONE = TD_ALL_EVENTS, /* Depends on context. */
-+ TD_READY, /* Is executable now. */
-+ TD_SLEEP, /* Blocked in a synchronization obj. */
-+ TD_SWITCHTO, /* Now assigned to a process. */
-+ TD_SWITCHFROM, /* Not anymore assigned to a process. */
-+ TD_LOCK_TRY, /* Trying to get an unavailable lock. */
-+ TD_CATCHSIG, /* Signal posted to the thread. */
-+ TD_IDLE, /* Process getting idle. */
-+ TD_CREATE, /* New thread created. */
-+ TD_DEATH, /* Thread terminated. */
-+ TD_PREEMPT, /* Preempted. */
-+ TD_PRI_INHERIT, /* Inherited elevated priority. */
-+ TD_REAP, /* Reaped. */
-+ TD_CONCURRENCY, /* Number of processes changing. */
-+ TD_TIMEOUT, /* Conditional variable wait timed out. */
-+ TD_MIN_EVENT_NUM = TD_READY,
-+ TD_MAX_EVENT_NUM = TD_TIMEOUT,
-+ TD_EVENTS_ENABLE = 31 /* Event reporting enabled. */
-+} td_event_e;
-+
-+/* Values representing the different ways events are reported. */
-+typedef enum
-+{
-+ NOTIFY_BPT, /* User must insert breakpoint at u.bptaddr. */
-+ NOTIFY_AUTOBPT, /* Breakpoint at u.bptaddr is automatically
-+ inserted. */
-+ NOTIFY_SYSCALL /* System call u.syscallno will be invoked. */
-+} td_notify_e;
-+
-+/* Description how event type is reported. */
-+typedef struct td_notify
-+{
-+ td_notify_e type; /* Way the event is reported. */
-+ union
-+ {
-+ psaddr_t bptaddr; /* Address of breakpoint. */
-+ int syscallno; /* Number of system call used. */
-+ } u;
-+} td_notify_t;
-+
-+/* Structure used to report event. */
-+typedef struct td_event_msg
-+{
-+ td_event_e event; /* Event type being reported. */
-+ const td_thrhandle_t *th_p; /* Thread reporting the event. */
-+ union
-+ {
-+# if 0
-+ td_synchandle_t *sh; /* Handle of synchronization object. */
-+#endif
-+ uintptr_t data; /* Event specific data. */
-+ } msg;
-+} td_event_msg_t;
-+
-+/* Structure containing event data available in each thread structure. */
-+typedef struct
-+{
-+ td_thr_events_t eventmask; /* Mask of enabled events. */
-+ td_event_e eventnum; /* Number of last event. */
-+ void *eventdata; /* Data associated with event. */
-+} td_eventbuf_t;
-+
-+
-+/* Gathered statistics about the process. */
-+typedef struct td_ta_stats
-+{
-+ int nthreads; /* Total number of threads in use. */
-+ int r_concurrency; /* Concurrency level requested by user. */
-+ int nrunnable_num; /* Average runnable threads, numerator. */
-+ int nrunnable_den; /* Average runnable threads, denominator. */
-+ int a_concurrency_num; /* Achieved concurrency level, numerator. */
-+ int a_concurrency_den; /* Achieved concurrency level, denominator. */
-+ int nlwps_num; /* Average number of processes in use,
-+ numerator. */
-+ int nlwps_den; /* Average number of processes in use,
-+ denominator. */
-+ int nidle_num; /* Average number of idling processes,
-+ numerator. */
-+ int nidle_den; /* Average number of idling processes,
-+ denominator. */
-+} td_ta_stats_t;
-+
-+
-+/* Since Sun's library is based on Solaris threads we have to define a few
-+ types to map them to POSIX threads. */
-+typedef pthread_t thread_t;
-+typedef pthread_key_t thread_key_t;
-+
-+
-+/* Callback for iteration over threads. */
-+typedef int td_thr_iter_f (const td_thrhandle_t *, void *);
-+
-+/* Callback for iteration over thread local data. */
-+typedef int td_key_iter_f (thread_key_t, void (*) (void *), void *);
-+
-+
-+
-+/* Forward declaration. This has to be defined by the user. */
-+struct ps_prochandle;
-+
-+
-+/* Information about the thread. */
-+typedef struct td_thrinfo
-+{
-+ td_thragent_t *ti_ta_p; /* Process handle. */
-+ unsigned int ti_user_flags; /* Unused. */
-+ thread_t ti_tid; /* Thread ID returned by
-+ pthread_create(). */
-+ char *ti_tls; /* Pointer to thread-local data. */
-+ psaddr_t ti_startfunc; /* Start function passed to
-+ pthread_create(). */
-+ psaddr_t ti_stkbase; /* Base of thread's stack. */
-+ long int ti_stksize; /* Size of thread's stack. */
-+ psaddr_t ti_ro_area; /* Unused. */
-+ int ti_ro_size; /* Unused. */
-+ td_thr_state_e ti_state; /* Thread state. */
-+ unsigned char ti_db_suspended; /* Nonzero if suspended by debugger. */
-+ td_thr_type_e ti_type; /* Type of the thread (system vs
-+ user thread). */
-+ intptr_t ti_pc; /* Unused. */
-+ intptr_t ti_sp; /* Unused. */
-+ short int ti_flags; /* Unused. */
-+ int ti_pri; /* Thread priority. */
-+ lwpid_t ti_lid; /* Unused. */
-+ sigset_t ti_sigmask; /* Signal mask. */
-+ unsigned char ti_traceme; /* Nonzero if event reporting
-+ enabled. */
-+ unsigned char ti_preemptflag; /* Unused. */
-+ unsigned char ti_pirecflag; /* Unused. */
-+ sigset_t ti_pending; /* Set of pending signals. */
-+ td_thr_events_t ti_events; /* Set of enabled events. */
-+} td_thrinfo_t;
-+
-+
-+
-+/* Prototypes for exported library functions. */
-+
-+/* Initialize the thread debug support library. */
-+extern td_err_e td_init (void);
-+
-+/* Historical relict. Should not be used anymore. */
-+extern td_err_e td_log (void);
-+
-+/* Generate new thread debug library handle for process PS. */
-+extern td_err_e td_ta_new (struct ps_prochandle *__ps, td_thragent_t **__ta);
-+
-+/* Free resources allocated for TA. */
-+extern td_err_e td_ta_delete (td_thragent_t *__ta);
-+
-+/* Get number of currently running threads in process associated with TA. */
-+extern td_err_e td_ta_get_nthreads (const td_thragent_t *__ta, int *__np);
-+
-+/* Return process handle passed in `td_ta_new' for process associated with
-+ TA. */
-+extern td_err_e td_ta_get_ph (const td_thragent_t *__ta,
-+ struct ps_prochandle **__ph);
-+
-+/* Map thread library handle PT to thread debug library handle for process
-+ associated with TA and store result in *TH. */
-+extern td_err_e td_ta_map_id2thr (const td_thragent_t *__ta, pthread_t __pt,
-+ td_thrhandle_t *__th);
-+
-+/* Map process ID LWPID to thread debug library handle for process
-+ associated with TA and store result in *TH. */
-+extern td_err_e td_ta_map_lwp2thr (const td_thragent_t *__ta, lwpid_t __lwpid,
-+ td_thrhandle_t *__th);
-+
-+
-+/* Call for each thread in a process associated with TA the callback function
-+ CALLBACK. */
-+extern td_err_e td_ta_thr_iter (const td_thragent_t *__ta,
-+ td_thr_iter_f *__callback, void *__cbdata_p,
-+ td_thr_state_e __state, int __ti_pri,
-+ sigset_t *__ti_sigmask_p,
-+ unsigned int __ti_user_flags);
-+
-+/* Call for each defined thread local data entry the callback function KI. */
-+extern td_err_e td_ta_tsd_iter (const td_thragent_t *__ta, td_key_iter_f *__ki,
-+ void *__p);
-+
-+
-+/* Get event address for EVENT. */
-+extern td_err_e td_ta_event_addr (const td_thragent_t *__ta,
-+ td_event_e __event, td_notify_t *__ptr);
-+
-+/* Enable EVENT in global mask. */
-+extern td_err_e td_ta_set_event (const td_thragent_t *__ta,
-+ td_thr_events_t *__event);
-+
-+/* Disable EVENT in global mask. */
-+extern td_err_e td_ta_clear_event (const td_thragent_t *__ta,
-+ td_thr_events_t *__event);
-+
-+/* Return information about last event. */
-+extern td_err_e td_ta_event_getmsg (const td_thragent_t *__ta,
-+ td_event_msg_t *msg);
-+
-+
-+/* Set suggested concurrency level for process associated with TA. */
-+extern td_err_e td_ta_setconcurrency (const td_thragent_t *__ta, int __level);
-+
-+
-+/* Enable collecting statistics for process associated with TA. */
-+extern td_err_e td_ta_enable_stats (const td_thragent_t *__ta, int __enable);
-+
-+/* Reset statistics. */
-+extern td_err_e td_ta_reset_stats (const td_thragent_t *__ta);
-+
-+/* Retrieve statistics from process associated with TA. */
-+extern td_err_e td_ta_get_stats (const td_thragent_t *__ta,
-+ td_ta_stats_t *__statsp);
-+
-+
-+/* Validate that TH is a thread handle. */
-+extern td_err_e td_thr_validate (const td_thrhandle_t *__th);
-+
-+/* Return information about thread TH. */
-+extern td_err_e td_thr_get_info (const td_thrhandle_t *__th,
-+ td_thrinfo_t *__infop);
-+
-+/* Retrieve floating-point register contents of process running thread TH. */
-+extern td_err_e td_thr_getfpregs (const td_thrhandle_t *__th,
-+ prfpregset_t *__regset);
-+
-+/* Retrieve general register contents of process running thread TH. */
-+extern td_err_e td_thr_getgregs (const td_thrhandle_t *__th,
-+ prgregset_t __gregs);
-+
-+/* Retrieve extended register contents of process running thread TH. */
-+extern td_err_e td_thr_getxregs (const td_thrhandle_t *__th, void *__xregs);
-+
-+/* Get size of extended register set of process running thread TH. */
-+extern td_err_e td_thr_getxregsize (const td_thrhandle_t *__th, int *__sizep);
-+
-+/* Set floating-point register contents of process running thread TH. */
-+extern td_err_e td_thr_setfpregs (const td_thrhandle_t *__th,
-+ const prfpregset_t *__fpregs);
-+
-+/* Set general register contents of process running thread TH. */
-+extern td_err_e td_thr_setgregs (const td_thrhandle_t *__th,
-+ prgregset_t __gregs);
-+
-+/* Set extended register contents of process running thread TH. */
-+extern td_err_e td_thr_setxregs (const td_thrhandle_t *__th,
-+ const void *__addr);
-+
-+
-+/* Enable reporting for EVENT for thread TH. */
-+extern td_err_e td_thr_event_enable (const td_thrhandle_t *__th, int __event);
-+
-+/* Enable EVENT for thread TH. */
-+extern td_err_e td_thr_set_event (const td_thrhandle_t *__th,
-+ td_thr_events_t *__event);
-+
-+/* Disable EVENT for thread TH. */
-+extern td_err_e td_thr_clear_event (const td_thrhandle_t *__th,
-+ td_thr_events_t *__event);
-+
-+/* Get event message for thread TH. */
-+extern td_err_e td_thr_event_getmsg (const td_thrhandle_t *__th,
-+ td_event_msg_t *__msg);
-+
-+
-+/* Set priority of thread TH. */
-+extern td_err_e td_thr_setprio (const td_thrhandle_t *__th, int __prio);
-+
-+
-+/* Set pending signals for thread TH. */
-+extern td_err_e td_thr_setsigpending (const td_thrhandle_t *__th,
-+ unsigned char __n, const sigset_t *__ss);
-+
-+/* Set signal mask for thread TH. */
-+extern td_err_e td_thr_sigsetmask (const td_thrhandle_t *__th,
-+ const sigset_t *__ss);
-+
-+
-+/* Return thread local data associated with key TK in thread TH. */
-+extern td_err_e td_thr_tsd (const td_thrhandle_t *__th,
-+ const thread_key_t __tk, void **__data);
-+
-+
-+/* Suspend execution of thread TH. */
-+extern td_err_e td_thr_dbsuspend (const td_thrhandle_t *__th);
-+
-+/* Resume execution of thread TH. */
-+extern td_err_e td_thr_dbresume (const td_thrhandle_t *__th);
-+
-+#endif /* thread_db.h */
-diff -Naur ../glibc-2.1.3/linuxthreads_db/thread_dbP.h glibc-2.1.3/linuxthreads_db/thread_dbP.h
---- ../glibc-2.1.3/linuxthreads_db/thread_dbP.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/linuxthreads_db/thread_dbP.h 1999-11-22 12:50:45.000000000 -0800
-@@ -0,0 +1,83 @@
-+/* Private header for thread debug library. */
-+#ifndef _THREAD_DBP_H
-+#define _THREAD_DBP_H 1
-+
-+#include <string.h>
-+#include "proc_service.h"
-+#include "thread_db.h"
-+#include "../linuxthreads/internals.h"
-+
-+
-+/* Comment out the following for less verbose output. */
-+#ifndef NDEBUG
-+# define LOG(c) if (__td_debug) __libc_write (2, c "\n", strlen (c "\n"))
-+extern int __td_debug;
-+#else
-+# define LOG(c)
-+#endif
-+
-+
-+/* Handle for a process. This type is opaque. */
-+struct td_thragent
-+{
-+ /* Delivered by the debugger and we have to pass it back in the
-+ proc callbacks. */
-+ struct ps_prochandle *ph;
-+
-+ /* Some cached information. */
-+
-+ /* Address of the `__pthread_handles' array. */
-+ struct pthread_handle_struct *handles;
-+
-+ /* Address of the `pthread_kyes' array. */
-+ struct pthread_key_struct *keys;
-+
-+ /* Maximum number of threads. */
-+ int pthread_threads_max;
-+
-+ /* Maximum number of thread-local data keys. */
-+ int pthread_keys_max;
-+
-+ /* Size of 2nd level array for thread-local data keys. */
-+ int pthread_key_2ndlevel_size;
-+
-+ /* Sizeof struct _pthread_descr_struct. */
-+ int sizeof_descr;
-+
-+ /* Pointer to the `__pthread_threads_events' variable in the target. */
-+ psaddr_t pthread_threads_eventsp;
-+
-+ /* Pointer to the `__pthread_last_event' variable in the target. */
-+ psaddr_t pthread_last_event;
-+
-+ /* Pointer to the `__pthread_handles_num' variable. */
-+ psaddr_t pthread_handles_num;
-+};
-+
-+
-+/* Type used internally to keep track of thread agent descriptors. */
-+struct agent_list
-+{
-+ td_thragent_t *ta;
-+ struct agent_list *next;
-+};
-+
-+/* List of all known descriptors. */
-+extern struct agent_list *__td_agent_list;
-+
-+/* Function used to test for correct thread agent pointer. */
-+static inline int
-+ta_ok (const td_thragent_t *ta)
-+{
-+ struct agent_list *runp = __td_agent_list;
-+
-+ if (ta == NULL)
-+ return 0;
-+
-+ while (runp != NULL && runp->ta != ta)
-+ runp = runp->next;
-+
-+ return runp != NULL;
-+}
-+
-+#endif /* thread_dbP.h */
-diff -Naur ../glibc-2.1.3/locale/C-ctype.c glibc-2.1.3/locale/C-ctype.c
---- ../glibc-2.1.3/locale/C-ctype.c 2000-02-24 14:48:02.000000000 -0800
-+++ glibc-2.1.3/locale/C-ctype.c 2000-02-25 15:43:32.000000000 -0800
-@@ -376,7 +376,7 @@
- { string: NULL },
- { string: (const char *) (_nl_C_LC_CTYPE_tolower + 128) }
- #if BYTE_ORDER == BIG_ENDIAN
-- { string: NULL },
-+ , { string: NULL }
- #endif
- }
- };
-diff -Naur ../glibc-2.1.3/locale/programs/ld-ctype.c glibc-2.1.3/locale/programs/ld-ctype.c
---- ../glibc-2.1.3/locale/programs/ld-ctype.c 2000-02-24 11:19:02.000000000 -0800
-+++ glibc-2.1.3/locale/programs/ld-ctype.c 2000-02-24 11:32:16.000000000 -0800
-@@ -493,12 +493,19 @@
- if (elem < _NL_ITEM_INDEX (_NL_NUM_LC_CTYPE))
- switch (elem)
- {
--#define CTYPE_DATA(name, base, len) \
-- case _NL_ITEM_INDEX (name): \
-- iov[2 + elem + offset].iov_base = (base); \
-- iov[2 + elem + offset].iov_len = (len); \
-- if (elem + 1 < nelems) \
-- idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; \
-+#define CTYPE_DATA(name, base, len) \
-+ case _NL_ITEM_INDEX (name): \
-+ if ( (len) % 4 == 0) { \
-+ iov[2 + elem + offset].iov_base = (base); \
-+ iov[2 + elem + offset].iov_len = (len); \
-+ } else { \
-+ iov[2 + elem + offset].iov_base = alloca (((len) + 3) & ~3); \
-+ memset (mempcpy (iov[2 + elem + offset].iov_base, (base), (len)), \
-+ '\0', 4 - ((len) & 3)); \
-+ iov[2 + elem + offset].iov_len = ((len) + 3) & ~3; \
-+ } \
-+ if (elem + 1 < nelems) \
-+ idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; \
- break
-
- CTYPE_DATA (_NL_CTYPE_CLASS,
-diff -Naur ../glibc-2.1.3/localedata/Makefile glibc-2.1.3/localedata/Makefile
---- ../glibc-2.1.3/localedata/Makefile 1999-06-18 19:05:36.000000000 -0700
-+++ glibc-2.1.3/localedata/Makefile 2000-02-23 17:10:51.000000000 -0800
-@@ -90,6 +90,7 @@
- install-locales:
- while read locale charset; do \
- case $$locale in \#*) continue;; esac; \
-+ set -x ; \
- $(LOCALEDEF) -i locales/`echo $$locale | sed 's/\([^.]*\).*/\1/'` \
- -c -f charmaps/$$charset \
- -u repertoiremaps/mnemonic.ds \
-diff -Naur ../glibc-2.1.3/mach/err_boot.sub glibc-2.1.3/mach/err_boot.sub
---- ../glibc-2.1.3/mach/err_boot.sub 1992-10-06 11:29:52.000000000 -0700
-+++ glibc-2.1.3/mach/err_boot.sub 1998-02-07 12:15:20.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: err_boot.sub,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:20 gafton
-+ * import from sourceware
-+ *
- * Revision 1.1 1992/10/06 18:29:52 roland
- * entered into RCS
- *
-diff -Naur ../glibc-2.1.3/mach/err_ipc.sub glibc-2.1.3/mach/err_ipc.sub
---- ../glibc-2.1.3/mach/err_ipc.sub 1992-10-06 11:29:52.000000000 -0700
-+++ glibc-2.1.3/mach/err_ipc.sub 1998-02-07 12:15:20.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: err_ipc.sub,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:20 gafton
-+ * import from sourceware
-+ *
- * Revision 1.1 1992/10/06 18:29:52 roland
- * entered into RCS
- *
-diff -Naur ../glibc-2.1.3/mach/err_kern.sub glibc-2.1.3/mach/err_kern.sub
---- ../glibc-2.1.3/mach/err_kern.sub 1996-12-19 17:32:34.000000000 -0800
-+++ glibc-2.1.3/mach/err_kern.sub 1998-02-07 12:15:21.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: err_kern.sub,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:21 gafton
-+ * import from sourceware
-+ *
- * Revision 1.5 1996/12/20 01:32:34 drepper
- * Update from main archive 961219
- *
-diff -Naur ../glibc-2.1.3/mach/err_mach.sub glibc-2.1.3/mach/err_mach.sub
---- ../glibc-2.1.3/mach/err_mach.sub 1992-10-06 11:29:52.000000000 -0700
-+++ glibc-2.1.3/mach/err_mach.sub 1998-02-07 12:15:21.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: err_mach.sub,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:21 gafton
-+ * import from sourceware
-+ *
- * Revision 1.1 1992/10/06 18:29:52 roland
- * entered into RCS
- *
-diff -Naur ../glibc-2.1.3/mach/err_server.sub glibc-2.1.3/mach/err_server.sub
---- ../glibc-2.1.3/mach/err_server.sub 1992-10-06 11:29:53.000000000 -0700
-+++ glibc-2.1.3/mach/err_server.sub 1998-02-07 12:15:22.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: err_server.sub,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:22 gafton
-+ * import from sourceware
-+ *
- * Revision 1.1 1992/10/06 18:29:53 roland
- * entered into RCS
- *
-diff -Naur ../glibc-2.1.3/mach/err_us.sub glibc-2.1.3/mach/err_us.sub
---- ../glibc-2.1.3/mach/err_us.sub 1993-11-23 13:14:05.000000000 -0800
-+++ glibc-2.1.3/mach/err_us.sub 1998-02-07 12:15:22.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: err_us.sub,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:22 gafton
-+ * import from sourceware
-+ *
- * Revision 1.2 1993/11/23 21:14:05 mib
- * entered into RCS
- *
-diff -Naur ../glibc-2.1.3/mach/error_compat.c glibc-2.1.3/mach/error_compat.c
---- ../glibc-2.1.3/mach/error_compat.c 1997-03-16 09:41:36.000000000 -0800
-+++ glibc-2.1.3/mach/error_compat.c 1998-02-07 12:15:22.000000000 -0800
-@@ -26,6 +26,9 @@
-
- /* This file was broken out from:
- $Log: error_compat.c,v $
-+ Revision 1.1.1.1 1998/02/07 20:15:22 gafton
-+ import from sourceware
-+
- Revision 1.2 1997/03/16 17:41:36 drepper
- (__mach_error_map_compat): Give full prototype.
-
-diff -Naur ../glibc-2.1.3/mach/errorlib.h glibc-2.1.3/mach/errorlib.h
---- ../glibc-2.1.3/mach/errorlib.h 1995-03-10 15:57:44.000000000 -0800
-+++ glibc-2.1.3/mach/errorlib.h 1998-02-07 12:15:23.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: errorlib.h,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:23 gafton
-+ * import from sourceware
-+ *
- * Revision 1.5 1995/03/10 23:57:44 roland
- * (errors): Use const for decl.
- *
-diff -Naur ../glibc-2.1.3/mach/errstring.c glibc-2.1.3/mach/errstring.c
---- ../glibc-2.1.3/mach/errstring.c 1997-03-16 09:41:48.000000000 -0800
-+++ glibc-2.1.3/mach/errstring.c 1998-02-07 12:15:23.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: errstring.c,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:23 gafton
-+ * import from sourceware
-+ *
- * Revision 1.2 1997/03/16 17:41:48 drepper
- * (mach_error_string_int): Give full prototype.
- *
-diff -Naur ../glibc-2.1.3/mach/mach/error.h glibc-2.1.3/mach/mach/error.h
---- ../glibc-2.1.3/mach/mach/error.h 1997-03-16 09:43:08.000000000 -0800
-+++ glibc-2.1.3/mach/mach/error.h 1998-02-07 12:15:28.000000000 -0800
-@@ -27,6 +27,9 @@
- /*
- * HISTORY
- * $Log: error.h,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:28 gafton
-+ * import from sourceware
-+ *
- * Revision 1.3 1997/03/16 17:43:08 drepper
- * (mach_error_fn_t): Comment out declaration; it appears to be entirely
- * unused dead code.
-diff -Naur ../glibc-2.1.3/mach/mach_error.c glibc-2.1.3/mach/mach_error.c
---- ../glibc-2.1.3/mach/mach_error.c 1997-03-16 09:42:02.000000000 -0800
-+++ glibc-2.1.3/mach/mach_error.c 1998-02-07 12:15:25.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: mach_error.c,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:25 gafton
-+ * import from sourceware
-+ *
- * Revision 1.2 1997/03/16 17:42:02 drepper
- * (mach_error_string_int): Give full prototype.
- *
-diff -Naur ../glibc-2.1.3/mach/mach_error.h glibc-2.1.3/mach/mach_error.h
---- ../glibc-2.1.3/mach/mach_error.h 1997-03-16 09:42:25.000000000 -0800
-+++ glibc-2.1.3/mach/mach_error.h 1998-02-07 12:15:25.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: mach_error.h,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:25 gafton
-+ * import from sourceware
-+ *
- * Revision 1.3 1997/03/16 17:42:25 drepper
- * (mach_error_string, mach_error, mach_error_type): Always provide
- * prototypes.
-diff -Naur ../glibc-2.1.3/mach/msg-destroy.c glibc-2.1.3/mach/msg-destroy.c
---- ../glibc-2.1.3/mach/msg-destroy.c 1997-06-20 18:40:07.000000000 -0700
-+++ glibc-2.1.3/mach/msg-destroy.c 1998-02-07 12:15:26.000000000 -0800
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: msg-destroy.c,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:26 gafton
-+ * import from sourceware
-+ *
- * Revision 1.5 1997/06/21 01:40:07 drepper
- * More 64bit changes.
- *
-diff -Naur ../glibc-2.1.3/mach/msgserver.c glibc-2.1.3/mach/msgserver.c
---- ../glibc-2.1.3/mach/msgserver.c 1996-12-19 17:32:35.000000000 -0800
-+++ glibc-2.1.3/mach/msgserver.c 1998-02-07 12:15:26.000000000 -0800
-@@ -49,6 +49,9 @@
- /*
- * HISTORY
- * $Log: msgserver.c,v $
-+ * Revision 1.1.1.1 1998/02/07 20:15:26 gafton
-+ * import from sourceware
-+ *
- * Revision 1.5 1996/12/20 01:32:35 drepper
- * Update from main archive 961219
- *
-diff -Naur ../glibc-2.1.3/malloc/malloc.c glibc-2.1.3/malloc/malloc.c
---- ../glibc-2.1.3/malloc/malloc.c 2000-02-22 23:02:55.000000000 -0800
-+++ glibc-2.1.3/malloc/malloc.c 2000-02-21 21:29:32.000000000 -0800
-@@ -19,7 +19,7 @@
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
--/* $Id: malloc.c,v 1.40.2.9 2000/02/22 04:48:48 drepper Exp $
-+/* $Id: malloc.c,v 1.1.1.2 2000/02/22 05:29:32 gafton Exp $
-
- This work is mainly derived from malloc-2.6.4 by Doug Lea
- <dl@cs.oswego.edu>, which is available from:
-diff -Naur ../glibc-2.1.3/malloc/thread-m.h glibc-2.1.3/malloc/thread-m.h
---- ../glibc-2.1.3/malloc/thread-m.h 1999-12-10 10:28:54.000000000 -0800
-+++ glibc-2.1.3/malloc/thread-m.h 1999-12-20 11:55:50.000000000 -0800
-@@ -19,7 +19,7 @@
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
--/* $Id: thread-m.h,v 1.10.2.1 1999/12/10 05:29:37 drepper Exp $
-+/* $Id: thread-m.h,v 1.1.1.1 1999/12/20 19:55:50 gafton Exp $
- One out of _LIBC, USE_PTHREADS, USE_THR or USE_SPROC should be
- defined, otherwise the token NO_THREADS and dummy implementations
- of the macros will be defined. */
-diff -Naur ../glibc-2.1.3/manual/.cvsignore glibc-2.1.3/manual/.cvsignore
---- ../glibc-2.1.3/manual/.cvsignore 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/manual/.cvsignore 2000-02-18 16:05:53.000000000 -0800
-@@ -0,0 +1,9 @@
-+libc.info-*
-+*.c.*
-+dir-add.info
-+top-menu.texi
-+chapters.texi
-+libc.info
-+summary.texi
-+stamp-summary
-+texis
-diff -Naur ../glibc-2.1.3/manual/add.c.texi glibc-2.1.3/manual/add.c.texi
---- ../glibc-2.1.3/manual/add.c.texi 1999-07-18 18:01:09.000000000 -0700
-+++ glibc-2.1.3/manual/add.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,30 +0,0 @@
--#include <stdarg.h>
--#include <stdio.h>
--
--int
--add_em_up (int count,...)
--@{
-- va_list ap;
-- int i, sum;
--
-- va_start (ap, count); /* @r{Initialize the argument list.} */
--
-- sum = 0;
-- for (i = 0; i < count; i++)
-- sum += va_arg (ap, int); /* @r{Get the next argument value.} */
--
-- va_end (ap); /* @r{Clean up.} */
-- return sum;
--@}
--
--int
--main (void)
--@{
-- /* @r{This call prints 16.} */
-- printf ("%d\n", add_em_up (3, 5, 5, 6));
--
-- /* @r{This call prints 55.} */
-- printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
--
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/argp-ex1.c.texi glibc-2.1.3/manual/argp-ex1.c.texi
---- ../glibc-2.1.3/manual/argp-ex1.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/argp-ex1.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,14 +0,0 @@
--/* @r{Argp example #1 -- a minimal program using argp} */
--
--/* @r{This is (probably) the smallest possible program that
-- uses argp. It won't do much except give an error
-- messages and exit when there are any arguments, and print
-- a (rather pointless) messages for --help.} */
--
--#include <argp.h>
--
--int main (int argc, char **argv)
--@{
-- argp_parse (0, argc, argv, 0, 0, 0);
-- exit (0);
--@}
-diff -Naur ../glibc-2.1.3/manual/argp-ex2.c.texi glibc-2.1.3/manual/argp-ex2.c.texi
---- ../glibc-2.1.3/manual/argp-ex2.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/argp-ex2.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,44 +0,0 @@
--/* @r{Argp example #2 -- a pretty minimal program using argp} */
--
--/* @r{This program doesn't use any options or arguments, but uses
-- argp to be compliant with the GNU standard command line
-- format.
--
-- In addition to making sure no arguments are given, and
-- implementing a --help option, this example will have a
-- --version option, and will put the given documentation string
-- and bug address in the --help output, as per GNU standards.
--
-- The variable ARGP contains the argument parser specification;
-- adding fields to this structure is the way most parameters are
-- passed to argp_parse (the first three fields are usually used,
-- but not in this small program). There are also two global
-- variables that argp knows about defined here,
-- ARGP_PROGRAM_VERSION and ARGP_PROGRAM_BUG_ADDRESS (they are
-- global variables becuase they will almost always be constant
-- for a given program, even if it uses different argument
-- parsers for various tasks).} */
--
--#include <argp.h>
--
--const char *argp_program_version =
-- "argp-ex2 1.0";
--const char *argp_program_bug_address =
-- "<bug-gnu-utils@@gnu.org>";
--
--/* @r{Program documentation.} */
--static char doc[] =
-- "Argp example #2 -- a pretty minimal program using argp";
--
--/* @r{Our argpument parser. The @code{options}, @code{parser}, and
-- @code{args_doc} fields are zero because we have neither options or
-- arguments; @code{doc} and @code{argp_program_bug_address} will be
-- used in the output for @samp{--help}, and the @samp{--version}
-- option will print out @code{argp_program_version}.} */
--static struct argp argp = @{ 0, 0, 0, doc @};
--
--int main (int argc, char **argv)
--@{
-- argp_parse (&argp, argc, argv, 0, 0, 0);
-- exit (0);
--@}
-diff -Naur ../glibc-2.1.3/manual/argp-ex3.c.texi glibc-2.1.3/manual/argp-ex3.c.texi
---- ../glibc-2.1.3/manual/argp-ex3.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/argp-ex3.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,152 +0,0 @@
--/* @r{Argp example #3 -- a program with options and arguments using argp} */
--
--/* @r{This program uses the same features as example 2, and uses options and
-- arguments.
--
-- We now use the first four fields in ARGP, so here's a description of them:
-- OPTIONS -- A pointer to a vector of struct argp_option (see below)
-- PARSER -- A function to parse a single option, called by argp
-- ARGS_DOC -- A string describing how the non-option arguments should look
-- DOC -- A descriptive string about this program; if it contains a
-- vertical tab character (\v), the part after it will be
-- printed *following* the options
--
-- The function PARSER takes the following arguments:
-- KEY -- An integer specifying which option this is (taken
-- from the KEY field in each struct argp_option), or
-- a special key specifying something else; the only
-- special keys we use here are ARGP_KEY_ARG, meaning
-- a non-option argument, and ARGP_KEY_END, meaning
-- that all argumens have been parsed
-- ARG -- For an option KEY, the string value of its
-- argument, or NULL if it has none
-- STATE-- A pointer to a struct argp_state, containing
-- various useful information about the parsing state; used here
-- are the INPUT field, which reflects the INPUT argument to
-- argp_parse, and the ARG_NUM field, which is the number of the
-- current non-option argument being parsed
-- It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the
-- given KEY wasn't recognized, or an errno value indicating some other
-- error.
--
-- Note that in this example, main uses a structure to communicate with the
-- parse_opt function, a pointer to which it passes in the INPUT argument to
-- argp_parse. Of course, it's also possible to use global variables
-- instead, but this is somewhat more flexible.
--
-- The OPTIONS field contains a pointer to a vector of struct argp_option's;
-- that structure has the following fields (if you assign your option
-- structures using array initialization like this example, unspecified
-- fields will be defaulted to 0, and need not be specified):
-- NAME -- The name of this option's long option (may be zero)
-- KEY -- The KEY to pass to the PARSER function when parsing this option,
-- *and* the name of this option's short option, if it is a
-- printable ascii character
-- ARG -- The name of this option's argument, if any
-- FLAGS -- Flags describing this option; some of them are:
-- OPTION_ARG_OPTIONAL -- The argument to this option is optional
-- OPTION_ALIAS -- This option is an alias for the
-- previous option
-- OPTION_HIDDEN -- Don't show this option in --help output
-- DOC -- A documentation string for this option, shown in --help output
--
-- An options vector should be terminated by an option with all fields zero.} */
--
--#include <argp.h>
--
--const char *argp_program_version =
-- "argp-ex3 1.0";
--const char *argp_program_bug_address =
-- "<bug-gnu-utils@@gnu.org>";
--
--/* @r{Program documentation.} */
--static char doc[] =
-- "Argp example #3 -- a program with options and arguments using argp";
--
--/* @r{A description of the arguments we accept.} */
--static char args_doc[] = "ARG1 ARG2";
--
--/* @r{The options we understand.} */
--static struct argp_option options[] = @{
-- @{"verbose", 'v', 0, 0, "Produce verbose output" @},
-- @{"quiet", 'q', 0, 0, "Don't produce any output" @},
-- @{"silent", 's', 0, OPTION_ALIAS @},
-- @{"output", 'o', "FILE", 0,
-- "Output to FILE instead of standard output" @},
-- @{ 0 @}
--@};
--
--/* @r{Used by @code{main} to communicate with @code{parse_opt}.} */
--struct arguments
--@{
-- char *args[2]; /* @r{@var{arg1} & @var{arg2}} */
-- int silent, verbose;
-- char *output_file;
--@};
--
--/* @r{Parse a single option.} */
--static error_t
--parse_opt (int key, char *arg, struct argp_state *state)
--@{
-- /* @r{Get the @var{input} argument from @code{argp_parse}, which we
-- know is a pointer to our arguments structure.} */
-- struct arguments *arguments = state->input;
--
-- switch (key)
-- @{
-- case 'q': case 's':
-- arguments->silent = 1;
-- break;
-- case 'v':
-- arguments->verbose = 1;
-- break;
-- case 'o':
-- arguments->output_file = arg;
-- break;
--
-- case ARGP_KEY_ARG:
-- if (state->arg_num >= 2)
-- /* @r{Too many arguments.} */
-- argp_usage (state);
--
-- arguments->args[state->arg_num] = arg;
--
-- break;
--
-- case ARGP_KEY_END:
-- if (state->arg_num < 2)
-- /* @r{Not enough arguments.} */
-- argp_usage (state);
-- break;
--
-- default:
-- return ARGP_ERR_UNKNOWN;
-- @}
-- return 0;
--@}
--
--/* @r{Our argp parser.} */
--static struct argp argp = @{ options, parse_opt, args_doc, doc @};
--
--int main (int argc, char **argv)
--@{
-- struct arguments arguments;
--
-- /* @r{Default values.} */
-- arguments.silent = 0;
-- arguments.verbose = 0;
-- arguments.output_file = "-";
--
-- /* @r{Parse our arguments; every option seen by @code{parse_opt} will
-- be reflected in @code{arguments}.} */
-- argp_parse (&argp, argc, argv, 0, 0, &arguments);
--
-- printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n"
-- "VERBOSE = %s\nSILENT = %s\n",
-- arguments.args[0], arguments.args[1],
-- arguments.output_file,
-- arguments.verbose ? "yes" : "no",
-- arguments.silent ? "yes" : "no");
--
-- exit (0);
--@}
-diff -Naur ../glibc-2.1.3/manual/argp-ex4.c.texi glibc-2.1.3/manual/argp-ex4.c.texi
---- ../glibc-2.1.3/manual/argp-ex4.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/argp-ex4.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,167 +0,0 @@
--/* @r{Argp example #4 -- a program with somewhat more complicated options} */
--
--/* @r{This program uses the same features as example 3, but has more
-- options, and somewhat more structure in the -help output. It
-- also shows how you can `steal' the remainder of the input
-- arguments past a certain point, for programs that accept a
-- list of items. It also shows the special argp KEY value
-- ARGP_KEY_NO_ARGS, which is only given if no non-option
-- arguments were supplied to the program.
--
-- For structuring the help output, two features are used,
-- *headers* which are entries in the options vector with the
-- first four fields being zero, and a two part documentation
-- string (in the variable DOC), which allows documentation both
-- before and after the options; the two parts of DOC are
-- separated by a vertical-tab character ('\v', or '\013'). By
-- convention, the documentation before the options is just a
-- short string saying what the program does, and that afterwards
-- is longer, describing the behavior in more detail. All
-- documentation strings are automatically filled for output,
-- although newlines may be included to force a line break at a
-- particular point. All documenation strings are also passed to
-- the `gettext' function, for possible translation into the
-- current locale.} */
--
--#include <stdlib.h>
--#include <error.h>
--#include <argp.h>
--
--const char *argp_program_version =
-- "argp-ex4 1.0";
--const char *argp_program_bug_address =
-- "<bug-gnu-utils@@prep.ai.mit.edu>";
--
--/* @r{Program documentation.} */
--static char doc[] =
-- "Argp example #4 -- a program with somewhat more complicated\
--options\
--\vThis part of the documentation comes *after* the options;\
-- note that the text is automatically filled, but it's possible\
-- to force a line-break, e.g.\n<-- here.";
--
--/* @r{A description of the arguments we accept.} */
--static char args_doc[] = "ARG1 [STRING...]";
--
--/* @r{Keys for options without short-options.} */
--#define OPT_ABORT 1 /* @r{--abort} */
--
--/* @r{The options we understand.} */
--static struct argp_option options[] = @{
-- @{"verbose", 'v', 0, 0, "Produce verbose output" @},
-- @{"quiet", 'q', 0, 0, "Don't produce any output" @},
-- @{"silent", 's', 0, OPTION_ALIAS @},
-- @{"output", 'o', "FILE", 0,
-- "Output to FILE instead of standard output" @},
--
-- @{0,0,0,0, "The following options should be grouped together:" @},
-- @{"repeat", 'r', "COUNT", OPTION_ARG_OPTIONAL,
-- "Repeat the output COUNT (default 10) times"@},
-- @{"abort", OPT_ABORT, 0, 0, "Abort before showing any output"@},
--
-- @{ 0 @}
--@};
--
--/* @r{Used by @code{main} to communicate with @code{parse_opt}.} */
--struct arguments
--@{
-- char *arg1; /* @r{@var{arg1}} */
-- char **strings; /* @r{[@var{string}@dots{}]} */
-- int silent, verbose, abort; /* @r{@samp{-s}, @samp{-v}, @samp{--abort}} */
-- char *output_file; /* @r{@var{file} arg to @samp{--output}} */
-- int repeat_count; /* @r{@var{count} arg to @samp{--repeat}} */
--@};
--
--/* @r{Parse a single option.} */
--static error_t
--parse_opt (int key, char *arg, struct argp_state *state)
--@{
-- /* @r{Get the @code{input} argument from @code{argp_parse}, which we
-- know is a pointer to our arguments structure.} */
-- struct arguments *arguments = state->input;
--
-- switch (key)
-- @{
-- case 'q': case 's':
-- arguments->silent = 1;
-- break;
-- case 'v':
-- arguments->verbose = 1;
-- break;
-- case 'o':
-- arguments->output_file = arg;
-- break;
-- case 'r':
-- arguments->repeat_count = arg ? atoi (arg) : 10;
-- break;
-- case OPT_ABORT:
-- arguments->abort = 1;
-- break;
--
-- case ARGP_KEY_NO_ARGS:
-- argp_usage (state);
--
-- case ARGP_KEY_ARG:
-- /* @r{Here we know that @code{state->arg_num == 0}, since we
-- force argument parsing to end before any more arguments can
-- get here.} */
-- arguments->arg1 = arg;
--
-- /* @r{Now we consume all the rest of the arguments.
-- @code{state->next} is the index in @code{state->argv} of the
-- next argument to be parsed, which is the first @var{string}
-- we're interested in, so we can just use
-- @code{&state->argv[state->next]} as the value for
-- arguments->strings.
--
-- @emph{In addition}, by setting @code{state->next} to the end
-- of the arguments, we can force argp to stop parsing here and
-- return.} */
-- arguments->strings = &state->argv[state->next];
-- state->next = state->argc;
--
-- break;
--
-- default:
-- return ARGP_ERR_UNKNOWN;
-- @}
-- return 0;
--@}
--
--/* @r{Our argp parser.} */
--static struct argp argp = @{ options, parse_opt, args_doc, doc @};
--
--int main (int argc, char **argv)
--@{
-- int i, j;
-- struct arguments arguments;
--
-- /* @r{Default values.} */
-- arguments.silent = 0;
-- arguments.verbose = 0;
-- arguments.output_file = "-";
-- arguments.repeat_count = 1;
-- arguments.abort = 0;
--
-- /* @r{Parse our arguments; every option seen by @code{parse_opt} will be
-- reflected in @code{arguments}.} */
-- argp_parse (&argp, argc, argv, 0, 0, &arguments);
--
-- if (arguments.abort)
-- error (10, 0, "ABORTED");
--
-- for (i = 0; i < arguments.repeat_count; i++)
-- @{
-- printf ("ARG1 = %s\n", arguments.arg1);
-- printf ("STRINGS = ");
-- for (j = 0; arguments.strings[j]; j++)
-- printf (j == 0 ? "%s" : ", %s", arguments.strings[j]);
-- printf ("\n");
-- printf ("OUTPUT_FILE = %s\nVERBOSE = %s\nSILENT = %s\n",
-- arguments.output_file,
-- arguments.verbose ? "yes" : "no",
-- arguments.silent ? "yes" : "no");
-- @}
--
-- exit (0);
--@}
-diff -Naur ../glibc-2.1.3/manual/atexit.c.texi glibc-2.1.3/manual/atexit.c.texi
---- ../glibc-2.1.3/manual/atexit.c.texi 1999-07-18 18:01:09.000000000 -0700
-+++ glibc-2.1.3/manual/atexit.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,15 +0,0 @@
--#include <stdio.h>
--#include <stdlib.h>
--
--void
--bye (void)
--@{
-- puts ("Goodbye, cruel world....");
--@}
--
--int
--main (void)
--@{
-- atexit (bye);
-- exit (EXIT_SUCCESS);
--@}
-diff -Naur ../glibc-2.1.3/manual/db.c.texi glibc-2.1.3/manual/db.c.texi
---- ../glibc-2.1.3/manual/db.c.texi 1999-07-18 18:01:09.000000000 -0700
-+++ glibc-2.1.3/manual/db.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,52 +0,0 @@
--#include <grp.h>
--#include <pwd.h>
--#include <sys/types.h>
--#include <unistd.h>
--#include <stdlib.h>
--
--int
--main (void)
--@{
-- uid_t me;
-- struct passwd *my_passwd;
-- struct group *my_group;
-- char **members;
--
-- /* @r{Get information about the user ID.} */
-- me = getuid ();
-- my_passwd = getpwuid (me);
-- if (!my_passwd)
-- @{
-- printf ("Couldn't find out about user %d.\n", (int) me);
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Print the information.} */
-- printf ("I am %s.\n", my_passwd->pw_gecos);
-- printf ("My login name is %s.\n", my_passwd->pw_name);
-- printf ("My uid is %d.\n", (int) (my_passwd->pw_uid));
-- printf ("My home directory is %s.\n", my_passwd->pw_dir);
-- printf ("My default shell is %s.\n", my_passwd->pw_shell);
--
-- /* @r{Get information about the default group ID.} */
-- my_group = getgrgid (my_passwd->pw_gid);
-- if (!my_group)
-- @{
-- printf ("Couldn't find out about group %d.\n",
-- (int) my_passwd->pw_gid);
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Print the information.} */
-- printf ("My default group is %s (%d).\n",
-- my_group->gr_name, (int) (my_passwd->pw_gid));
-- printf ("The members of this group are:\n");
-- members = my_group->gr_mem;
-- while (*members)
-- @{
-- printf (" %s\n", *(members));
-- members++;
-- @}
--
-- return EXIT_SUCCESS;
--@}
-diff -Naur ../glibc-2.1.3/manual/dir glibc-2.1.3/manual/dir
---- ../glibc-2.1.3/manual/dir 1997-06-19 11:22:50.000000000 -0700
-+++ glibc-2.1.3/manual/dir 1998-02-07 12:16:10.000000000 -0800
-@@ -1,4 +1,4 @@
--$Id: dir,v 2.1 1997/06/19 18:22:50 drepper Exp $
-+$Id: dir,v 1.1.1.1 1998/02/07 20:16:10 gafton Exp $
- This is the file .../info/dir, which contains the topmost node of the
- Info hierarchy. The first time you invoke Info you start off
- looking at that node, which is (dir)Top.
-diff -Naur ../glibc-2.1.3/manual/dir-add.info glibc-2.1.3/manual/dir-add.info
---- ../glibc-2.1.3/manual/dir-add.info 2000-01-05 19:18:18.000000000 -0800
-+++ glibc-2.1.3/manual/dir-add.info 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1502 +0,0 @@
--INFO-DIR-SECTION GNU C library functions
--START-INFO-DIR-ENTRY
--* (*gconv_end_fct): (libc)glibc iconv Implementation.
--* (*gconv_fct): (libc)glibc iconv Implementation.
--* (*gconv_init_fct): (libc)glibc iconv Implementation.
--* AF_INET6: (libc)Internet Namespace.
--* ALTWERASE: (libc)Local Modes.
--* ARGP_ERR_UNKNOWN: (libc)Argp Parser Functions.
--* ARG_MAX: (libc)General Limits.
--* BC_BASE_MAX: (libc)Utility Limits.
--* BC_DIM_MAX: (libc)Utility Limits.
--* BC_SCALE_MAX: (libc)Utility Limits.
--* BC_STRING_MAX: (libc)Utility Limits.
--* BRKINT: (libc)Input Modes.
--* BUFSIZ: (libc)Controlling Buffering.
--* CCTS_OFLOW: (libc)Control Modes.
--* CHILD_MAX: (libc)General Limits.
--* CIGNORE: (libc)Control Modes.
--* CLK_TCK: (libc)Basic CPU Time.
--* CLOCAL: (libc)Control Modes.
--* CLOCKS_PER_SEC: (libc)Basic CPU Time.
--* COLL_WEIGHTS_MAX: (libc)Utility Limits.
--* CREAD: (libc)Control Modes.
--* CRTS_IFLOW: (libc)Control Modes.
--* CS5: (libc)Control Modes.
--* CS6: (libc)Control Modes.
--* CS7: (libc)Control Modes.
--* CS8: (libc)Control Modes.
--* CSIZE: (libc)Control Modes.
--* CSTOPB: (libc)Control Modes.
--* DES_FAILED: (libc)DES Encryption.
--* DTTOIF: (libc)Directory Entries.
--* E2BIG: (libc)Error Codes.
--* EACCES: (libc)Error Codes.
--* EADDRINUSE: (libc)Error Codes.
--* EADDRNOTAVAIL: (libc)Error Codes.
--* EADV: (libc)Error Codes.
--* EAFNOSUPPORT: (libc)Error Codes.
--* EAGAIN: (libc)Error Codes.
--* EALREADY: (libc)Error Codes.
--* EAUTH: (libc)Error Codes.
--* EBACKGROUND: (libc)Error Codes.
--* EBADE: (libc)Error Codes.
--* EBADF: (libc)Error Codes.
--* EBADFD: (libc)Error Codes.
--* EBADMSG: (libc)Error Codes.
--* EBADR: (libc)Error Codes.
--* EBADRPC: (libc)Error Codes.
--* EBADRQC: (libc)Error Codes.
--* EBADSLT: (libc)Error Codes.
--* EBFONT: (libc)Error Codes.
--* EBUSY: (libc)Error Codes.
--* ECHILD: (libc)Error Codes.
--* ECHO: (libc)Local Modes.
--* ECHOCTL: (libc)Local Modes.
--* ECHOE: (libc)Local Modes.
--* ECHOK: (libc)Local Modes.
--* ECHOKE: (libc)Local Modes.
--* ECHONL: (libc)Local Modes.
--* ECHOPRT: (libc)Local Modes.
--* ECHRNG: (libc)Error Codes.
--* ECOMM: (libc)Error Codes.
--* ECONNABORTED: (libc)Error Codes.
--* ECONNREFUSED: (libc)Error Codes.
--* ECONNRESET: (libc)Error Codes.
--* ED: (libc)Error Codes.
--* EDEADLK: (libc)Error Codes.
--* EDEADLOCK: (libc)Error Codes.
--* EDESTADDRREQ: (libc)Error Codes.
--* EDIED: (libc)Error Codes.
--* EDOM: (libc)Error Codes.
--* EDOTDOT: (libc)Error Codes.
--* EDQUOT: (libc)Error Codes.
--* EEXIST: (libc)Error Codes.
--* EFAULT: (libc)Error Codes.
--* EFBIG: (libc)Error Codes.
--* EFTYPE: (libc)Error Codes.
--* EGRATUITOUS: (libc)Error Codes.
--* EGREGIOUS: (libc)Error Codes.
--* EHOSTDOWN: (libc)Error Codes.
--* EHOSTUNREACH: (libc)Error Codes.
--* EIDRM: (libc)Error Codes.
--* EIEIO: (libc)Error Codes.
--* EILSEQ: (libc)Error Codes.
--* EINPROGRESS: (libc)Error Codes.
--* EINTR: (libc)Error Codes.
--* EINVAL: (libc)Error Codes.
--* EIO: (libc)Error Codes.
--* EISCONN: (libc)Error Codes.
--* EISDIR: (libc)Error Codes.
--* EISNAM: (libc)Error Codes.
--* EL2HLT: (libc)Error Codes.
--* EL2NSYNC: (libc)Error Codes.
--* EL3HLT: (libc)Error Codes.
--* EL3RST: (libc)Error Codes.
--* ELIBACC: (libc)Error Codes.
--* ELIBBAD: (libc)Error Codes.
--* ELIBEXEC: (libc)Error Codes.
--* ELIBMAX: (libc)Error Codes.
--* ELIBSCN: (libc)Error Codes.
--* ELNRNG: (libc)Error Codes.
--* ELOOP: (libc)Error Codes.
--* EMEDIUMTYPE: (libc)Error Codes.
--* EMFILE: (libc)Error Codes.
--* EMLINK: (libc)Error Codes.
--* EMSGSIZE: (libc)Error Codes.
--* EMULTIHOP: (libc)Error Codes.
--* ENAMETOOLONG: (libc)Error Codes.
--* ENAVAIL: (libc)Error Codes.
--* ENEEDAUTH: (libc)Error Codes.
--* ENETDOWN: (libc)Error Codes.
--* ENETRESET: (libc)Error Codes.
--* ENETUNREACH: (libc)Error Codes.
--* ENFILE: (libc)Error Codes.
--* ENOANO: (libc)Error Codes.
--* ENOBUFS: (libc)Error Codes.
--* ENOCSI: (libc)Error Codes.
--* ENODATA: (libc)Error Codes.
--* ENODEV: (libc)Error Codes.
--* ENOENT: (libc)Error Codes.
--* ENOEXEC: (libc)Error Codes.
--* ENOLCK: (libc)Error Codes.
--* ENOLINK: (libc)Error Codes.
--* ENOMEDIUM: (libc)Error Codes.
--* ENOMEM: (libc)Error Codes.
--* ENOMSG: (libc)Error Codes.
--* ENONET: (libc)Error Codes.
--* ENOPKG: (libc)Error Codes.
--* ENOPROTOOPT: (libc)Error Codes.
--* ENOSPC: (libc)Error Codes.
--* ENOSR: (libc)Error Codes.
--* ENOSTR: (libc)Error Codes.
--* ENOSYS: (libc)Error Codes.
--* ENOTBLK: (libc)Error Codes.
--* ENOTCONN: (libc)Error Codes.
--* ENOTDIR: (libc)Error Codes.
--* ENOTEMPTY: (libc)Error Codes.
--* ENOTNAM: (libc)Error Codes.
--* ENOTSOCK: (libc)Error Codes.
--* ENOTSUP: (libc)Error Codes.
--* ENOTTY: (libc)Error Codes.
--* ENOTUNIQ: (libc)Error Codes.
--* ENXIO: (libc)Error Codes.
--* EOF: (libc)EOF and Errors.
--* EOPNOTSUPP: (libc)Error Codes.
--* EOVERFLOW: (libc)Error Codes.
--* EPERM: (libc)Error Codes.
--* EPFNOSUPPORT: (libc)Error Codes.
--* EPIPE: (libc)Error Codes.
--* EPROCLIM: (libc)Error Codes.
--* EPROCUNAVAIL: (libc)Error Codes.
--* EPROGMISMATCH: (libc)Error Codes.
--* EPROGUNAVAIL: (libc)Error Codes.
--* EPROTO: (libc)Error Codes.
--* EPROTONOSUPPORT: (libc)Error Codes.
--* EPROTOTYPE: (libc)Error Codes.
--* EQUIV_CLASS_MAX: (libc)Utility Limits.
--* ERANGE: (libc)Error Codes.
--* EREMCHG: (libc)Error Codes.
--* EREMOTE: (libc)Error Codes.
--* EREMOTEIO: (libc)Error Codes.
--* ERESTART: (libc)Error Codes.
--* EROFS: (libc)Error Codes.
--* ERPCMISMATCH: (libc)Error Codes.
--* ESHUTDOWN: (libc)Error Codes.
--* ESOCKTNOSUPPORT: (libc)Error Codes.
--* ESPIPE: (libc)Error Codes.
--* ESRCH: (libc)Error Codes.
--* ESRMNT: (libc)Error Codes.
--* ESTALE: (libc)Error Codes.
--* ESTRPIPE: (libc)Error Codes.
--* ETIME: (libc)Error Codes.
--* ETIMEDOUT: (libc)Error Codes.
--* ETOOMANYREFS: (libc)Error Codes.
--* ETXTBSY: (libc)Error Codes.
--* EUCLEAN: (libc)Error Codes.
--* EUNATCH: (libc)Error Codes.
--* EUSERS: (libc)Error Codes.
--* EWOULDBLOCK: (libc)Error Codes.
--* EXDEV: (libc)Error Codes.
--* EXFULL: (libc)Error Codes.
--* EXIT_FAILURE: (libc)Exit Status.
--* EXIT_SUCCESS: (libc)Exit Status.
--* EXPR_NEST_MAX: (libc)Utility Limits.
--* FD_CLOEXEC: (libc)Descriptor Flags.
--* FD_CLR: (libc)Waiting for I/O.
--* FD_ISSET: (libc)Waiting for I/O.
--* FD_SET: (libc)Waiting for I/O.
--* FD_SETSIZE: (libc)Waiting for I/O.
--* FD_ZERO: (libc)Waiting for I/O.
--* FILENAME_MAX: (libc)Limits for Files.
--* FLUSHO: (libc)Local Modes.
--* FOPEN_MAX: (libc)Opening Streams.
--* FP_ILOGB0: (libc)Exponents and Logarithms.
--* FP_ILOGBNAN: (libc)Exponents and Logarithms.
--* F_DUPFD: (libc)Duplicating Descriptors.
--* F_GETFD: (libc)Descriptor Flags.
--* F_GETFL: (libc)Getting File Status Flags.
--* F_GETLK: (libc)File Locks.
--* F_GETOWN: (libc)Interrupt Input.
--* F_OK: (libc)Testing File Access.
--* F_SETFD: (libc)Descriptor Flags.
--* F_SETFL: (libc)Getting File Status Flags.
--* F_SETLK: (libc)File Locks.
--* F_SETLKW: (libc)File Locks.
--* F_SETOWN: (libc)Interrupt Input.
--* HUGE_VAL: (libc)Math Error Reporting.
--* HUGE_VALF: (libc)Math Error Reporting.
--* HUGE_VALL: (libc)Math Error Reporting.
--* HUPCL: (libc)Control Modes.
--* I: (libc)Complex Numbers.
--* ICANON: (libc)Local Modes.
--* ICRNL: (libc)Input Modes.
--* IEXTEN: (libc)Local Modes.
--* IFNAMSIZ: (libc)Interface Naming.
--* IFTODT: (libc)Directory Entries.
--* IGNBRK: (libc)Input Modes.
--* IGNCR: (libc)Input Modes.
--* IGNPAR: (libc)Input Modes.
--* IMAXBEL: (libc)Input Modes.
--* INADDR_ANY: (libc)Host Address Data Type.
--* INADDR_BROADCAST: (libc)Host Address Data Type.
--* INADDR_LOOPBACK: (libc)Host Address Data Type.
--* INADDR_NONE: (libc)Host Address Data Type.
--* INFINITY: (libc)Infinity and NaN.
--* INLCR: (libc)Input Modes.
--* INPCK: (libc)Input Modes.
--* IPPORT_RESERVED: (libc)Ports.
--* IPPORT_USERRESERVED: (libc)Ports.
--* ISIG: (libc)Local Modes.
--* ISTRIP: (libc)Input Modes.
--* IXANY: (libc)Input Modes.
--* IXOFF: (libc)Input Modes.
--* IXON: (libc)Input Modes.
--* LINE_MAX: (libc)Utility Limits.
--* LINK_MAX: (libc)Limits for Files.
--* L_ctermid: (libc)Identifying the Terminal.
--* L_cuserid: (libc)Who Logged In.
--* L_tmpnam: (libc)Temporary Files.
--* MAXNAMLEN: (libc)Limits for Files.
--* MAX_CANON: (libc)Limits for Files.
--* MAX_INPUT: (libc)Limits for Files.
--* MB_CUR_MAX: (libc)Selecting the Conversion.
--* MB_LEN_MAX: (libc)Selecting the Conversion.
--* MDMBUF: (libc)Control Modes.
--* MSG_DONTROUTE: (libc)Socket Data Options.
--* MSG_OOB: (libc)Socket Data Options.
--* MSG_PEEK: (libc)Socket Data Options.
--* NAME_MAX: (libc)Limits for Files.
--* NAN: (libc)Infinity and NaN.
--* NCCS: (libc)Mode Data Types.
--* NGROUPS_MAX: (libc)General Limits.
--* NOFLSH: (libc)Local Modes.
--* NOKERNINFO: (libc)Local Modes.
--* NSIG: (libc)Standard Signals.
--* NULL: (libc)Null Pointer Constant.
--* ONLCR: (libc)Output Modes.
--* ONOEOT: (libc)Output Modes.
--* OPEN_MAX: (libc)General Limits.
--* OPOST: (libc)Output Modes.
--* OXTABS: (libc)Output Modes.
--* O_ACCMODE: (libc)Access Modes.
--* O_APPEND: (libc)Operating Modes.
--* O_ASYNC: (libc)Operating Modes.
--* O_CREAT: (libc)Open-time Flags.
--* O_EXCL: (libc)Open-time Flags.
--* O_EXEC: (libc)Access Modes.
--* O_EXLOCK: (libc)Open-time Flags.
--* O_FSYNC: (libc)Operating Modes.
--* O_IGNORE_CTTY: (libc)Open-time Flags.
--* O_NDELAY: (libc)Operating Modes.
--* O_NOATIME: (libc)Operating Modes.
--* O_NOCTTY: (libc)Open-time Flags.
--* O_NOLINK: (libc)Open-time Flags.
--* O_NONBLOCK: (libc)Open-time Flags.
--* O_NONBLOCK: (libc)Operating Modes.
--* O_NOTRANS: (libc)Open-time Flags.
--* O_RDONLY: (libc)Access Modes.
--* O_RDWR: (libc)Access Modes.
--* O_READ: (libc)Access Modes.
--* O_SHLOCK: (libc)Open-time Flags.
--* O_SYNC: (libc)Operating Modes.
--* O_TRUNC: (libc)Open-time Flags.
--* O_WRITE: (libc)Access Modes.
--* O_WRONLY: (libc)Access Modes.
--* PARENB: (libc)Control Modes.
--* PARMRK: (libc)Input Modes.
--* PARODD: (libc)Control Modes.
--* PATH_MAX: (libc)Limits for Files.
--* PA_FLAG_MASK: (libc)Parsing a Template String.
--* PENDIN: (libc)Local Modes.
--* PF_FILE: (libc)Local Namespace Details.
--* PF_INET: (libc)Internet Namespace.
--* PF_LOCAL: (libc)Local Namespace Details.
--* PF_UNIX: (libc)Local Namespace Details.
--* PIPE_BUF: (libc)Limits for Files.
--* P_tmpdir: (libc)Temporary Files.
--* RAND_MAX: (libc)ISO Random.
--* RE_DUP_MAX: (libc)General Limits.
--* RLIM_INFINITY: (libc)Limits on Resources.
--* R_OK: (libc)Testing File Access.
--* SA_NOCLDSTOP: (libc)Flags for Sigaction.
--* SA_ONSTACK: (libc)Flags for Sigaction.
--* SA_RESTART: (libc)Flags for Sigaction.
--* SEEK_CUR: (libc)File Positioning.
--* SEEK_END: (libc)File Positioning.
--* SEEK_SET: (libc)File Positioning.
--* SIGABRT: (libc)Program Error Signals.
--* SIGALRM: (libc)Alarm Signals.
--* SIGBUS: (libc)Program Error Signals.
--* SIGCHLD: (libc)Job Control Signals.
--* SIGCLD: (libc)Job Control Signals.
--* SIGCONT: (libc)Job Control Signals.
--* SIGEMT: (libc)Program Error Signals.
--* SIGFPE: (libc)Program Error Signals.
--* SIGHUP: (libc)Termination Signals.
--* SIGILL: (libc)Program Error Signals.
--* SIGINFO: (libc)Miscellaneous Signals.
--* SIGINT: (libc)Termination Signals.
--* SIGIO: (libc)Asynchronous I/O Signals.
--* SIGIOT: (libc)Program Error Signals.
--* SIGKILL: (libc)Termination Signals.
--* SIGLOST: (libc)Operation Error Signals.
--* SIGPIPE: (libc)Operation Error Signals.
--* SIGPOLL: (libc)Asynchronous I/O Signals.
--* SIGPROF: (libc)Alarm Signals.
--* SIGQUIT: (libc)Termination Signals.
--* SIGSEGV: (libc)Program Error Signals.
--* SIGSTOP: (libc)Job Control Signals.
--* SIGSYS: (libc)Program Error Signals.
--* SIGTERM: (libc)Termination Signals.
--* SIGTRAP: (libc)Program Error Signals.
--* SIGTSTP: (libc)Job Control Signals.
--* SIGTTIN: (libc)Job Control Signals.
--* SIGTTOU: (libc)Job Control Signals.
--* SIGURG: (libc)Asynchronous I/O Signals.
--* SIGUSR1: (libc)Miscellaneous Signals.
--* SIGUSR2: (libc)Miscellaneous Signals.
--* SIGVTALRM: (libc)Alarm Signals.
--* SIGWINCH: (libc)Miscellaneous Signals.
--* SIGXCPU: (libc)Operation Error Signals.
--* SIGXFSZ: (libc)Operation Error Signals.
--* SIG_ERR: (libc)Basic Signal Handling.
--* SOCK_DGRAM: (libc)Communication Styles.
--* SOCK_RAW: (libc)Communication Styles.
--* SOCK_RDM: (libc)Communication Styles.
--* SOCK_SEQPACKET: (libc)Communication Styles.
--* SOCK_STREAM: (libc)Communication Styles.
--* SOL_SOCKET: (libc)Socket-Level Options.
--* SSIZE_MAX: (libc)General Limits.
--* STREAM_MAX: (libc)General Limits.
--* SUN_LEN: (libc)Local Namespace Details.
--* SV_INTERRUPT: (libc)BSD Handler.
--* SV_ONSTACK: (libc)BSD Handler.
--* SV_RESETHAND: (libc)BSD Handler.
--* S_IFMT: (libc)Testing File Type.
--* S_ISBLK: (libc)Testing File Type.
--* S_ISCHR: (libc)Testing File Type.
--* S_ISDIR: (libc)Testing File Type.
--* S_ISFIFO: (libc)Testing File Type.
--* S_ISLNK: (libc)Testing File Type.
--* S_ISREG: (libc)Testing File Type.
--* S_ISSOCK: (libc)Testing File Type.
--* TMP_MAX: (libc)Temporary Files.
--* TOSTOP: (libc)Local Modes.
--* TZNAME_MAX: (libc)General Limits.
--* VDISCARD: (libc)Other Special.
--* VDSUSP: (libc)Signal Characters.
--* VEOF: (libc)Editing Characters.
--* VEOL2: (libc)Editing Characters.
--* VEOL: (libc)Editing Characters.
--* VERASE: (libc)Editing Characters.
--* VINTR: (libc)Signal Characters.
--* VKILL: (libc)Editing Characters.
--* VLNEXT: (libc)Other Special.
--* VMIN: (libc)Noncanonical Input.
--* VQUIT: (libc)Signal Characters.
--* VREPRINT: (libc)Editing Characters.
--* VSTART: (libc)Start/Stop Characters.
--* VSTATUS: (libc)Other Special.
--* VSTOP: (libc)Start/Stop Characters.
--* VSUSP: (libc)Signal Characters.
--* VTIME: (libc)Noncanonical Input.
--* VWERASE: (libc)Editing Characters.
--* WCHAR_MAX: (libc)Extended Char Intro.
--* WCHAR_MIN: (libc)Extended Char Intro.
--* WCOREDUMP: (libc)Process Completion Status.
--* WEOF: (libc)Extended Char Intro.
--* WEXITSTATUS: (libc)Process Completion Status.
--* WIFEXITED: (libc)Process Completion Status.
--* WIFSIGNALED: (libc)Process Completion Status.
--* WIFSTOPPED: (libc)Process Completion Status.
--* WSTOPSIG: (libc)Process Completion Status.
--* WTERMSIG: (libc)Process Completion Status.
--* W_OK: (libc)Testing File Access.
--* X_OK: (libc)Testing File Access.
--* _Complex_I: (libc)Complex Numbers.
--* _Exit: (libc)Termination Internals.
--* _IOFBF: (libc)Controlling Buffering.
--* _IOLBF: (libc)Controlling Buffering.
--* _IONBF: (libc)Controlling Buffering.
--* _Imaginary_I: (libc)Complex Numbers.
--* _PATH_UTMP: (libc)Manipulating the Database.
--* _PATH_WTMP: (libc)Manipulating the Database.
--* _POSIX2_C_DEV: (libc)System Options.
--* _POSIX2_C_VERSION: (libc)Version Supported.
--* _POSIX2_FORT_DEV: (libc)System Options.
--* _POSIX2_FORT_RUN: (libc)System Options.
--* _POSIX2_LOCALEDEF: (libc)System Options.
--* _POSIX2_SW_DEV: (libc)System Options.
--* _POSIX_CHOWN_RESTRICTED: (libc)Options for Files.
--* _POSIX_JOB_CONTROL: (libc)System Options.
--* _POSIX_NO_TRUNC: (libc)Options for Files.
--* _POSIX_SAVED_IDS: (libc)System Options.
--* _POSIX_VDISABLE: (libc)Options for Files.
--* _POSIX_VERSION: (libc)Version Supported.
--* __va_copy: (libc)Argument Macros.
--* _exit: (libc)Termination Internals.
--* _tolower: (libc)Case Conversion.
--* _toupper: (libc)Case Conversion.
--* a64l: (libc)Encode Binary Data.
--* abort: (libc)Aborting a Program.
--* abs: (libc)Absolute Value.
--* accept: (libc)Accepting Connections.
--* access: (libc)Testing File Access.
--* acos: (libc)Inverse Trig Functions.
--* acosf: (libc)Inverse Trig Functions.
--* acosh: (libc)Hyperbolic Functions.
--* acoshf: (libc)Hyperbolic Functions.
--* acoshl: (libc)Hyperbolic Functions.
--* acosl: (libc)Inverse Trig Functions.
--* addmntent: (libc)Filesystem handling.
--* addseverity: (libc)Adding Severity Classes.
--* adjtime: (libc)High-Resolution Calendar.
--* aio_cancel64: (libc)Cancel AIO Operations.
--* aio_cancel: (libc)Cancel AIO Operations.
--* aio_error64: (libc)Status of AIO Operations.
--* aio_error: (libc)Status of AIO Operations.
--* aio_fsync64: (libc)Synchronizing AIO Operations.
--* aio_fsync: (libc)Synchronizing AIO Operations.
--* aio_init: (libc)Configuration of AIO.
--* aio_read64: (libc)Asynchronous Reads/Writes.
--* aio_read: (libc)Asynchronous Reads/Writes.
--* aio_return64: (libc)Status of AIO Operations.
--* aio_return: (libc)Status of AIO Operations.
--* aio_suspend64: (libc)Synchronizing AIO Operations.
--* aio_suspend: (libc)Synchronizing AIO Operations.
--* aio_write64: (libc)Asynchronous Reads/Writes.
--* aio_write: (libc)Asynchronous Reads/Writes.
--* alarm: (libc)Setting an Alarm.
--* alloca: (libc)Variable Size Automatic.
--* alphasort64: (libc)Scanning Directory Content.
--* alphasort: (libc)Scanning Directory Content.
--* argp_error: (libc)Argp Helper Functions.
--* argp_failure: (libc)Argp Helper Functions.
--* argp_help: (libc)Argp Help.
--* argp_parse: (libc)Argp.
--* argp_state_help: (libc)Argp Helper Functions.
--* argp_usage: (libc)Argp Helper Functions.
--* argz_add: (libc)Argz Functions.
--* argz_add_sep: (libc)Argz Functions.
--* argz_append: (libc)Argz Functions.
--* argz_count: (libc)Argz Functions.
--* argz_create: (libc)Argz Functions.
--* argz_create_sep: (libc)Argz Functions.
--* argz_delete: (libc)Argz Functions.
--* argz_extract: (libc)Argz Functions.
--* argz_insert: (libc)Argz Functions.
--* argz_next: (libc)Argz Functions.
--* argz_replace: (libc)Argz Functions.
--* argz_stringify: (libc)Argz Functions.
--* asctime: (libc)Formatting Date and Time.
--* asctime_r: (libc)Formatting Date and Time.
--* asin: (libc)Inverse Trig Functions.
--* asinf: (libc)Inverse Trig Functions.
--* asinh: (libc)Hyperbolic Functions.
--* asinhf: (libc)Hyperbolic Functions.
--* asinhl: (libc)Hyperbolic Functions.
--* asinl: (libc)Inverse Trig Functions.
--* asprintf: (libc)Dynamic Output.
--* assert: (libc)Consistency Checking.
--* assert_perror: (libc)Consistency Checking.
--* atan2: (libc)Inverse Trig Functions.
--* atan2f: (libc)Inverse Trig Functions.
--* atan2l: (libc)Inverse Trig Functions.
--* atan: (libc)Inverse Trig Functions.
--* atanf: (libc)Inverse Trig Functions.
--* atanh: (libc)Hyperbolic Functions.
--* atanhf: (libc)Hyperbolic Functions.
--* atanhl: (libc)Hyperbolic Functions.
--* atanl: (libc)Inverse Trig Functions.
--* atexit: (libc)Cleanups on Exit.
--* atof: (libc)Parsing of Floats.
--* atoi: (libc)Parsing of Integers.
--* atol: (libc)Parsing of Integers.
--* atoll: (libc)Parsing of Integers.
--* bcmp: (libc)String/Array Comparison.
--* bcopy: (libc)Copying and Concatenation.
--* bind: (libc)Setting Address.
--* bindtextdomain: (libc)Locating gettext catalog.
--* bsearch: (libc)Array Search Function.
--* btowc: (libc)Converting a Character.
--* bzero: (libc)Copying and Concatenation.
--* cabs: (libc)Absolute Value.
--* cabsf: (libc)Absolute Value.
--* cabsl: (libc)Absolute Value.
--* cacos: (libc)Inverse Trig Functions.
--* cacosf: (libc)Inverse Trig Functions.
--* cacosh: (libc)Hyperbolic Functions.
--* cacoshf: (libc)Hyperbolic Functions.
--* cacoshl: (libc)Hyperbolic Functions.
--* cacosl: (libc)Inverse Trig Functions.
--* calloc: (libc)Allocating Cleared Space.
--* carg: (libc)Operations on Complex.
--* cargf: (libc)Operations on Complex.
--* cargl: (libc)Operations on Complex.
--* casin: (libc)Inverse Trig Functions.
--* casinf: (libc)Inverse Trig Functions.
--* casinh: (libc)Hyperbolic Functions.
--* casinhf: (libc)Hyperbolic Functions.
--* casinhl: (libc)Hyperbolic Functions.
--* casinl: (libc)Inverse Trig Functions.
--* catan: (libc)Inverse Trig Functions.
--* catanf: (libc)Inverse Trig Functions.
--* catanh: (libc)Hyperbolic Functions.
--* catanhf: (libc)Hyperbolic Functions.
--* catanhl: (libc)Hyperbolic Functions.
--* catanl: (libc)Inverse Trig Functions.
--* catclose: (libc)The catgets Functions.
--* catgets: (libc)The catgets Functions.
--* catopen: (libc)The catgets Functions.
--* cbc_crypt: (libc)DES Encryption.
--* cbrt: (libc)Exponents and Logarithms.
--* cbrtf: (libc)Exponents and Logarithms.
--* cbrtl: (libc)Exponents and Logarithms.
--* ccos: (libc)Trig Functions.
--* ccosf: (libc)Trig Functions.
--* ccosh: (libc)Hyperbolic Functions.
--* ccoshf: (libc)Hyperbolic Functions.
--* ccoshl: (libc)Hyperbolic Functions.
--* ccosl: (libc)Trig Functions.
--* ceil: (libc)Rounding Functions.
--* ceilf: (libc)Rounding Functions.
--* ceill: (libc)Rounding Functions.
--* cexp: (libc)Exponents and Logarithms.
--* cexpf: (libc)Exponents and Logarithms.
--* cexpl: (libc)Exponents and Logarithms.
--* cfgetispeed: (libc)Line Speed.
--* cfgetospeed: (libc)Line Speed.
--* cfmakeraw: (libc)Noncanonical Input.
--* cfree: (libc)Freeing after Malloc.
--* cfsetispeed: (libc)Line Speed.
--* cfsetospeed: (libc)Line Speed.
--* cfsetspeed: (libc)Line Speed.
--* chdir: (libc)Working Directory.
--* chmod: (libc)Setting Permissions.
--* chown: (libc)File Owner.
--* cimag: (libc)Operations on Complex.
--* cimagf: (libc)Operations on Complex.
--* cimagl: (libc)Operations on Complex.
--* clearenv: (libc)Environment Access.
--* clearerr: (libc)EOF and Errors.
--* clock: (libc)Basic CPU Time.
--* clog10: (libc)Exponents and Logarithms.
--* clog10f: (libc)Exponents and Logarithms.
--* clog10l: (libc)Exponents and Logarithms.
--* clog: (libc)Exponents and Logarithms.
--* clogf: (libc)Exponents and Logarithms.
--* clogl: (libc)Exponents and Logarithms.
--* close: (libc)Opening and Closing Files.
--* closedir: (libc)Reading/Closing Directory.
--* confstr: (libc)String Parameters.
--* conj: (libc)Operations on Complex.
--* conjf: (libc)Operations on Complex.
--* conjl: (libc)Operations on Complex.
--* connect: (libc)Connecting.
--* copysign: (libc)FP Bit Twiddling.
--* copysignf: (libc)FP Bit Twiddling.
--* copysignl: (libc)FP Bit Twiddling.
--* cos: (libc)Trig Functions.
--* cosf: (libc)Trig Functions.
--* cosh: (libc)Hyperbolic Functions.
--* coshf: (libc)Hyperbolic Functions.
--* coshl: (libc)Hyperbolic Functions.
--* cosl: (libc)Trig Functions.
--* cpow: (libc)Exponents and Logarithms.
--* cpowf: (libc)Exponents and Logarithms.
--* cpowl: (libc)Exponents and Logarithms.
--* cproj: (libc)Operations on Complex.
--* cprojf: (libc)Operations on Complex.
--* cprojl: (libc)Operations on Complex.
--* creal: (libc)Operations on Complex.
--* crealf: (libc)Operations on Complex.
--* creall: (libc)Operations on Complex.
--* creat64: (libc)Opening and Closing Files.
--* creat: (libc)Opening and Closing Files.
--* crypt: (libc)crypt.
--* crypt_r: (libc)crypt.
--* csin: (libc)Trig Functions.
--* csinf: (libc)Trig Functions.
--* csinh: (libc)Hyperbolic Functions.
--* csinhf: (libc)Hyperbolic Functions.
--* csinhl: (libc)Hyperbolic Functions.
--* csinl: (libc)Trig Functions.
--* csqrt: (libc)Exponents and Logarithms.
--* csqrtf: (libc)Exponents and Logarithms.
--* csqrtl: (libc)Exponents and Logarithms.
--* ctan: (libc)Trig Functions.
--* ctanf: (libc)Trig Functions.
--* ctanh: (libc)Hyperbolic Functions.
--* ctanhf: (libc)Hyperbolic Functions.
--* ctanhl: (libc)Hyperbolic Functions.
--* ctanl: (libc)Trig Functions.
--* ctermid: (libc)Identifying the Terminal.
--* ctime: (libc)Formatting Date and Time.
--* ctime_r: (libc)Formatting Date and Time.
--* cuserid: (libc)Who Logged In.
--* dcgettext: (libc)Translation with gettext.
--* des_setparity: (libc)DES Encryption.
--* dgettext: (libc)Translation with gettext.
--* difftime: (libc)Simple Calendar Time.
--* div: (libc)Integer Division.
--* drand48: (libc)SVID Random.
--* drand48_r: (libc)SVID Random.
--* drem: (libc)Remainder Functions.
--* dremf: (libc)Remainder Functions.
--* dreml: (libc)Remainder Functions.
--* dup2: (libc)Duplicating Descriptors.
--* dup: (libc)Duplicating Descriptors.
--* ecb_crypt: (libc)DES Encryption.
--* ecvt: (libc)System V Number Conversion.
--* ecvt_r: (libc)System V Number Conversion.
--* encrypt: (libc)DES Encryption.
--* encrypt_r: (libc)DES Encryption.
--* endfsent: (libc)Filesystem handling.
--* endgrent: (libc)Scanning All Groups.
--* endhostent: (libc)Host Names.
--* endmntent: (libc)Filesystem handling.
--* endnetent: (libc)Networks Database.
--* endnetgrent: (libc)Lookup Netgroup.
--* endprotoent: (libc)Protocols Database.
--* endpwent: (libc)Scanning All Users.
--* endservent: (libc)Services Database.
--* endutent: (libc)Manipulating the Database.
--* endutxent: (libc)XPG Functions.
--* envz_add: (libc)Envz Functions.
--* envz_entry: (libc)Envz Functions.
--* envz_get: (libc)Envz Functions.
--* envz_merge: (libc)Envz Functions.
--* envz_strip: (libc)Envz Functions.
--* erand48: (libc)SVID Random.
--* erand48_r: (libc)SVID Random.
--* erf: (libc)Special Functions.
--* erfc: (libc)Special Functions.
--* erfcf: (libc)Special Functions.
--* erfcl: (libc)Special Functions.
--* erff: (libc)Special Functions.
--* erfl: (libc)Special Functions.
--* errno: (libc)Checking for Errors.
--* execl: (libc)Executing a File.
--* execle: (libc)Executing a File.
--* execlp: (libc)Executing a File.
--* execv: (libc)Executing a File.
--* execve: (libc)Executing a File.
--* execvp: (libc)Executing a File.
--* exit: (libc)Normal Termination.
--* exp10: (libc)Exponents and Logarithms.
--* exp10f: (libc)Exponents and Logarithms.
--* exp10l: (libc)Exponents and Logarithms.
--* exp2: (libc)Exponents and Logarithms.
--* exp2f: (libc)Exponents and Logarithms.
--* exp2l: (libc)Exponents and Logarithms.
--* exp: (libc)Exponents and Logarithms.
--* expf: (libc)Exponents and Logarithms.
--* expl: (libc)Exponents and Logarithms.
--* expm1: (libc)Exponents and Logarithms.
--* expm1f: (libc)Exponents and Logarithms.
--* expm1l: (libc)Exponents and Logarithms.
--* fabs: (libc)Absolute Value.
--* fabsf: (libc)Absolute Value.
--* fabsl: (libc)Absolute Value.
--* fchmod: (libc)Setting Permissions.
--* fchown: (libc)File Owner.
--* fclean: (libc)Cleaning Streams.
--* fclose: (libc)Closing Streams.
--* fcloseall: (libc)Closing Streams.
--* fcntl: (libc)Control Operations.
--* fcvt: (libc)System V Number Conversion.
--* fcvt_r: (libc)System V Number Conversion.
--* fdatasync: (libc)Synchronizing I/O.
--* fdim: (libc)Misc FP Arithmetic.
--* fdimf: (libc)Misc FP Arithmetic.
--* fdiml: (libc)Misc FP Arithmetic.
--* fdopen: (libc)Descriptors and Streams.
--* feclearexcept: (libc)Status bit operations.
--* fegetenv: (libc)Control Functions.
--* fegetexceptflag: (libc)Status bit operations.
--* fegetround: (libc)Rounding.
--* feholdexcept: (libc)Control Functions.
--* feof: (libc)EOF and Errors.
--* ferror: (libc)EOF and Errors.
--* fesetenv: (libc)Control Functions.
--* fesetexceptflag: (libc)Status bit operations.
--* fesetround: (libc)Rounding.
--* fetestexcept: (libc)Status bit operations.
--* feupdateenv: (libc)Control Functions.
--* fflush: (libc)Flushing Buffers.
--* fgetc: (libc)Character Input.
--* fgetgrent: (libc)Scanning All Groups.
--* fgetgrent_r: (libc)Scanning All Groups.
--* fgetpos64: (libc)Portable Positioning.
--* fgetpos: (libc)Portable Positioning.
--* fgetpwent: (libc)Scanning All Users.
--* fgetpwent_r: (libc)Scanning All Users.
--* fgets: (libc)Line Input.
--* fileno: (libc)Descriptors and Streams.
--* finite: (libc)Floating Point Classes.
--* finitef: (libc)Floating Point Classes.
--* finitel: (libc)Floating Point Classes.
--* floor: (libc)Rounding Functions.
--* floorf: (libc)Rounding Functions.
--* floorl: (libc)Rounding Functions.
--* fma: (libc)Misc FP Arithmetic.
--* fmaf: (libc)Misc FP Arithmetic.
--* fmal: (libc)Misc FP Arithmetic.
--* fmax: (libc)Misc FP Arithmetic.
--* fmaxf: (libc)Misc FP Arithmetic.
--* fmaxl: (libc)Misc FP Arithmetic.
--* fmemopen: (libc)String Streams.
--* fmin: (libc)Misc FP Arithmetic.
--* fminf: (libc)Misc FP Arithmetic.
--* fminl: (libc)Misc FP Arithmetic.
--* fmod: (libc)Remainder Functions.
--* fmodf: (libc)Remainder Functions.
--* fmodl: (libc)Remainder Functions.
--* fmtmsg: (libc)Printing Formatted Messages.
--* fnmatch: (libc)Wildcard Matching.
--* fopen64: (libc)Opening Streams.
--* fopen: (libc)Opening Streams.
--* fopencookie: (libc)Streams and Cookies.
--* fork: (libc)Creating a Process.
--* forkpty: (libc)Pseudo-Terminal Pairs.
--* fpathconf: (libc)Pathconf.
--* fpclassify: (libc)Floating Point Classes.
--* fprintf: (libc)Formatted Output Functions.
--* fputc: (libc)Simple Output.
--* fputs: (libc)Simple Output.
--* fread: (libc)Block Input/Output.
--* free: (libc)Freeing after Malloc.
--* freopen64: (libc)Opening Streams.
--* freopen: (libc)Opening Streams.
--* frexp: (libc)Normalization Functions.
--* frexpf: (libc)Normalization Functions.
--* frexpl: (libc)Normalization Functions.
--* fscanf: (libc)Formatted Input Functions.
--* fseek: (libc)File Positioning.
--* fseeko64: (libc)File Positioning.
--* fseeko: (libc)File Positioning.
--* fsetpos64: (libc)Portable Positioning.
--* fsetpos: (libc)Portable Positioning.
--* fstat64: (libc)Reading Attributes.
--* fstat: (libc)Reading Attributes.
--* fsync: (libc)Synchronizing I/O.
--* ftell: (libc)File Positioning.
--* ftello64: (libc)File Positioning.
--* ftello: (libc)File Positioning.
--* ftruncate64: (libc)Truncating Files.
--* ftruncate: (libc)File Size.
--* ftruncate: (libc)Truncating Files.
--* ftw64: (libc)Working on Directory Trees.
--* ftw: (libc)Working on Directory Trees.
--* fwrite: (libc)Block Input/Output.
--* gamma: (libc)Special Functions.
--* gammaf: (libc)Special Functions.
--* gammal: (libc)Special Functions.
--* gcvt: (libc)System V Number Conversion.
--* getc: (libc)Character Input.
--* getchar: (libc)Character Input.
--* getcwd: (libc)Working Directory.
--* getdate: (libc)General Time String Parsing.
--* getdate_r: (libc)General Time String Parsing.
--* getdelim: (libc)Line Input.
--* getegid: (libc)Reading Persona.
--* getenv: (libc)Environment Access.
--* geteuid: (libc)Reading Persona.
--* getfsent: (libc)Filesystem handling.
--* getfsfile: (libc)Filesystem handling.
--* getfsspec: (libc)Filesystem handling.
--* getgid: (libc)Reading Persona.
--* getgrent: (libc)Scanning All Groups.
--* getgrent_r: (libc)Scanning All Groups.
--* getgrgid: (libc)Lookup Group.
--* getgrgid_r: (libc)Lookup Group.
--* getgrnam: (libc)Lookup Group.
--* getgrnam_r: (libc)Lookup Group.
--* getgroups: (libc)Reading Persona.
--* gethostbyaddr: (libc)Host Names.
--* gethostbyaddr_r: (libc)Host Names.
--* gethostbyname2: (libc)Host Names.
--* gethostbyname2_r: (libc)Host Names.
--* gethostbyname: (libc)Host Names.
--* gethostbyname_r: (libc)Host Names.
--* gethostent: (libc)Host Names.
--* gethostid: (libc)Host Identification.
--* gethostname: (libc)Host Identification.
--* getitimer: (libc)Setting an Alarm.
--* getline: (libc)Line Input.
--* getlogin: (libc)Who Logged In.
--* getmntent: (libc)Filesystem handling.
--* getmntent_r: (libc)Filesystem handling.
--* getnetbyaddr: (libc)Networks Database.
--* getnetbyname: (libc)Networks Database.
--* getnetent: (libc)Networks Database.
--* getnetgrent: (libc)Lookup Netgroup.
--* getnetgrent_r: (libc)Lookup Netgroup.
--* getopt: (libc)Using Getopt.
--* getopt_long: (libc)Getopt Long Options.
--* getpass: (libc)getpass.
--* getpeername: (libc)Who is Connected.
--* getpgid: (libc)Process Group Functions.
--* getpgrp: (libc)Process Group Functions.
--* getpgrp: (libc)Process Group Functions.
--* getpid: (libc)Process Identification.
--* getppid: (libc)Process Identification.
--* getpriority: (libc)Priority.
--* getprotobyname: (libc)Protocols Database.
--* getprotobynumber: (libc)Protocols Database.
--* getprotoent: (libc)Protocols Database.
--* getpt: (libc)Allocation.
--* getpwent: (libc)Scanning All Users.
--* getpwent_r: (libc)Scanning All Users.
--* getpwnam: (libc)Lookup User.
--* getpwnam_r: (libc)Lookup User.
--* getpwuid: (libc)Lookup User.
--* getpwuid_r: (libc)Lookup User.
--* getrlimit64: (libc)Limits on Resources.
--* getrlimit: (libc)Limits on Resources.
--* getrusage: (libc)Resource Usage.
--* gets: (libc)Line Input.
--* getservbyname: (libc)Services Database.
--* getservbyport: (libc)Services Database.
--* getservent: (libc)Services Database.
--* getsid: (libc)Process Group Functions.
--* getsockname: (libc)Reading Address.
--* getsockopt: (libc)Socket Option Functions.
--* getsubopt: (libc)Suboptions.
--* gettext: (libc)Translation with gettext.
--* gettimeofday: (libc)High-Resolution Calendar.
--* getuid: (libc)Reading Persona.
--* getumask: (libc)Setting Permissions.
--* getutent: (libc)Manipulating the Database.
--* getutent_r: (libc)Manipulating the Database.
--* getutid: (libc)Manipulating the Database.
--* getutid_r: (libc)Manipulating the Database.
--* getutline: (libc)Manipulating the Database.
--* getutline_r: (libc)Manipulating the Database.
--* getutxent: (libc)XPG Functions.
--* getutxid: (libc)XPG Functions.
--* getutxline: (libc)XPG Functions.
--* getw: (libc)Character Input.
--* getwd: (libc)Working Directory.
--* glob: (libc)Calling Glob.
--* globfree: (libc)More Flags for Globbing.
--* gmtime: (libc)Broken-down Time.
--* gmtime_r: (libc)Broken-down Time.
--* grantpt: (libc)Allocation.
--* gsignal: (libc)Signaling Yourself.
--* hasmntopt: (libc)Filesystem handling.
--* hcreate: (libc)Hash Search Function.
--* hcreate_r: (libc)Hash Search Function.
--* hdestroy: (libc)Hash Search Function.
--* hdestroy_r: (libc)Hash Search Function.
--* hsearch: (libc)Hash Search Function.
--* hsearch_r: (libc)Hash Search Function.
--* htonl: (libc)Byte Order.
--* htons: (libc)Byte Order.
--* hypot: (libc)Exponents and Logarithms.
--* hypotf: (libc)Exponents and Logarithms.
--* hypotl: (libc)Exponents and Logarithms.
--* iconv: (libc)Generic Conversion Interface.
--* iconv_close: (libc)Generic Conversion Interface.
--* iconv_open: (libc)Generic Conversion Interface.
--* if_freenameindex: (libc)Interface Naming.
--* if_indextoname: (libc)Interface Naming.
--* if_nameindex: (libc)Interface Naming.
--* if_nametoindex: (libc)Interface Naming.
--* ilogb: (libc)Exponents and Logarithms.
--* ilogbf: (libc)Exponents and Logarithms.
--* ilogbl: (libc)Exponents and Logarithms.
--* imaxabs: (libc)Absolute Value.
--* imaxdiv: (libc)Integer Division.
--* in6addr_any: (libc)Host Address Data Type.
--* in6addr_loopback: (libc)Host Address Data Type.
--* index: (libc)Search Functions.
--* inet_addr: (libc)Host Address Functions.
--* inet_aton: (libc)Host Address Functions.
--* inet_lnaof: (libc)Host Address Functions.
--* inet_makeaddr: (libc)Host Address Functions.
--* inet_netof: (libc)Host Address Functions.
--* inet_network: (libc)Host Address Functions.
--* inet_ntoa: (libc)Host Address Functions.
--* inet_ntop: (libc)Host Address Functions.
--* inet_pton: (libc)Host Address Functions.
--* infnan: (libc)Floating Point Classes.
--* initgroups: (libc)Setting Groups.
--* initstate: (libc)BSD Random.
--* innetgr: (libc)Netgroup Membership.
--* ioctl: (libc)IOCTLs.
--* isalnum: (libc)Classification of Characters.
--* isalpha: (libc)Classification of Characters.
--* isascii: (libc)Classification of Characters.
--* isatty: (libc)Is It a Terminal.
--* isblank: (libc)Classification of Characters.
--* iscntrl: (libc)Classification of Characters.
--* isdigit: (libc)Classification of Characters.
--* isfinite: (libc)Floating Point Classes.
--* isgraph: (libc)Classification of Characters.
--* isgreater: (libc)FP Comparison Functions.
--* isgreaterequal: (libc)FP Comparison Functions.
--* isinf: (libc)Floating Point Classes.
--* isinff: (libc)Floating Point Classes.
--* isinfl: (libc)Floating Point Classes.
--* isless: (libc)FP Comparison Functions.
--* islessequal: (libc)FP Comparison Functions.
--* islessgreater: (libc)FP Comparison Functions.
--* islower: (libc)Classification of Characters.
--* isnan: (libc)Floating Point Classes.
--* isnan: (libc)Floating Point Classes.
--* isnanf: (libc)Floating Point Classes.
--* isnanl: (libc)Floating Point Classes.
--* isnormal: (libc)Floating Point Classes.
--* isprint: (libc)Classification of Characters.
--* ispunct: (libc)Classification of Characters.
--* isspace: (libc)Classification of Characters.
--* isunordered: (libc)FP Comparison Functions.
--* isupper: (libc)Classification of Characters.
--* iswalnum: (libc)Classification of Wide Characters.
--* iswalpha: (libc)Classification of Wide Characters.
--* iswblank: (libc)Classification of Wide Characters.
--* iswcntrl: (libc)Classification of Wide Characters.
--* iswctype: (libc)Classification of Wide Characters.
--* iswdigit: (libc)Classification of Wide Characters.
--* iswgraph: (libc)Classification of Wide Characters.
--* iswlower: (libc)Classification of Wide Characters.
--* iswprint: (libc)Classification of Wide Characters.
--* iswpunct: (libc)Classification of Wide Characters.
--* iswspace: (libc)Classification of Wide Characters.
--* iswupper: (libc)Classification of Wide Characters.
--* iswxdigit: (libc)Classification of Wide Characters.
--* isxdigit: (libc)Classification of Characters.
--* j0: (libc)Special Functions.
--* j0f: (libc)Special Functions.
--* j0l: (libc)Special Functions.
--* j1: (libc)Special Functions.
--* j1f: (libc)Special Functions.
--* j1l: (libc)Special Functions.
--* jn: (libc)Special Functions.
--* jnf: (libc)Special Functions.
--* jnl: (libc)Special Functions.
--* jrand48: (libc)SVID Random.
--* jrand48_r: (libc)SVID Random.
--* kill: (libc)Signaling Another Process.
--* killpg: (libc)Signaling Another Process.
--* l64a: (libc)Encode Binary Data.
--* labs: (libc)Absolute Value.
--* lcong48: (libc)SVID Random.
--* lcong48_r: (libc)SVID Random.
--* ldexp: (libc)Normalization Functions.
--* ldexpf: (libc)Normalization Functions.
--* ldexpl: (libc)Normalization Functions.
--* ldiv: (libc)Integer Division.
--* lfind: (libc)Array Search Function.
--* lgamma: (libc)Special Functions.
--* lgamma_r: (libc)Special Functions.
--* lgammaf: (libc)Special Functions.
--* lgammaf_r: (libc)Special Functions.
--* lgammal: (libc)Special Functions.
--* lgammal_r: (libc)Special Functions.
--* link: (libc)Hard Links.
--* lio_listio64: (libc)Asynchronous Reads/Writes.
--* lio_listio: (libc)Asynchronous Reads/Writes.
--* listen: (libc)Listening.
--* llabs: (libc)Absolute Value.
--* lldiv: (libc)Integer Division.
--* llrint: (libc)Rounding Functions.
--* llrintf: (libc)Rounding Functions.
--* llrintl: (libc)Rounding Functions.
--* llround: (libc)Rounding Functions.
--* llroundf: (libc)Rounding Functions.
--* llroundl: (libc)Rounding Functions.
--* localeconv: (libc)The Lame Way to Locale Data.
--* localtime: (libc)Broken-down Time.
--* localtime_r: (libc)Broken-down Time.
--* log10: (libc)Exponents and Logarithms.
--* log10f: (libc)Exponents and Logarithms.
--* log10l: (libc)Exponents and Logarithms.
--* log1p: (libc)Exponents and Logarithms.
--* log1pf: (libc)Exponents and Logarithms.
--* log1pl: (libc)Exponents and Logarithms.
--* log2: (libc)Exponents and Logarithms.
--* log2f: (libc)Exponents and Logarithms.
--* log2l: (libc)Exponents and Logarithms.
--* log: (libc)Exponents and Logarithms.
--* logb: (libc)Exponents and Logarithms.
--* logb: (libc)Normalization Functions.
--* logbf: (libc)Exponents and Logarithms.
--* logbf: (libc)Normalization Functions.
--* logbl: (libc)Exponents and Logarithms.
--* logbl: (libc)Normalization Functions.
--* logf: (libc)Exponents and Logarithms.
--* login: (libc)Logging In and Out.
--* login_tty: (libc)Logging In and Out.
--* logl: (libc)Exponents and Logarithms.
--* logout: (libc)Logging In and Out.
--* logwtmp: (libc)Logging In and Out.
--* longjmp: (libc)Non-Local Details.
--* lrand48: (libc)SVID Random.
--* lrand48_r: (libc)SVID Random.
--* lrint: (libc)Rounding Functions.
--* lrintf: (libc)Rounding Functions.
--* lrintl: (libc)Rounding Functions.
--* lround: (libc)Rounding Functions.
--* lroundf: (libc)Rounding Functions.
--* lroundl: (libc)Rounding Functions.
--* lsearch: (libc)Array Search Function.
--* lseek64: (libc)File Position Primitive.
--* lseek: (libc)File Position Primitive.
--* lstat64: (libc)Reading Attributes.
--* lstat: (libc)Reading Attributes.
--* mallinfo: (libc)Statistics of Malloc.
--* malloc: (libc)Basic Allocation.
--* mallopt: (libc)Malloc Tunable Parameters.
--* mblen: (libc)Non-reentrant Character Conversion.
--* mbrlen: (libc)Converting a Character.
--* mbrtowc: (libc)Converting a Character.
--* mbsinit: (libc)Keeping the state.
--* mbsnrtowcs: (libc)Converting Strings.
--* mbsrtowcs: (libc)Converting Strings.
--* mbstowcs: (libc)Non-reentrant String Conversion.
--* mbtowc: (libc)Non-reentrant Character Conversion.
--* mcheck: (libc)Heap Consistency Checking.
--* memalign: (libc)Aligned Memory Blocks.
--* memccpy: (libc)Copying and Concatenation.
--* memchr: (libc)Search Functions.
--* memcmp: (libc)String/Array Comparison.
--* memcpy: (libc)Copying and Concatenation.
--* memmem: (libc)Search Functions.
--* memmove: (libc)Copying and Concatenation.
--* mempcpy: (libc)Copying and Concatenation.
--* memset: (libc)Copying and Concatenation.
--* mkdir: (libc)Creating Directories.
--* mkfifo: (libc)FIFO Special Files.
--* mknod: (libc)Making Special Files.
--* mkstemp: (libc)Temporary Files.
--* mktemp: (libc)Temporary Files.
--* mktime: (libc)Broken-down Time.
--* mmap: (libc)Memory-mapped I/O.
--* modf: (libc)Rounding Functions.
--* modff: (libc)Rounding Functions.
--* modfl: (libc)Rounding Functions.
--* mprobe: (libc)Heap Consistency Checking.
--* mrand48: (libc)SVID Random.
--* mrand48_r: (libc)SVID Random.
--* mremap: (libc)Memory-mapped I/O.
--* msync: (libc)Memory-mapped I/O.
--* mtrace: (libc)Tracing malloc.
--* munmap: (libc)Memory-mapped I/O.
--* muntrace: (libc)Tracing malloc.
--* nan: (libc)FP Bit Twiddling.
--* nanf: (libc)FP Bit Twiddling.
--* nanl: (libc)FP Bit Twiddling.
--* nanosleep: (libc)Sleeping.
--* nearbyint: (libc)Rounding Functions.
--* nearbyintf: (libc)Rounding Functions.
--* nearbyintl: (libc)Rounding Functions.
--* nextafter: (libc)FP Bit Twiddling.
--* nextafterf: (libc)FP Bit Twiddling.
--* nextafterl: (libc)FP Bit Twiddling.
--* nexttoward: (libc)FP Bit Twiddling.
--* nexttowardf: (libc)FP Bit Twiddling.
--* nexttowardl: (libc)FP Bit Twiddling.
--* nftw64: (libc)Working on Directory Trees.
--* nftw: (libc)Working on Directory Trees.
--* nice: (libc)Priority.
--* nl_langinfo: (libc)The Elegant and Fast Way.
--* nrand48: (libc)SVID Random.
--* nrand48_r: (libc)SVID Random.
--* ntohl: (libc)Byte Order.
--* ntohs: (libc)Byte Order.
--* ntp_adjtime: (libc)Precision Time.
--* ntp_gettime: (libc)Precision Time.
--* obstack_1grow: (libc)Growing Objects.
--* obstack_1grow_fast: (libc)Extra Fast Growing.
--* obstack_alignment_mask: (libc)Obstacks Data Alignment.
--* obstack_alloc: (libc)Allocation in an Obstack.
--* obstack_base: (libc)Status of an Obstack.
--* obstack_blank: (libc)Growing Objects.
--* obstack_blank_fast: (libc)Extra Fast Growing.
--* obstack_chunk_size: (libc)Obstack Chunks.
--* obstack_copy0: (libc)Allocation in an Obstack.
--* obstack_copy: (libc)Allocation in an Obstack.
--* obstack_finish: (libc)Growing Objects.
--* obstack_free: (libc)Freeing Obstack Objects.
--* obstack_grow0: (libc)Growing Objects.
--* obstack_grow: (libc)Growing Objects.
--* obstack_init: (libc)Preparing for Obstacks.
--* obstack_int_grow: (libc)Growing Objects.
--* obstack_int_grow_fast: (libc)Extra Fast Growing.
--* obstack_next_free: (libc)Status of an Obstack.
--* obstack_object_size: (libc)Growing Objects.
--* obstack_object_size: (libc)Status of an Obstack.
--* obstack_printf: (libc)Dynamic Output.
--* obstack_ptr_grow: (libc)Growing Objects.
--* obstack_ptr_grow_fast: (libc)Extra Fast Growing.
--* obstack_room: (libc)Extra Fast Growing.
--* obstack_vprintf: (libc)Variable Arguments Output.
--* offsetof: (libc)Structure Measurement.
--* on_exit: (libc)Cleanups on Exit.
--* open64: (libc)Opening and Closing Files.
--* open: (libc)Opening and Closing Files.
--* open_memstream: (libc)String Streams.
--* open_obstack_stream: (libc)Obstack Streams.
--* opendir: (libc)Opening a Directory.
--* openpty: (libc)Pseudo-Terminal Pairs.
--* parse_printf_format: (libc)Parsing a Template String.
--* pathconf: (libc)Pathconf.
--* pause: (libc)Using Pause.
--* pclose: (libc)Pipe to a Subprocess.
--* perror: (libc)Error Messages.
--* pipe: (libc)Creating a Pipe.
--* popen: (libc)Pipe to a Subprocess.
--* pow10: (libc)Exponents and Logarithms.
--* pow10f: (libc)Exponents and Logarithms.
--* pow10l: (libc)Exponents and Logarithms.
--* pow: (libc)Exponents and Logarithms.
--* powf: (libc)Exponents and Logarithms.
--* powl: (libc)Exponents and Logarithms.
--* pread64: (libc)I/O Primitives.
--* pread: (libc)I/O Primitives.
--* printf: (libc)Formatted Output Functions.
--* printf_size: (libc)Predefined Printf Handlers.
--* printf_size_info: (libc)Predefined Printf Handlers.
--* psignal: (libc)Signal Messages.
--* pthread_atfork: (libc)Miscellaneous Thread Functions.
--* pthread_attr_destroy: (libc)Thread Attributes.
--* pthread_attr_get@var{attr}: (libc)Thread Attributes.
--* pthread_attr_init: (libc)Thread Attributes.
--* pthread_attr_set@var{attr}: (libc)Thread Attributes.
--* pthread_cancel: (libc)Basic Thread Operations.
--* pthread_cleanup_pop: (libc)Cleanup Handlers.
--* pthread_cleanup_pop_restore_np: (libc)Cleanup Handlers.
--* pthread_cleanup_push: (libc)Cleanup Handlers.
--* pthread_cleanup_push_defer_np: (libc)Cleanup Handlers.
--* pthread_cond_broadcast: (libc)Condition Variables.
--* pthread_cond_destroy: (libc)Condition Variables.
--* pthread_cond_init: (libc)Condition Variables.
--* pthread_cond_signal: (libc)Condition Variables.
--* pthread_cond_timedwait: (libc)Condition Variables.
--* pthread_cond_wait: (libc)Condition Variables.
--* pthread_condattr_destroy: (libc)Condition Variables.
--* pthread_condattr_init: (libc)Condition Variables.
--* pthread_create: (libc)Basic Thread Operations.
--* pthread_detach: (libc)Miscellaneous Thread Functions.
--* pthread_equal: (libc)Miscellaneous Thread Functions.
--* pthread_exit: (libc)Basic Thread Operations.
--* pthread_getschedparam: (libc)Miscellaneous Thread Functions.
--* pthread_getspecific: (libc)Thread-Specific Data.
--* pthread_join: (libc)Basic Thread Operations.
--* pthread_key_create: (libc)Thread-Specific Data.
--* pthread_key_delete: (libc)Thread-Specific Data.
--* pthread_kill: (libc)Threads and Signal Handling.
--* pthread_kill_other_threads_np: (libc)Miscellaneous Thread Functions.
--* pthread_mutex_destroy: (libc)Mutexes.
--* pthread_mutex_init: (libc)Mutexes.
--* pthread_mutex_lock: (libc)Mutexes.
--* pthread_mutex_trylock: (libc)Mutexes.
--* pthread_mutex_unlock: (libc)Mutexes.
--* pthread_mutexattr_destroy: (libc)Mutexes.
--* pthread_mutexattr_getkind_np: (libc)Mutexes.
--* pthread_mutexattr_init: (libc)Mutexes.
--* pthread_mutexattr_setkind_np: (libc)Mutexes.
--* pthread_once: (libc)Miscellaneous Thread Functions.
--* pthread_self: (libc)Miscellaneous Thread Functions.
--* pthread_setcancelstate: (libc)Cancellation.
--* pthread_setcanceltype: (libc)Cancellation.
--* pthread_setschedparam: (libc)Miscellaneous Thread Functions.
--* pthread_setspecific: (libc)Thread-Specific Data.
--* pthread_sigmask: (libc)Threads and Signal Handling.
--* pthread_testcancel: (libc)Cancellation.
--* ptsname: (libc)Allocation.
--* ptsname_r: (libc)Allocation.
--* putc: (libc)Simple Output.
--* putchar: (libc)Simple Output.
--* putenv: (libc)Environment Access.
--* putpwent: (libc)Writing a User Entry.
--* puts: (libc)Simple Output.
--* pututline: (libc)Manipulating the Database.
--* pututxline: (libc)XPG Functions.
--* putw: (libc)Simple Output.
--* pwrite64: (libc)I/O Primitives.
--* pwrite: (libc)I/O Primitives.
--* qecvt: (libc)System V Number Conversion.
--* qecvt_r: (libc)System V Number Conversion.
--* qfcvt: (libc)System V Number Conversion.
--* qfcvt_r: (libc)System V Number Conversion.
--* qgcvt: (libc)System V Number Conversion.
--* qsort: (libc)Array Sort Function.
--* raise: (libc)Signaling Yourself.
--* rand: (libc)ISO Random.
--* rand_r: (libc)ISO Random.
--* random: (libc)BSD Random.
--* read: (libc)I/O Primitives.
--* readdir: (libc)Reading/Closing Directory.
--* readdir_r: (libc)Reading/Closing Directory.
--* readlink: (libc)Symbolic Links.
--* readv: (libc)Scatter-Gather.
--* realloc: (libc)Changing Block Size.
--* recv: (libc)Receiving Data.
--* recvfrom: (libc)Receiving Datagrams.
--* recvmsg: (libc)Receiving Datagrams.
--* regcomp: (libc)POSIX Regexp Compilation.
--* regerror: (libc)Regexp Cleanup.
--* regexec: (libc)Matching POSIX Regexps.
--* regfree: (libc)Regexp Cleanup.
--* register_printf_function: (libc)Registering New Conversions.
--* remainder: (libc)Remainder Functions.
--* remainderf: (libc)Remainder Functions.
--* remainderl: (libc)Remainder Functions.
--* remove: (libc)Deleting Files.
--* rename: (libc)Renaming Files.
--* rewind: (libc)File Positioning.
--* rewinddir: (libc)Random Access Directory.
--* rindex: (libc)Search Functions.
--* rint: (libc)Rounding Functions.
--* rintf: (libc)Rounding Functions.
--* rintl: (libc)Rounding Functions.
--* rmdir: (libc)Deleting Files.
--* round: (libc)Rounding Functions.
--* roundf: (libc)Rounding Functions.
--* roundl: (libc)Rounding Functions.
--* scalb: (libc)Normalization Functions.
--* scalbf: (libc)Normalization Functions.
--* scalbl: (libc)Normalization Functions.
--* scalbln: (libc)Normalization Functions.
--* scalblnf: (libc)Normalization Functions.
--* scalblnl: (libc)Normalization Functions.
--* scalbn: (libc)Normalization Functions.
--* scalbnf: (libc)Normalization Functions.
--* scalbnl: (libc)Normalization Functions.
--* scandir64: (libc)Scanning Directory Content.
--* scandir: (libc)Scanning Directory Content.
--* scanf: (libc)Formatted Input Functions.
--* seed48: (libc)SVID Random.
--* seed48_r: (libc)SVID Random.
--* seekdir: (libc)Random Access Directory.
--* select: (libc)Waiting for I/O.
--* sem_destroy: (libc)POSIX Semaphores.
--* sem_getvalue: (libc)POSIX Semaphores.
--* sem_init: (libc)POSIX Semaphores.
--* sem_post: (libc)POSIX Semaphores.
--* sem_trywait: (libc)POSIX Semaphores.
--* sem_wait: (libc)POSIX Semaphores.
--* send: (libc)Sending Data.
--* sendmsg: (libc)Receiving Datagrams.
--* sendto: (libc)Sending Datagrams.
--* setbuf: (libc)Controlling Buffering.
--* setbuffer: (libc)Controlling Buffering.
--* setegid: (libc)Setting Groups.
--* setenv: (libc)Environment Access.
--* seteuid: (libc)Setting User ID.
--* setfsent: (libc)Filesystem handling.
--* setgid: (libc)Setting Groups.
--* setgrent: (libc)Scanning All Groups.
--* setgroups: (libc)Setting Groups.
--* sethostent: (libc)Host Names.
--* sethostid: (libc)Host Identification.
--* sethostname: (libc)Host Identification.
--* setitimer: (libc)Setting an Alarm.
--* setjmp: (libc)Non-Local Details.
--* setkey: (libc)DES Encryption.
--* setkey_r: (libc)DES Encryption.
--* setlinebuf: (libc)Controlling Buffering.
--* setlocale: (libc)Setting the Locale.
--* setmntent: (libc)Filesystem handling.
--* setnetent: (libc)Networks Database.
--* setnetgrent: (libc)Lookup Netgroup.
--* setpgid: (libc)Process Group Functions.
--* setpgrp: (libc)Process Group Functions.
--* setpriority: (libc)Priority.
--* setprotoent: (libc)Protocols Database.
--* setpwent: (libc)Scanning All Users.
--* setregid: (libc)Setting Groups.
--* setreuid: (libc)Setting User ID.
--* setrlimit64: (libc)Limits on Resources.
--* setrlimit: (libc)Limits on Resources.
--* setservent: (libc)Services Database.
--* setsid: (libc)Process Group Functions.
--* setsockopt: (libc)Socket Option Functions.
--* setstate: (libc)BSD Random.
--* settimeofday: (libc)High-Resolution Calendar.
--* setuid: (libc)Setting User ID.
--* setutent: (libc)Manipulating the Database.
--* setutxent: (libc)XPG Functions.
--* setvbuf: (libc)Controlling Buffering.
--* shutdown: (libc)Closing a Socket.
--* sigaction: (libc)Advanced Signal Handling.
--* sigaddset: (libc)Signal Sets.
--* sigaltstack: (libc)Signal Stack.
--* sigblock: (libc)Blocking in BSD.
--* sigdelset: (libc)Signal Sets.
--* sigemptyset: (libc)Signal Sets.
--* sigfillset: (libc)Signal Sets.
--* siginterrupt: (libc)BSD Handler.
--* sigismember: (libc)Signal Sets.
--* siglongjmp: (libc)Non-Local Exits and Signals.
--* sigmask: (libc)Blocking in BSD.
--* signal: (libc)Basic Signal Handling.
--* signbit: (libc)FP Bit Twiddling.
--* significand: (libc)Normalization Functions.
--* significandf: (libc)Normalization Functions.
--* significandl: (libc)Normalization Functions.
--* sigpause: (libc)Blocking in BSD.
--* sigpending: (libc)Checking for Pending Signals.
--* sigprocmask: (libc)Process Signal Mask.
--* sigsetjmp: (libc)Non-Local Exits and Signals.
--* sigsetmask: (libc)Blocking in BSD.
--* sigstack: (libc)Signal Stack.
--* sigsuspend: (libc)Sigsuspend.
--* sigvec: (libc)BSD Handler.
--* sigwait: (libc)Threads and Signal Handling.
--* sin: (libc)Trig Functions.
--* sincos: (libc)Trig Functions.
--* sincosf: (libc)Trig Functions.
--* sincosl: (libc)Trig Functions.
--* sinf: (libc)Trig Functions.
--* sinh: (libc)Hyperbolic Functions.
--* sinhf: (libc)Hyperbolic Functions.
--* sinhl: (libc)Hyperbolic Functions.
--* sinl: (libc)Trig Functions.
--* sleep: (libc)Sleeping.
--* snprintf: (libc)Formatted Output Functions.
--* socket: (libc)Creating a Socket.
--* socketpair: (libc)Socket Pairs.
--* sprintf: (libc)Formatted Output Functions.
--* sqrt: (libc)Exponents and Logarithms.
--* sqrtf: (libc)Exponents and Logarithms.
--* sqrtl: (libc)Exponents and Logarithms.
--* srand48: (libc)SVID Random.
--* srand48_r: (libc)SVID Random.
--* srand: (libc)ISO Random.
--* srandom: (libc)BSD Random.
--* sscanf: (libc)Formatted Input Functions.
--* ssignal: (libc)Basic Signal Handling.
--* stat64: (libc)Reading Attributes.
--* stat: (libc)Reading Attributes.
--* stpcpy: (libc)Copying and Concatenation.
--* stpncpy: (libc)Copying and Concatenation.
--* strcasecmp: (libc)String/Array Comparison.
--* strcat: (libc)Copying and Concatenation.
--* strchr: (libc)Search Functions.
--* strcmp: (libc)String/Array Comparison.
--* strcoll: (libc)Collation Functions.
--* strcpy: (libc)Copying and Concatenation.
--* strcspn: (libc)Search Functions.
--* strdup: (libc)Copying and Concatenation.
--* strdupa: (libc)Copying and Concatenation.
--* strerror: (libc)Error Messages.
--* strerror_r: (libc)Error Messages.
--* strfmon: (libc)Formatting Numbers.
--* strftime: (libc)Formatting Date and Time.
--* strlen: (libc)String Length.
--* strncasecmp: (libc)String/Array Comparison.
--* strncat: (libc)Copying and Concatenation.
--* strncmp: (libc)String/Array Comparison.
--* strncpy: (libc)Copying and Concatenation.
--* strndup: (libc)Copying and Concatenation.
--* strndupa: (libc)Copying and Concatenation.
--* strnlen: (libc)String Length.
--* strpbrk: (libc)Search Functions.
--* strptime: (libc)Low-Level Time String Parsing.
--* strrchr: (libc)Search Functions.
--* strsep: (libc)Finding Tokens in a String.
--* strsignal: (libc)Signal Messages.
--* strspn: (libc)Search Functions.
--* strstr: (libc)Search Functions.
--* strtod: (libc)Parsing of Floats.
--* strtof: (libc)Parsing of Floats.
--* strtok: (libc)Finding Tokens in a String.
--* strtok_r: (libc)Finding Tokens in a String.
--* strtol: (libc)Parsing of Integers.
--* strtold: (libc)Parsing of Floats.
--* strtoll: (libc)Parsing of Integers.
--* strtoq: (libc)Parsing of Integers.
--* strtoul: (libc)Parsing of Integers.
--* strtoull: (libc)Parsing of Integers.
--* strtouq: (libc)Parsing of Integers.
--* strverscmp: (libc)String/Array Comparison.
--* strxfrm: (libc)Collation Functions.
--* symlink: (libc)Symbolic Links.
--* sync: (libc)Synchronizing I/O.
--* sysconf: (libc)Sysconf Definition.
--* system: (libc)Running a Command.
--* sysv_signal: (libc)Basic Signal Handling.
--* tan: (libc)Trig Functions.
--* tanf: (libc)Trig Functions.
--* tanh: (libc)Hyperbolic Functions.
--* tanhf: (libc)Hyperbolic Functions.
--* tanhl: (libc)Hyperbolic Functions.
--* tanl: (libc)Trig Functions.
--* tcdrain: (libc)Line Control.
--* tcflow: (libc)Line Control.
--* tcflush: (libc)Line Control.
--* tcgetattr: (libc)Mode Functions.
--* tcgetpgrp: (libc)Terminal Access Functions.
--* tcgetsid: (libc)Terminal Access Functions.
--* tcsendbreak: (libc)Line Control.
--* tcsetattr: (libc)Mode Functions.
--* tcsetpgrp: (libc)Terminal Access Functions.
--* tdelete: (libc)Tree Search Function.
--* tdestroy: (libc)Tree Search Function.
--* telldir: (libc)Random Access Directory.
--* tempnam: (libc)Temporary Files.
--* textdomain: (libc)Locating gettext catalog.
--* tfind: (libc)Tree Search Function.
--* tgamma: (libc)Special Functions.
--* tgammaf: (libc)Special Functions.
--* tgammal: (libc)Special Functions.
--* time: (libc)Simple Calendar Time.
--* times: (libc)Detailed CPU Time.
--* tmpfile64: (libc)Temporary Files.
--* tmpfile: (libc)Temporary Files.
--* tmpnam: (libc)Temporary Files.
--* tmpnam_r: (libc)Temporary Files.
--* toascii: (libc)Case Conversion.
--* tolower: (libc)Case Conversion.
--* toupper: (libc)Case Conversion.
--* towctrans: (libc)Wide Character Case Conversion.
--* towlower: (libc)Wide Character Case Conversion.
--* towupper: (libc)Wide Character Case Conversion.
--* trunc: (libc)Rounding Functions.
--* truncate64: (libc)Truncating Files.
--* truncate: (libc)File Size.
--* truncate: (libc)Truncating Files.
--* truncf: (libc)Rounding Functions.
--* truncl: (libc)Rounding Functions.
--* tsearch: (libc)Tree Search Function.
--* ttyname: (libc)Is It a Terminal.
--* ttyname_r: (libc)Is It a Terminal.
--* twalk: (libc)Tree Search Function.
--* tzset: (libc)Time Zone Functions.
--* umask: (libc)Setting Permissions.
--* uname: (libc)Hardware/Software Type ID.
--* ungetc: (libc)How Unread.
--* unlink: (libc)Deleting Files.
--* unlockpt: (libc)Allocation.
--* unsetenv: (libc)Environment Access.
--* updwtmp: (libc)Manipulating the Database.
--* utime: (libc)File Times.
--* utimes: (libc)File Times.
--* utmpname: (libc)Manipulating the Database.
--* va_arg: (libc)Argument Macros.
--* va_end: (libc)Argument Macros.
--* va_start: (libc)Argument Macros.
--* va_start: (libc)Old Varargs.
--* valloc: (libc)Aligned Memory Blocks.
--* vasprintf: (libc)Variable Arguments Output.
--* versionsort64: (libc)Scanning Directory Content.
--* versionsort: (libc)Scanning Directory Content.
--* vfork: (libc)Creating a Process.
--* vfprintf: (libc)Variable Arguments Output.
--* vfscanf: (libc)Variable Arguments Input.
--* vprintf: (libc)Variable Arguments Output.
--* vscanf: (libc)Variable Arguments Input.
--* vsnprintf: (libc)Variable Arguments Output.
--* vsprintf: (libc)Variable Arguments Output.
--* vsscanf: (libc)Variable Arguments Input.
--* wait3: (libc)BSD Wait Functions.
--* wait4: (libc)Process Completion.
--* wait: (libc)Process Completion.
--* waitpid: (libc)Process Completion.
--* wcrtomb: (libc)Converting a Character.
--* wcsnrtombs: (libc)Converting Strings.
--* wcsrtombs: (libc)Converting Strings.
--* wcstombs: (libc)Non-reentrant String Conversion.
--* wctob: (libc)Converting a Character.
--* wctomb: (libc)Non-reentrant Character Conversion.
--* wctrans: (libc)Wide Character Case Conversion.
--* wctype: (libc)Classification of Wide Characters.
--* wordexp: (libc)Calling Wordexp.
--* wordfree: (libc)Calling Wordexp.
--* write: (libc)I/O Primitives.
--* writev: (libc)Scatter-Gather.
--* y0: (libc)Special Functions.
--* y0f: (libc)Special Functions.
--* y0l: (libc)Special Functions.
--* y1: (libc)Special Functions.
--* y1f: (libc)Special Functions.
--* y1l: (libc)Special Functions.
--* yn: (libc)Special Functions.
--* ynf: (libc)Special Functions.
--* ynl: (libc)Special Functions.
--END-INFO-DIR-ENTRY
-diff -Naur ../glibc-2.1.3/manual/dir.c.texi glibc-2.1.3/manual/dir.c.texi
---- ../glibc-2.1.3/manual/dir.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/dir.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,25 +0,0 @@
--@group
--#include <stddef.h>
--#include <stdio.h>
--#include <sys/types.h>
--#include <dirent.h>
--@end group
--
--int
--main (void)
--@{
-- DIR *dp;
-- struct dirent *ep;
--
-- dp = opendir ("./");
-- if (dp != NULL)
-- @{
-- while (ep = readdir (dp))
-- puts (ep->d_name);
-- (void) closedir (dp);
-- @}
-- else
-- puts ("Couldn't open the directory.");
--
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/dir2.c.texi glibc-2.1.3/manual/dir2.c.texi
---- ../glibc-2.1.3/manual/dir2.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/dir2.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,29 +0,0 @@
--@group
--#include <stdio.h>
--#include <dirent.h>
--@end group
--
--static int
--one (struct dirent *unused)
--@{
-- return 1;
--@}
--
--int
--main (void)
--@{
-- struct dirent **eps;
-- int n;
--
-- n = scandir ("./", &eps, one, alphasort);
-- if (n >= 0)
-- @{
-- int cnt;
-- for (cnt = 0; cnt < n; ++cnt)
-- puts (eps[cnt]->d_name);
-- @}
-- else
-- perror ("Couldn't open the directory");
--
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/filecli.c.texi glibc-2.1.3/manual/filecli.c.texi
---- ../glibc-2.1.3/manual/filecli.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/filecli.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,54 +0,0 @@
--#include <stdio.h>
--#include <errno.h>
--#include <unistd.h>
--#include <stdlib.h>
--#include <sys/socket.h>
--#include <sys/un.h>
--
--#define SERVER "/tmp/serversocket"
--#define CLIENT "/tmp/mysocket"
--#define MAXMSG 512
--#define MESSAGE "Yow!!! Are we having fun yet?!?"
--
--int
--main (void)
--@{
-- extern int make_named_socket (const char *name);
-- int sock;
-- char message[MAXMSG];
-- struct sockaddr_un name;
-- size_t size;
-- int nbytes;
--
-- /* @r{Make the socket.} */
-- sock = make_named_socket (CLIENT);
--
-- /* @r{Initialize the server socket address.} */
-- name.sun_family = AF_LOCAL;
-- strcpy (name.sun_path, SERVER);
-- size = strlen (name.sun_path) + sizeof (name.sun_family);
--
-- /* @r{Send the datagram.} */
-- nbytes = sendto (sock, MESSAGE, strlen (MESSAGE) + 1, 0,
-- (struct sockaddr *) & name, size);
-- if (nbytes < 0)
-- @{
-- perror ("sendto (client)");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Wait for a reply.} */
-- nbytes = recvfrom (sock, message, MAXMSG, 0, NULL, 0);
-- if (nbytes < 0)
-- @{
-- perror ("recfrom (client)");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Print a diagnostic message.} */
-- fprintf (stderr, "Client: got message: %s\n", message);
--
-- /* @r{Clean up.} */
-- remove (CLIENT);
-- close (sock);
--@}
-diff -Naur ../glibc-2.1.3/manual/filesrv.c.texi glibc-2.1.3/manual/filesrv.c.texi
---- ../glibc-2.1.3/manual/filesrv.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/filesrv.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,48 +0,0 @@
--#include <stdio.h>
--#include <errno.h>
--#include <stdlib.h>
--#include <sys/socket.h>
--#include <sys/un.h>
--
--#define SERVER "/tmp/serversocket"
--#define MAXMSG 512
--
--int
--main (void)
--@{
-- int sock;
-- char message[MAXMSG];
-- struct sockaddr_un name;
-- size_t size;
-- int nbytes;
--
-- /* @r{Remove the filename first, it's ok if the call fails} */
-- unlink (SERVER);
--
-- /* @r{Make the socket, then loop endlessly.} */
-- sock = make_named_socket (SERVER);
-- while (1)
-- @{
-- /* @r{Wait for a datagram.} */
-- size = sizeof (name);
-- nbytes = recvfrom (sock, message, MAXMSG, 0,
-- (struct sockaddr *) & name, &size);
-- if (nbytes < 0)
-- @{
-- perror ("recfrom (server)");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Give a diagnostic message.} */
-- fprintf (stderr, "Server: got message: %s\n", message);
--
-- /* @r{Bounce the message back to the sender.} */
-- nbytes = sendto (sock, message, nbytes, 0,
-- (struct sockaddr *) & name, size);
-- if (nbytes < 0)
-- @{
-- perror ("sendto (server)");
-- exit (EXIT_FAILURE);
-- @}
-- @}
--@}
-diff -Naur ../glibc-2.1.3/manual/fmtmsgexpl.c.texi glibc-2.1.3/manual/fmtmsgexpl.c.texi
---- ../glibc-2.1.3/manual/fmtmsgexpl.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/fmtmsgexpl.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,12 +0,0 @@
--#include <fmtmsg.h>
--
--int
--main (void)
--@{
-- addseverity (5, "NOTE2");
-- fmtmsg (MM_PRINT, "only1field", MM_INFO, "text2", "action2", "tag2");
-- fmtmsg (MM_PRINT, "UX:cat", 5, "invalid syntax", "refer to manual",
-- "UX:cat:001");
-- fmtmsg (MM_PRINT, "label:foo", 6, "text", "action", "tag");
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/inetcli.c.texi glibc-2.1.3/manual/inetcli.c.texi
---- ../glibc-2.1.3/manual/inetcli.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/inetcli.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,59 +0,0 @@
--#include <stdio.h>
--#include <errno.h>
--#include <stdlib.h>
--#include <unistd.h>
--#include <sys/types.h>
--#include <sys/socket.h>
--#include <netinet/in.h>
--#include <netdb.h>
--
--#define PORT 5555
--#define MESSAGE "Yow!!! Are we having fun yet?!?"
--#define SERVERHOST "mescaline.gnu.org"
--
--void
--write_to_server (int filedes)
--@{
-- int nbytes;
--
-- nbytes = write (filedes, MESSAGE, strlen (MESSAGE) + 1);
-- if (nbytes < 0)
-- @{
-- perror ("write");
-- exit (EXIT_FAILURE);
-- @}
--@}
--
--
--int
--main (void)
--@{
-- extern void init_sockaddr (struct sockaddr_in *name,
-- const char *hostname,
-- uint16_t port);
-- int sock;
-- struct sockaddr_in servername;
--
-- /* @r{Create the socket.} */
-- sock = socket (PF_INET, SOCK_STREAM, 0);
-- if (sock < 0)
-- @{
-- perror ("socket (client)");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Connect to the server.} */
-- init_sockaddr (&servername, SERVERHOST, PORT);
-- if (0 > connect (sock,
-- (struct sockaddr *) &servername,
-- sizeof (servername)))
-- @{
-- perror ("connect (client)");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Send data to the server.} */
-- write_to_server (sock);
-- close (sock);
-- exit (EXIT_SUCCESS);
--@}
-diff -Naur ../glibc-2.1.3/manual/inetsrv.c.texi glibc-2.1.3/manual/inetsrv.c.texi
---- ../glibc-2.1.3/manual/inetsrv.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/inetsrv.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,103 +0,0 @@
--#include <stdio.h>
--#include <errno.h>
--#include <stdlib.h>
--#include <unistd.h>
--#include <sys/types.h>
--#include <sys/socket.h>
--#include <netinet/in.h>
--#include <netdb.h>
--
--#define PORT 5555
--#define MAXMSG 512
--
--int
--read_from_client (int filedes)
--@{
-- char buffer[MAXMSG];
-- int nbytes;
--
-- nbytes = read (filedes, buffer, MAXMSG);
-- if (nbytes < 0)
-- @{
-- /* @r{Read error.} */
-- perror ("read");
-- exit (EXIT_FAILURE);
-- @}
-- else if (nbytes == 0)
-- /* @r{End-of-file.} */
-- return -1;
-- else
-- @{
-- /* @r{Data read.} */
-- fprintf (stderr, "Server: got message: `%s'\n", buffer);
-- return 0;
-- @}
--@}
--
--int
--main (void)
--@{
-- extern int make_socket (uint16_t port);
-- int sock;
-- fd_set active_fd_set, read_fd_set;
-- int i;
-- struct sockaddr_in clientname;
-- size_t size;
--
-- /* @r{Create the socket and set it up to accept connections.} */
-- sock = make_socket (PORT);
-- if (listen (sock, 1) < 0)
-- @{
-- perror ("listen");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Initialize the set of active sockets.} */
-- FD_ZERO (&active_fd_set);
-- FD_SET (sock, &active_fd_set);
--
-- while (1)
-- @{
-- /* @r{Block until input arrives on one or more active sockets.} */
-- read_fd_set = active_fd_set;
-- if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
-- @{
-- perror ("select");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Service all the sockets with input pending.} */
-- for (i = 0; i < FD_SETSIZE; ++i)
-- if (FD_ISSET (i, &read_fd_set))
-- @{
-- if (i == sock)
-- @{
-- /* @r{Connection request on original socket.} */
-- int new;
-- size = sizeof (clientname);
-- new = accept (sock,
-- (struct sockaddr *) &clientname,
-- &size);
-- if (new < 0)
-- @{
-- perror ("accept");
-- exit (EXIT_FAILURE);
-- @}
-- fprintf (stderr,
-- "Server: connect from host %s, port %hd.\n",
-- inet_ntoa (clientname.sin_addr),
-- ntohs (clientname.sin_port));
-- FD_SET (new, &active_fd_set);
-- @}
-- else
-- @{
-- /* @r{Data arriving on an already-connected socket.} */
-- if (read_from_client (i) < 0)
-- @{
-- close (i);
-- FD_CLR (i, &active_fd_set);
-- @}
-- @}
-- @}
-- @}
--@}
-diff -Naur ../glibc-2.1.3/manual/isockad.c.texi glibc-2.1.3/manual/isockad.c.texi
---- ../glibc-2.1.3/manual/isockad.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/isockad.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,23 +0,0 @@
--#include <stdio.h>
--#include <stdlib.h>
--#include <sys/socket.h>
--#include <netinet/in.h>
--#include <netdb.h>
--
--void
--init_sockaddr (struct sockaddr_in *name,
-- const char *hostname,
-- uint16_t port)
--@{
-- struct hostent *hostinfo;
--
-- name->sin_family = AF_INET;
-- name->sin_port = htons (port);
-- hostinfo = gethostbyname (hostname);
-- if (hostinfo == NULL)
-- @{
-- fprintf (stderr, "Unknown host %s.\n", hostname);
-- exit (EXIT_FAILURE);
-- @}
-- name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
--@}
-diff -Naur ../glibc-2.1.3/manual/libc.cp glibc-2.1.3/manual/libc.cp
---- ../glibc-2.1.3/manual/libc.cp 2000-01-05 19:19:29.000000000 -0800
-+++ glibc-2.1.3/manual/libc.cp 1969-12-31 16:00:00.000000000 -0800
-@@ -1,939 +0,0 @@
--\entry{library}{1}{library}
--\entry{standards}{1}{standards}
--\entry{ISO C}{2}{ISO C}
--\entry{POSIX}{2}{POSIX}
--\entry{POSIX.1}{2}{POSIX.1}
--\entry{IEEE Std 1003.1}{2}{IEEE Std 1003.1}
--\entry{ISO/IEC 9945-1}{2}{ISO/IEC 9945-1}
--\entry{POSIX.2}{2}{POSIX.2}
--\entry{IEEE Std 1003.2}{2}{IEEE Std 1003.2}
--\entry{ISO/IEC 9945-2}{2}{ISO/IEC 9945-2}
--\entry{BSD Unix}{3}{BSD Unix}
--\entry{4.n BSD Unix}{3}{4.\var {n} BSD Unix}
--\entry{Berkeley Unix}{3}{Berkeley Unix}
--\entry{SunOS}{3}{SunOS}
--\entry{Unix, Berkeley}{3}{Unix, Berkeley}
--\entry{SVID}{3}{SVID}
--\entry{System V Unix}{3}{System V Unix}
--\entry{Unix, System V}{3}{Unix, System V}
--\entry{header files}{4}{header files}
--\entry{definition (compared to declaration)}{4}{definition (compared to declaration)}
--\entry{declaration (compared to definition)}{4}{declaration (compared to definition)}
--\entry{shadowing functions with macros}{5}{shadowing functions with macros}
--\entry{removing macros that shadow functions}{5}{removing macros that shadow functions}
--\entry{undefining macros that shadow functions}{5}{undefining macros that shadow functions}
--\entry{reserved names}{5}{reserved names}
--\entry{name space}{5}{name space}
--\entry{feature test macros}{7}{feature test macros}
--\entry{BSD compatibility library.}{8}{BSD compatibility library.}
--\entry{error reporting}{15}{error reporting}
--\entry{reporting errors}{15}{reporting errors}
--\entry{error codes}{15}{error codes}
--\entry{status codes}{15}{status codes}
--\entry{program name}{28}{program name}
--\entry{name of running program}{28}{name of running program}
--\entry{memory allocation}{31}{memory allocation}
--\entry{storage allocation}{31}{storage allocation}
--\entry{dynamic allocation}{31}{dynamic allocation}
--\entry{static allocation}{31}{static allocation}
--\entry{automatic allocation}{31}{automatic allocation}
--\entry{unconstrained storage allocation}{32}{unconstrained storage allocation}
--\entry{malloc function}{32}{\code {malloc} function}
--\entry{heap, dynamic allocation from}{32}{heap, dynamic allocation from}
--\entry{allocation of memory with malloc}{32}{allocation of memory with \code {malloc}}
--\entry{freeing memory allocated with malloc}{34}{freeing memory allocated with \code {malloc}}
--\entry{heap, freeing memory from}{34}{heap, freeing memory from}
--\entry{changing the size of a block (malloc)}{34}{changing the size of a block (\code {malloc})}
--\entry{efficiency and malloc}{36}{efficiency and \code {malloc}}
--\entry{page boundary}{36}{page boundary}
--\entry{alignment (with malloc)}{36}{alignment (with \code {malloc})}
--\entry{heap consistency checking}{37}{heap consistency checking}
--\entry{consistency checking, of heap}{37}{consistency checking, of heap}
--\entry{allocation hooks, for malloc}{39}{allocation hooks, for \code {malloc}}
--\entry{allocation statistics}{41}{allocation statistics}
--\entry{allocation debugging}{43}{allocation debugging}
--\entry{malloc debugger}{43}{malloc debugger}
--\entry{obstacks}{47}{obstacks}
--\entry{allocation (obstacks)}{48}{allocation (obstacks)}
--\entry{freeing (obstacks)}{50}{freeing (obstacks)}
--\entry{macros}{50}{macros}
--\entry{growing objects (in obstacks)}{51}{growing objects (in obstacks)}
--\entry{changing the size of a block (obstacks)}{51}{changing the size of a block (obstacks)}
--\entry{shrinking objects}{52}{shrinking objects}
--\entry{efficiency and obstacks}{52}{efficiency and obstacks}
--\entry{obstack status}{54}{obstack status}
--\entry{status of obstack}{54}{status of obstack}
--\entry{alignment (in obstacks)}{55}{alignment (in obstacks)}
--\entry{efficiency of chunks}{55}{efficiency of chunks}
--\entry{chunks}{55}{chunks}
--\entry{automatic freeing}{57}{automatic freeing}
--\entry{alloca function}{57}{\code {alloca} function}
--\entry{automatic storage with variable size}{57}{automatic storage with variable size}
--\entry{longjmp}{58}{longjmp}
--\entry{alloca disadvantages}{59}{\code {alloca} disadvantages}
--\entry{disadvantages of alloca}{59}{disadvantages of \code {alloca}}
--\entry{variable-sized arrays}{59}{variable-sized arrays}
--\entry{character testing}{61}{character testing}
--\entry{classification of characters}{61}{classification of characters}
--\entry{predicates on characters}{61}{predicates on characters}
--\entry{character predicates}{61}{character predicates}
--\entry{lower-case character}{61}{lower-case character}
--\entry{upper-case character}{61}{upper-case character}
--\entry{alphabetic character}{61}{alphabetic character}
--\entry{digit character}{62}{digit character}
--\entry{decimal digit character}{62}{decimal digit character}
--\entry{alphanumeric character}{62}{alphanumeric character}
--\entry{hexadecimal digit character}{62}{hexadecimal digit character}
--\entry{punctuation character}{62}{punctuation character}
--\entry{whitespace character}{62}{whitespace character}
--\entry{blank character}{62}{blank character}
--\entry{graphic character}{62}{graphic character}
--\entry{printing character}{62}{printing character}
--\entry{control character}{62}{control character}
--\entry{ASCII character}{63}{ASCII character}
--\entry{character case conversion}{63}{character case conversion}
--\entry{case conversion of characters}{63}{case conversion of characters}
--\entry{converting case of characters}{63}{converting case of characters}
--\entry{alphanumeric character}{64}{alphanumeric character}
--\entry{alphabetic character}{65}{alphabetic character}
--\entry{control character}{65}{control character}
--\entry{digit character}{65}{digit character}
--\entry{graphic character}{65}{graphic character}
--\entry{lower-case character}{66}{lower-case character}
--\entry{printing character}{66}{printing character}
--\entry{punctuation character}{66}{punctuation character}
--\entry{whitespace character}{66}{whitespace character}
--\entry{upper-case character}{67}{upper-case character}
--\entry{hexadecimal digit character}{67}{hexadecimal digit character}
--\entry{blank character}{67}{blank character}
--\entry{string, representation of}{71}{string, representation of}
--\entry{string}{71}{string}
--\entry{null character}{71}{null character}
--\entry{string literal}{71}{string literal}
--\entry{length of string}{71}{length of string}
--\entry{allocation size of string}{71}{allocation size of string}
--\entry{size of string}{71}{size of string}
--\entry{string length}{71}{string length}
--\entry{string allocation}{71}{string allocation}
--\entry{copying strings and arrays}{73}{copying strings and arrays}
--\entry{string copy functions}{73}{string copy functions}
--\entry{array copy functions}{73}{array copy functions}
--\entry{concatenating strings}{73}{concatenating strings}
--\entry{string concatenation functions}{73}{string concatenation functions}
--\entry{{\_}{\_}va{\_}copy}{77}{__va_copy}
--\entry{va{\_}copy}{77}{va_copy}
--\entry{comparing strings and arrays}{80}{comparing strings and arrays}
--\entry{string comparison functions}{80}{string comparison functions}
--\entry{array comparison functions}{80}{array comparison functions}
--\entry{predicates on strings}{80}{predicates on strings}
--\entry{predicates on arrays}{80}{predicates on arrays}
--\entry{collating strings}{83}{collating strings}
--\entry{string collation functions}{83}{string collation functions}
--\entry{converting string to collation order}{84}{converting string to collation order}
--\entry{search functions (for strings)}{86}{search functions (for strings)}
--\entry{string search functions}{86}{string search functions}
--\entry{tokenizing strings}{88}{tokenizing strings}
--\entry{breaking a string into tokens}{88}{breaking a string into tokens}
--\entry{parsing tokens from a string}{88}{parsing tokens from a string}
--\entry{argz vectors (string vectors)}{93}{argz vectors (string vectors)}
--\entry{string vectors, null-character separated}{93}{string vectors, null-character separated}
--\entry{argument vectors, null-character separated}{93}{argument vectors, null-character separated}
--\entry{envz vectors (environment vectors)}{93}{envz vectors (environment vectors)}
--\entry{environment vectors, null-character separated}{93}{environment vectors, null-character separated}
--\entry{internal representation}{97}{internal representation}
--\entry{wide character}{97}{wide character}
--\entry{Unicode}{97}{Unicode}
--\entry{ISO 10646}{97}{ISO 10646}
--\entry{UCS2}{97}{UCS2}
--\entry{UCS4}{97}{UCS4}
--\entry{multibyte character}{99}{multibyte character}
--\entry{EBCDIC}{99}{EBCDIC}
--\entry{ISO 2022}{99}{ISO 2022}
--\entry{EUC}{99}{EUC}
--\entry{SJIS}{99}{SJIS}
--\entry{ISO 6937}{100}{ISO 6937}
--\entry{UTF-8}{100}{UTF-8}
--\entry{UTF-7}{100}{UTF-7}
--\entry{stateful}{102}{stateful}
--\entry{shift state}{102}{shift state}
--\entry{stateful}{105}{stateful}
--\entry{stateful}{110}{stateful}
--\entry{stateful}{121}{stateful}
--\entry{stateful}{124}{stateful}
--\entry{triangulation}{126}{triangulation}
--\entry{ISO-2022-JP}{127}{ISO-2022-JP}
--\entry{EUC-JP}{127}{EUC-JP}
--\entry{stateful}{135}{stateful}
--\entry{internationalization}{141}{internationalization}
--\entry{locales}{141}{locales}
--\entry{combining locales}{142}{combining locales}
--\entry{categories for locales}{142}{categories for locales}
--\entry{locale categories}{142}{locale categories}
--\entry{changing the locale}{143}{changing the locale}
--\entry{locale, changing}{143}{locale, changing}
--\entry{monetary value formatting}{146}{monetary value formatting}
--\entry{numeric value formatting}{146}{numeric value formatting}
--\entry{decimal-point separator}{146}{decimal-point separator}
--\entry{grouping of digits}{146}{grouping of digits}
--\entry{currency symbols}{147}{currency symbols}
--\entry{NLSPATH environment variable}{160}{NLSPATH environment variable}
--\entry{LC{\_}ALL environment variable}{161}{LC_ALL environment variable}
--\entry{LC{\_}MESSAGES environment variable}{161}{LC_MESSAGES environment variable}
--\entry{LANG environment variable}{161}{LANG environment variable}
--\entry{gencat}{164}{gencat}
--\entry{Comparison Function}{177}{Comparison Function}
--\entry{search function (for arrays)}{177}{search function (for arrays)}
--\entry{binary search function (for arrays)}{177}{binary search function (for arrays)}
--\entry{array search function}{177}{array search function}
--\entry{sort function (for arrays)}{178}{sort function (for arrays)}
--\entry{quick sort function (for arrays)}{178}{quick sort function (for arrays)}
--\entry{array sort function}{178}{array sort function}
--\entry{stable sorting}{178}{stable sorting}
--\entry{Kermit the frog}{181}{Kermit the frog}
--\entry{globbing}{188}{globbing}
--\entry{word expansion}{198}{word expansion}
--\entry{expansion of shell words}{198}{expansion of shell words}
--\entry{tilde expansion}{199}{tilde expansion}
--\entry{variable substitution}{199}{variable substitution}
--\entry{substitution of variables and commands}{199}{substitution of variables and commands}
--\entry{command substitution}{199}{command substitution}
--\entry{arithmetic expansion}{199}{arithmetic expansion}
--\entry{field splitting}{199}{field splitting}
--\entry{wildcard expansion}{199}{wildcard expansion}
--\entry{quote removal}{199}{quote removal}
--\entry{removal of quotes}{199}{removal of quotes}
--\entry{opening a file}{205}{opening a file}
--\entry{file position}{206}{file position}
--\entry{sequential-access files}{206}{sequential-access files}
--\entry{random-access files}{206}{random-access files}
--\entry{append-access files}{207}{append-access files}
--\entry{file name}{207}{file name}
--\entry{directory}{207}{directory}
--\entry{link}{207}{link}
--\entry{directory entry}{207}{directory entry}
--\entry{file name component}{207}{file name component}
--\entry{file name resolution}{208}{file name resolution}
--\entry{root directory}{208}{root directory}
--\entry{absolute file name}{208}{absolute file name}
--\entry{relative file name}{208}{relative file name}
--\entry{parent directory}{208}{parent directory}
--\entry{file name errors}{208}{file name errors}
--\entry{usual file name errors}{208}{usual file name errors}
--\entry{file pointer}{211}{file pointer}
--\entry{standard streams}{211}{standard streams}
--\entry{streams, standard}{211}{streams, standard}
--\entry{standard input stream}{211}{standard input stream}
--\entry{standard output stream}{211}{standard output stream}
--\entry{standard error stream}{212}{standard error stream}
--\entry{opening a stream}{212}{opening a stream}
--\entry{closing a stream}{214}{closing a stream}
--\entry{writing to a stream, by characters}{215}{writing to a stream, by characters}
--\entry{reading from a stream, by characters}{216}{reading from a stream, by characters}
--\entry{peeking at input}{219}{peeking at input}
--\entry{unreading characters}{219}{unreading characters}
--\entry{pushing input back}{219}{pushing input back}
--\entry{binary I/O to a stream}{221}{binary I/O to a stream}
--\entry{block I/O to a stream}{221}{block I/O to a stream}
--\entry{reading from a stream, by blocks}{221}{reading from a stream, by blocks}
--\entry{writing to a stream, by blocks}{221}{writing to a stream, by blocks}
--\entry{format string, for printf}{221}{format string, for \code {printf}}
--\entry{template, for printf}{221}{template, for \code {printf}}
--\entry{formatted output to a stream}{221}{formatted output to a stream}
--\entry{writing to a stream, formatted}{221}{writing to a stream, formatted}
--\entry{conversion specifications (printf)}{222}{conversion specifications (\code {printf})}
--\entry{flag character (printf)}{223}{flag character (\code {printf})}
--\entry{minimum field width (printf)}{223}{minimum field width (\code {printf})}
--\entry{precision (printf)}{223}{precision (\code {printf})}
--\entry{type modifier character (printf)}{224}{type modifier character (\code {printf})}
--\entry{output conversions, for printf}{224}{output conversions, for \code {printf}}
--\entry{parsing a template string}{234}{parsing a template string}
--\entry{customizing printf}{237}{customizing \code {printf}}
--\entry{defining new printf conversions}{237}{defining new \code {printf} conversions}
--\entry{extending printf}{237}{extending \code {printf}}
--\entry{formatted input from a stream}{242}{formatted input from a stream}
--\entry{reading from a stream, formatted}{242}{reading from a stream, formatted}
--\entry{format string, for scanf}{242}{format string, for \code {scanf}}
--\entry{template, for scanf}{242}{template, for \code {scanf}}
--\entry{conversion specifications (scanf)}{243}{conversion specifications (\code {scanf})}
--\entry{matching failure, in scanf}{243}{matching failure, in \code {scanf}}
--\entry{flag character (scanf)}{244}{flag character (\code {scanf})}
--\entry{maximum field width (scanf)}{244}{maximum field width (\code {scanf})}
--\entry{type modifier character (scanf)}{244}{type modifier character (\code {scanf})}
--\entry{input conversions, for scanf}{244}{input conversions, for \code {scanf}}
--\entry{end of file, on a stream}{250}{end of file, on a stream}
--\entry{text stream}{251}{text stream}
--\entry{binary stream}{251}{binary stream}
--\entry{lines (in a text file)}{251}{lines (in a text file)}
--\entry{file positioning on a stream}{252}{file positioning on a stream}
--\entry{positioning a stream}{252}{positioning a stream}
--\entry{seeking on a stream}{252}{seeking on a stream}
--\entry{buffering of streams}{256}{buffering of streams}
--\entry{unbuffered stream}{256}{unbuffered stream}
--\entry{line buffered stream}{257}{line buffered stream}
--\entry{fully buffered stream}{257}{fully buffered stream}
--\entry{flushing a stream}{257}{flushing a stream}
--\entry{buffering, controlling}{257}{buffering, controlling}
--\entry{stream, for I/O to a string}{259}{stream, for I/O to a string}
--\entry{string stream}{259}{string stream}
--\entry{custom streams}{262}{custom streams}
--\entry{programming your own streams}{262}{programming your own streams}
--\entry{cookie, for custom stream}{262}{cookie, for custom stream}
--\entry{hook functions (of custom streams)}{263}{hook functions (of custom streams)}
--\entry{formatted messages}{264}{formatted messages}
--\entry{severity class}{266}{severity class}
--\entry{severity class}{267}{severity class}
--\entry{opening a file descriptor}{271}{opening a file descriptor}
--\entry{closing a file descriptor}{271}{closing a file descriptor}
--\entry{reading from a file descriptor}{275}{reading from a file descriptor}
--\entry{end-of-file, on a file descriptor}{275}{end-of-file, on a file descriptor}
--\entry{writing to a file descriptor}{277}{writing to a file descriptor}
--\entry{file positioning on a file descriptor}{279}{file positioning on a file descriptor}
--\entry{positioning a file descriptor}{279}{positioning a file descriptor}
--\entry{seeking on a file descriptor}{279}{seeking on a file descriptor}
--\entry{sparse files}{280}{sparse files}
--\entry{holes in files}{280}{holes in files}
--\entry{streams, and file descriptors}{282}{streams, and file descriptors}
--\entry{converting file descriptor to stream}{282}{converting file descriptor to stream}
--\entry{extracting file descriptor from stream}{282}{extracting file descriptor from stream}
--\entry{standard file descriptors}{283}{standard file descriptors}
--\entry{file descriptors, standard}{283}{file descriptors, standard}
--\entry{standard input file descriptor}{283}{standard input file descriptor}
--\entry{standard output file descriptor}{283}{standard output file descriptor}
--\entry{standard error file descriptor}{283}{standard error file descriptor}
--\entry{channels}{283}{channels}
--\entry{streams and descriptors}{283}{streams and descriptors}
--\entry{descriptors and streams}{283}{descriptors and streams}
--\entry{mixing descriptors and streams}{283}{mixing descriptors and streams}
--\entry{linked channels}{283}{linked channels}
--\entry{cleaning up a stream}{283}{cleaning up a stream}
--\entry{independent channels}{284}{independent channels}
--\entry{scatter-gather}{285}{scatter-gather}
--\entry{waiting for input or output}{289}{waiting for input or output}
--\entry{multiplexing input}{289}{multiplexing input}
--\entry{input from multiple files}{289}{input from multiple files}
--\entry{file descriptor sets, for select}{289}{file descriptor sets, for \code {select}}
--\entry{synchronizing}{292}{synchronizing}
--\entry{synchronizing}{301}{synchronizing}
--\entry{control operations on files}{305}{control operations on files}
--\entry{fcntl function}{305}{\code {fcntl} function}
--\entry{duplicating file descriptors}{306}{duplicating file descriptors}
--\entry{redirecting input and output}{306}{redirecting input and output}
--\entry{file descriptor flags}{307}{file descriptor flags}
--\entry{close-on-exec (file descriptor flag)}{308}{close-on-exec (file descriptor flag)}
--\entry{file status flags}{309}{file status flags}
--\entry{file name translation flags}{310}{file name translation flags}
--\entry{flags, file name translation}{310}{flags, file name translation}
--\entry{open-time action flags}{310}{open-time action flags}
--\entry{flags, open-time action}{310}{flags, open-time action}
--\entry{create on open (file status flag)}{310}{create on open (file status flag)}
--\entry{non-blocking open}{310}{non-blocking open}
--\entry{controlling terminal, setting}{311}{controlling terminal, setting}
--\entry{symbolic link, opening}{311}{symbolic link, opening}
--\entry{file locks}{314}{file locks}
--\entry{record locking}{314}{record locking}
--\entry{exclusive lock}{314}{exclusive lock}
--\entry{write lock}{314}{write lock}
--\entry{shared lock}{314}{shared lock}
--\entry{read lock}{314}{read lock}
--\entry{interrupt-driven input}{317}{interrupt-driven input}
--\entry{generic i/o control operations}{318}{generic i/o control operations}
--\entry{IOCTLs}{318}{IOCTLs}
--\entry{current working directory}{319}{current working directory}
--\entry{working directory}{319}{working directory}
--\entry{change working directory}{319}{change working directory}
--\entry{accessing directories}{320}{accessing directories}
--\entry{reading from a directory}{320}{reading from a directory}
--\entry{directories, accessing}{320}{directories, accessing}
--\entry{directory stream}{320}{directory stream}
--\entry{directory hierarchy}{327}{directory hierarchy}
--\entry{hierarchy, directory}{327}{hierarchy, directory}
--\entry{tree, directory}{327}{tree, directory}
--\entry{hard link}{331}{hard link}
--\entry{link, hard}{331}{link, hard}
--\entry{multiple names for one file}{331}{multiple names for one file}
--\entry{file names, multiple}{331}{file names, multiple}
--\entry{soft link}{332}{soft link}
--\entry{link, soft}{332}{link, soft}
--\entry{symbolic link}{332}{symbolic link}
--\entry{link, symbolic}{332}{link, symbolic}
--\entry{deleting a file}{333}{deleting a file}
--\entry{removing a file}{333}{removing a file}
--\entry{unlinking a file}{333}{unlinking a file}
--\entry{directories, deleting}{334}{directories, deleting}
--\entry{deleting a directory}{334}{deleting a directory}
--\entry{renaming a file}{334}{renaming a file}
--\entry{creating a directory}{335}{creating a directory}
--\entry{directories, creating}{335}{directories, creating}
--\entry{status of a file}{336}{status of a file}
--\entry{attributes of a file}{336}{attributes of a file}
--\entry{file attributes}{336}{file attributes}
--\entry{inode number}{339}{inode number}
--\entry{file owner}{343}{file owner}
--\entry{owner of a file}{343}{owner of a file}
--\entry{group owner of a file}{343}{group owner of a file}
--\entry{file permission bits}{344}{file permission bits}
--\entry{sticky bit}{345}{sticky bit}
--\entry{permission to access a file}{346}{permission to access a file}
--\entry{access permission for a file}{346}{access permission for a file}
--\entry{file access permission}{346}{file access permission}
--\entry{file creation mask}{346}{file creation mask}
--\entry{umask}{346}{umask}
--\entry{testing access permission}{348}{testing access permission}
--\entry{access, testing for}{348}{access, testing for}
--\entry{setuid programs and file access}{348}{setuid programs and file access}
--\entry{file access time}{349}{file access time}
--\entry{file modification time}{349}{file modification time}
--\entry{file attribute modification time}{349}{file attribute modification time}
--\entry{creating special files}{352}{creating special files}
--\entry{special files}{352}{special files}
--\entry{TMPDIR environment variable}{355}{TMPDIR environment variable}
--\entry{pipe}{357}{pipe}
--\entry{FIFO special file}{357}{FIFO special file}
--\entry{creating a pipe}{357}{creating a pipe}
--\entry{opening a pipe}{357}{opening a pipe}
--\entry{interprocess communication, with pipes}{357}{interprocess communication, with pipes}
--\entry{creating a pipe to a subprocess}{359}{creating a pipe to a subprocess}
--\entry{pipe to a subprocess}{359}{pipe to a subprocess}
--\entry{filtering i/o through subprocess}{359}{filtering i/o through subprocess}
--\entry{creating a FIFO special file}{360}{creating a FIFO special file}
--\entry{interprocess communication, with FIFO}{360}{interprocess communication, with FIFO}
--\entry{socket}{363}{socket}
--\entry{interprocess communication, with sockets}{363}{interprocess communication, with sockets}
--\entry{communication style (of a socket)}{363}{communication style (of a socket)}
--\entry{style of communication (of a socket)}{363}{style of communication (of a socket)}
--\entry{packet}{363}{packet}
--\entry{byte stream}{363}{byte stream}
--\entry{stream (sockets)}{363}{stream (sockets)}
--\entry{loss of data on sockets}{363}{loss of data on sockets}
--\entry{data loss on sockets}{363}{data loss on sockets}
--\entry{namespace (of socket)}{363}{namespace (of socket)}
--\entry{domain (of socket)}{363}{domain (of socket)}
--\entry{socket namespace}{363}{socket namespace}
--\entry{socket domain}{363}{socket domain}
--\entry{network protocol}{363}{network protocol}
--\entry{protocol (of socket)}{363}{protocol (of socket)}
--\entry{socket protocol}{363}{socket protocol}
--\entry{protocol family}{363}{protocol family}
--\entry{address of socket}{365}{address of socket}
--\entry{name of socket}{365}{name of socket}
--\entry{binding a socket address}{365}{binding a socket address}
--\entry{socket address (name) binding}{365}{socket address (name) binding}
--\entry{local namespace, for sockets}{369}{local namespace, for sockets}
--\entry{Internet namespace, for sockets}{371}{Internet namespace, for sockets}
--\entry{host address, Internet}{373}{host address, Internet}
--\entry{Internet host address}{373}{Internet host address}
--\entry{network number}{373}{network number}
--\entry{local network address number}{373}{local network address number}
--\entry{standard dot notation, for Internet addresses}{373}{standard dot notation, for Internet addresses}
--\entry{dot notation, for Internet addresses}{373}{dot notation, for Internet addresses}
--\entry{hosts database}{377}{hosts database}
--\entry{converting host name to address}{377}{converting host name to address}
--\entry{converting host address to name}{377}{converting host address to name}
--\entry{port number}{381}{port number}
--\entry{services database}{381}{services database}
--\entry{converting service name to port number}{381}{converting service name to port number}
--\entry{converting port number to service name}{381}{converting port number to service name}
--\entry{byte order conversion, for socket}{382}{byte order conversion, for socket}
--\entry{converting byte order}{382}{converting byte order}
--\entry{big-endian}{382}{big-endian}
--\entry{little-endian}{382}{little-endian}
--\entry{network byte order}{382}{network byte order}
--\entry{protocols database}{383}{protocols database}
--\entry{TCP (Internet protocol)}{383}{TCP (Internet protocol)}
--\entry{creating a socket}{386}{creating a socket}
--\entry{socket, creating}{386}{socket, creating}
--\entry{opening a socket}{386}{opening a socket}
--\entry{socket, closing}{387}{socket, closing}
--\entry{closing a socket}{387}{closing a socket}
--\entry{shutting down a socket}{387}{shutting down a socket}
--\entry{socket shutdown}{387}{socket shutdown}
--\entry{creating a socket pair}{387}{creating a socket pair}
--\entry{socket pair}{387}{socket pair}
--\entry{opening a socket pair}{387}{opening a socket pair}
--\entry{connection}{388}{connection}
--\entry{client}{388}{client}
--\entry{server}{388}{server}
--\entry{connecting a socket}{388}{connecting a socket}
--\entry{socket, connecting}{388}{socket, connecting}
--\entry{socket, initiating a connection}{388}{socket, initiating a connection}
--\entry{socket, client actions}{388}{socket, client actions}
--\entry{listening (sockets)}{390}{listening (sockets)}
--\entry{sockets, server actions}{390}{sockets, server actions}
--\entry{sockets, listening}{390}{sockets, listening}
--\entry{sockets, accepting connections}{390}{sockets, accepting connections}
--\entry{accepting connections}{390}{accepting connections}
--\entry{reading from a socket}{392}{reading from a socket}
--\entry{writing to a socket}{392}{writing to a socket}
--\entry{out-of-band data}{398}{out-of-band data}
--\entry{high-priority data}{398}{high-priority data}
--\entry{urgent socket condition}{398}{urgent socket condition}
--\entry{datagram socket}{401}{datagram socket}
--\entry{sending a datagram}{401}{sending a datagram}
--\entry{transmitting datagrams}{401}{transmitting datagrams}
--\entry{datagrams, transmitting}{401}{datagrams, transmitting}
--\entry{receiving datagrams}{401}{receiving datagrams}
--\entry{socket options}{406}{socket options}
--\entry{level, for socket options}{406}{level, for socket options}
--\entry{socket option level}{406}{socket option level}
--\entry{networks database}{408}{networks database}
--\entry{converting network number to network name}{408}{converting network number to network name}
--\entry{converting network name to network number}{408}{converting network name to network number}
--\entry{terminal identification}{411}{terminal identification}
--\entry{identifying terminals}{411}{identifying terminals}
--\entry{terminal input queue}{412}{terminal input queue}
--\entry{typeahead buffer}{412}{typeahead buffer}
--\entry{terminal output queue}{412}{terminal output queue}
--\entry{canonical input processing}{412}{canonical input processing}
--\entry{noncanonical input processing}{412}{noncanonical input processing}
--\entry{terminal mode data types}{413}{terminal mode data types}
--\entry{terminal mode functions}{414}{terminal mode functions}
--\entry{parity checking}{416}{parity checking}
--\entry{break condition, detecting}{417}{break condition, detecting}
--\entry{modem status lines}{419}{modem status lines}
--\entry{carrier detect}{419}{carrier detect}
--\entry{modem disconnect}{419}{modem disconnect}
--\entry{echo of terminal input}{421}{echo of terminal input}
--\entry{interactive signals, from terminal}{422}{interactive signals, from terminal}
--\entry{line speed}{423}{line speed}
--\entry{baud rate}{423}{baud rate}
--\entry{terminal line speed}{423}{terminal line speed}
--\entry{terminal line speed}{423}{terminal line speed}
--\entry{EOF character}{425}{EOF character}
--\entry{EOL character}{425}{EOL character}
--\entry{EOL2 character}{425}{EOL2 character}
--\entry{ERASE character}{426}{ERASE character}
--\entry{WERASE character}{426}{WERASE character}
--\entry{KILL character}{426}{KILL character}
--\entry{REPRINT character}{426}{REPRINT character}
--\entry{INTR character}{427}{INTR character}
--\entry{interrupt character}{427}{interrupt character}
--\entry{QUIT character}{427}{QUIT character}
--\entry{SUSP character}{427}{SUSP character}
--\entry{suspend character}{427}{suspend character}
--\entry{DSUSP character}{427}{DSUSP character}
--\entry{delayed suspend character}{427}{delayed suspend character}
--\entry{START character}{428}{START character}
--\entry{STOP character}{428}{STOP character}
--\entry{LNEXT character}{428}{LNEXT character}
--\entry{DISCARD character}{428}{DISCARD character}
--\entry{STATUS character}{429}{STATUS character}
--\entry{MIN termios slot}{429}{MIN termios slot}
--\entry{TIME termios slot}{429}{TIME termios slot}
--\entry{terminal line control functions}{430}{terminal line control functions}
--\entry{break condition, generating}{430}{break condition, generating}
--\entry{flushing terminal output queue}{431}{flushing terminal output queue}
--\entry{terminal output queue, flushing}{431}{terminal output queue, flushing}
--\entry{clearing terminal input queue}{431}{clearing terminal input queue}
--\entry{terminal input queue, clearing}{431}{terminal input queue, clearing}
--\entry{flow control, terminal}{432}{flow control, terminal}
--\entry{terminal flow control}{432}{terminal flow control}
--\entry{pseudo-terminals}{434}{pseudo-terminals}
--\entry{allocating pseudo-terminals}{434}{allocating pseudo-terminals}
--\entry{opening a pseudo-terminal pair}{436}{opening a pseudo-terminal pair}
--\entry{constants}{439}{constants}
--\entry{mathematical constants}{439}{mathematical constants}
--\entry{trigonometric functions}{440}{trigonometric functions}
--\entry{pi (trigonometric constant)}{440}{pi (trigonometric constant)}
--\entry{complex trigonometric functions}{441}{complex trigonometric functions}
--\entry{inverse trigonometric functions}{442}{inverse trigonometric functions}
--\entry{inverse complex trigonometric functions}{442}{inverse complex trigonometric functions}
--\entry{exponentiation functions}{443}{exponentiation functions}
--\entry{power functions}{443}{power functions}
--\entry{logarithm functions}{443}{logarithm functions}
--\entry{square root function}{445}{square root function}
--\entry{cube root function}{445}{cube root function}
--\entry{complex exponentiation functions}{446}{complex exponentiation functions}
--\entry{complex logarithm functions}{446}{complex logarithm functions}
--\entry{hyperbolic functions}{447}{hyperbolic functions}
--\entry{hyperbolic functions}{447}{hyperbolic functions}
--\entry{inverse hyperbolic functions}{448}{inverse hyperbolic functions}
--\entry{inverse complex hyperbolic functions}{448}{inverse complex hyperbolic functions}
--\entry{special functions}{449}{special functions}
--\entry{Bessel functions}{449}{Bessel functions}
--\entry{gamma function}{449}{gamma function}
--\entry{random numbers}{451}{random numbers}
--\entry{pseudo-random numbers}{451}{pseudo-random numbers}
--\entry{seed (for random numbers)}{451}{seed (for random numbers)}
--\entry{Optimization}{457}{Optimization}
--\entry{floating point}{459}{floating point}
--\entry{IEEE 754}{459}{IEEE 754}
--\entry{IEEE floating point}{459}{IEEE floating point}
--\entry{floating-point classes}{459}{floating-point classes}
--\entry{classes, floating-point}{459}{classes, floating-point}
--\entry{exception}{461}{exception}
--\entry{signal}{461}{signal}
--\entry{zero divide}{461}{zero divide}
--\entry{division by zero}{461}{division by zero}
--\entry{inexact exception}{461}{inexact exception}
--\entry{invalid exception}{461}{invalid exception}
--\entry{overflow exception}{461}{overflow exception}
--\entry{underflow exception}{461}{underflow exception}
--\entry{infinity}{463}{infinity}
--\entry{not a number}{463}{not a number}
--\entry{NaN}{463}{NaN}
--\entry{errors, mathematical}{465}{errors, mathematical}
--\entry{domain error}{465}{domain error}
--\entry{range error}{465}{range error}
--\entry{absolute value functions}{468}{absolute value functions}
--\entry{normalization functions (floating-point)}{469}{normalization functions (floating-point)}
--\entry{converting floats to integers}{471}{converting floats to integers}
--\entry{FP arithmetic}{473}{FP arithmetic}
--\entry{NaN}{474}{NaN}
--\entry{unordered comparison}{474}{unordered comparison}
--\entry{minimum}{475}{minimum}
--\entry{maximum}{475}{maximum}
--\entry{positive difference}{475}{positive difference}
--\entry{multiply-add}{475}{multiply-add}
--\entry{butterfly}{476}{butterfly}
--\entry{complex numbers}{476}{complex numbers}
--\entry{project complex numbers}{477}{project complex numbers}
--\entry{conjugate complex numbers}{477}{conjugate complex numbers}
--\entry{decompose complex numbers}{477}{decompose complex numbers}
--\entry{integer division functions}{478}{integer division functions}
--\entry{parsing numbers (in formatted input)}{479}{parsing numbers (in formatted input)}
--\entry{converting strings to numbers}{479}{converting strings to numbers}
--\entry{number syntax, parsing}{479}{number syntax, parsing}
--\entry{syntax, for reading numbers}{479}{syntax, for reading numbers}
--\entry{parsing numbers and locales}{481}{parsing numbers and locales}
--\entry{locales, parsing numbers and}{481}{locales, parsing numbers and}
--\entry{gcvt{\_}r}{485}{gcvt_r}
--\entry{CPU time}{487}{CPU time}
--\entry{processor time}{487}{processor time}
--\entry{clock ticks}{487}{clock ticks}
--\entry{ticks, clock}{487}{ticks, clock}
--\entry{time, elapsed CPU}{487}{time, elapsed CPU}
--\entry{Gregorian calendar}{489}{Gregorian calendar}
--\entry{time, calendar}{489}{time, calendar}
--\entry{date and time}{489}{date and time}
--\entry{calendar time}{489}{calendar time}
--\entry{high-resolution time}{489}{high-resolution time}
--\entry{local time}{489}{local time}
--\entry{broken-down time}{489}{broken-down time}
--\entry{epoch}{489}{epoch}
--\entry{broken-down time}{492}{broken-down time}
--\entry{calendar time and broken-down time}{492}{calendar time and broken-down time}
--\entry{leap second}{492}{leap second}
--\entry{Daylight Saving Time}{493}{Daylight Saving Time}
--\entry{summer time}{493}{summer time}
--\entry{time zone}{507}{time zone}
--\entry{time zone database}{509}{time zone database}
--\entry{time, high precision}{511}{time, high precision}
--\entry{setting an alarm}{513}{setting an alarm}
--\entry{interval timer, setting}{513}{interval timer, setting}
--\entry{alarms, setting}{513}{alarms, setting}
--\entry{timers, setting}{513}{timers, setting}
--\entry{real-time timer}{513}{real-time timer}
--\entry{timer, real-time}{513}{timer, real-time}
--\entry{virtual timer}{513}{virtual timer}
--\entry{timer, virtual}{513}{timer, virtual}
--\entry{profiling timer}{513}{profiling timer}
--\entry{timer, profiling}{513}{timer, profiling}
--\entry{resource limits}{518}{resource limits}
--\entry{limits on resource usage}{518}{limits on resource usage}
--\entry{usage limits}{518}{usage limits}
--\entry{soft limit}{519}{soft limit}
--\entry{hard limit}{520}{hard limit}
--\entry{process priority}{521}{process priority}
--\entry{priority of a process}{521}{priority of a process}
--\entry{non-local exits}{523}{non-local exits}
--\entry{long jumps}{523}{long jumps}
--\entry{signal}{527}{signal}
--\entry{generation of signals}{528}{generation of signals}
--\entry{delivery of signals}{528}{delivery of signals}
--\entry{pending signals}{528}{pending signals}
--\entry{blocked signals}{528}{blocked signals}
--\entry{specified action (for a signal)}{528}{specified action (for a signal)}
--\entry{default action (for a signal)}{528}{default action (for a signal)}
--\entry{signal action}{528}{signal action}
--\entry{catching signals}{528}{catching signals}
--\entry{signal names}{529}{signal names}
--\entry{names of signals}{529}{names of signals}
--\entry{signal number}{529}{signal number}
--\entry{program error signals}{529}{program error signals}
--\entry{exception}{530}{exception}
--\entry{floating-point exception}{530}{floating-point exception}
--\entry{illegal instruction}{531}{illegal instruction}
--\entry{segmentation violation}{531}{segmentation violation}
--\entry{bus error}{531}{bus error}
--\entry{abort signal}{532}{abort signal}
--\entry{program termination signals}{532}{program termination signals}
--\entry{termination signal}{532}{termination signal}
--\entry{interrupt signal}{532}{interrupt signal}
--\entry{quit signal}{533}{quit signal}
--\entry{quit signal}{533}{quit signal}
--\entry{kill signal}{533}{kill signal}
--\entry{hangup signal}{533}{hangup signal}
--\entry{alarm signal}{534}{alarm signal}
--\entry{virtual time alarm signal}{534}{virtual time alarm signal}
--\entry{profiling alarm signal}{534}{profiling alarm signal}
--\entry{input available signal}{534}{input available signal}
--\entry{output possible signal}{534}{output possible signal}
--\entry{urgent data signal}{534}{urgent data signal}
--\entry{job control signals}{534}{job control signals}
--\entry{child process signal}{534}{child process signal}
--\entry{continue signal}{535}{continue signal}
--\entry{stop signal}{535}{stop signal}
--\entry{interactive stop signal}{535}{interactive stop signal}
--\entry{terminal input signal}{535}{terminal input signal}
--\entry{terminal output signal}{536}{terminal output signal}
--\entry{pipe signal}{536}{pipe signal}
--\entry{broken pipe signal}{536}{broken pipe signal}
--\entry{lost resource signal}{536}{lost resource signal}
--\entry{user signals}{537}{user signals}
--\entry{signal messages}{537}{signal messages}
--\entry{signal actions}{538}{signal actions}
--\entry{establishing a handler}{538}{establishing a handler}
--\entry{signal function}{538}{\code {signal} function}
--\entry{default action for a signal}{539}{default action for a signal}
--\entry{ignore action for a signal}{539}{ignore action for a signal}
--\entry{sigaction function}{540}{\code {sigaction} function}
--\entry{signal flags}{543}{signal flags}
--\entry{flags for sigaction}{543}{flags for \code {sigaction}}
--\entry{sigaction flags}{543}{\code {sigaction} flags}
--\entry{initial signal actions}{544}{initial signal actions}
--\entry{signal handler function}{544}{signal handler function}
--\entry{non-local exit, from signal handler}{547}{non-local exit, from signal handler}
--\entry{race conditions, relating to signals}{548}{race conditions, relating to signals}
--\entry{handling multiple signals}{549}{handling multiple signals}
--\entry{successive signals}{549}{successive signals}
--\entry{merging of signals}{549}{merging of signals}
--\entry{restrictions on signal handler functions}{551}{restrictions on signal handler functions}
--\entry{volatile declarations}{552}{\code {volatile} declarations}
--\entry{reentrant functions}{552}{reentrant functions}
--\entry{EINTR, and restarting interrupted primitives}{556}{EINTR, and restarting interrupted primitives}
--\entry{restarting interrupted primitives}{556}{restarting interrupted primitives}
--\entry{interrupting primitives}{556}{interrupting primitives}
--\entry{primitives, interrupting}{556}{primitives, interrupting}
--\entry{sending signals}{556}{sending signals}
--\entry{raising signals}{556}{raising signals}
--\entry{signals, generating}{556}{signals, generating}
--\entry{killing a process}{557}{killing a process}
--\entry{interprocess communication, with signals}{559}{interprocess communication, with signals}
--\entry{blocking signals}{560}{blocking signals}
--\entry{signal set}{561}{signal set}
--\entry{signal mask}{562}{signal mask}
--\entry{process signal mask}{562}{process signal mask}
--\entry{blocking signals, in a handler}{564}{blocking signals, in a handler}
--\entry{pending signals, checking for}{565}{pending signals, checking for}
--\entry{blocked signals, checking for}{565}{blocked signals, checking for}
--\entry{checking for pending signals}{565}{checking for pending signals}
--\entry{timing error in signal handling}{567}{timing error in signal handling}
--\entry{waiting for a signal}{567}{waiting for a signal}
--\entry{pause function}{567}{\code {pause} function}
--\entry{process}{575}{process}
--\entry{program arguments}{575}{program arguments}
--\entry{command line arguments}{575}{command line arguments}
--\entry{arguments, to program}{575}{arguments, to program}
--\entry{program startup}{575}{program startup}
--\entry{startup of program}{575}{startup of program}
--\entry{invocation of program}{575}{invocation of program}
--\entry{main function}{575}{\code {main} function}
--\entry{argc (program argument count)}{575}{argc (program argument count)}
--\entry{argv (program argument vector)}{575}{argv (program argument vector)}
--\entry{program argument syntax}{575}{program argument syntax}
--\entry{syntax, for program arguments}{575}{syntax, for program arguments}
--\entry{command argument syntax}{575}{command argument syntax}
--\entry{long-named options}{576}{long-named options}
--\entry{program arguments, parsing}{576}{program arguments, parsing}
--\entry{command arguments, parsing}{576}{command arguments, parsing}
--\entry{parsing program arguments}{576}{parsing program arguments}
--\entry{argp (program argument parser)}{584}{argp (program argument parser)}
--\entry{argument parsing with argp}{584}{argument parsing with argp}
--\entry{option parsing with argp}{584}{option parsing with argp}
--\entry{argp parser functions}{588}{argp parser functions}
--\entry{usage messages, in argp}{591}{usage messages, in argp}
--\entry{syntax error messages, in argp}{591}{syntax error messages, in argp}
--\entry{error messages, in argp}{591}{error messages, in argp}
--\entry{ARGP{\_}HELP{\_}FMT environment variable}{606}{ARGP_HELP_FMT environment variable}
--\entry{environment variable}{609}{environment variable}
--\entry{environment}{610}{environment}
--\entry{environment access}{610}{environment access}
--\entry{environment representation}{610}{environment representation}
--\entry{standard environment variables}{611}{standard environment variables}
--\entry{HOME environment variable}{612}{\code {HOME} environment variable}
--\entry{home directory}{612}{home directory}
--\entry{LOGNAME environment variable}{612}{\code {LOGNAME} environment variable}
--\entry{PATH environment variable}{612}{\code {PATH} environment variable}
--\entry{TERM environment variable}{612}{\code {TERM} environment variable}
--\entry{TZ environment variable}{612}{\code {TZ} environment variable}
--\entry{LANG environment variable}{612}{\code {LANG} environment variable}
--\entry{LC{\_}ALL environment variable}{613}{\code {LC_ALL} environment variable}
--\entry{LC{\_}COLLATE environment variable}{613}{\code {LC_COLLATE} environment variable}
--\entry{LC{\_}CTYPE environment variable}{613}{\code {LC_CTYPE} environment variable}
--\entry{LC{\_}MESSAGES environment variable}{613}{\code {LC_MESSAGES} environment variable}
--\entry{LC{\_}MONETARY environment variable}{613}{\code {LC_MONETARY} environment variable}
--\entry{LC{\_}NUMERIC environment variable}{613}{\code {LC_NUMERIC} environment variable}
--\entry{LC{\_}TIME environment variable}{613}{\code {LC_TIME} environment variable}
--\entry{NLSPATH environment variable}{613}{\code {NLSPATH} environment variable}
--\entry{{\_}POSIX{\_}OPTION{\_}ORDER environment variable.}{613}{\code {_POSIX_OPTION_ORDER} environment variable.}
--\entry{program termination}{613}{program termination}
--\entry{process termination}{613}{process termination}
--\entry{exit status value}{613}{exit status value}
--\entry{exit status}{614}{exit status}
--\entry{aborting a program}{616}{aborting a program}
--\entry{process}{619}{process}
--\entry{child process}{619}{child process}
--\entry{parent process}{619}{parent process}
--\entry{running a command}{619}{running a command}
--\entry{process ID}{620}{process ID}
--\entry{process lifetime}{620}{process lifetime}
--\entry{creating a process}{620}{creating a process}
--\entry{forking a process}{620}{forking a process}
--\entry{child process}{620}{child process}
--\entry{parent process}{620}{parent process}
--\entry{process image}{620}{process image}
--\entry{executing a file}{622}{executing a file}
--\entry{exec functions}{622}{\code {exec} functions}
--\entry{process completion}{624}{process completion}
--\entry{waiting for completion of child process}{624}{waiting for completion of child process}
--\entry{testing exit status of child process}{624}{testing exit status of child process}
--\entry{process groups}{631}{process groups}
--\entry{job control}{631}{job control}
--\entry{job}{631}{job}
--\entry{session}{631}{session}
--\entry{shell}{631}{shell}
--\entry{session}{631}{session}
--\entry{session leader}{631}{session leader}
--\entry{controlling terminal}{631}{controlling terminal}
--\entry{foreground job}{631}{foreground job}
--\entry{background job}{631}{background job}
--\entry{stopped job}{632}{stopped job}
--\entry{job control is optional}{632}{job control is optional}
--\entry{controlling process}{632}{controlling process}
--\entry{controlling terminal, access to}{632}{controlling terminal, access to}
--\entry{SIGTTIN, from background job}{632}{\code {SIGTTIN}, from background job}
--\entry{SIGTTOU, from background job}{633}{\code {SIGTTOU}, from background job}
--\entry{orphaned process group}{633}{orphaned process group}
--\entry{job control, enabling}{635}{job control, enabling}
--\entry{subshell}{635}{subshell}
--\entry{job control, enabling}{635}{job control, enabling}
--\entry{launching jobs}{637}{launching jobs}
--\entry{process group leader}{637}{process group leader}
--\entry{process group ID}{637}{process group ID}
--\entry{race conditions, relating to job control}{637}{race conditions, relating to job control}
--\entry{foreground job, launching}{640}{foreground job, launching}
--\entry{background job, launching}{641}{background job, launching}
--\entry{stopped jobs, detecting}{641}{stopped jobs, detecting}
--\entry{terminated jobs, detecting}{641}{terminated jobs, detecting}
--\entry{SIGCHLD, handling of}{642}{\code {SIGCHLD}, handling of}
--\entry{stopped jobs, continuing}{644}{stopped jobs, continuing}
--\entry{process group functions}{646}{process group functions}
--\entry{job control functions}{646}{job control functions}
--\entry{controlling terminal, determining}{646}{controlling terminal, determining}
--\entry{BSD compatibility library}{647}{BSD compatibility library}
--\entry{Name Service Switch}{651}{Name Service Switch}
--\entry{NSS}{651}{NSS}
--\entry{databases}{651}{databases}
--\entry{ethers}{651}{ethers}
--\entry{group}{651}{group}
--\entry{hosts}{651}{hosts}
--\entry{netgroup}{651}{netgroup}
--\entry{networks}{651}{networks}
--\entry{protocols}{651}{protocols}
--\entry{passwd}{651}{passwd}
--\entry{rpc}{651}{rpc}
--\entry{services}{651}{services}
--\entry{shadow}{651}{shadow}
--\entry{/etc/nsswitch.conf}{652}{\file {/etc/nsswitch.conf}}
--\entry{nsswitch.conf}{652}{\file {nsswitch.conf}}
--\entry{DNS server unavailable}{653}{DNS server unavailable}
--\entry{nisplus, and completeness}{653}{nisplus, and completeness}
--\entry{nisplus, and booting}{653}{nisplus, and booting}
--\entry{bootstrapping, and services}{653}{bootstrapping, and services}
--\entry{default value, and NSS}{654}{default value, and NSS}
--\entry{optimizing NSS}{654}{optimizing NSS}
--\entry{reentrant NSS functions}{655}{reentrant NSS functions}
--\entry{login name}{661}{login name}
--\entry{user name}{661}{user name}
--\entry{user ID}{661}{user ID}
--\entry{group name}{661}{group name}
--\entry{group ID}{661}{group ID}
--\entry{persona}{661}{persona}
--\entry{effective user ID}{661}{effective user ID}
--\entry{effective group ID}{661}{effective group ID}
--\entry{supplementary group IDs}{661}{supplementary group IDs}
--\entry{real user ID}{661}{real user ID}
--\entry{real group ID}{661}{real group ID}
--\entry{setuid programs}{662}{\code {setuid} programs}
--\entry{saved set-user-ID}{662}{saved set-user-ID}
--\entry{saved set-group-ID}{662}{saved set-group-ID}
--\entry{{\_}POSIX{\_}SAVED{\_}IDS}{662}{\code {_POSIX_SAVED_IDS}}
--\entry{login name, determining}{670}{login name, determining}
--\entry{user ID, determining}{670}{user ID, determining}
--\entry{user accounting database}{671}{user accounting database}
--\entry{user database}{678}{user database}
--\entry{password database}{678}{password database}
--\entry{converting user ID to user name}{679}{converting user ID to user name}
--\entry{converting user name to user ID}{679}{converting user name to user ID}
--\entry{scanning the user list}{680}{scanning the user list}
--\entry{group database}{681}{group database}
--\entry{converting group name to group ID}{682}{converting group name to group ID}
--\entry{converting group ID to group name}{682}{converting group ID to group name}
--\entry{scanning the group list}{683}{scanning the group list}
--\entry{Netgroup}{685}{Netgroup}
--\entry{POSIX capacity limits}{697}{POSIX capacity limits}
--\entry{limits, POSIX}{697}{limits, POSIX}
--\entry{capacity limits, POSIX}{697}{capacity limits, POSIX}
--\entry{limits, program argument size}{697}{limits, program argument size}
--\entry{limits, number of processes}{697}{limits, number of processes}
--\entry{limits, number of open files}{697}{limits, number of open files}
--\entry{limits, time zone name length}{697}{limits, time zone name length}
--\entry{limits, number of supplementary group IDs}{698}{limits, number of supplementary group IDs}
--\entry{POSIX optional features}{698}{POSIX optional features}
--\entry{optional POSIX features}{698}{optional POSIX features}
--\entry{limits, link count of files}{709}{limits, link count of files}
--\entry{limits, terminal input queue}{709}{limits, terminal input queue}
--\entry{limits, file name length}{709}{limits, file name length}
--\entry{limits, pipe buffer size}{710}{limits, pipe buffer size}
--\entry{consistency checking}{743}{consistency checking}
--\entry{impossible events}{743}{impossible events}
--\entry{assertions}{743}{assertions}
--\entry{variable number of arguments}{744}{variable number of arguments}
--\entry{variadic functions}{744}{variadic functions}
--\entry{optional arguments}{744}{optional arguments}
--\entry{function prototypes (variadic)}{745}{function prototypes (variadic)}
--\entry{prototypes for variadic functions}{745}{prototypes for variadic functions}
--\entry{variadic function prototypes}{745}{variadic function prototypes}
--\entry{variadic function argument access}{746}{variadic function argument access}
--\entry{arguments (variadic functions)}{746}{arguments (variadic functions)}
--\entry{number of arguments passed}{747}{number of arguments passed}
--\entry{how many arguments}{747}{how many arguments}
--\entry{arguments, how many}{747}{arguments, how many}
--\entry{variadic functions, calling}{747}{variadic functions, calling}
--\entry{calling variadic functions}{747}{calling variadic functions}
--\entry{declaring variadic functions}{747}{declaring variadic functions}
--\entry{default argument promotions}{747}{default argument promotions}
--\entry{argument promotion}{747}{argument promotion}
--\entry{null pointer constant}{750}{null pointer constant}
--\entry{integer type width}{752}{integer type width}
--\entry{width of integer type}{752}{width of integer type}
--\entry{type measurements, integer}{752}{type measurements, integer}
--\entry{integer type range}{752}{integer type range}
--\entry{range of integer type}{752}{range of integer type}
--\entry{limits, integer types}{752}{limits, integer types}
--\entry{floating type measurements}{754}{floating type measurements}
--\entry{measurements of floating types}{754}{measurements of floating types}
--\entry{type measurements, floating}{754}{type measurements, floating}
--\entry{limits, floating types}{754}{limits, floating types}
--\entry{sign (of floating point number)}{754}{sign (of floating point number)}
--\entry{base (of floating point number)}{754}{base (of floating point number)}
--\entry{radix (of floating point number)}{754}{radix (of floating point number)}
--\entry{exponent (of floating point number)}{754}{exponent (of floating point number)}
--\entry{bias (of floating point number exponent)}{754}{bias (of floating point number exponent)}
--\entry{mantissa (of floating point number)}{754}{mantissa (of floating point number)}
--\entry{significand (of floating point number)}{754}{significand (of floating point number)}
--\entry{precision (of floating point number)}{754}{precision (of floating point number)}
--\entry{hidden bit (of floating point number mantissa)}{754}{hidden bit (of floating point number mantissa)}
--\entry{normalized floating point number}{755}{normalized floating point number}
--\entry{IEEE floating point representation}{758}{IEEE floating point representation}
--\entry{floating point, IEEE}{758}{floating point, IEEE}
--\entry{configuring}{857}{configuring}
--\entry{compiling}{857}{compiling}
--\entry{installing}{859}{installing}
--\entry{installation tools}{860}{installation tools}
--\entry{tools, for installing library}{860}{tools, for installing library}
--\entry{configurations, all supported}{861}{configurations, all supported}
--\entry{upgrading from libc5}{862}{upgrading from libc5}
--\entry{kernel header files}{862}{kernel header files}
--\entry{reporting bugs}{863}{reporting bugs}
--\entry{bugs, reporting}{863}{bugs, reporting}
-diff -Naur ../glibc-2.1.3/manual/libc.cps glibc-2.1.3/manual/libc.cps
---- ../glibc-2.1.3/manual/libc.cps 2000-01-05 19:19:03.000000000 -0800
-+++ glibc-2.1.3/manual/libc.cps 1969-12-31 16:00:00.000000000 -0800
-@@ -1,935 +0,0 @@
--\initial {/}
--\entry {\file {/etc/nsswitch.conf}}{652}
--\initial {{\_}}
--\entry {__va_copy}{77}
--\entry {\code {_POSIX_OPTION_ORDER} environment variable.}{613}
--\entry {\code {_POSIX_SAVED_IDS}}{662}
--\initial {4}
--\entry {4.\var {n} BSD Unix}{3}
--\initial {A}
--\entry {abort signal}{532}
--\entry {aborting a program}{616}
--\entry {absolute file name}{208}
--\entry {absolute value functions}{468}
--\entry {accepting connections}{390}
--\entry {access permission for a file}{346}
--\entry {access, testing for}{348}
--\entry {accessing directories}{320}
--\entry {address of socket}{365}
--\entry {alarm signal}{534}
--\entry {alarms, setting}{513}
--\entry {alignment (in obstacks)}{55}
--\entry {alignment (with \code {malloc})}{36}
--\entry {\code {alloca} disadvantages}{59}
--\entry {\code {alloca} function}{57}
--\entry {allocating pseudo-terminals}{434}
--\entry {allocation (obstacks)}{48}
--\entry {allocation debugging}{43}
--\entry {allocation hooks, for \code {malloc}}{39}
--\entry {allocation of memory with \code {malloc}}{32}
--\entry {allocation size of string}{71}
--\entry {allocation statistics}{41}
--\entry {alphabetic character}{61, 65}
--\entry {alphanumeric character}{62, 64}
--\entry {append-access files}{207}
--\entry {argc (program argument count)}{575}
--\entry {argp (program argument parser)}{584}
--\entry {argp parser functions}{588}
--\entry {ARGP_HELP_FMT environment variable}{606}
--\entry {argument parsing with argp}{584}
--\entry {argument promotion}{747}
--\entry {argument vectors, null-character separated}{93}
--\entry {arguments (variadic functions)}{746}
--\entry {arguments, how many}{747}
--\entry {arguments, to program}{575}
--\entry {argv (program argument vector)}{575}
--\entry {argz vectors (string vectors)}{93}
--\entry {arithmetic expansion}{199}
--\entry {array comparison functions}{80}
--\entry {array copy functions}{73}
--\entry {array search function}{177}
--\entry {array sort function}{178}
--\entry {ASCII character}{63}
--\entry {assertions}{743}
--\entry {attributes of a file}{336}
--\entry {automatic allocation}{31}
--\entry {automatic freeing}{57}
--\entry {automatic storage with variable size}{57}
--\initial {B}
--\entry {background job}{631}
--\entry {background job, launching}{641}
--\entry {base (of floating point number)}{754}
--\entry {baud rate}{423}
--\entry {Berkeley Unix}{3}
--\entry {Bessel functions}{449}
--\entry {bias (of floating point number exponent)}{754}
--\entry {big-endian}{382}
--\entry {binary I/O to a stream}{221}
--\entry {binary search function (for arrays)}{177}
--\entry {binary stream}{251}
--\entry {binding a socket address}{365}
--\entry {blank character}{62, 67}
--\entry {block I/O to a stream}{221}
--\entry {blocked signals}{528}
--\entry {blocked signals, checking for}{565}
--\entry {blocking signals}{560}
--\entry {blocking signals, in a handler}{564}
--\entry {bootstrapping, and services}{653}
--\entry {break condition, detecting}{417}
--\entry {break condition, generating}{430}
--\entry {breaking a string into tokens}{88}
--\entry {broken pipe signal}{536}
--\entry {broken-down time}{489, 492}
--\entry {BSD compatibility library}{647}
--\entry {BSD compatibility library.}{8}
--\entry {BSD Unix}{3}
--\entry {buffering of streams}{256}
--\entry {buffering, controlling}{257}
--\entry {bugs, reporting}{863}
--\entry {bus error}{531}
--\entry {butterfly}{476}
--\entry {byte order conversion, for socket}{382}
--\entry {byte stream}{363}
--\initial {C}
--\entry {calendar time}{489}
--\entry {calendar time and broken-down time}{492}
--\entry {calling variadic functions}{747}
--\entry {canonical input processing}{412}
--\entry {capacity limits, POSIX}{697}
--\entry {carrier detect}{419}
--\entry {case conversion of characters}{63}
--\entry {catching signals}{528}
--\entry {categories for locales}{142}
--\entry {change working directory}{319}
--\entry {changing the locale}{143}
--\entry {changing the size of a block (\code {malloc})}{34}
--\entry {changing the size of a block (obstacks)}{51}
--\entry {channels}{283}
--\entry {character case conversion}{63}
--\entry {character predicates}{61}
--\entry {character testing}{61}
--\entry {checking for pending signals}{565}
--\entry {child process}{619, 620}
--\entry {child process signal}{534}
--\entry {chunks}{55}
--\entry {classes, floating-point}{459}
--\entry {classification of characters}{61}
--\entry {cleaning up a stream}{283}
--\entry {clearing terminal input queue}{431}
--\entry {client}{388}
--\entry {clock ticks}{487}
--\entry {close-on-exec (file descriptor flag)}{308}
--\entry {closing a file descriptor}{271}
--\entry {closing a socket}{387}
--\entry {closing a stream}{214}
--\entry {collating strings}{83}
--\entry {combining locales}{142}
--\entry {command argument syntax}{575}
--\entry {command arguments, parsing}{576}
--\entry {command line arguments}{575}
--\entry {command substitution}{199}
--\entry {communication style (of a socket)}{363}
--\entry {comparing strings and arrays}{80}
--\entry {Comparison Function}{177}
--\entry {compiling}{857}
--\entry {complex exponentiation functions}{446}
--\entry {complex logarithm functions}{446}
--\entry {complex numbers}{476}
--\entry {complex trigonometric functions}{441}
--\entry {concatenating strings}{73}
--\entry {configurations, all supported}{861}
--\entry {configuring}{857}
--\entry {conjugate complex numbers}{477}
--\entry {connecting a socket}{388}
--\entry {connection}{388}
--\entry {consistency checking}{743}
--\entry {consistency checking, of heap}{37}
--\entry {constants}{439}
--\entry {continue signal}{535}
--\entry {control character}{62, 65}
--\entry {control operations on files}{305}
--\entry {controlling process}{632}
--\entry {controlling terminal}{631}
--\entry {controlling terminal, access to}{632}
--\entry {controlling terminal, determining}{646}
--\entry {controlling terminal, setting}{311}
--\entry {conversion specifications (\code {printf})}{222}
--\entry {conversion specifications (\code {scanf})}{243}
--\entry {converting byte order}{382}
--\entry {converting case of characters}{63}
--\entry {converting file descriptor to stream}{282}
--\entry {converting floats to integers}{471}
--\entry {converting group ID to group name}{682}
--\entry {converting group name to group ID}{682}
--\entry {converting host address to name}{377}
--\entry {converting host name to address}{377}
--\entry {converting network name to network number}{408}
--\entry {converting network number to network name}{408}
--\entry {converting port number to service name}{381}
--\entry {converting service name to port number}{381}
--\entry {converting string to collation order}{84}
--\entry {converting strings to numbers}{479}
--\entry {converting user ID to user name}{679}
--\entry {converting user name to user ID}{679}
--\entry {cookie, for custom stream}{262}
--\entry {copying strings and arrays}{73}
--\entry {CPU time}{487}
--\entry {create on open (file status flag)}{310}
--\entry {creating a directory}{335}
--\entry {creating a FIFO special file}{360}
--\entry {creating a pipe}{357}
--\entry {creating a pipe to a subprocess}{359}
--\entry {creating a process}{620}
--\entry {creating a socket}{386}
--\entry {creating a socket pair}{387}
--\entry {creating special files}{352}
--\entry {cube root function}{445}
--\entry {currency symbols}{147}
--\entry {current working directory}{319}
--\entry {custom streams}{262}
--\entry {customizing \code {printf}}{237}
--\initial {D}
--\entry {data loss on sockets}{363}
--\entry {databases}{651}
--\entry {datagram socket}{401}
--\entry {datagrams, transmitting}{401}
--\entry {date and time}{489}
--\entry {Daylight Saving Time}{493}
--\entry {decimal digit character}{62}
--\entry {decimal-point separator}{146}
--\entry {declaration (compared to definition)}{4}
--\entry {declaring variadic functions}{747}
--\entry {decompose complex numbers}{477}
--\entry {default action (for a signal)}{528}
--\entry {default action for a signal}{539}
--\entry {default argument promotions}{747}
--\entry {default value, and NSS}{654}
--\entry {defining new \code {printf} conversions}{237}
--\entry {definition (compared to declaration)}{4}
--\entry {delayed suspend character}{427}
--\entry {deleting a directory}{334}
--\entry {deleting a file}{333}
--\entry {delivery of signals}{528}
--\entry {descriptors and streams}{283}
--\entry {digit character}{62, 65}
--\entry {directories, accessing}{320}
--\entry {directories, creating}{335}
--\entry {directories, deleting}{334}
--\entry {directory}{207}
--\entry {directory entry}{207}
--\entry {directory hierarchy}{327}
--\entry {directory stream}{320}
--\entry {disadvantages of \code {alloca}}{59}
--\entry {DISCARD character}{428}
--\entry {division by zero}{461}
--\entry {DNS server unavailable}{653}
--\entry {domain (of socket)}{363}
--\entry {domain error}{465}
--\entry {dot notation, for Internet addresses}{373}
--\entry {DSUSP character}{427}
--\entry {duplicating file descriptors}{306}
--\entry {dynamic allocation}{31}
--\initial {E}
--\entry {EBCDIC}{99}
--\entry {echo of terminal input}{421}
--\entry {effective group ID}{661}
--\entry {effective user ID}{661}
--\entry {efficiency and \code {malloc}}{36}
--\entry {efficiency and obstacks}{52}
--\entry {efficiency of chunks}{55}
--\entry {EINTR, and restarting interrupted primitives}{556}
--\entry {end of file, on a stream}{250}
--\entry {end-of-file, on a file descriptor}{275}
--\entry {environment}{610}
--\entry {environment access}{610}
--\entry {environment representation}{610}
--\entry {environment variable}{609}
--\entry {environment vectors, null-character separated}{93}
--\entry {envz vectors (environment vectors)}{93}
--\entry {EOF character}{425}
--\entry {EOL character}{425}
--\entry {EOL2 character}{425}
--\entry {epoch}{489}
--\entry {ERASE character}{426}
--\entry {error codes}{15}
--\entry {error messages, in argp}{591}
--\entry {error reporting}{15}
--\entry {errors, mathematical}{465}
--\entry {establishing a handler}{538}
--\entry {ethers}{651}
--\entry {EUC}{99}
--\entry {EUC-JP}{127}
--\entry {exception}{461, 530}
--\entry {exclusive lock}{314}
--\entry {\code {exec} functions}{622}
--\entry {executing a file}{622}
--\entry {exit status}{614}
--\entry {exit status value}{613}
--\entry {expansion of shell words}{198}
--\entry {exponent (of floating point number)}{754}
--\entry {exponentiation functions}{443}
--\entry {extending \code {printf}}{237}
--\entry {extracting file descriptor from stream}{282}
--\initial {F}
--\entry {\code {fcntl} function}{305}
--\entry {feature test macros}{7}
--\entry {field splitting}{199}
--\entry {FIFO special file}{357}
--\entry {file access permission}{346}
--\entry {file access time}{349}
--\entry {file attribute modification time}{349}
--\entry {file attributes}{336}
--\entry {file creation mask}{346}
--\entry {file descriptor flags}{307}
--\entry {file descriptor sets, for \code {select}}{289}
--\entry {file descriptors, standard}{283}
--\entry {file locks}{314}
--\entry {file modification time}{349}
--\entry {file name}{207}
--\entry {file name component}{207}
--\entry {file name errors}{208}
--\entry {file name resolution}{208}
--\entry {file name translation flags}{310}
--\entry {file names, multiple}{331}
--\entry {file owner}{343}
--\entry {file permission bits}{344}
--\entry {file pointer}{211}
--\entry {file position}{206}
--\entry {file positioning on a file descriptor}{279}
--\entry {file positioning on a stream}{252}
--\entry {file status flags}{309}
--\entry {filtering i/o through subprocess}{359}
--\entry {flag character (\code {printf})}{223}
--\entry {flag character (\code {scanf})}{244}
--\entry {flags for \code {sigaction}}{543}
--\entry {flags, file name translation}{310}
--\entry {flags, open-time action}{310}
--\entry {floating point}{459}
--\entry {floating point, IEEE}{758}
--\entry {floating type measurements}{754}
--\entry {floating-point classes}{459}
--\entry {floating-point exception}{530}
--\entry {flow control, terminal}{432}
--\entry {flushing a stream}{257}
--\entry {flushing terminal output queue}{431}
--\entry {foreground job}{631}
--\entry {foreground job, launching}{640}
--\entry {forking a process}{620}
--\entry {format string, for \code {printf}}{221}
--\entry {format string, for \code {scanf}}{242}
--\entry {formatted input from a stream}{242}
--\entry {formatted messages}{264}
--\entry {formatted output to a stream}{221}
--\entry {FP arithmetic}{473}
--\entry {freeing (obstacks)}{50}
--\entry {freeing memory allocated with \code {malloc}}{34}
--\entry {fully buffered stream}{257}
--\entry {function prototypes (variadic)}{745}
--\initial {G}
--\entry {gamma function}{449}
--\entry {gcvt_r}{485}
--\entry {gencat}{164}
--\entry {generation of signals}{528}
--\entry {generic i/o control operations}{318}
--\entry {globbing}{188}
--\entry {graphic character}{62, 65}
--\entry {Gregorian calendar}{489}
--\entry {group}{651}
--\entry {group database}{681}
--\entry {group ID}{661}
--\entry {group name}{661}
--\entry {group owner of a file}{343}
--\entry {grouping of digits}{146}
--\entry {growing objects (in obstacks)}{51}
--\initial {H}
--\entry {handling multiple signals}{549}
--\entry {hangup signal}{533}
--\entry {hard limit}{520}
--\entry {hard link}{331}
--\entry {header files}{4}
--\entry {heap consistency checking}{37}
--\entry {heap, dynamic allocation from}{32}
--\entry {heap, freeing memory from}{34}
--\entry {hexadecimal digit character}{62, 67}
--\entry {hidden bit (of floating point number mantissa)}{754}
--\entry {hierarchy, directory}{327}
--\entry {high-priority data}{398}
--\entry {high-resolution time}{489}
--\entry {holes in files}{280}
--\entry {home directory}{612}
--\entry {\code {HOME} environment variable}{612}
--\entry {hook functions (of custom streams)}{263}
--\entry {host address, Internet}{373}
--\entry {hosts}{651}
--\entry {hosts database}{377}
--\entry {how many arguments}{747}
--\entry {hyperbolic functions}{447}
--\initial {I}
--\entry {identifying terminals}{411}
--\entry {IEEE 754}{459}
--\entry {IEEE floating point}{459}
--\entry {IEEE floating point representation}{758}
--\entry {IEEE Std 1003.1}{2}
--\entry {IEEE Std 1003.2}{2}
--\entry {ignore action for a signal}{539}
--\entry {illegal instruction}{531}
--\entry {impossible events}{743}
--\entry {independent channels}{284}
--\entry {inexact exception}{461}
--\entry {infinity}{463}
--\entry {initial signal actions}{544}
--\entry {inode number}{339}
--\entry {input available signal}{534}
--\entry {input conversions, for \code {scanf}}{244}
--\entry {input from multiple files}{289}
--\entry {installation tools}{860}
--\entry {installing}{859}
--\entry {integer division functions}{478}
--\entry {integer type range}{752}
--\entry {integer type width}{752}
--\entry {interactive signals, from terminal}{422}
--\entry {interactive stop signal}{535}
--\entry {internal representation}{97}
--\entry {internationalization}{141}
--\entry {Internet host address}{373}
--\entry {Internet namespace, for sockets}{371}
--\entry {interprocess communication, with FIFO}{360}
--\entry {interprocess communication, with pipes}{357}
--\entry {interprocess communication, with signals}{559}
--\entry {interprocess communication, with sockets}{363}
--\entry {interrupt character}{427}
--\entry {interrupt signal}{532}
--\entry {interrupt-driven input}{317}
--\entry {interrupting primitives}{556}
--\entry {interval timer, setting}{513}
--\entry {INTR character}{427}
--\entry {invalid exception}{461}
--\entry {inverse complex hyperbolic functions}{448}
--\entry {inverse complex trigonometric functions}{442}
--\entry {inverse hyperbolic functions}{448}
--\entry {inverse trigonometric functions}{442}
--\entry {invocation of program}{575}
--\entry {IOCTLs}{318}
--\entry {ISO 10646}{97}
--\entry {ISO 2022}{99}
--\entry {ISO 6937}{100}
--\entry {ISO C}{2}
--\entry {ISO-2022-JP}{127}
--\entry {ISO/IEC 9945-1}{2}
--\entry {ISO/IEC 9945-2}{2}
--\initial {J}
--\entry {job}{631}
--\entry {job control}{631}
--\entry {job control functions}{646}
--\entry {job control is optional}{632}
--\entry {job control signals}{534}
--\entry {job control, enabling}{635}
--\initial {K}
--\entry {Kermit the frog}{181}
--\entry {kernel header files}{862}
--\entry {KILL character}{426}
--\entry {kill signal}{533}
--\entry {killing a process}{557}
--\initial {L}
--\entry {LANG environment variable}{161}
--\entry {\code {LANG} environment variable}{612}
--\entry {launching jobs}{637}
--\entry {LC_ALL environment variable}{161}
--\entry {\code {LC_ALL} environment variable}{613}
--\entry {\code {LC_COLLATE} environment variable}{613}
--\entry {\code {LC_CTYPE} environment variable}{613}
--\entry {LC_MESSAGES environment variable}{161}
--\entry {\code {LC_MESSAGES} environment variable}{613}
--\entry {\code {LC_MONETARY} environment variable}{613}
--\entry {\code {LC_NUMERIC} environment variable}{613}
--\entry {\code {LC_TIME} environment variable}{613}
--\entry {leap second}{492}
--\entry {length of string}{71}
--\entry {level, for socket options}{406}
--\entry {library}{1}
--\entry {limits on resource usage}{518}
--\entry {limits, file name length}{709}
--\entry {limits, floating types}{754}
--\entry {limits, integer types}{752}
--\entry {limits, link count of files}{709}
--\entry {limits, number of open files}{697}
--\entry {limits, number of processes}{697}
--\entry {limits, number of supplementary group IDs}{698}
--\entry {limits, pipe buffer size}{710}
--\entry {limits, POSIX}{697}
--\entry {limits, program argument size}{697}
--\entry {limits, terminal input queue}{709}
--\entry {limits, time zone name length}{697}
--\entry {line buffered stream}{257}
--\entry {line speed}{423}
--\entry {lines (in a text file)}{251}
--\entry {link}{207}
--\entry {link, hard}{331}
--\entry {link, soft}{332}
--\entry {link, symbolic}{332}
--\entry {linked channels}{283}
--\entry {listening (sockets)}{390}
--\entry {little-endian}{382}
--\entry {LNEXT character}{428}
--\entry {local namespace, for sockets}{369}
--\entry {local network address number}{373}
--\entry {local time}{489}
--\entry {locale categories}{142}
--\entry {locale, changing}{143}
--\entry {locales}{141}
--\entry {locales, parsing numbers and}{481}
--\entry {logarithm functions}{443}
--\entry {login name}{661}
--\entry {login name, determining}{670}
--\entry {\code {LOGNAME} environment variable}{612}
--\entry {long jumps}{523}
--\entry {long-named options}{576}
--\entry {longjmp}{58}
--\entry {loss of data on sockets}{363}
--\entry {lost resource signal}{536}
--\entry {lower-case character}{61, 66}
--\initial {M}
--\entry {macros}{50}
--\entry {\code {main} function}{575}
--\entry {malloc debugger}{43}
--\entry {\code {malloc} function}{32}
--\entry {mantissa (of floating point number)}{754}
--\entry {matching failure, in \code {scanf}}{243}
--\entry {mathematical constants}{439}
--\entry {maximum}{475}
--\entry {maximum field width (\code {scanf})}{244}
--\entry {measurements of floating types}{754}
--\entry {memory allocation}{31}
--\entry {merging of signals}{549}
--\entry {MIN termios slot}{429}
--\entry {minimum}{475}
--\entry {minimum field width (\code {printf})}{223}
--\entry {mixing descriptors and streams}{283}
--\entry {modem disconnect}{419}
--\entry {modem status lines}{419}
--\entry {monetary value formatting}{146}
--\entry {multibyte character}{99}
--\entry {multiple names for one file}{331}
--\entry {multiplexing input}{289}
--\entry {multiply-add}{475}
--\initial {N}
--\entry {name of running program}{28}
--\entry {name of socket}{365}
--\entry {Name Service Switch}{651}
--\entry {name space}{5}
--\entry {names of signals}{529}
--\entry {namespace (of socket)}{363}
--\entry {NaN}{463, 474}
--\entry {netgroup}{651}
--\entry {Netgroup}{685}
--\entry {network byte order}{382}
--\entry {network number}{373}
--\entry {network protocol}{363}
--\entry {networks}{651}
--\entry {networks database}{408}
--\entry {nisplus, and booting}{653}
--\entry {nisplus, and completeness}{653}
--\entry {NLSPATH environment variable}{160}
--\entry {\code {NLSPATH} environment variable}{613}
--\entry {non-blocking open}{310}
--\entry {non-local exit, from signal handler}{547}
--\entry {non-local exits}{523}
--\entry {noncanonical input processing}{412}
--\entry {normalization functions (floating-point)}{469}
--\entry {normalized floating point number}{755}
--\entry {not a number}{463}
--\entry {NSS}{651}
--\entry {\file {nsswitch.conf}}{652}
--\entry {null character}{71}
--\entry {null pointer constant}{750}
--\entry {number of arguments passed}{747}
--\entry {number syntax, parsing}{479}
--\entry {numeric value formatting}{146}
--\initial {O}
--\entry {obstack status}{54}
--\entry {obstacks}{47}
--\entry {open-time action flags}{310}
--\entry {opening a file}{205}
--\entry {opening a file descriptor}{271}
--\entry {opening a pipe}{357}
--\entry {opening a pseudo-terminal pair}{436}
--\entry {opening a socket}{386}
--\entry {opening a socket pair}{387}
--\entry {opening a stream}{212}
--\entry {Optimization}{457}
--\entry {optimizing NSS}{654}
--\entry {option parsing with argp}{584}
--\entry {optional arguments}{744}
--\entry {optional POSIX features}{698}
--\entry {orphaned process group}{633}
--\entry {out-of-band data}{398}
--\entry {output conversions, for \code {printf}}{224}
--\entry {output possible signal}{534}
--\entry {overflow exception}{461}
--\entry {owner of a file}{343}
--\initial {P}
--\entry {packet}{363}
--\entry {page boundary}{36}
--\entry {parent directory}{208}
--\entry {parent process}{619, 620}
--\entry {parity checking}{416}
--\entry {parsing a template string}{234}
--\entry {parsing numbers (in formatted input)}{479}
--\entry {parsing numbers and locales}{481}
--\entry {parsing program arguments}{576}
--\entry {parsing tokens from a string}{88}
--\entry {passwd}{651}
--\entry {password database}{678}
--\entry {\code {PATH} environment variable}{612}
--\entry {\code {pause} function}{567}
--\entry {peeking at input}{219}
--\entry {pending signals}{528}
--\entry {pending signals, checking for}{565}
--\entry {permission to access a file}{346}
--\entry {persona}{661}
--\entry {pi (trigonometric constant)}{440}
--\entry {pipe}{357}
--\entry {pipe signal}{536}
--\entry {pipe to a subprocess}{359}
--\entry {port number}{381}
--\entry {positioning a file descriptor}{279}
--\entry {positioning a stream}{252}
--\entry {positive difference}{475}
--\entry {POSIX}{2}
--\entry {POSIX capacity limits}{697}
--\entry {POSIX optional features}{698}
--\entry {POSIX.1}{2}
--\entry {POSIX.2}{2}
--\entry {power functions}{443}
--\entry {precision (of floating point number)}{754}
--\entry {precision (\code {printf})}{223}
--\entry {predicates on arrays}{80}
--\entry {predicates on characters}{61}
--\entry {predicates on strings}{80}
--\entry {primitives, interrupting}{556}
--\entry {printing character}{62, 66}
--\entry {priority of a process}{521}
--\entry {process}{575, 619}
--\entry {process completion}{624}
--\entry {process group functions}{646}
--\entry {process group ID}{637}
--\entry {process group leader}{637}
--\entry {process groups}{631}
--\entry {process ID}{620}
--\entry {process image}{620}
--\entry {process lifetime}{620}
--\entry {process priority}{521}
--\entry {process signal mask}{562}
--\entry {process termination}{613}
--\entry {processor time}{487}
--\entry {profiling alarm signal}{534}
--\entry {profiling timer}{513}
--\entry {program argument syntax}{575}
--\entry {program arguments}{575}
--\entry {program arguments, parsing}{576}
--\entry {program error signals}{529}
--\entry {program name}{28}
--\entry {program startup}{575}
--\entry {program termination}{613}
--\entry {program termination signals}{532}
--\entry {programming your own streams}{262}
--\entry {project complex numbers}{477}
--\entry {protocol (of socket)}{363}
--\entry {protocol family}{363}
--\entry {protocols}{651}
--\entry {protocols database}{383}
--\entry {prototypes for variadic functions}{745}
--\entry {pseudo-random numbers}{451}
--\entry {pseudo-terminals}{434}
--\entry {punctuation character}{62, 66}
--\entry {pushing input back}{219}
--\initial {Q}
--\entry {quick sort function (for arrays)}{178}
--\entry {QUIT character}{427}
--\entry {quit signal}{533}
--\entry {quote removal}{199}
--\initial {R}
--\entry {race conditions, relating to job control}{637}
--\entry {race conditions, relating to signals}{548}
--\entry {radix (of floating point number)}{754}
--\entry {raising signals}{556}
--\entry {random numbers}{451}
--\entry {random-access files}{206}
--\entry {range error}{465}
--\entry {range of integer type}{752}
--\entry {read lock}{314}
--\entry {reading from a directory}{320}
--\entry {reading from a file descriptor}{275}
--\entry {reading from a socket}{392}
--\entry {reading from a stream, by blocks}{221}
--\entry {reading from a stream, by characters}{216}
--\entry {reading from a stream, formatted}{242}
--\entry {real group ID}{661}
--\entry {real user ID}{661}
--\entry {real-time timer}{513}
--\entry {receiving datagrams}{401}
--\entry {record locking}{314}
--\entry {redirecting input and output}{306}
--\entry {reentrant functions}{552}
--\entry {reentrant NSS functions}{655}
--\entry {relative file name}{208}
--\entry {removal of quotes}{199}
--\entry {removing a file}{333}
--\entry {removing macros that shadow functions}{5}
--\entry {renaming a file}{334}
--\entry {reporting bugs}{863}
--\entry {reporting errors}{15}
--\entry {REPRINT character}{426}
--\entry {reserved names}{5}
--\entry {resource limits}{518}
--\entry {restarting interrupted primitives}{556}
--\entry {restrictions on signal handler functions}{551}
--\entry {root directory}{208}
--\entry {rpc}{651}
--\entry {running a command}{619}
--\initial {S}
--\entry {saved set-group-ID}{662}
--\entry {saved set-user-ID}{662}
--\entry {scanning the group list}{683}
--\entry {scanning the user list}{680}
--\entry {scatter-gather}{285}
--\entry {search function (for arrays)}{177}
--\entry {search functions (for strings)}{86}
--\entry {seed (for random numbers)}{451}
--\entry {seeking on a file descriptor}{279}
--\entry {seeking on a stream}{252}
--\entry {segmentation violation}{531}
--\entry {sending a datagram}{401}
--\entry {sending signals}{556}
--\entry {sequential-access files}{206}
--\entry {server}{388}
--\entry {services}{651}
--\entry {services database}{381}
--\entry {session}{631}
--\entry {session leader}{631}
--\entry {setting an alarm}{513}
--\entry {\code {setuid} programs}{662}
--\entry {setuid programs and file access}{348}
--\entry {severity class}{266, 267}
--\entry {shadow}{651}
--\entry {shadowing functions with macros}{5}
--\entry {shared lock}{314}
--\entry {shell}{631}
--\entry {shift state}{102}
--\entry {shrinking objects}{52}
--\entry {shutting down a socket}{387}
--\entry {\code {sigaction} flags}{543}
--\entry {\code {sigaction} function}{540}
--\entry {\code {SIGCHLD}, handling of}{642}
--\entry {sign (of floating point number)}{754}
--\entry {signal}{461, 527}
--\entry {signal action}{528}
--\entry {signal actions}{538}
--\entry {signal flags}{543}
--\entry {\code {signal} function}{538}
--\entry {signal handler function}{544}
--\entry {signal mask}{562}
--\entry {signal messages}{537}
--\entry {signal names}{529}
--\entry {signal number}{529}
--\entry {signal set}{561}
--\entry {signals, generating}{556}
--\entry {significand (of floating point number)}{754}
--\entry {\code {SIGTTIN}, from background job}{632}
--\entry {\code {SIGTTOU}, from background job}{633}
--\entry {size of string}{71}
--\entry {SJIS}{99}
--\entry {socket}{363}
--\entry {socket address (name) binding}{365}
--\entry {socket domain}{363}
--\entry {socket namespace}{363}
--\entry {socket option level}{406}
--\entry {socket options}{406}
--\entry {socket pair}{387}
--\entry {socket protocol}{363}
--\entry {socket shutdown}{387}
--\entry {socket, client actions}{388}
--\entry {socket, closing}{387}
--\entry {socket, connecting}{388}
--\entry {socket, creating}{386}
--\entry {socket, initiating a connection}{388}
--\entry {sockets, accepting connections}{390}
--\entry {sockets, listening}{390}
--\entry {sockets, server actions}{390}
--\entry {soft limit}{519}
--\entry {soft link}{332}
--\entry {sort function (for arrays)}{178}
--\entry {sparse files}{280}
--\entry {special files}{352}
--\entry {special functions}{449}
--\entry {specified action (for a signal)}{528}
--\entry {square root function}{445}
--\entry {stable sorting}{178}
--\entry {standard dot notation, for Internet addresses}{373}
--\entry {standard environment variables}{611}
--\entry {standard error file descriptor}{283}
--\entry {standard error stream}{212}
--\entry {standard file descriptors}{283}
--\entry {standard input file descriptor}{283}
--\entry {standard input stream}{211}
--\entry {standard output file descriptor}{283}
--\entry {standard output stream}{211}
--\entry {standard streams}{211}
--\entry {standards}{1}
--\entry {START character}{428}
--\entry {startup of program}{575}
--\entry {stateful}{102, 105, 110, 121, 124, 135}
--\entry {static allocation}{31}
--\entry {STATUS character}{429}
--\entry {status codes}{15}
--\entry {status of a file}{336}
--\entry {status of obstack}{54}
--\entry {sticky bit}{345}
--\entry {STOP character}{428}
--\entry {stop signal}{535}
--\entry {stopped job}{632}
--\entry {stopped jobs, continuing}{644}
--\entry {stopped jobs, detecting}{641}
--\entry {storage allocation}{31}
--\entry {stream (sockets)}{363}
--\entry {stream, for I/O to a string}{259}
--\entry {streams and descriptors}{283}
--\entry {streams, and file descriptors}{282}
--\entry {streams, standard}{211}
--\entry {string}{71}
--\entry {string allocation}{71}
--\entry {string collation functions}{83}
--\entry {string comparison functions}{80}
--\entry {string concatenation functions}{73}
--\entry {string copy functions}{73}
--\entry {string length}{71}
--\entry {string literal}{71}
--\entry {string search functions}{86}
--\entry {string stream}{259}
--\entry {string vectors, null-character separated}{93}
--\entry {string, representation of}{71}
--\entry {style of communication (of a socket)}{363}
--\entry {subshell}{635}
--\entry {substitution of variables and commands}{199}
--\entry {successive signals}{549}
--\entry {summer time}{493}
--\entry {SunOS}{3}
--\entry {supplementary group IDs}{661}
--\entry {SUSP character}{427}
--\entry {suspend character}{427}
--\entry {SVID}{3}
--\entry {symbolic link}{332}
--\entry {symbolic link, opening}{311}
--\entry {synchronizing}{292, 301}
--\entry {syntax error messages, in argp}{591}
--\entry {syntax, for program arguments}{575}
--\entry {syntax, for reading numbers}{479}
--\entry {System V Unix}{3}
--\initial {T}
--\entry {TCP (Internet protocol)}{383}
--\entry {template, for \code {printf}}{221}
--\entry {template, for \code {scanf}}{242}
--\entry {\code {TERM} environment variable}{612}
--\entry {terminal flow control}{432}
--\entry {terminal identification}{411}
--\entry {terminal input queue}{412}
--\entry {terminal input queue, clearing}{431}
--\entry {terminal input signal}{535}
--\entry {terminal line control functions}{430}
--\entry {terminal line speed}{423}
--\entry {terminal mode data types}{413}
--\entry {terminal mode functions}{414}
--\entry {terminal output queue}{412}
--\entry {terminal output queue, flushing}{431}
--\entry {terminal output signal}{536}
--\entry {terminated jobs, detecting}{641}
--\entry {termination signal}{532}
--\entry {testing access permission}{348}
--\entry {testing exit status of child process}{624}
--\entry {text stream}{251}
--\entry {ticks, clock}{487}
--\entry {tilde expansion}{199}
--\entry {TIME termios slot}{429}
--\entry {time zone}{507}
--\entry {time zone database}{509}
--\entry {time, calendar}{489}
--\entry {time, elapsed CPU}{487}
--\entry {time, high precision}{511}
--\entry {timer, profiling}{513}
--\entry {timer, real-time}{513}
--\entry {timer, virtual}{513}
--\entry {timers, setting}{513}
--\entry {timing error in signal handling}{567}
--\entry {TMPDIR environment variable}{355}
--\entry {tokenizing strings}{88}
--\entry {tools, for installing library}{860}
--\entry {transmitting datagrams}{401}
--\entry {tree, directory}{327}
--\entry {triangulation}{126}
--\entry {trigonometric functions}{440}
--\entry {type measurements, floating}{754}
--\entry {type measurements, integer}{752}
--\entry {type modifier character (\code {printf})}{224}
--\entry {type modifier character (\code {scanf})}{244}
--\entry {typeahead buffer}{412}
--\entry {\code {TZ} environment variable}{612}
--\initial {U}
--\entry {UCS2}{97}
--\entry {UCS4}{97}
--\entry {umask}{346}
--\entry {unbuffered stream}{256}
--\entry {unconstrained storage allocation}{32}
--\entry {undefining macros that shadow functions}{5}
--\entry {underflow exception}{461}
--\entry {Unicode}{97}
--\entry {Unix, Berkeley}{3}
--\entry {Unix, System V}{3}
--\entry {unlinking a file}{333}
--\entry {unordered comparison}{474}
--\entry {unreading characters}{219}
--\entry {upgrading from libc5}{862}
--\entry {upper-case character}{61, 67}
--\entry {urgent data signal}{534}
--\entry {urgent socket condition}{398}
--\entry {usage limits}{518}
--\entry {usage messages, in argp}{591}
--\entry {user accounting database}{671}
--\entry {user database}{678}
--\entry {user ID}{661}
--\entry {user ID, determining}{670}
--\entry {user name}{661}
--\entry {user signals}{537}
--\entry {usual file name errors}{208}
--\entry {UTF-7}{100}
--\entry {UTF-8}{100}
--\initial {V}
--\entry {va_copy}{77}
--\entry {variable number of arguments}{744}
--\entry {variable substitution}{199}
--\entry {variable-sized arrays}{59}
--\entry {variadic function argument access}{746}
--\entry {variadic function prototypes}{745}
--\entry {variadic functions}{744}
--\entry {variadic functions, calling}{747}
--\entry {virtual time alarm signal}{534}
--\entry {virtual timer}{513}
--\entry {\code {volatile} declarations}{552}
--\initial {W}
--\entry {waiting for a signal}{567}
--\entry {waiting for completion of child process}{624}
--\entry {waiting for input or output}{289}
--\entry {WERASE character}{426}
--\entry {whitespace character}{62, 66}
--\entry {wide character}{97}
--\entry {width of integer type}{752}
--\entry {wildcard expansion}{199}
--\entry {word expansion}{198}
--\entry {working directory}{319}
--\entry {write lock}{314}
--\entry {writing to a file descriptor}{277}
--\entry {writing to a socket}{392}
--\entry {writing to a stream, by blocks}{221}
--\entry {writing to a stream, by characters}{215}
--\entry {writing to a stream, formatted}{221}
--\initial {Z}
--\entry {zero divide}{461}
-diff -Naur ../glibc-2.1.3/manual/libc.fn glibc-2.1.3/manual/libc.fn
---- ../glibc-2.1.3/manual/libc.fn 2000-01-05 19:19:29.000000000 -0800
-+++ glibc-2.1.3/manual/libc.fn 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1142 +0,0 @@
--\entry{strerror}{27}{\code {strerror}}
--\entry{strerror{\_}r}{27}{\code {strerror_r}}
--\entry{perror}{27}{\code {perror}}
--\entry{malloc}{32}{\code {malloc}}
--\entry{free}{34}{\code {free}}
--\entry{cfree}{34}{\code {cfree}}
--\entry{realloc}{35}{\code {realloc}}
--\entry{calloc}{35}{\code {calloc}}
--\entry{memalign}{36}{\code {memalign}}
--\entry{valloc}{36}{\code {valloc}}
--\entry{mallopt}{37}{\code {mallopt}}
--\entry{mcheck}{37}{\code {mcheck}}
--\entry{mprobe}{38}{\code {mprobe}}
--\entry{mallinfo}{42}{\code {mallinfo}}
--\entry{mtrace}{43}{\code {mtrace}}
--\entry{muntrace}{43}{\code {muntrace}}
--\entry{obstack{\_}chunk{\_}alloc}{47}{\code {obstack_chunk_alloc}}
--\entry{obstack{\_}chunk{\_}free}{47}{\code {obstack_chunk_free}}
--\entry{obstack{\_}init}{48}{\code {obstack_init}}
--\entry{obstack{\_}alloc}{49}{\code {obstack_alloc}}
--\entry{obstack{\_}copy}{49}{\code {obstack_copy}}
--\entry{obstack{\_}copy0}{49}{\code {obstack_copy0}}
--\entry{obstack{\_}free}{50}{\code {obstack_free}}
--\entry{obstack{\_}blank}{51}{\code {obstack_blank}}
--\entry{obstack{\_}grow}{51}{\code {obstack_grow}}
--\entry{obstack{\_}grow0}{51}{\code {obstack_grow0}}
--\entry{obstack{\_}1grow}{51}{\code {obstack_1grow}}
--\entry{obstack{\_}ptr{\_}grow}{52}{\code {obstack_ptr_grow}}
--\entry{obstack{\_}int{\_}grow}{52}{\code {obstack_int_grow}}
--\entry{obstack{\_}finish}{52}{\code {obstack_finish}}
--\entry{obstack{\_}object{\_}size}{52}{\code {obstack_object_size}}
--\entry{obstack{\_}room}{53}{\code {obstack_room}}
--\entry{obstack{\_}1grow{\_}fast}{53}{\code {obstack_1grow_fast}}
--\entry{obstack{\_}ptr{\_}grow{\_}fast}{53}{\code {obstack_ptr_grow_fast}}
--\entry{obstack{\_}int{\_}grow{\_}fast}{53}{\code {obstack_int_grow_fast}}
--\entry{obstack{\_}blank{\_}fast}{53}{\code {obstack_blank_fast}}
--\entry{obstack{\_}base}{54}{\code {obstack_base}}
--\entry{obstack{\_}next{\_}free}{54}{\code {obstack_next_free}}
--\entry{obstack{\_}object{\_}size}{54}{\code {obstack_object_size}}
--\entry{obstack{\_}alignment{\_}mask}{55}{\code {obstack_alignment_mask}}
--\entry{obstack{\_}chunk{\_}size}{56}{\code {obstack_chunk_size}}
--\entry{alloca}{57}{\code {alloca}}
--\entry{islower}{61}{\code {islower}}
--\entry{isupper}{61}{\code {isupper}}
--\entry{isalpha}{61}{\code {isalpha}}
--\entry{isdigit}{62}{\code {isdigit}}
--\entry{isalnum}{62}{\code {isalnum}}
--\entry{isxdigit}{62}{\code {isxdigit}}
--\entry{ispunct}{62}{\code {ispunct}}
--\entry{isspace}{62}{\code {isspace}}
--\entry{isblank}{62}{\code {isblank}}
--\entry{isgraph}{62}{\code {isgraph}}
--\entry{isprint}{62}{\code {isprint}}
--\entry{iscntrl}{63}{\code {iscntrl}}
--\entry{isascii}{63}{\code {isascii}}
--\entry{tolower}{63}{\code {tolower}}
--\entry{toupper}{63}{\code {toupper}}
--\entry{toascii}{63}{\code {toascii}}
--\entry{{\_}tolower}{63}{\code {_tolower}}
--\entry{{\_}toupper}{63}{\code {_toupper}}
--\entry{wctype}{64}{\code {wctype}}
--\entry{iswctype}{64}{\code {iswctype}}
--\entry{iswalnum}{65}{\code {iswalnum}}
--\entry{iswalpha}{65}{\code {iswalpha}}
--\entry{iswcntrl}{65}{\code {iswcntrl}}
--\entry{iswdigit}{65}{\code {iswdigit}}
--\entry{iswgraph}{66}{\code {iswgraph}}
--\entry{iswlower}{66}{\code {iswlower}}
--\entry{iswprint}{66}{\code {iswprint}}
--\entry{iswpunct}{66}{\code {iswpunct}}
--\entry{iswspace}{66}{\code {iswspace}}
--\entry{iswupper}{67}{\code {iswupper}}
--\entry{iswxdigit}{67}{\code {iswxdigit}}
--\entry{iswblank}{67}{\code {iswblank}}
--\entry{wctrans}{68}{\code {wctrans}}
--\entry{towctrans}{69}{\code {towctrans}}
--\entry{towlower}{69}{\code {towlower}}
--\entry{towupper}{69}{\code {towupper}}
--\entry{strlen}{72}{\code {strlen}}
--\entry{strnlen}{73}{\code {strnlen}}
--\entry{memcpy}{74}{\code {memcpy}}
--\entry{mempcpy}{74}{\code {mempcpy}}
--\entry{memmove}{74}{\code {memmove}}
--\entry{memccpy}{74}{\code {memccpy}}
--\entry{memset}{74}{\code {memset}}
--\entry{strcpy}{74}{\code {strcpy}}
--\entry{strncpy}{75}{\code {strncpy}}
--\entry{strdup}{75}{\code {strdup}}
--\entry{strndup}{75}{\code {strndup}}
--\entry{stpcpy}{75}{\code {stpcpy}}
--\entry{stpncpy}{76}{\code {stpncpy}}
--\entry{strdupa}{76}{\code {strdupa}}
--\entry{strndupa}{77}{\code {strndupa}}
--\entry{strcat}{77}{\code {strcat}}
--\entry{strncat}{79}{\code {strncat}}
--\entry{bcopy}{80}{\code {bcopy}}
--\entry{bzero}{80}{\code {bzero}}
--\entry{memcmp}{81}{\code {memcmp}}
--\entry{strcmp}{81}{\code {strcmp}}
--\entry{strcasecmp}{81}{\code {strcasecmp}}
--\entry{strncasecmp}{82}{\code {strncasecmp}}
--\entry{strncmp}{82}{\code {strncmp}}
--\entry{strverscmp}{82}{\code {strverscmp}}
--\entry{bcmp}{83}{\code {bcmp}}
--\entry{strcoll}{84}{\code {strcoll}}
--\entry{strxfrm}{84}{\code {strxfrm}}
--\entry{memchr}{86}{\code {memchr}}
--\entry{strchr}{86}{\code {strchr}}
--\entry{index}{87}{\code {index}}
--\entry{strrchr}{87}{\code {strrchr}}
--\entry{rindex}{87}{\code {rindex}}
--\entry{strstr}{87}{\code {strstr}}
--\entry{memmem}{88}{\code {memmem}}
--\entry{strspn}{88}{\code {strspn}}
--\entry{strcspn}{88}{\code {strcspn}}
--\entry{strpbrk}{88}{\code {strpbrk}}
--\entry{strtok}{88}{\code {strtok}}
--\entry{strtok{\_}r}{90}{\code {strtok_r}}
--\entry{strsep}{90}{\code {strsep}}
--\entry{l64a}{91}{\code {l64a}}
--\entry{a64l}{92}{\code {a64l}}
--\entry{argz{\_}create}{93}{\code {argz_create}}
--\entry{argz{\_}create{\_}sep}{93}{\code {argz_create_sep}}
--\entry{argz{\_}count}{93}{\code {argz_count}}
--\entry{argz{\_}extract}{94}{\code {argz_extract}}
--\entry{argz{\_}stringify}{94}{\code {argz_stringify}}
--\entry{argz{\_}add}{94}{\code {argz_add}}
--\entry{argz{\_}add{\_}sep}{94}{\code {argz_add_sep}}
--\entry{argz{\_}append}{94}{\code {argz_append}}
--\entry{argz{\_}delete}{94}{\code {argz_delete}}
--\entry{argz{\_}insert}{94}{\code {argz_insert}}
--\entry{argz{\_}next}{95}{\code {argz_next}}
--\entry{argz{\_}replace}{95}{\code {argz_replace}}
--\entry{envz{\_}entry}{95}{\code {envz_entry}}
--\entry{envz{\_}get}{96}{\code {envz_get}}
--\entry{envz{\_}add}{96}{\code {envz_add}}
--\entry{envz{\_}merge}{96}{\code {envz_merge}}
--\entry{envz{\_}strip}{96}{\code {envz_strip}}
--\entry{mbsinit}{103}{\code {mbsinit}}
--\entry{btowc}{104}{\code {btowc}}
--\entry{wctob}{105}{\code {wctob}}
--\entry{mbrtowc}{105}{\code {mbrtowc}}
--\entry{mbrlen}{106}{\code {mbrlen}}
--\entry{wcrtomb}{107}{\code {wcrtomb}}
--\entry{mbsrtowcs}{110}{\code {mbsrtowcs}}
--\entry{wcsrtombs}{111}{\code {wcsrtombs}}
--\entry{mbsnrtowcs}{112}{\code {mbsnrtowcs}}
--\entry{wcsnrtombs}{112}{\code {wcsnrtombs}}
--\entry{mbtowc}{115}{\code {mbtowc}}
--\entry{wctomb}{115}{\code {wctomb}}
--\entry{mblen}{116}{\code {mblen}}
--\entry{mbstowcs}{116}{\code {mbstowcs}}
--\entry{wcstombs}{117}{\code {wcstombs}}
--\entry{iconv{\_}open}{119}{\code {iconv_open}}
--\entry{iconv{\_}close}{120}{\code {iconv_close}}
--\entry{iconv}{121}{\code {iconv}}
--\entry{setlocale}{143}{\code {setlocale}}
--\entry{localeconv}{146}{\code {localeconv}}
--\entry{nl{\_}langinfo}{150}{\code {nl_langinfo}}
--\entry{strfmon}{155}{\code {strfmon}}
--\entry{catopen}{159}{\code {catopen}}
--\entry{catgets}{162}{\code {catgets}}
--\entry{catclose}{162}{\code {catclose}}
--\entry{gettext}{169}{\code {gettext}}
--\entry{dgettext}{170}{\code {dgettext}}
--\entry{dcgettext}{170}{\code {dcgettext}}
--\entry{textdomain}{172}{\code {textdomain}}
--\entry{bindtextdomain}{172}{\code {bindtextdomain}}
--\entry{lfind}{177}{\code {lfind}}
--\entry{lsearch}{178}{\code {lsearch}}
--\entry{bsearch}{178}{\code {bsearch}}
--\entry{qsort}{178}{\code {qsort}}
--\entry{hcreate}{182}{\code {hcreate}}
--\entry{hdestroy}{182}{\code {hdestroy}}
--\entry{hsearch}{183}{\code {hsearch}}
--\entry{hcreate{\_}r}{183}{\code {hcreate_r}}
--\entry{hdestroy{\_}r}{183}{\code {hdestroy_r}}
--\entry{hsearch{\_}r}{184}{\code {hsearch_r}}
--\entry{tsearch}{184}{\code {tsearch}}
--\entry{tfind}{185}{\code {tfind}}
--\entry{tdelete}{185}{\code {tdelete}}
--\entry{tdestroy}{185}{\code {tdestroy}}
--\entry{twalk}{186}{\code {twalk}}
--\entry{fnmatch}{187}{\code {fnmatch}}
--\entry{glob}{189}{\code {glob}}
--\entry{globfree}{193}{\code {globfree}}
--\entry{regcomp}{194}{\code {regcomp}}
--\entry{regexec}{195}{\code {regexec}}
--\entry{regfree}{198}{\code {regfree}}
--\entry{regerror}{198}{\code {regerror}}
--\entry{wordexp}{200}{\code {wordexp}}
--\entry{wordfree}{200}{\code {wordfree}}
--\entry{fopen}{212}{\code {fopen}}
--\entry{fopen64}{213}{\code {fopen64}}
--\entry{freopen}{214}{\code {freopen}}
--\entry{freopen64}{214}{\code {freopen64}}
--\entry{fclose}{214}{\code {fclose}}
--\entry{fcloseall}{215}{\code {fcloseall}}
--\entry{fputc}{215}{\code {fputc}}
--\entry{putc}{215}{\code {putc}}
--\entry{putchar}{216}{\code {putchar}}
--\entry{fputs}{216}{\code {fputs}}
--\entry{puts}{216}{\code {puts}}
--\entry{putw}{216}{\code {putw}}
--\entry{fgetc}{216}{\code {fgetc}}
--\entry{getc}{217}{\code {getc}}
--\entry{getchar}{217}{\code {getchar}}
--\entry{getw}{217}{\code {getw}}
--\entry{getline}{218}{\code {getline}}
--\entry{getdelim}{218}{\code {getdelim}}
--\entry{fgets}{218}{\code {fgets}}
--\entry{gets}{219}{\code {gets}}
--\entry{ungetc}{220}{\code {ungetc}}
--\entry{fread}{221}{\code {fread}}
--\entry{fwrite}{221}{\code {fwrite}}
--\entry{printf}{230}{\code {printf}}
--\entry{fprintf}{230}{\code {fprintf}}
--\entry{sprintf}{230}{\code {sprintf}}
--\entry{snprintf}{230}{\code {snprintf}}
--\entry{asprintf}{231}{\code {asprintf}}
--\entry{obstack{\_}printf}{231}{\code {obstack_printf}}
--\entry{vprintf}{232}{\code {vprintf}}
--\entry{vfprintf}{233}{\code {vfprintf}}
--\entry{vsprintf}{233}{\code {vsprintf}}
--\entry{vsnprintf}{233}{\code {vsnprintf}}
--\entry{vasprintf}{233}{\code {vasprintf}}
--\entry{obstack{\_}vprintf}{233}{\code {obstack_vprintf}}
--\entry{parse{\_}printf{\_}format}{234}{\code {parse_printf_format}}
--\entry{register{\_}printf{\_}function}{237}{\code {register_printf_function}}
--\entry{printf{\_}size}{241}{\code {printf_size}}
--\entry{printf{\_}size{\_}info}{242}{\code {printf_size_info}}
--\entry{scanf}{249}{\code {scanf}}
--\entry{fscanf}{249}{\code {fscanf}}
--\entry{sscanf}{249}{\code {sscanf}}
--\entry{vscanf}{250}{\code {vscanf}}
--\entry{vfscanf}{250}{\code {vfscanf}}
--\entry{vsscanf}{250}{\code {vsscanf}}
--\entry{clearerr}{250}{\code {clearerr}}
--\entry{feof}{251}{\code {feof}}
--\entry{ferror}{251}{\code {ferror}}
--\entry{ftell}{252}{\code {ftell}}
--\entry{ftello}{252}{\code {ftello}}
--\entry{ftello64}{252}{\code {ftello64}}
--\entry{fseek}{253}{\code {fseek}}
--\entry{fseeko}{253}{\code {fseeko}}
--\entry{fseeko64}{253}{\code {fseeko64}}
--\entry{rewind}{254}{\code {rewind}}
--\entry{fgetpos}{255}{\code {fgetpos}}
--\entry{fgetpos64}{255}{\code {fgetpos64}}
--\entry{fsetpos}{256}{\code {fsetpos}}
--\entry{fsetpos64}{256}{\code {fsetpos64}}
--\entry{fflush}{257}{\code {fflush}}
--\entry{setvbuf}{258}{\code {setvbuf}}
--\entry{setbuf}{259}{\code {setbuf}}
--\entry{setbuffer}{259}{\code {setbuffer}}
--\entry{setlinebuf}{259}{\code {setlinebuf}}
--\entry{fmemopen}{259}{\code {fmemopen}}
--\entry{open{\_}memstream}{260}{\code {open_memstream}}
--\entry{open{\_}obstack{\_}stream}{261}{\code {open_obstack_stream}}
--\entry{fopencookie}{263}{\code {fopencookie}}
--\entry{fmtmsg}{265}{\code {fmtmsg}}
--\entry{addseverity}{267}{\code {addseverity}}
--\entry{open}{271}{\code {open}}
--\entry{open64}{272}{\code {open64}}
--\entry{creat}{272}{\code {creat}}
--\entry{creat64}{273}{\code {creat64}}
--\entry{close}{273}{\code {close}}
--\entry{truncate}{274}{\code {truncate}}
--\entry{truncate64}{274}{\code {truncate64}}
--\entry{ftruncate}{274}{\code {ftruncate}}
--\entry{ftruncate64}{275}{\code {ftruncate64}}
--\entry{read}{275}{\code {read}}
--\entry{pread}{276}{\code {pread}}
--\entry{pread64}{277}{\code {pread64}}
--\entry{write}{277}{\code {write}}
--\entry{pwrite}{279}{\code {pwrite}}
--\entry{pwrite64}{279}{\code {pwrite64}}
--\entry{lseek}{280}{\code {lseek}}
--\entry{lseek64}{281}{\code {lseek64}}
--\entry{fdopen}{282}{\code {fdopen}}
--\entry{fileno}{283}{\code {fileno}}
--\entry{fclean}{284}{\code {fclean}}
--\entry{readv}{285}{\code {readv}}
--\entry{writev}{285}{\code {writev}}
--\entry{mmap}{286}{\code {mmap}}
--\entry{munmap}{288}{\code {munmap}}
--\entry{msync}{288}{\code {msync}}
--\entry{mremap}{288}{\code {mremap}}
--\entry{FD{\_}ZERO}{290}{\code {FD_ZERO}}
--\entry{FD{\_}SET}{290}{\code {FD_SET}}
--\entry{FD{\_}CLR}{290}{\code {FD_CLR}}
--\entry{FD{\_}ISSET}{290}{\code {FD_ISSET}}
--\entry{select}{290}{\code {select}}
--\entry{sync}{292}{\code {sync}}
--\entry{fsync}{292}{\code {fsync}}
--\entry{fdatasync}{293}{\code {fdatasync}}
--\entry{aio{\_}read}{296}{\code {aio_read}}
--\entry{aio{\_}read64}{297}{\code {aio_read64}}
--\entry{aio{\_}write}{297}{\code {aio_write}}
--\entry{aio{\_}write64}{298}{\code {aio_write64}}
--\entry{lio{\_}listio}{298}{\code {lio_listio}}
--\entry{lio{\_}listio64}{299}{\code {lio_listio64}}
--\entry{aio{\_}error}{300}{\code {aio_error}}
--\entry{aio{\_}error64}{300}{\code {aio_error64}}
--\entry{aio{\_}return}{300}{\code {aio_return}}
--\entry{aio{\_}return64}{301}{\code {aio_return64}}
--\entry{aio{\_}fsync}{301}{\code {aio_fsync}}
--\entry{aio{\_}fsync64}{302}{\code {aio_fsync64}}
--\entry{aio{\_}suspend}{302}{\code {aio_suspend}}
--\entry{aio{\_}suspend64}{303}{\code {aio_suspend64}}
--\entry{aio{\_}cancel}{303}{\code {aio_cancel}}
--\entry{aio{\_}cancel64}{304}{\code {aio_cancel64}}
--\entry{aio{\_}init}{304}{\code {aio_init}}
--\entry{fcntl}{305}{\code {fcntl}}
--\entry{dup}{306}{\code {dup}}
--\entry{dup2}{306}{\code {dup2}}
--\entry{ioctl}{318}{\code {ioctl}}
--\entry{getcwd}{319}{\code {getcwd}}
--\entry{getwd}{320}{\code {getwd}}
--\entry{chdir}{320}{\code {chdir}}
--\entry{IFTODT}{321}{\code {IFTODT}}
--\entry{DTTOIF}{322}{\code {DTTOIF}}
--\entry{opendir}{322}{\code {opendir}}
--\entry{readdir}{323}{\code {readdir}}
--\entry{readdir{\_}r}{323}{\code {readdir_r}}
--\entry{closedir}{323}{\code {closedir}}
--\entry{rewinddir}{324}{\code {rewinddir}}
--\entry{telldir}{324}{\code {telldir}}
--\entry{seekdir}{324}{\code {seekdir}}
--\entry{scandir}{325}{\code {scandir}}
--\entry{alphasort}{325}{\code {alphasort}}
--\entry{versionsort}{325}{\code {versionsort}}
--\entry{scandir64}{325}{\code {scandir64}}
--\entry{alphasort64}{326}{\code {alphasort64}}
--\entry{versionsort64}{326}{\code {versionsort64}}
--\entry{ftw}{329}{\code {ftw}}
--\entry{ftw64}{329}{\code {ftw64}}
--\entry{nftw}{329}{\code {nftw}}
--\entry{nftw64}{330}{\code {nftw64}}
--\entry{link}{331}{\code {link}}
--\entry{symlink}{332}{\code {symlink}}
--\entry{readlink}{332}{\code {readlink}}
--\entry{unlink}{333}{\code {unlink}}
--\entry{rmdir}{334}{\code {rmdir}}
--\entry{remove}{334}{\code {remove}}
--\entry{rename}{334}{\code {rename}}
--\entry{mkdir}{335}{\code {mkdir}}
--\entry{stat}{340}{\code {stat}}
--\entry{stat64}{340}{\code {stat64}}
--\entry{fstat}{341}{\code {fstat}}
--\entry{fstat64}{341}{\code {fstat64}}
--\entry{lstat}{341}{\code {lstat}}
--\entry{lstat64}{341}{\code {lstat64}}
--\entry{S{\_}ISDIR}{342}{\code {S_ISDIR}}
--\entry{S{\_}ISCHR}{342}{\code {S_ISCHR}}
--\entry{S{\_}ISBLK}{342}{\code {S_ISBLK}}
--\entry{S{\_}ISREG}{342}{\code {S_ISREG}}
--\entry{S{\_}ISFIFO}{342}{\code {S_ISFIFO}}
--\entry{S{\_}ISLNK}{342}{\code {S_ISLNK}}
--\entry{S{\_}ISSOCK}{342}{\code {S_ISSOCK}}
--\entry{chown}{343}{\code {chown}}
--\entry{fchown}{344}{\code {fchown}}
--\entry{chmod}{346}{\code {chmod}}
--\entry{umask}{347}{\code {umask}}
--\entry{getumask}{347}{\code {getumask}}
--\entry{chmod}{347}{\code {chmod}}
--\entry{fchmod}{347}{\code {fchmod}}
--\entry{access}{348}{\code {access}}
--\entry{utime}{350}{\code {utime}}
--\entry{utimes}{350}{\code {utimes}}
--\entry{truncate}{351}{\code {truncate}}
--\entry{ftruncate}{351}{\code {ftruncate}}
--\entry{mknod}{352}{\code {mknod}}
--\entry{tmpfile}{353}{\code {tmpfile}}
--\entry{tmpfile64}{353}{\code {tmpfile64}}
--\entry{tmpnam}{354}{\code {tmpnam}}
--\entry{tmpnam{\_}r}{354}{\code {tmpnam_r}}
--\entry{tempnam}{354}{\code {tempnam}}
--\entry{mktemp}{355}{\code {mktemp}}
--\entry{mkstemp}{355}{\code {mkstemp}}
--\entry{pipe}{357}{\code {pipe}}
--\entry{popen}{359}{\code {popen}}
--\entry{pclose}{359}{\code {pclose}}
--\entry{mkfifo}{360}{\code {mkfifo}}
--\entry{bind}{367}{\code {bind}}
--\entry{getsockname}{367}{\code {getsockname}}
--\entry{if{\_}nametoindex}{368}{\code {if_nametoindex}}
--\entry{if{\_}indextoname}{368}{\code {if_indextoname}}
--\entry{if{\_}nameindex}{368}{\code {if_nameindex}}
--\entry{if{\_}freenameindex}{369}{\code {if_freenameindex}}
--\entry{SUN{\_}LEN}{370}{\code {SUN_LEN}}
--\entry{inet{\_}aton}{376}{\code {inet_aton}}
--\entry{inet{\_}addr}{376}{\code {inet_addr}}
--\entry{inet{\_}network}{376}{\code {inet_network}}
--\entry{inet{\_}ntoa}{376}{\code {inet_ntoa}}
--\entry{inet{\_}makeaddr}{376}{\code {inet_makeaddr}}
--\entry{inet{\_}lnaof}{376}{\code {inet_lnaof}}
--\entry{inet{\_}netof}{377}{\code {inet_netof}}
--\entry{inet{\_}pton}{377}{\code {inet_pton}}
--\entry{inet{\_}ntop}{377}{\code {inet_ntop}}
--\entry{gethostbyname}{378}{\code {gethostbyname}}
--\entry{gethostbyname2}{378}{\code {gethostbyname2}}
--\entry{gethostbyaddr}{378}{\code {gethostbyaddr}}
--\entry{gethostbyname{\_}r}{379}{\code {gethostbyname_r}}
--\entry{gethostbyname2{\_}r}{380}{\code {gethostbyname2_r}}
--\entry{gethostbyaddr{\_}r}{380}{\code {gethostbyaddr_r}}
--\entry{sethostent}{380}{\code {sethostent}}
--\entry{gethostent}{380}{\code {gethostent}}
--\entry{endhostent}{380}{\code {endhostent}}
--\entry{getservbyname}{382}{\code {getservbyname}}
--\entry{getservbyport}{382}{\code {getservbyport}}
--\entry{setservent}{382}{\code {setservent}}
--\entry{getservent}{382}{\code {getservent}}
--\entry{endservent}{382}{\code {endservent}}
--\entry{htons}{383}{\code {htons}}
--\entry{ntohs}{383}{\code {ntohs}}
--\entry{htonl}{383}{\code {htonl}}
--\entry{ntohl}{383}{\code {ntohl}}
--\entry{getprotobyname}{384}{\code {getprotobyname}}
--\entry{getprotobynumber}{384}{\code {getprotobynumber}}
--\entry{setprotoent}{384}{\code {setprotoent}}
--\entry{getprotoent}{384}{\code {getprotoent}}
--\entry{endprotoent}{385}{\code {endprotoent}}
--\entry{socket}{386}{\code {socket}}
--\entry{shutdown}{387}{\code {shutdown}}
--\entry{socketpair}{388}{\code {socketpair}}
--\entry{connect}{389}{\code {connect}}
--\entry{listen}{390}{\code {listen}}
--\entry{accept}{391}{\code {accept}}
--\entry{getpeername}{391}{\code {getpeername}}
--\entry{send}{392}{\code {send}}
--\entry{recv}{393}{\code {recv}}
--\entry{sendto}{401}{\code {sendto}}
--\entry{recvfrom}{401}{\code {recvfrom}}
--\entry{getsockopt}{406}{\code {getsockopt}}
--\entry{setsockopt}{407}{\code {setsockopt}}
--\entry{getnetbyname}{409}{\code {getnetbyname}}
--\entry{getnetbyaddr}{409}{\code {getnetbyaddr}}
--\entry{setnetent}{409}{\code {setnetent}}
--\entry{getnetent}{409}{\code {getnetent}}
--\entry{endnetent}{409}{\code {endnetent}}
--\entry{isatty}{411}{\code {isatty}}
--\entry{ttyname}{411}{\code {ttyname}}
--\entry{ttyname{\_}r}{411}{\code {ttyname_r}}
--\entry{tcgetattr}{414}{\code {tcgetattr}}
--\entry{tcsetattr}{414}{\code {tcsetattr}}
--\entry{cfgetospeed}{424}{\code {cfgetospeed}}
--\entry{cfgetispeed}{424}{\code {cfgetispeed}}
--\entry{cfsetospeed}{424}{\code {cfsetospeed}}
--\entry{cfsetispeed}{424}{\code {cfsetispeed}}
--\entry{cfsetspeed}{424}{\code {cfsetspeed}}
--\entry{cfmakeraw}{430}{\code {cfmakeraw}}
--\entry{tcsendbreak}{431}{\code {tcsendbreak}}
--\entry{tcdrain}{431}{\code {tcdrain}}
--\entry{tcflush}{431}{\code {tcflush}}
--\entry{tcflow}{432}{\code {tcflow}}
--\entry{getpt}{434}{\code {getpt}}
--\entry{grantpt}{434}{\code {grantpt}}
--\entry{unlockpt}{435}{\code {unlockpt}}
--\entry{ptsname}{435}{\code {ptsname}}
--\entry{ptsname{\_}r}{435}{\code {ptsname_r}}
--\entry{openpty}{436}{\code {openpty}}
--\entry{forkpty}{437}{\code {forkpty}}
--\entry{sin}{440}{\code {sin}}
--\entry{sinf}{440}{\code {sinf}}
--\entry{sinl}{440}{\code {sinl}}
--\entry{cos}{440}{\code {cos}}
--\entry{cosf}{440}{\code {cosf}}
--\entry{cosl}{440}{\code {cosl}}
--\entry{tan}{440}{\code {tan}}
--\entry{tanf}{440}{\code {tanf}}
--\entry{tanl}{440}{\code {tanl}}
--\entry{sincos}{441}{\code {sincos}}
--\entry{sincosf}{441}{\code {sincosf}}
--\entry{sincosl}{441}{\code {sincosl}}
--\entry{csin}{441}{\code {csin}}
--\entry{csinf}{441}{\code {csinf}}
--\entry{csinl}{441}{\code {csinl}}
--\entry{ccos}{441}{\code {ccos}}
--\entry{ccosf}{441}{\code {ccosf}}
--\entry{ccosl}{441}{\code {ccosl}}
--\entry{ctan}{441}{\code {ctan}}
--\entry{ctanf}{441}{\code {ctanf}}
--\entry{ctanl}{441}{\code {ctanl}}
--\entry{asin}{442}{\code {asin}}
--\entry{asinf}{442}{\code {asinf}}
--\entry{asinl}{442}{\code {asinl}}
--\entry{acos}{442}{\code {acos}}
--\entry{acosf}{442}{\code {acosf}}
--\entry{acosl}{442}{\code {acosl}}
--\entry{atan}{442}{\code {atan}}
--\entry{atanf}{442}{\code {atanf}}
--\entry{atanl}{442}{\code {atanl}}
--\entry{atan2}{442}{\code {atan2}}
--\entry{atan2f}{442}{\code {atan2f}}
--\entry{atan2l}{442}{\code {atan2l}}
--\entry{casin}{443}{\code {casin}}
--\entry{casinf}{443}{\code {casinf}}
--\entry{casinl}{443}{\code {casinl}}
--\entry{cacos}{443}{\code {cacos}}
--\entry{cacosf}{443}{\code {cacosf}}
--\entry{cacosl}{443}{\code {cacosl}}
--\entry{catan}{443}{\code {catan}}
--\entry{catanf}{443}{\code {catanf}}
--\entry{catanl}{443}{\code {catanl}}
--\entry{exp}{443}{\code {exp}}
--\entry{expf}{443}{\code {expf}}
--\entry{expl}{443}{\code {expl}}
--\entry{exp2}{443}{\code {exp2}}
--\entry{exp2f}{443}{\code {exp2f}}
--\entry{exp2l}{443}{\code {exp2l}}
--\entry{exp10}{443}{\code {exp10}}
--\entry{exp10f}{443}{\code {exp10f}}
--\entry{exp10l}{443}{\code {exp10l}}
--\entry{pow10}{443}{\code {pow10}}
--\entry{pow10f}{443}{\code {pow10f}}
--\entry{pow10l}{443}{\code {pow10l}}
--\entry{log}{444}{\code {log}}
--\entry{logf}{444}{\code {logf}}
--\entry{logl}{444}{\code {logl}}
--\entry{log10}{444}{\code {log10}}
--\entry{log10f}{444}{\code {log10f}}
--\entry{log10l}{444}{\code {log10l}}
--\entry{log2}{444}{\code {log2}}
--\entry{log2f}{444}{\code {log2f}}
--\entry{log2l}{444}{\code {log2l}}
--\entry{logb}{444}{\code {logb}}
--\entry{logbf}{444}{\code {logbf}}
--\entry{logbl}{444}{\code {logbl}}
--\entry{ilogb}{444}{\code {ilogb}}
--\entry{ilogbf}{444}{\code {ilogbf}}
--\entry{ilogbl}{444}{\code {ilogbl}}
--\entry{pow}{445}{\code {pow}}
--\entry{powf}{445}{\code {powf}}
--\entry{powl}{445}{\code {powl}}
--\entry{sqrt}{445}{\code {sqrt}}
--\entry{sqrtf}{445}{\code {sqrtf}}
--\entry{sqrtl}{445}{\code {sqrtl}}
--\entry{cbrt}{445}{\code {cbrt}}
--\entry{cbrtf}{445}{\code {cbrtf}}
--\entry{cbrtl}{445}{\code {cbrtl}}
--\entry{hypot}{445}{\code {hypot}}
--\entry{hypotf}{445}{\code {hypotf}}
--\entry{hypotl}{445}{\code {hypotl}}
--\entry{expm1}{446}{\code {expm1}}
--\entry{expm1f}{446}{\code {expm1f}}
--\entry{expm1l}{446}{\code {expm1l}}
--\entry{log1p}{446}{\code {log1p}}
--\entry{log1pf}{446}{\code {log1pf}}
--\entry{log1pl}{446}{\code {log1pl}}
--\entry{cexp}{446}{\code {cexp}}
--\entry{cexpf}{446}{\code {cexpf}}
--\entry{cexpl}{446}{\code {cexpl}}
--\entry{clog}{446}{\code {clog}}
--\entry{clogf}{446}{\code {clogf}}
--\entry{clogl}{446}{\code {clogl}}
--\entry{clog10}{446}{\code {clog10}}
--\entry{clog10f}{446}{\code {clog10f}}
--\entry{clog10l}{446}{\code {clog10l}}
--\entry{csqrt}{447}{\code {csqrt}}
--\entry{csqrtf}{447}{\code {csqrtf}}
--\entry{csqrtl}{447}{\code {csqrtl}}
--\entry{cpow}{447}{\code {cpow}}
--\entry{cpowf}{447}{\code {cpowf}}
--\entry{cpowl}{447}{\code {cpowl}}
--\entry{sinh}{447}{\code {sinh}}
--\entry{sinhf}{447}{\code {sinhf}}
--\entry{sinhl}{447}{\code {sinhl}}
--\entry{cosh}{447}{\code {cosh}}
--\entry{coshf}{447}{\code {coshf}}
--\entry{coshl}{447}{\code {coshl}}
--\entry{tanh}{447}{\code {tanh}}
--\entry{tanhf}{447}{\code {tanhf}}
--\entry{tanhl}{447}{\code {tanhl}}
--\entry{csinh}{447}{\code {csinh}}
--\entry{csinhf}{447}{\code {csinhf}}
--\entry{csinhl}{447}{\code {csinhl}}
--\entry{ccosh}{448}{\code {ccosh}}
--\entry{ccoshf}{448}{\code {ccoshf}}
--\entry{ccoshl}{448}{\code {ccoshl}}
--\entry{ctanh}{448}{\code {ctanh}}
--\entry{ctanhf}{448}{\code {ctanhf}}
--\entry{ctanhl}{448}{\code {ctanhl}}
--\entry{asinh}{448}{\code {asinh}}
--\entry{asinhf}{448}{\code {asinhf}}
--\entry{asinhl}{448}{\code {asinhl}}
--\entry{acosh}{448}{\code {acosh}}
--\entry{acoshf}{448}{\code {acoshf}}
--\entry{acoshl}{448}{\code {acoshl}}
--\entry{atanh}{448}{\code {atanh}}
--\entry{atanhf}{448}{\code {atanhf}}
--\entry{atanhl}{448}{\code {atanhl}}
--\entry{casinh}{448}{\code {casinh}}
--\entry{casinhf}{448}{\code {casinhf}}
--\entry{casinhl}{448}{\code {casinhl}}
--\entry{cacosh}{448}{\code {cacosh}}
--\entry{cacoshf}{448}{\code {cacoshf}}
--\entry{cacoshl}{448}{\code {cacoshl}}
--\entry{catanh}{449}{\code {catanh}}
--\entry{catanhf}{449}{\code {catanhf}}
--\entry{catanhl}{449}{\code {catanhl}}
--\entry{erf}{449}{\code {erf}}
--\entry{erff}{449}{\code {erff}}
--\entry{erfl}{449}{\code {erfl}}
--\entry{erfc}{449}{\code {erfc}}
--\entry{erfcf}{449}{\code {erfcf}}
--\entry{erfcl}{449}{\code {erfcl}}
--\entry{lgamma}{449}{\code {lgamma}}
--\entry{lgammaf}{449}{\code {lgammaf}}
--\entry{lgammal}{449}{\code {lgammal}}
--\entry{lgamma{\_}r}{450}{\code {lgamma_r}}
--\entry{lgammaf{\_}r}{450}{\code {lgammaf_r}}
--\entry{lgammal{\_}r}{450}{\code {lgammal_r}}
--\entry{gamma}{450}{\code {gamma}}
--\entry{gammaf}{450}{\code {gammaf}}
--\entry{gammal}{450}{\code {gammal}}
--\entry{tgamma}{450}{\code {tgamma}}
--\entry{tgammaf}{450}{\code {tgammaf}}
--\entry{tgammal}{450}{\code {tgammal}}
--\entry{j0}{450}{\code {j0}}
--\entry{j0f}{450}{\code {j0f}}
--\entry{j0l}{450}{\code {j0l}}
--\entry{j1}{450}{\code {j1}}
--\entry{j1f}{450}{\code {j1f}}
--\entry{j1l}{450}{\code {j1l}}
--\entry{jn}{450}{\code {jn}}
--\entry{jnf}{450}{\code {jnf}}
--\entry{jnl}{450}{\code {jnl}}
--\entry{y0}{450}{\code {y0}}
--\entry{y0f}{450}{\code {y0f}}
--\entry{y0l}{450}{\code {y0l}}
--\entry{y1}{451}{\code {y1}}
--\entry{y1f}{451}{\code {y1f}}
--\entry{y1l}{451}{\code {y1l}}
--\entry{yn}{451}{\code {yn}}
--\entry{ynf}{451}{\code {ynf}}
--\entry{ynl}{451}{\code {ynl}}
--\entry{rand}{452}{\code {rand}}
--\entry{srand}{452}{\code {srand}}
--\entry{rand{\_}r}{452}{\code {rand_r}}
--\entry{random}{452}{\code {random}}
--\entry{srandom}{452}{\code {srandom}}
--\entry{initstate}{453}{\code {initstate}}
--\entry{setstate}{453}{\code {setstate}}
--\entry{drand48}{453}{\code {drand48}}
--\entry{erand48}{454}{\code {erand48}}
--\entry{lrand48}{454}{\code {lrand48}}
--\entry{nrand48}{454}{\code {nrand48}}
--\entry{mrand48}{454}{\code {mrand48}}
--\entry{jrand48}{454}{\code {jrand48}}
--\entry{srand48}{454}{\code {srand48}}
--\entry{seed48}{455}{\code {seed48}}
--\entry{lcong48}{455}{\code {lcong48}}
--\entry{drand48{\_}r}{455}{\code {drand48_r}}
--\entry{erand48{\_}r}{456}{\code {erand48_r}}
--\entry{lrand48{\_}r}{456}{\code {lrand48_r}}
--\entry{nrand48{\_}r}{456}{\code {nrand48_r}}
--\entry{mrand48{\_}r}{456}{\code {mrand48_r}}
--\entry{jrand48{\_}r}{456}{\code {jrand48_r}}
--\entry{srand48{\_}r}{457}{\code {srand48_r}}
--\entry{seed48{\_}r}{457}{\code {seed48_r}}
--\entry{lcong48{\_}r}{457}{\code {lcong48_r}}
--\entry{fpclassify}{459}{\code {fpclassify}}
--\entry{isfinite}{460}{\code {isfinite}}
--\entry{isnormal}{460}{\code {isnormal}}
--\entry{isnan}{460}{\code {isnan}}
--\entry{isinf}{460}{\code {isinf}}
--\entry{isinff}{460}{\code {isinff}}
--\entry{isinfl}{460}{\code {isinfl}}
--\entry{isnan}{460}{\code {isnan}}
--\entry{isnanf}{460}{\code {isnanf}}
--\entry{isnanl}{460}{\code {isnanl}}
--\entry{finite}{461}{\code {finite}}
--\entry{finitef}{461}{\code {finitef}}
--\entry{finitel}{461}{\code {finitel}}
--\entry{infnan}{461}{\code {infnan}}
--\entry{matherr}{461}{\code {matherr}}
--\entry{feclearexcept}{464}{\code {feclearexcept}}
--\entry{fetestexcept}{464}{\code {fetestexcept}}
--\entry{fegetexceptflag}{465}{\code {fegetexceptflag}}
--\entry{fesetexceptflag}{465}{\code {fesetexceptflag}}
--\entry{fegetround}{467}{\code {fegetround}}
--\entry{fesetround}{467}{\code {fesetround}}
--\entry{fegetenv}{468}{\code {fegetenv}}
--\entry{feholdexcept}{468}{\code {feholdexcept}}
--\entry{fesetenv}{468}{\code {fesetenv}}
--\entry{feupdateenv}{468}{\code {feupdateenv}}
--\entry{abs}{469}{\code {abs}}
--\entry{labs}{469}{\code {labs}}
--\entry{llabs}{469}{\code {llabs}}
--\entry{imaxabs}{469}{\code {imaxabs}}
--\entry{fabs}{469}{\code {fabs}}
--\entry{fabsf}{469}{\code {fabsf}}
--\entry{fabsl}{469}{\code {fabsl}}
--\entry{cabs}{469}{\code {cabs}}
--\entry{cabsf}{469}{\code {cabsf}}
--\entry{cabsl}{469}{\code {cabsl}}
--\entry{frexp}{469}{\code {frexp}}
--\entry{frexpf}{469}{\code {frexpf}}
--\entry{frexpl}{469}{\code {frexpl}}
--\entry{ldexp}{470}{\code {ldexp}}
--\entry{ldexpf}{470}{\code {ldexpf}}
--\entry{ldexpl}{470}{\code {ldexpl}}
--\entry{logb}{470}{\code {logb}}
--\entry{logbf}{470}{\code {logbf}}
--\entry{logbl}{470}{\code {logbl}}
--\entry{scalb}{470}{\code {scalb}}
--\entry{scalbf}{470}{\code {scalbf}}
--\entry{scalbl}{470}{\code {scalbl}}
--\entry{scalbn}{470}{\code {scalbn}}
--\entry{scalbnf}{470}{\code {scalbnf}}
--\entry{scalbnl}{470}{\code {scalbnl}}
--\entry{scalbln}{470}{\code {scalbln}}
--\entry{scalblnf}{470}{\code {scalblnf}}
--\entry{scalblnl}{470}{\code {scalblnl}}
--\entry{significand}{470}{\code {significand}}
--\entry{significandf}{470}{\code {significandf}}
--\entry{significandl}{470}{\code {significandl}}
--\entry{ceil}{471}{\code {ceil}}
--\entry{ceilf}{471}{\code {ceilf}}
--\entry{ceill}{471}{\code {ceill}}
--\entry{floor}{471}{\code {floor}}
--\entry{floorf}{471}{\code {floorf}}
--\entry{floorl}{471}{\code {floorl}}
--\entry{trunc}{471}{\code {trunc}}
--\entry{truncf}{471}{\code {truncf}}
--\entry{truncl}{471}{\code {truncl}}
--\entry{rint}{471}{\code {rint}}
--\entry{rintf}{471}{\code {rintf}}
--\entry{rintl}{471}{\code {rintl}}
--\entry{nearbyint}{471}{\code {nearbyint}}
--\entry{nearbyintf}{471}{\code {nearbyintf}}
--\entry{nearbyintl}{471}{\code {nearbyintl}}
--\entry{round}{472}{\code {round}}
--\entry{roundf}{472}{\code {roundf}}
--\entry{roundl}{472}{\code {roundl}}
--\entry{lrint}{472}{\code {lrint}}
--\entry{lrintf}{472}{\code {lrintf}}
--\entry{lrintl}{472}{\code {lrintl}}
--\entry{llrint}{472}{\code {llrint}}
--\entry{llrintf}{472}{\code {llrintf}}
--\entry{llrintl}{472}{\code {llrintl}}
--\entry{lround}{472}{\code {lround}}
--\entry{lroundf}{472}{\code {lroundf}}
--\entry{lroundl}{472}{\code {lroundl}}
--\entry{llround}{472}{\code {llround}}
--\entry{llroundf}{472}{\code {llroundf}}
--\entry{llroundl}{472}{\code {llroundl}}
--\entry{modf}{472}{\code {modf}}
--\entry{modff}{472}{\code {modff}}
--\entry{modfl}{472}{\code {modfl}}
--\entry{fmod}{472}{\code {fmod}}
--\entry{fmodf}{473}{\code {fmodf}}
--\entry{fmodl}{473}{\code {fmodl}}
--\entry{drem}{473}{\code {drem}}
--\entry{dremf}{473}{\code {dremf}}
--\entry{dreml}{473}{\code {dreml}}
--\entry{remainder}{473}{\code {remainder}}
--\entry{remainderf}{473}{\code {remainderf}}
--\entry{remainderl}{473}{\code {remainderl}}
--\entry{copysign}{473}{\code {copysign}}
--\entry{copysignf}{473}{\code {copysignf}}
--\entry{copysignl}{473}{\code {copysignl}}
--\entry{signbit}{474}{\code {signbit}}
--\entry{nextafter}{474}{\code {nextafter}}
--\entry{nextafterf}{474}{\code {nextafterf}}
--\entry{nextafterl}{474}{\code {nextafterl}}
--\entry{nexttoward}{474}{\code {nexttoward}}
--\entry{nexttowardf}{474}{\code {nexttowardf}}
--\entry{nexttowardl}{474}{\code {nexttowardl}}
--\entry{nan}{474}{\code {nan}}
--\entry{nanf}{474}{\code {nanf}}
--\entry{nanl}{474}{\code {nanl}}
--\entry{isgreater}{475}{\code {isgreater}}
--\entry{isgreaterequal}{475}{\code {isgreaterequal}}
--\entry{isless}{475}{\code {isless}}
--\entry{islessequal}{475}{\code {islessequal}}
--\entry{islessgreater}{475}{\code {islessgreater}}
--\entry{isunordered}{475}{\code {isunordered}}
--\entry{fmin}{475}{\code {fmin}}
--\entry{fminf}{475}{\code {fminf}}
--\entry{fminl}{475}{\code {fminl}}
--\entry{fmax}{476}{\code {fmax}}
--\entry{fmaxf}{476}{\code {fmaxf}}
--\entry{fmaxl}{476}{\code {fmaxl}}
--\entry{fdim}{476}{\code {fdim}}
--\entry{fdimf}{476}{\code {fdimf}}
--\entry{fdiml}{476}{\code {fdiml}}
--\entry{fma}{476}{\code {fma}}
--\entry{fmaf}{476}{\code {fmaf}}
--\entry{fmal}{476}{\code {fmal}}
--\entry{creal}{477}{\code {creal}}
--\entry{crealf}{477}{\code {crealf}}
--\entry{creall}{477}{\code {creall}}
--\entry{cimag}{477}{\code {cimag}}
--\entry{cimagf}{477}{\code {cimagf}}
--\entry{cimagl}{477}{\code {cimagl}}
--\entry{conj}{477}{\code {conj}}
--\entry{conjf}{477}{\code {conjf}}
--\entry{conjl}{477}{\code {conjl}}
--\entry{carg}{477}{\code {carg}}
--\entry{cargf}{477}{\code {cargf}}
--\entry{cargl}{477}{\code {cargl}}
--\entry{cproj}{478}{\code {cproj}}
--\entry{cprojf}{478}{\code {cprojf}}
--\entry{cprojl}{478}{\code {cprojl}}
--\entry{div}{478}{\code {div}}
--\entry{ldiv}{479}{\code {ldiv}}
--\entry{lldiv}{479}{\code {lldiv}}
--\entry{imaxdiv}{479}{\code {imaxdiv}}
--\entry{strtol}{480}{\code {strtol}}
--\entry{strtoul}{480}{\code {strtoul}}
--\entry{strtoll}{481}{\code {strtoll}}
--\entry{strtoq}{481}{\code {strtoq}}
--\entry{strtoull}{481}{\code {strtoull}}
--\entry{strtouq}{481}{\code {strtouq}}
--\entry{atol}{481}{\code {atol}}
--\entry{atoi}{481}{\code {atoi}}
--\entry{atoll}{481}{\code {atoll}}
--\entry{strtol{\_}l}{481}{\code {strtol_l}}
--\entry{strtoul{\_}l}{481}{\code {strtoul_l}}
--\entry{strtoll{\_}l}{481}{\code {strtoll_l}}
--\entry{strtoull{\_}l}{481}{\code {strtoull_l}}
--\entry{strtod}{482}{\code {strtod}}
--\entry{strtof}{483}{\code {strtof}}
--\entry{strtold}{483}{\code {strtold}}
--\entry{atof}{483}{\code {atof}}
--\entry{ecvt}{484}{\code {ecvt}}
--\entry{fcvt}{484}{\code {fcvt}}
--\entry{gcvt}{484}{\code {gcvt}}
--\entry{qecvt}{484}{\code {qecvt}}
--\entry{qfcvt}{484}{\code {qfcvt}}
--\entry{qgcvt}{485}{\code {qgcvt}}
--\entry{ecvt{\_}r}{485}{\code {ecvt_r}}
--\entry{fcvt{\_}r}{485}{\code {fcvt_r}}
--\entry{qecvt{\_}r}{485}{\code {qecvt_r}}
--\entry{qfcvt{\_}r}{485}{\code {qfcvt_r}}
--\entry{clock}{488}{\code {clock}}
--\entry{times}{489}{\code {times}}
--\entry{difftime}{490}{\code {difftime}}
--\entry{time}{490}{\code {time}}
--\entry{gettimeofday}{491}{\code {gettimeofday}}
--\entry{settimeofday}{491}{\code {settimeofday}}
--\entry{adjtime}{492}{\code {adjtime}}
--\entry{localtime}{493}{\code {localtime}}
--\entry{localtime{\_}r}{494}{\code {localtime_r}}
--\entry{gmtime}{494}{\code {gmtime}}
--\entry{gmtime{\_}r}{494}{\code {gmtime_r}}
--\entry{mktime}{494}{\code {mktime}}
--\entry{asctime}{495}{\code {asctime}}
--\entry{asctime{\_}r}{495}{\code {asctime_r}}
--\entry{ctime}{495}{\code {ctime}}
--\entry{ctime{\_}r}{495}{\code {ctime_r}}
--\entry{strftime}{495}{\code {strftime}}
--\entry{strptime}{500}{\code {strptime}}
--\entry{getdate}{505}{\code {getdate}}
--\entry{getdate{\_}r}{507}{\code {getdate_r}}
--\entry{tzset}{509}{\code {tzset}}
--\entry{ntp{\_}gettime}{511}{\code {ntp_gettime}}
--\entry{ntp{\_}adjtime}{513}{\code {ntp_adjtime}}
--\entry{setitimer}{514}{\code {setitimer}}
--\entry{getitimer}{514}{\code {getitimer}}
--\entry{ITIMER{\_}REAL}{514}{\code {ITIMER_REAL}}
--\entry{ITIMER{\_}VIRTUAL}{514}{\code {ITIMER_VIRTUAL}}
--\entry{ITIMER{\_}PROF}{515}{\code {ITIMER_PROF}}
--\entry{alarm}{515}{\code {alarm}}
--\entry{sleep}{515}{\code {sleep}}
--\entry{nanosleep}{516}{\code {nanosleep}}
--\entry{getrusage}{517}{\code {getrusage}}
--\entry{getrlimit}{519}{\code {getrlimit}}
--\entry{getrlimit64}{519}{\code {getrlimit64}}
--\entry{setrlimit}{519}{\code {setrlimit}}
--\entry{setrlimit64}{519}{\code {setrlimit64}}
--\entry{getpriority}{521}{\code {getpriority}}
--\entry{setpriority}{522}{\code {setpriority}}
--\entry{nice}{522}{\code {nice}}
--\entry{setjmp}{524}{\code {setjmp}}
--\entry{longjmp}{525}{\code {longjmp}}
--\entry{sigsetjmp}{526}{\code {sigsetjmp}}
--\entry{siglongjmp}{526}{\code {siglongjmp}}
--\entry{strsignal}{537}{\code {strsignal}}
--\entry{psignal}{538}{\code {psignal}}
--\entry{signal}{538}{\code {signal}}
--\entry{sysv{\_}signal}{540}{\code {sysv_signal}}
--\entry{ssignal}{540}{\code {ssignal}}
--\entry{sigaction}{541}{\code {sigaction}}
--\entry{TEMP{\_}FAILURE{\_}RETRY}{555}{\code {TEMP_FAILURE_RETRY}}
--\entry{raise}{556}{\code {raise}}
--\entry{gsignal}{556}{\code {gsignal}}
--\entry{kill}{557}{\code {kill}}
--\entry{killpg}{558}{\code {killpg}}
--\entry{sigemptyset}{562}{\code {sigemptyset}}
--\entry{sigfillset}{562}{\code {sigfillset}}
--\entry{sigaddset}{562}{\code {sigaddset}}
--\entry{sigdelset}{562}{\code {sigdelset}}
--\entry{sigismember}{562}{\code {sigismember}}
--\entry{sigprocmask}{562}{\code {sigprocmask}}
--\entry{sigpending}{565}{\code {sigpending}}
--\entry{pause}{567}{\code {pause}}
--\entry{sigsuspend}{569}{\code {sigsuspend}}
--\entry{sigaltstack}{571}{\code {sigaltstack}}
--\entry{sigstack}{571}{\code {sigstack}}
--\entry{sigvec}{573}{\code {sigvec}}
--\entry{siginterrupt}{573}{\code {siginterrupt}}
--\entry{sigmask}{573}{\code {sigmask}}
--\entry{sigblock}{573}{\code {sigblock}}
--\entry{sigsetmask}{573}{\code {sigsetmask}}
--\entry{sigpause}{573}{\code {sigpause}}
--\entry{main}{575}{\code {main}}
--\entry{getopt}{577}{\code {getopt}}
--\entry{getopt{\_}long}{581}{\code {getopt_long}}
--\entry{argp{\_}parse}{584}{\code {argp_parse}}
--\entry{argp{\_}usage}{591}{\code {argp_usage}}
--\entry{argp{\_}error}{591}{\code {argp_error}}
--\entry{argp{\_}failure}{591}{\code {argp_failure}}
--\entry{argp{\_}state{\_}help}{592}{\code {argp_state_help}}
--\entry{argp{\_}help}{596}{\code {argp_help}}
--\entry{getsubopt}{607}{\code {getsubopt}}
--\entry{getenv}{610}{\code {getenv}}
--\entry{putenv}{610}{\code {putenv}}
--\entry{setenv}{610}{\code {setenv}}
--\entry{unsetenv}{611}{\code {unsetenv}}
--\entry{clearenv}{611}{\code {clearenv}}
--\entry{exit}{614}{\code {exit}}
--\entry{atexit}{615}{\code {atexit}}
--\entry{on{\_}exit}{615}{\code {on_exit}}
--\entry{abort}{616}{\code {abort}}
--\entry{{\_}exit}{616}{\code {_exit}}
--\entry{{\_}Exit}{616}{\code {_Exit}}
--\entry{system}{619}{\code {system}}
--\entry{getpid}{620}{\code {getpid}}
--\entry{getppid}{620}{\code {getppid}}
--\entry{fork}{621}{\code {fork}}
--\entry{vfork}{621}{\code {vfork}}
--\entry{execv}{622}{\code {execv}}
--\entry{execl}{622}{\code {execl}}
--\entry{execve}{622}{\code {execve}}
--\entry{execle}{622}{\code {execle}}
--\entry{execvp}{623}{\code {execvp}}
--\entry{execlp}{623}{\code {execlp}}
--\entry{waitpid}{624}{\code {waitpid}}
--\entry{wait}{626}{\code {wait}}
--\entry{wait4}{626}{\code {wait4}}
--\entry{WIFEXITED}{627}{\code {WIFEXITED}}
--\entry{WEXITSTATUS}{627}{\code {WEXITSTATUS}}
--\entry{WIFSIGNALED}{627}{\code {WIFSIGNALED}}
--\entry{WTERMSIG}{627}{\code {WTERMSIG}}
--\entry{WCOREDUMP}{627}{\code {WCOREDUMP}}
--\entry{WIFSTOPPED}{627}{\code {WIFSTOPPED}}
--\entry{WSTOPSIG}{627}{\code {WSTOPSIG}}
--\entry{wait3}{628}{\code {wait3}}
--\entry{ctermid}{646}{\code {ctermid}}
--\entry{setsid}{647}{\code {setsid}}
--\entry{getsid}{647}{\code {getsid}}
--\entry{getpgrp}{647}{\code {getpgrp}}
--\entry{getpgrp}{647}{\code {getpgrp}}
--\entry{getpgid}{647}{\code {getpgid}}
--\entry{setpgid}{648}{\code {setpgid}}
--\entry{setpgrp}{648}{\code {setpgrp}}
--\entry{tcgetpgrp}{648}{\code {tcgetpgrp}}
--\entry{tcsetpgrp}{649}{\code {tcsetpgrp}}
--\entry{tcgetsid}{649}{\code {tcgetsid}}
--\entry{success}{653}{\code {success}}
--\entry{notfound}{653}{\code {notfound}}
--\entry{unavail}{653}{\code {unavail}}
--\entry{tryagain}{653}{\code {tryagain}}
--\entry{NSS{\_}STATUS{\_}TRYAGAIN}{656}{\code {NSS_STATUS_TRYAGAIN}}
--\entry{NSS{\_}STATUS{\_}UNAVAIL}{656}{\code {NSS_STATUS_UNAVAIL}}
--\entry{NSS{\_}STATUS{\_}NOTFOUND}{656}{\code {NSS_STATUS_NOTFOUND}}
--\entry{NSS{\_}STATUS{\_}SUCCESS}{656}{\code {NSS_STATUS_SUCCESS}}
--\entry{getuid}{663}{\code {getuid}}
--\entry{getgid}{663}{\code {getgid}}
--\entry{geteuid}{663}{\code {geteuid}}
--\entry{getegid}{663}{\code {getegid}}
--\entry{getgroups}{663}{\code {getgroups}}
--\entry{seteuid}{664}{\code {seteuid}}
--\entry{setuid}{664}{\code {setuid}}
--\entry{setreuid}{665}{\code {setreuid}}
--\entry{setegid}{665}{\code {setegid}}
--\entry{setgid}{665}{\code {setgid}}
--\entry{setregid}{665}{\code {setregid}}
--\entry{setgroups}{666}{\code {setgroups}}
--\entry{initgroups}{666}{\code {initgroups}}
--\entry{getlogin}{670}{\code {getlogin}}
--\entry{cuserid}{670}{\code {cuserid}}
--\entry{setutent}{673}{\code {setutent}}
--\entry{getutent}{673}{\code {getutent}}
--\entry{endutent}{673}{\code {endutent}}
--\entry{getutid}{673}{\code {getutid}}
--\entry{getutline}{674}{\code {getutline}}
--\entry{pututline}{674}{\code {pututline}}
--\entry{getutent{\_}r}{674}{\code {getutent_r}}
--\entry{getutid{\_}r}{674}{\code {getutid_r}}
--\entry{getutline{\_}r}{675}{\code {getutline_r}}
--\entry{utmpname}{675}{\code {utmpname}}
--\entry{updwtmp}{675}{\code {updwtmp}}
--\entry{setutxent}{677}{\code {setutxent}}
--\entry{getutxent}{677}{\code {getutxent}}
--\entry{endutxent}{677}{\code {endutxent}}
--\entry{getutxid}{677}{\code {getutxid}}
--\entry{getutxline}{677}{\code {getutxline}}
--\entry{pututxline}{677}{\code {pututxline}}
--\entry{login{\_}tty}{678}{\code {login_tty}}
--\entry{login}{678}{\code {login}}
--\entry{logout}{678}{\code {logout}}
--\entry{logwtmp}{678}{\code {logwtmp}}
--\entry{getpwuid}{679}{\code {getpwuid}}
--\entry{getpwuid{\_}r}{679}{\code {getpwuid_r}}
--\entry{getpwnam}{680}{\code {getpwnam}}
--\entry{getpwnam{\_}r}{680}{\code {getpwnam_r}}
--\entry{fgetpwent}{680}{\code {fgetpwent}}
--\entry{fgetpwent{\_}r}{680}{\code {fgetpwent_r}}
--\entry{setpwent}{681}{\code {setpwent}}
--\entry{getpwent}{681}{\code {getpwent}}
--\entry{getpwent{\_}r}{681}{\code {getpwent_r}}
--\entry{endpwent}{681}{\code {endpwent}}
--\entry{putpwent}{681}{\code {putpwent}}
--\entry{getgrgid}{682}{\code {getgrgid}}
--\entry{getgrgid{\_}r}{682}{\code {getgrgid_r}}
--\entry{getgrnam}{682}{\code {getgrnam}}
--\entry{getgrnam{\_}r}{683}{\code {getgrnam_r}}
--\entry{fgetgrent}{683}{\code {fgetgrent}}
--\entry{fgetgrent{\_}r}{683}{\code {fgetgrent_r}}
--\entry{setgrent}{683}{\code {setgrent}}
--\entry{getgrent}{683}{\code {getgrent}}
--\entry{getgrent{\_}r}{684}{\code {getgrent_r}}
--\entry{endgrent}{684}{\code {endgrent}}
--\entry{setnetgrent}{686}{\code {setnetgrent}}
--\entry{getnetgrent}{686}{\code {getnetgrent}}
--\entry{getnetgrent{\_}r}{686}{\code {getnetgrent_r}}
--\entry{endnetgrent}{687}{\code {endnetgrent}}
--\entry{innetgr}{687}{\code {innetgr}}
--\entry{gethostname}{689}{\code {gethostname}}
--\entry{sethostname}{689}{\code {sethostname}}
--\entry{gethostid}{689}{\code {gethostid}}
--\entry{sethostid}{690}{\code {sethostid}}
--\entry{uname}{691}{\code {uname}}
--\entry{setfsent}{692}{\code {setfsent}}
--\entry{endfsent}{693}{\code {endfsent}}
--\entry{getfsent}{693}{\code {getfsent}}
--\entry{getfsspec}{693}{\code {getfsspec}}
--\entry{getfsfile}{693}{\code {getfsfile}}
--\entry{setmntent}{695}{\code {setmntent}}
--\entry{endmntent}{695}{\code {endmntent}}
--\entry{getmntent}{695}{\code {getmntent}}
--\entry{getmntent{\_}r}{696}{\code {getmntent_r}}
--\entry{addmntent}{696}{\code {addmntent}}
--\entry{hasmntopt}{696}{\code {hasmntopt}}
--\entry{sysconf}{700}{\code {sysconf}}
--\entry{pathconf}{712}{\code {pathconf}}
--\entry{fpathconf}{712}{\code {fpathconf}}
--\entry{confstr}{715}{\code {confstr}}
--\entry{getpass}{718}{\code {getpass}}
--\entry{crypt}{718}{\code {crypt}}
--\entry{crypt{\_}r}{720}{\code {crypt_r}}
--\entry{setkey}{721}{\code {setkey}}
--\entry{encrypt}{721}{\code {encrypt}}
--\entry{setkey{\_}r}{721}{\code {setkey_r}}
--\entry{encrypt{\_}r}{721}{\code {encrypt_r}}
--\entry{ecb{\_}crypt}{721}{\code {ecb_crypt}}
--\entry{DES{\_}ENCRYPT}{721}{\code {DES_ENCRYPT}}
--\entry{DES{\_}DECRYPT}{721}{\code {DES_DECRYPT}}
--\entry{DES{\_}HW}{722}{\code {DES_HW}}
--\entry{DES{\_}SW}{722}{\code {DES_SW}}
--\entry{DESERR{\_}NONE}{722}{\code {DESERR_NONE}}
--\entry{DESERR{\_}NOHWDEVICE}{722}{\code {DESERR_NOHWDEVICE}}
--\entry{DESERR{\_}HWERROR}{722}{\code {DESERR_HWERROR}}
--\entry{DESERR{\_}BADPARAM}{722}{\code {DESERR_BADPARAM}}
--\entry{DES{\_}FAILED}{722}{\code {DES_FAILED}}
--\entry{cbc{\_}crypt}{722}{\code {cbc_crypt}}
--\entry{des{\_}setparity}{722}{\code {des_setparity}}
--\entry{pthread{\_}create}{723}{\code {pthread_create}}
--\entry{pthread{\_}exit}{723}{\code {pthread_exit}}
--\entry{pthread{\_}cancel}{724}{\code {pthread_cancel}}
--\entry{pthread{\_}join}{724}{\code {pthread_join}}
--\entry{pthread{\_}attr{\_}init}{724}{\code {pthread_attr_init}}
--\entry{pthread{\_}attr{\_}destroy}{725}{\code {pthread_attr_destroy}}
--\entry{pthread{\_}attr{\_}setinheritsched}{725}{\code {pthread_attr_setinheritsched}}
--\entry{pthread{\_}attr{\_}setschedparam}{725}{\code {pthread_attr_setschedparam}}
--\entry{pthread{\_}attr{\_}setschedpolicy}{725}{\code {pthread_attr_setschedpolicy}}
--\entry{pthread{\_}attr{\_}setscope}{725}{\code {pthread_attr_setscope}}
--\entry{pthread{\_}attr{\_}setattr}{725}{\code {pthread_attr_set\var {attr}}}
--\entry{pthread{\_}attr{\_}getinheritsched}{725}{\code {pthread_attr_getinheritsched}}
--\entry{pthread{\_}attr{\_}getschedparam}{725}{\code {pthread_attr_getschedparam}}
--\entry{pthread{\_}attr{\_}getschedpolicy}{725}{\code {pthread_attr_getschedpolicy}}
--\entry{pthread{\_}attr{\_}getscope}{725}{\code {pthread_attr_getscope}}
--\entry{pthread{\_}attr{\_}getattr}{725}{\code {pthread_attr_get\var {attr}}}
--\entry{pthread{\_}setcancelstate}{727}{\code {pthread_setcancelstate}}
--\entry{pthread{\_}setcanceltype}{727}{\code {pthread_setcanceltype}}
--\entry{pthread{\_}testcancel}{727}{\code {pthread_testcancel}}
--\entry{pthread{\_}cleanup{\_}push}{728}{\code {pthread_cleanup_push}}
--\entry{pthread{\_}cleanup{\_}pop}{728}{\code {pthread_cleanup_pop}}
--\entry{pthread{\_}cleanup{\_}push{\_}defer{\_}np}{729}{\code {pthread_cleanup_push_defer_np}}
--\entry{pthread{\_}cleanup{\_}pop{\_}restore{\_}np}{729}{\code {pthread_cleanup_pop_restore_np}}
--\entry{pthread{\_}mutex{\_}init}{730}{\code {pthread_mutex_init}}
--\entry{pthread{\_}mutex{\_}lock}{730}{\code {pthread_mutex_lock}}
--\entry{pthread{\_}mutex{\_}trylock}{730}{\code {pthread_mutex_trylock}}
--\entry{pthread{\_}mutex{\_}unlock}{730}{\code {pthread_mutex_unlock}}
--\entry{pthread{\_}mutex{\_}destroy}{731}{\code {pthread_mutex_destroy}}
--\entry{pthread{\_}mutexattr{\_}init}{731}{\code {pthread_mutexattr_init}}
--\entry{pthread{\_}mutexattr{\_}destroy}{731}{\code {pthread_mutexattr_destroy}}
--\entry{pthread{\_}mutexattr{\_}setkind{\_}np}{732}{\code {pthread_mutexattr_setkind_np}}
--\entry{pthread{\_}mutexattr{\_}getkind{\_}np}{732}{\code {pthread_mutexattr_getkind_np}}
--\entry{pthread{\_}cond{\_}init}{732}{\code {pthread_cond_init}}
--\entry{pthread{\_}cond{\_}signal}{733}{\code {pthread_cond_signal}}
--\entry{pthread{\_}cond{\_}broadcast}{733}{\code {pthread_cond_broadcast}}
--\entry{pthread{\_}cond{\_}wait}{733}{\code {pthread_cond_wait}}
--\entry{pthread{\_}cond{\_}timedwait}{733}{\code {pthread_cond_timedwait}}
--\entry{pthread{\_}cond{\_}destroy}{733}{\code {pthread_cond_destroy}}
--\entry{pthread{\_}condattr{\_}init}{735}{\code {pthread_condattr_init}}
--\entry{pthread{\_}condattr{\_}destroy}{735}{\code {pthread_condattr_destroy}}
--\entry{sem{\_}init}{735}{\code {sem_init}}
--\entry{sem{\_}destroy}{735}{\code {sem_destroy}}
--\entry{sem{\_}wait}{736}{\code {sem_wait}}
--\entry{sem{\_}trywait}{736}{\code {sem_trywait}}
--\entry{sem{\_}post}{736}{\code {sem_post}}
--\entry{sem{\_}getvalue}{736}{\code {sem_getvalue}}
--\entry{pthread{\_}key{\_}create}{737}{\code {pthread_key_create}}
--\entry{pthread{\_}key{\_}delete}{737}{\code {pthread_key_delete}}
--\entry{pthread{\_}setspecific}{737}{\code {pthread_setspecific}}
--\entry{pthread{\_}getspecific}{737}{\code {pthread_getspecific}}
--\entry{pthread{\_}sigmask}{738}{\code {pthread_sigmask}}
--\entry{pthread{\_}kill}{739}{\code {pthread_kill}}
--\entry{sigwait}{739}{\code {sigwait}}
--\entry{pthread{\_}self}{739}{\code {pthread_self}}
--\entry{pthread{\_}equal}{739}{\code {pthread_equal}}
--\entry{pthread{\_}detach}{740}{\code {pthread_detach}}
--\entry{pthread{\_}atfork}{740}{\code {pthread_atfork}}
--\entry{pthread{\_}kill{\_}other{\_}threads{\_}np}{740}{\code {pthread_kill_other_threads_np}}
--\entry{pthread{\_}once}{741}{\code {pthread_once}}
--\entry{pthread{\_}setschedparam}{741}{\code {pthread_setschedparam}}
--\entry{pthread{\_}getschedparam}{741}{\code {pthread_getschedparam}}
--\entry{assert}{743}{\code {assert}}
--\entry{assert{\_}perror}{744}{\code {assert_perror}}
--\entry{va{\_}start}{748}{\code {va_start}}
--\entry{va{\_}arg}{748}{\code {va_arg}}
--\entry{va{\_}end}{748}{\code {va_end}}
--\entry{{\_}{\_}va{\_}copy}{748}{\code {__va_copy}}
--\entry{va{\_}alist}{750}{\code {va_alist}}
--\entry{va{\_}dcl}{750}{\code {va_dcl}}
--\entry{va{\_}start}{750}{\code {va_start}}
--\entry{offsetof}{759}{\code {offsetof}}
-diff -Naur ../glibc-2.1.3/manual/libc.fns glibc-2.1.3/manual/libc.fns
---- ../glibc-2.1.3/manual/libc.fns 2000-01-05 19:19:03.000000000 -0800
-+++ glibc-2.1.3/manual/libc.fns 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1157 +0,0 @@
--\initial {{\_}}
--\entry {\code {__va_copy}}{748}
--\entry {\code {_exit}}{616}
--\entry {\code {_Exit}}{616}
--\entry {\code {_tolower}}{63}
--\entry {\code {_toupper}}{63}
--\initial {A}
--\entry {\code {a64l}}{92}
--\entry {\code {abort}}{616}
--\entry {\code {abs}}{469}
--\entry {\code {accept}}{391}
--\entry {\code {access}}{348}
--\entry {\code {acos}}{442}
--\entry {\code {acosf}}{442}
--\entry {\code {acosh}}{448}
--\entry {\code {acoshf}}{448}
--\entry {\code {acoshl}}{448}
--\entry {\code {acosl}}{442}
--\entry {\code {addmntent}}{696}
--\entry {\code {addseverity}}{267}
--\entry {\code {adjtime}}{492}
--\entry {\code {aio_cancel}}{303}
--\entry {\code {aio_cancel64}}{304}
--\entry {\code {aio_error}}{300}
--\entry {\code {aio_error64}}{300}
--\entry {\code {aio_fsync}}{301}
--\entry {\code {aio_fsync64}}{302}
--\entry {\code {aio_init}}{304}
--\entry {\code {aio_read}}{296}
--\entry {\code {aio_read64}}{297}
--\entry {\code {aio_return}}{300}
--\entry {\code {aio_return64}}{301}
--\entry {\code {aio_suspend}}{302}
--\entry {\code {aio_suspend64}}{303}
--\entry {\code {aio_write}}{297}
--\entry {\code {aio_write64}}{298}
--\entry {\code {alarm}}{515}
--\entry {\code {alloca}}{57}
--\entry {\code {alphasort}}{325}
--\entry {\code {alphasort64}}{326}
--\entry {\code {argp_error}}{591}
--\entry {\code {argp_failure}}{591}
--\entry {\code {argp_help}}{596}
--\entry {\code {argp_parse}}{584}
--\entry {\code {argp_state_help}}{592}
--\entry {\code {argp_usage}}{591}
--\entry {\code {argz_add}}{94}
--\entry {\code {argz_add_sep}}{94}
--\entry {\code {argz_append}}{94}
--\entry {\code {argz_count}}{93}
--\entry {\code {argz_create}}{93}
--\entry {\code {argz_create_sep}}{93}
--\entry {\code {argz_delete}}{94}
--\entry {\code {argz_extract}}{94}
--\entry {\code {argz_insert}}{94}
--\entry {\code {argz_next}}{95}
--\entry {\code {argz_replace}}{95}
--\entry {\code {argz_stringify}}{94}
--\entry {\code {asctime}}{495}
--\entry {\code {asctime_r}}{495}
--\entry {\code {asin}}{442}
--\entry {\code {asinf}}{442}
--\entry {\code {asinh}}{448}
--\entry {\code {asinhf}}{448}
--\entry {\code {asinhl}}{448}
--\entry {\code {asinl}}{442}
--\entry {\code {asprintf}}{231}
--\entry {\code {assert}}{743}
--\entry {\code {assert_perror}}{744}
--\entry {\code {atan}}{442}
--\entry {\code {atan2}}{442}
--\entry {\code {atan2f}}{442}
--\entry {\code {atan2l}}{442}
--\entry {\code {atanf}}{442}
--\entry {\code {atanh}}{448}
--\entry {\code {atanhf}}{448}
--\entry {\code {atanhl}}{448}
--\entry {\code {atanl}}{442}
--\entry {\code {atexit}}{615}
--\entry {\code {atof}}{483}
--\entry {\code {atoi}}{481}
--\entry {\code {atol}}{481}
--\entry {\code {atoll}}{481}
--\initial {B}
--\entry {\code {bcmp}}{83}
--\entry {\code {bcopy}}{80}
--\entry {\code {bind}}{367}
--\entry {\code {bindtextdomain}}{172}
--\entry {\code {bsearch}}{178}
--\entry {\code {btowc}}{104}
--\entry {\code {bzero}}{80}
--\initial {C}
--\entry {\code {cabs}}{469}
--\entry {\code {cabsf}}{469}
--\entry {\code {cabsl}}{469}
--\entry {\code {cacos}}{443}
--\entry {\code {cacosf}}{443}
--\entry {\code {cacosh}}{448}
--\entry {\code {cacoshf}}{448}
--\entry {\code {cacoshl}}{448}
--\entry {\code {cacosl}}{443}
--\entry {\code {calloc}}{35}
--\entry {\code {carg}}{477}
--\entry {\code {cargf}}{477}
--\entry {\code {cargl}}{477}
--\entry {\code {casin}}{443}
--\entry {\code {casinf}}{443}
--\entry {\code {casinh}}{448}
--\entry {\code {casinhf}}{448}
--\entry {\code {casinhl}}{448}
--\entry {\code {casinl}}{443}
--\entry {\code {catan}}{443}
--\entry {\code {catanf}}{443}
--\entry {\code {catanh}}{449}
--\entry {\code {catanhf}}{449}
--\entry {\code {catanhl}}{449}
--\entry {\code {catanl}}{443}
--\entry {\code {catclose}}{162}
--\entry {\code {catgets}}{162}
--\entry {\code {catopen}}{159}
--\entry {\code {cbc_crypt}}{722}
--\entry {\code {cbrt}}{445}
--\entry {\code {cbrtf}}{445}
--\entry {\code {cbrtl}}{445}
--\entry {\code {ccos}}{441}
--\entry {\code {ccosf}}{441}
--\entry {\code {ccosh}}{448}
--\entry {\code {ccoshf}}{448}
--\entry {\code {ccoshl}}{448}
--\entry {\code {ccosl}}{441}
--\entry {\code {ceil}}{471}
--\entry {\code {ceilf}}{471}
--\entry {\code {ceill}}{471}
--\entry {\code {cexp}}{446}
--\entry {\code {cexpf}}{446}
--\entry {\code {cexpl}}{446}
--\entry {\code {cfgetispeed}}{424}
--\entry {\code {cfgetospeed}}{424}
--\entry {\code {cfmakeraw}}{430}
--\entry {\code {cfree}}{34}
--\entry {\code {cfsetispeed}}{424}
--\entry {\code {cfsetospeed}}{424}
--\entry {\code {cfsetspeed}}{424}
--\entry {\code {chdir}}{320}
--\entry {\code {chmod}}{346, 347}
--\entry {\code {chown}}{343}
--\entry {\code {cimag}}{477}
--\entry {\code {cimagf}}{477}
--\entry {\code {cimagl}}{477}
--\entry {\code {clearenv}}{611}
--\entry {\code {clearerr}}{250}
--\entry {\code {clock}}{488}
--\entry {\code {clog}}{446}
--\entry {\code {clog10}}{446}
--\entry {\code {clog10f}}{446}
--\entry {\code {clog10l}}{446}
--\entry {\code {clogf}}{446}
--\entry {\code {clogl}}{446}
--\entry {\code {close}}{273}
--\entry {\code {closedir}}{323}
--\entry {\code {confstr}}{715}
--\entry {\code {conj}}{477}
--\entry {\code {conjf}}{477}
--\entry {\code {conjl}}{477}
--\entry {\code {connect}}{389}
--\entry {\code {copysign}}{473}
--\entry {\code {copysignf}}{473}
--\entry {\code {copysignl}}{473}
--\entry {\code {cos}}{440}
--\entry {\code {cosf}}{440}
--\entry {\code {cosh}}{447}
--\entry {\code {coshf}}{447}
--\entry {\code {coshl}}{447}
--\entry {\code {cosl}}{440}
--\entry {\code {cpow}}{447}
--\entry {\code {cpowf}}{447}
--\entry {\code {cpowl}}{447}
--\entry {\code {cproj}}{478}
--\entry {\code {cprojf}}{478}
--\entry {\code {cprojl}}{478}
--\entry {\code {creal}}{477}
--\entry {\code {crealf}}{477}
--\entry {\code {creall}}{477}
--\entry {\code {creat}}{272}
--\entry {\code {creat64}}{273}
--\entry {\code {crypt}}{718}
--\entry {\code {crypt_r}}{720}
--\entry {\code {csin}}{441}
--\entry {\code {csinf}}{441}
--\entry {\code {csinh}}{447}
--\entry {\code {csinhf}}{447}
--\entry {\code {csinhl}}{447}
--\entry {\code {csinl}}{441}
--\entry {\code {csqrt}}{447}
--\entry {\code {csqrtf}}{447}
--\entry {\code {csqrtl}}{447}
--\entry {\code {ctan}}{441}
--\entry {\code {ctanf}}{441}
--\entry {\code {ctanh}}{448}
--\entry {\code {ctanhf}}{448}
--\entry {\code {ctanhl}}{448}
--\entry {\code {ctanl}}{441}
--\entry {\code {ctermid}}{646}
--\entry {\code {ctime}}{495}
--\entry {\code {ctime_r}}{495}
--\entry {\code {cuserid}}{670}
--\initial {D}
--\entry {\code {dcgettext}}{170}
--\entry {\code {DES_DECRYPT}}{721}
--\entry {\code {DES_ENCRYPT}}{721}
--\entry {\code {DES_FAILED}}{722}
--\entry {\code {DES_HW}}{722}
--\entry {\code {des_setparity}}{722}
--\entry {\code {DES_SW}}{722}
--\entry {\code {DESERR_BADPARAM}}{722}
--\entry {\code {DESERR_HWERROR}}{722}
--\entry {\code {DESERR_NOHWDEVICE}}{722}
--\entry {\code {DESERR_NONE}}{722}
--\entry {\code {dgettext}}{170}
--\entry {\code {difftime}}{490}
--\entry {\code {div}}{478}
--\entry {\code {drand48}}{453}
--\entry {\code {drand48_r}}{455}
--\entry {\code {drem}}{473}
--\entry {\code {dremf}}{473}
--\entry {\code {dreml}}{473}
--\entry {\code {DTTOIF}}{322}
--\entry {\code {dup}}{306}
--\entry {\code {dup2}}{306}
--\initial {E}
--\entry {\code {ecb_crypt}}{721}
--\entry {\code {ecvt}}{484}
--\entry {\code {ecvt_r}}{485}
--\entry {\code {encrypt}}{721}
--\entry {\code {encrypt_r}}{721}
--\entry {\code {endfsent}}{693}
--\entry {\code {endgrent}}{684}
--\entry {\code {endhostent}}{380}
--\entry {\code {endmntent}}{695}
--\entry {\code {endnetent}}{409}
--\entry {\code {endnetgrent}}{687}
--\entry {\code {endprotoent}}{385}
--\entry {\code {endpwent}}{681}
--\entry {\code {endservent}}{382}
--\entry {\code {endutent}}{673}
--\entry {\code {endutxent}}{677}
--\entry {\code {envz_add}}{96}
--\entry {\code {envz_entry}}{95}
--\entry {\code {envz_get}}{96}
--\entry {\code {envz_merge}}{96}
--\entry {\code {envz_strip}}{96}
--\entry {\code {erand48}}{454}
--\entry {\code {erand48_r}}{456}
--\entry {\code {erf}}{449}
--\entry {\code {erfc}}{449}
--\entry {\code {erfcf}}{449}
--\entry {\code {erfcl}}{449}
--\entry {\code {erff}}{449}
--\entry {\code {erfl}}{449}
--\entry {\code {execl}}{622}
--\entry {\code {execle}}{622}
--\entry {\code {execlp}}{623}
--\entry {\code {execv}}{622}
--\entry {\code {execve}}{622}
--\entry {\code {execvp}}{623}
--\entry {\code {exit}}{614}
--\entry {\code {exp}}{443}
--\entry {\code {exp10}}{443}
--\entry {\code {exp10f}}{443}
--\entry {\code {exp10l}}{443}
--\entry {\code {exp2}}{443}
--\entry {\code {exp2f}}{443}
--\entry {\code {exp2l}}{443}
--\entry {\code {expf}}{443}
--\entry {\code {expl}}{443}
--\entry {\code {expm1}}{446}
--\entry {\code {expm1f}}{446}
--\entry {\code {expm1l}}{446}
--\initial {F}
--\entry {\code {fabs}}{469}
--\entry {\code {fabsf}}{469}
--\entry {\code {fabsl}}{469}
--\entry {\code {fchmod}}{347}
--\entry {\code {fchown}}{344}
--\entry {\code {fclean}}{284}
--\entry {\code {fclose}}{214}
--\entry {\code {fcloseall}}{215}
--\entry {\code {fcntl}}{305}
--\entry {\code {fcvt}}{484}
--\entry {\code {fcvt_r}}{485}
--\entry {\code {FD_CLR}}{290}
--\entry {\code {FD_ISSET}}{290}
--\entry {\code {FD_SET}}{290}
--\entry {\code {FD_ZERO}}{290}
--\entry {\code {fdatasync}}{293}
--\entry {\code {fdim}}{476}
--\entry {\code {fdimf}}{476}
--\entry {\code {fdiml}}{476}
--\entry {\code {fdopen}}{282}
--\entry {\code {feclearexcept}}{464}
--\entry {\code {fegetenv}}{468}
--\entry {\code {fegetexceptflag}}{465}
--\entry {\code {fegetround}}{467}
--\entry {\code {feholdexcept}}{468}
--\entry {\code {feof}}{251}
--\entry {\code {ferror}}{251}
--\entry {\code {fesetenv}}{468}
--\entry {\code {fesetexceptflag}}{465}
--\entry {\code {fesetround}}{467}
--\entry {\code {fetestexcept}}{464}
--\entry {\code {feupdateenv}}{468}
--\entry {\code {fflush}}{257}
--\entry {\code {fgetc}}{216}
--\entry {\code {fgetgrent}}{683}
--\entry {\code {fgetgrent_r}}{683}
--\entry {\code {fgetpos}}{255}
--\entry {\code {fgetpos64}}{255}
--\entry {\code {fgetpwent}}{680}
--\entry {\code {fgetpwent_r}}{680}
--\entry {\code {fgets}}{218}
--\entry {\code {fileno}}{283}
--\entry {\code {finite}}{461}
--\entry {\code {finitef}}{461}
--\entry {\code {finitel}}{461}
--\entry {\code {floor}}{471}
--\entry {\code {floorf}}{471}
--\entry {\code {floorl}}{471}
--\entry {\code {fma}}{476}
--\entry {\code {fmaf}}{476}
--\entry {\code {fmal}}{476}
--\entry {\code {fmax}}{476}
--\entry {\code {fmaxf}}{476}
--\entry {\code {fmaxl}}{476}
--\entry {\code {fmemopen}}{259}
--\entry {\code {fmin}}{475}
--\entry {\code {fminf}}{475}
--\entry {\code {fminl}}{475}
--\entry {\code {fmod}}{472}
--\entry {\code {fmodf}}{473}
--\entry {\code {fmodl}}{473}
--\entry {\code {fmtmsg}}{265}
--\entry {\code {fnmatch}}{187}
--\entry {\code {fopen}}{212}
--\entry {\code {fopen64}}{213}
--\entry {\code {fopencookie}}{263}
--\entry {\code {fork}}{621}
--\entry {\code {forkpty}}{437}
--\entry {\code {fpathconf}}{712}
--\entry {\code {fpclassify}}{459}
--\entry {\code {fprintf}}{230}
--\entry {\code {fputc}}{215}
--\entry {\code {fputs}}{216}
--\entry {\code {fread}}{221}
--\entry {\code {free}}{34}
--\entry {\code {freopen}}{214}
--\entry {\code {freopen64}}{214}
--\entry {\code {frexp}}{469}
--\entry {\code {frexpf}}{469}
--\entry {\code {frexpl}}{469}
--\entry {\code {fscanf}}{249}
--\entry {\code {fseek}}{253}
--\entry {\code {fseeko}}{253}
--\entry {\code {fseeko64}}{253}
--\entry {\code {fsetpos}}{256}
--\entry {\code {fsetpos64}}{256}
--\entry {\code {fstat}}{341}
--\entry {\code {fstat64}}{341}
--\entry {\code {fsync}}{292}
--\entry {\code {ftell}}{252}
--\entry {\code {ftello}}{252}
--\entry {\code {ftello64}}{252}
--\entry {\code {ftruncate}}{274, 351}
--\entry {\code {ftruncate64}}{275}
--\entry {\code {ftw}}{329}
--\entry {\code {ftw64}}{329}
--\entry {\code {fwrite}}{221}
--\initial {G}
--\entry {\code {gamma}}{450}
--\entry {\code {gammaf}}{450}
--\entry {\code {gammal}}{450}
--\entry {\code {gcvt}}{484}
--\entry {\code {getc}}{217}
--\entry {\code {getchar}}{217}
--\entry {\code {getcwd}}{319}
--\entry {\code {getdate}}{505}
--\entry {\code {getdate_r}}{507}
--\entry {\code {getdelim}}{218}
--\entry {\code {getegid}}{663}
--\entry {\code {getenv}}{610}
--\entry {\code {geteuid}}{663}
--\entry {\code {getfsent}}{693}
--\entry {\code {getfsfile}}{693}
--\entry {\code {getfsspec}}{693}
--\entry {\code {getgid}}{663}
--\entry {\code {getgrent}}{683}
--\entry {\code {getgrent_r}}{684}
--\entry {\code {getgrgid}}{682}
--\entry {\code {getgrgid_r}}{682}
--\entry {\code {getgrnam}}{682}
--\entry {\code {getgrnam_r}}{683}
--\entry {\code {getgroups}}{663}
--\entry {\code {gethostbyaddr}}{378}
--\entry {\code {gethostbyaddr_r}}{380}
--\entry {\code {gethostbyname}}{378}
--\entry {\code {gethostbyname_r}}{379}
--\entry {\code {gethostbyname2}}{378}
--\entry {\code {gethostbyname2_r}}{380}
--\entry {\code {gethostent}}{380}
--\entry {\code {gethostid}}{689}
--\entry {\code {gethostname}}{689}
--\entry {\code {getitimer}}{514}
--\entry {\code {getline}}{218}
--\entry {\code {getlogin}}{670}
--\entry {\code {getmntent}}{695}
--\entry {\code {getmntent_r}}{696}
--\entry {\code {getnetbyaddr}}{409}
--\entry {\code {getnetbyname}}{409}
--\entry {\code {getnetent}}{409}
--\entry {\code {getnetgrent}}{686}
--\entry {\code {getnetgrent_r}}{686}
--\entry {\code {getopt}}{577}
--\entry {\code {getopt_long}}{581}
--\entry {\code {getpass}}{718}
--\entry {\code {getpeername}}{391}
--\entry {\code {getpgid}}{647}
--\entry {\code {getpgrp}}{647}
--\entry {\code {getpid}}{620}
--\entry {\code {getppid}}{620}
--\entry {\code {getpriority}}{521}
--\entry {\code {getprotobyname}}{384}
--\entry {\code {getprotobynumber}}{384}
--\entry {\code {getprotoent}}{384}
--\entry {\code {getpt}}{434}
--\entry {\code {getpwent}}{681}
--\entry {\code {getpwent_r}}{681}
--\entry {\code {getpwnam}}{680}
--\entry {\code {getpwnam_r}}{680}
--\entry {\code {getpwuid}}{679}
--\entry {\code {getpwuid_r}}{679}
--\entry {\code {getrlimit}}{519}
--\entry {\code {getrlimit64}}{519}
--\entry {\code {getrusage}}{517}
--\entry {\code {gets}}{219}
--\entry {\code {getservbyname}}{382}
--\entry {\code {getservbyport}}{382}
--\entry {\code {getservent}}{382}
--\entry {\code {getsid}}{647}
--\entry {\code {getsockname}}{367}
--\entry {\code {getsockopt}}{406}
--\entry {\code {getsubopt}}{607}
--\entry {\code {gettext}}{169}
--\entry {\code {gettimeofday}}{491}
--\entry {\code {getuid}}{663}
--\entry {\code {getumask}}{347}
--\entry {\code {getutent}}{673}
--\entry {\code {getutent_r}}{674}
--\entry {\code {getutid}}{673}
--\entry {\code {getutid_r}}{674}
--\entry {\code {getutline}}{674}
--\entry {\code {getutline_r}}{675}
--\entry {\code {getutxent}}{677}
--\entry {\code {getutxid}}{677}
--\entry {\code {getutxline}}{677}
--\entry {\code {getw}}{217}
--\entry {\code {getwd}}{320}
--\entry {\code {glob}}{189}
--\entry {\code {globfree}}{193}
--\entry {\code {gmtime}}{494}
--\entry {\code {gmtime_r}}{494}
--\entry {\code {grantpt}}{434}
--\entry {\code {gsignal}}{556}
--\initial {H}
--\entry {\code {hasmntopt}}{696}
--\entry {\code {hcreate}}{182}
--\entry {\code {hcreate_r}}{183}
--\entry {\code {hdestroy}}{182}
--\entry {\code {hdestroy_r}}{183}
--\entry {\code {hsearch}}{183}
--\entry {\code {hsearch_r}}{184}
--\entry {\code {htonl}}{383}
--\entry {\code {htons}}{383}
--\entry {\code {hypot}}{445}
--\entry {\code {hypotf}}{445}
--\entry {\code {hypotl}}{445}
--\initial {I}
--\entry {\code {iconv}}{121}
--\entry {\code {iconv_close}}{120}
--\entry {\code {iconv_open}}{119}
--\entry {\code {if_freenameindex}}{369}
--\entry {\code {if_indextoname}}{368}
--\entry {\code {if_nameindex}}{368}
--\entry {\code {if_nametoindex}}{368}
--\entry {\code {IFTODT}}{321}
--\entry {\code {ilogb}}{444}
--\entry {\code {ilogbf}}{444}
--\entry {\code {ilogbl}}{444}
--\entry {\code {imaxabs}}{469}
--\entry {\code {imaxdiv}}{479}
--\entry {\code {index}}{87}
--\entry {\code {inet_addr}}{376}
--\entry {\code {inet_aton}}{376}
--\entry {\code {inet_lnaof}}{376}
--\entry {\code {inet_makeaddr}}{376}
--\entry {\code {inet_netof}}{377}
--\entry {\code {inet_network}}{376}
--\entry {\code {inet_ntoa}}{376}
--\entry {\code {inet_ntop}}{377}
--\entry {\code {inet_pton}}{377}
--\entry {\code {infnan}}{461}
--\entry {\code {initgroups}}{666}
--\entry {\code {initstate}}{453}
--\entry {\code {innetgr}}{687}
--\entry {\code {ioctl}}{318}
--\entry {\code {isalnum}}{62}
--\entry {\code {isalpha}}{61}
--\entry {\code {isascii}}{63}
--\entry {\code {isatty}}{411}
--\entry {\code {isblank}}{62}
--\entry {\code {iscntrl}}{63}
--\entry {\code {isdigit}}{62}
--\entry {\code {isfinite}}{460}
--\entry {\code {isgraph}}{62}
--\entry {\code {isgreater}}{475}
--\entry {\code {isgreaterequal}}{475}
--\entry {\code {isinf}}{460}
--\entry {\code {isinff}}{460}
--\entry {\code {isinfl}}{460}
--\entry {\code {isless}}{475}
--\entry {\code {islessequal}}{475}
--\entry {\code {islessgreater}}{475}
--\entry {\code {islower}}{61}
--\entry {\code {isnan}}{460}
--\entry {\code {isnanf}}{460}
--\entry {\code {isnanl}}{460}
--\entry {\code {isnormal}}{460}
--\entry {\code {isprint}}{62}
--\entry {\code {ispunct}}{62}
--\entry {\code {isspace}}{62}
--\entry {\code {isunordered}}{475}
--\entry {\code {isupper}}{61}
--\entry {\code {iswalnum}}{65}
--\entry {\code {iswalpha}}{65}
--\entry {\code {iswblank}}{67}
--\entry {\code {iswcntrl}}{65}
--\entry {\code {iswctype}}{64}
--\entry {\code {iswdigit}}{65}
--\entry {\code {iswgraph}}{66}
--\entry {\code {iswlower}}{66}
--\entry {\code {iswprint}}{66}
--\entry {\code {iswpunct}}{66}
--\entry {\code {iswspace}}{66}
--\entry {\code {iswupper}}{67}
--\entry {\code {iswxdigit}}{67}
--\entry {\code {isxdigit}}{62}
--\entry {\code {ITIMER_PROF}}{515}
--\entry {\code {ITIMER_REAL}}{514}
--\entry {\code {ITIMER_VIRTUAL}}{514}
--\initial {J}
--\entry {\code {j0}}{450}
--\entry {\code {j0f}}{450}
--\entry {\code {j0l}}{450}
--\entry {\code {j1}}{450}
--\entry {\code {j1f}}{450}
--\entry {\code {j1l}}{450}
--\entry {\code {jn}}{450}
--\entry {\code {jnf}}{450}
--\entry {\code {jnl}}{450}
--\entry {\code {jrand48}}{454}
--\entry {\code {jrand48_r}}{456}
--\initial {K}
--\entry {\code {kill}}{557}
--\entry {\code {killpg}}{558}
--\initial {L}
--\entry {\code {l64a}}{91}
--\entry {\code {labs}}{469}
--\entry {\code {lcong48}}{455}
--\entry {\code {lcong48_r}}{457}
--\entry {\code {ldexp}}{470}
--\entry {\code {ldexpf}}{470}
--\entry {\code {ldexpl}}{470}
--\entry {\code {ldiv}}{479}
--\entry {\code {lfind}}{177}
--\entry {\code {lgamma}}{449}
--\entry {\code {lgamma_r}}{450}
--\entry {\code {lgammaf}}{449}
--\entry {\code {lgammaf_r}}{450}
--\entry {\code {lgammal}}{449}
--\entry {\code {lgammal_r}}{450}
--\entry {\code {link}}{331}
--\entry {\code {lio_listio}}{298}
--\entry {\code {lio_listio64}}{299}
--\entry {\code {listen}}{390}
--\entry {\code {llabs}}{469}
--\entry {\code {lldiv}}{479}
--\entry {\code {llrint}}{472}
--\entry {\code {llrintf}}{472}
--\entry {\code {llrintl}}{472}
--\entry {\code {llround}}{472}
--\entry {\code {llroundf}}{472}
--\entry {\code {llroundl}}{472}
--\entry {\code {localeconv}}{146}
--\entry {\code {localtime}}{493}
--\entry {\code {localtime_r}}{494}
--\entry {\code {log}}{444}
--\entry {\code {log10}}{444}
--\entry {\code {log10f}}{444}
--\entry {\code {log10l}}{444}
--\entry {\code {log1p}}{446}
--\entry {\code {log1pf}}{446}
--\entry {\code {log1pl}}{446}
--\entry {\code {log2}}{444}
--\entry {\code {log2f}}{444}
--\entry {\code {log2l}}{444}
--\entry {\code {logb}}{444, 470}
--\entry {\code {logbf}}{444, 470}
--\entry {\code {logbl}}{444, 470}
--\entry {\code {logf}}{444}
--\entry {\code {login}}{678}
--\entry {\code {login_tty}}{678}
--\entry {\code {logl}}{444}
--\entry {\code {logout}}{678}
--\entry {\code {logwtmp}}{678}
--\entry {\code {longjmp}}{525}
--\entry {\code {lrand48}}{454}
--\entry {\code {lrand48_r}}{456}
--\entry {\code {lrint}}{472}
--\entry {\code {lrintf}}{472}
--\entry {\code {lrintl}}{472}
--\entry {\code {lround}}{472}
--\entry {\code {lroundf}}{472}
--\entry {\code {lroundl}}{472}
--\entry {\code {lsearch}}{178}
--\entry {\code {lseek}}{280}
--\entry {\code {lseek64}}{281}
--\entry {\code {lstat}}{341}
--\entry {\code {lstat64}}{341}
--\initial {M}
--\entry {\code {main}}{575}
--\entry {\code {mallinfo}}{42}
--\entry {\code {malloc}}{32}
--\entry {\code {mallopt}}{37}
--\entry {\code {matherr}}{461}
--\entry {\code {mblen}}{116}
--\entry {\code {mbrlen}}{106}
--\entry {\code {mbrtowc}}{105}
--\entry {\code {mbsinit}}{103}
--\entry {\code {mbsnrtowcs}}{112}
--\entry {\code {mbsrtowcs}}{110}
--\entry {\code {mbstowcs}}{116}
--\entry {\code {mbtowc}}{115}
--\entry {\code {mcheck}}{37}
--\entry {\code {memalign}}{36}
--\entry {\code {memccpy}}{74}
--\entry {\code {memchr}}{86}
--\entry {\code {memcmp}}{81}
--\entry {\code {memcpy}}{74}
--\entry {\code {memmem}}{88}
--\entry {\code {memmove}}{74}
--\entry {\code {mempcpy}}{74}
--\entry {\code {memset}}{74}
--\entry {\code {mkdir}}{335}
--\entry {\code {mkfifo}}{360}
--\entry {\code {mknod}}{352}
--\entry {\code {mkstemp}}{355}
--\entry {\code {mktemp}}{355}
--\entry {\code {mktime}}{494}
--\entry {\code {mmap}}{286}
--\entry {\code {modf}}{472}
--\entry {\code {modff}}{472}
--\entry {\code {modfl}}{472}
--\entry {\code {mprobe}}{38}
--\entry {\code {mrand48}}{454}
--\entry {\code {mrand48_r}}{456}
--\entry {\code {mremap}}{288}
--\entry {\code {msync}}{288}
--\entry {\code {mtrace}}{43}
--\entry {\code {munmap}}{288}
--\entry {\code {muntrace}}{43}
--\initial {N}
--\entry {\code {nan}}{474}
--\entry {\code {nanf}}{474}
--\entry {\code {nanl}}{474}
--\entry {\code {nanosleep}}{516}
--\entry {\code {nearbyint}}{471}
--\entry {\code {nearbyintf}}{471}
--\entry {\code {nearbyintl}}{471}
--\entry {\code {nextafter}}{474}
--\entry {\code {nextafterf}}{474}
--\entry {\code {nextafterl}}{474}
--\entry {\code {nexttoward}}{474}
--\entry {\code {nexttowardf}}{474}
--\entry {\code {nexttowardl}}{474}
--\entry {\code {nftw}}{329}
--\entry {\code {nftw64}}{330}
--\entry {\code {nice}}{522}
--\entry {\code {nl_langinfo}}{150}
--\entry {\code {notfound}}{653}
--\entry {\code {nrand48}}{454}
--\entry {\code {nrand48_r}}{456}
--\entry {\code {NSS_STATUS_NOTFOUND}}{656}
--\entry {\code {NSS_STATUS_SUCCESS}}{656}
--\entry {\code {NSS_STATUS_TRYAGAIN}}{656}
--\entry {\code {NSS_STATUS_UNAVAIL}}{656}
--\entry {\code {ntohl}}{383}
--\entry {\code {ntohs}}{383}
--\entry {\code {ntp_adjtime}}{513}
--\entry {\code {ntp_gettime}}{511}
--\initial {O}
--\entry {\code {obstack_1grow}}{51}
--\entry {\code {obstack_1grow_fast}}{53}
--\entry {\code {obstack_alignment_mask}}{55}
--\entry {\code {obstack_alloc}}{49}
--\entry {\code {obstack_base}}{54}
--\entry {\code {obstack_blank}}{51}
--\entry {\code {obstack_blank_fast}}{53}
--\entry {\code {obstack_chunk_alloc}}{47}
--\entry {\code {obstack_chunk_free}}{47}
--\entry {\code {obstack_chunk_size}}{56}
--\entry {\code {obstack_copy}}{49}
--\entry {\code {obstack_copy0}}{49}
--\entry {\code {obstack_finish}}{52}
--\entry {\code {obstack_free}}{50}
--\entry {\code {obstack_grow}}{51}
--\entry {\code {obstack_grow0}}{51}
--\entry {\code {obstack_init}}{48}
--\entry {\code {obstack_int_grow}}{52}
--\entry {\code {obstack_int_grow_fast}}{53}
--\entry {\code {obstack_next_free}}{54}
--\entry {\code {obstack_object_size}}{52, 54}
--\entry {\code {obstack_printf}}{231}
--\entry {\code {obstack_ptr_grow}}{52}
--\entry {\code {obstack_ptr_grow_fast}}{53}
--\entry {\code {obstack_room}}{53}
--\entry {\code {obstack_vprintf}}{233}
--\entry {\code {offsetof}}{759}
--\entry {\code {on_exit}}{615}
--\entry {\code {open}}{271}
--\entry {\code {open_memstream}}{260}
--\entry {\code {open_obstack_stream}}{261}
--\entry {\code {open64}}{272}
--\entry {\code {opendir}}{322}
--\entry {\code {openpty}}{436}
--\initial {P}
--\entry {\code {parse_printf_format}}{234}
--\entry {\code {pathconf}}{712}
--\entry {\code {pause}}{567}
--\entry {\code {pclose}}{359}
--\entry {\code {perror}}{27}
--\entry {\code {pipe}}{357}
--\entry {\code {popen}}{359}
--\entry {\code {pow}}{445}
--\entry {\code {pow10}}{443}
--\entry {\code {pow10f}}{443}
--\entry {\code {pow10l}}{443}
--\entry {\code {powf}}{445}
--\entry {\code {powl}}{445}
--\entry {\code {pread}}{276}
--\entry {\code {pread64}}{277}
--\entry {\code {printf}}{230}
--\entry {\code {printf_size}}{241}
--\entry {\code {printf_size_info}}{242}
--\entry {\code {psignal}}{538}
--\entry {\code {pthread_atfork}}{740}
--\entry {\code {pthread_attr_destroy}}{725}
--\entry {\code {pthread_attr_get\var {attr}}}{725}
--\entry {\code {pthread_attr_getinheritsched}}{725}
--\entry {\code {pthread_attr_getschedparam}}{725}
--\entry {\code {pthread_attr_getschedpolicy}}{725}
--\entry {\code {pthread_attr_getscope}}{725}
--\entry {\code {pthread_attr_init}}{724}
--\entry {\code {pthread_attr_set\var {attr}}}{725}
--\entry {\code {pthread_attr_setinheritsched}}{725}
--\entry {\code {pthread_attr_setschedparam}}{725}
--\entry {\code {pthread_attr_setschedpolicy}}{725}
--\entry {\code {pthread_attr_setscope}}{725}
--\entry {\code {pthread_cancel}}{724}
--\entry {\code {pthread_cleanup_pop}}{728}
--\entry {\code {pthread_cleanup_pop_restore_np}}{729}
--\entry {\code {pthread_cleanup_push}}{728}
--\entry {\code {pthread_cleanup_push_defer_np}}{729}
--\entry {\code {pthread_cond_broadcast}}{733}
--\entry {\code {pthread_cond_destroy}}{733}
--\entry {\code {pthread_cond_init}}{732}
--\entry {\code {pthread_cond_signal}}{733}
--\entry {\code {pthread_cond_timedwait}}{733}
--\entry {\code {pthread_cond_wait}}{733}
--\entry {\code {pthread_condattr_destroy}}{735}
--\entry {\code {pthread_condattr_init}}{735}
--\entry {\code {pthread_create}}{723}
--\entry {\code {pthread_detach}}{740}
--\entry {\code {pthread_equal}}{739}
--\entry {\code {pthread_exit}}{723}
--\entry {\code {pthread_getschedparam}}{741}
--\entry {\code {pthread_getspecific}}{737}
--\entry {\code {pthread_join}}{724}
--\entry {\code {pthread_key_create}}{737}
--\entry {\code {pthread_key_delete}}{737}
--\entry {\code {pthread_kill}}{739}
--\entry {\code {pthread_kill_other_threads_np}}{740}
--\entry {\code {pthread_mutex_destroy}}{731}
--\entry {\code {pthread_mutex_init}}{730}
--\entry {\code {pthread_mutex_lock}}{730}
--\entry {\code {pthread_mutex_trylock}}{730}
--\entry {\code {pthread_mutex_unlock}}{730}
--\entry {\code {pthread_mutexattr_destroy}}{731}
--\entry {\code {pthread_mutexattr_getkind_np}}{732}
--\entry {\code {pthread_mutexattr_init}}{731}
--\entry {\code {pthread_mutexattr_setkind_np}}{732}
--\entry {\code {pthread_once}}{741}
--\entry {\code {pthread_self}}{739}
--\entry {\code {pthread_setcancelstate}}{727}
--\entry {\code {pthread_setcanceltype}}{727}
--\entry {\code {pthread_setschedparam}}{741}
--\entry {\code {pthread_setspecific}}{737}
--\entry {\code {pthread_sigmask}}{738}
--\entry {\code {pthread_testcancel}}{727}
--\entry {\code {ptsname}}{435}
--\entry {\code {ptsname_r}}{435}
--\entry {\code {putc}}{215}
--\entry {\code {putchar}}{216}
--\entry {\code {putenv}}{610}
--\entry {\code {putpwent}}{681}
--\entry {\code {puts}}{216}
--\entry {\code {pututline}}{674}
--\entry {\code {pututxline}}{677}
--\entry {\code {putw}}{216}
--\entry {\code {pwrite}}{279}
--\entry {\code {pwrite64}}{279}
--\initial {Q}
--\entry {\code {qecvt}}{484}
--\entry {\code {qecvt_r}}{485}
--\entry {\code {qfcvt}}{484}
--\entry {\code {qfcvt_r}}{485}
--\entry {\code {qgcvt}}{485}
--\entry {\code {qsort}}{178}
--\initial {R}
--\entry {\code {raise}}{556}
--\entry {\code {rand}}{452}
--\entry {\code {rand_r}}{452}
--\entry {\code {random}}{452}
--\entry {\code {read}}{275}
--\entry {\code {readdir}}{323}
--\entry {\code {readdir_r}}{323}
--\entry {\code {readlink}}{332}
--\entry {\code {readv}}{285}
--\entry {\code {realloc}}{35}
--\entry {\code {recv}}{393}
--\entry {\code {recvfrom}}{401}
--\entry {\code {regcomp}}{194}
--\entry {\code {regerror}}{198}
--\entry {\code {regexec}}{195}
--\entry {\code {regfree}}{198}
--\entry {\code {register_printf_function}}{237}
--\entry {\code {remainder}}{473}
--\entry {\code {remainderf}}{473}
--\entry {\code {remainderl}}{473}
--\entry {\code {remove}}{334}
--\entry {\code {rename}}{334}
--\entry {\code {rewind}}{254}
--\entry {\code {rewinddir}}{324}
--\entry {\code {rindex}}{87}
--\entry {\code {rint}}{471}
--\entry {\code {rintf}}{471}
--\entry {\code {rintl}}{471}
--\entry {\code {rmdir}}{334}
--\entry {\code {round}}{472}
--\entry {\code {roundf}}{472}
--\entry {\code {roundl}}{472}
--\initial {S}
--\entry {\code {S_ISBLK}}{342}
--\entry {\code {S_ISCHR}}{342}
--\entry {\code {S_ISDIR}}{342}
--\entry {\code {S_ISFIFO}}{342}
--\entry {\code {S_ISLNK}}{342}
--\entry {\code {S_ISREG}}{342}
--\entry {\code {S_ISSOCK}}{342}
--\entry {\code {scalb}}{470}
--\entry {\code {scalbf}}{470}
--\entry {\code {scalbl}}{470}
--\entry {\code {scalbln}}{470}
--\entry {\code {scalblnf}}{470}
--\entry {\code {scalblnl}}{470}
--\entry {\code {scalbn}}{470}
--\entry {\code {scalbnf}}{470}
--\entry {\code {scalbnl}}{470}
--\entry {\code {scandir}}{325}
--\entry {\code {scandir64}}{325}
--\entry {\code {scanf}}{249}
--\entry {\code {seed48}}{455}
--\entry {\code {seed48_r}}{457}
--\entry {\code {seekdir}}{324}
--\entry {\code {select}}{290}
--\entry {\code {sem_destroy}}{735}
--\entry {\code {sem_getvalue}}{736}
--\entry {\code {sem_init}}{735}
--\entry {\code {sem_post}}{736}
--\entry {\code {sem_trywait}}{736}
--\entry {\code {sem_wait}}{736}
--\entry {\code {send}}{392}
--\entry {\code {sendto}}{401}
--\entry {\code {setbuf}}{259}
--\entry {\code {setbuffer}}{259}
--\entry {\code {setegid}}{665}
--\entry {\code {setenv}}{610}
--\entry {\code {seteuid}}{664}
--\entry {\code {setfsent}}{692}
--\entry {\code {setgid}}{665}
--\entry {\code {setgrent}}{683}
--\entry {\code {setgroups}}{666}
--\entry {\code {sethostent}}{380}
--\entry {\code {sethostid}}{690}
--\entry {\code {sethostname}}{689}
--\entry {\code {setitimer}}{514}
--\entry {\code {setjmp}}{524}
--\entry {\code {setkey}}{721}
--\entry {\code {setkey_r}}{721}
--\entry {\code {setlinebuf}}{259}
--\entry {\code {setlocale}}{143}
--\entry {\code {setmntent}}{695}
--\entry {\code {setnetent}}{409}
--\entry {\code {setnetgrent}}{686}
--\entry {\code {setpgid}}{648}
--\entry {\code {setpgrp}}{648}
--\entry {\code {setpriority}}{522}
--\entry {\code {setprotoent}}{384}
--\entry {\code {setpwent}}{681}
--\entry {\code {setregid}}{665}
--\entry {\code {setreuid}}{665}
--\entry {\code {setrlimit}}{519}
--\entry {\code {setrlimit64}}{519}
--\entry {\code {setservent}}{382}
--\entry {\code {setsid}}{647}
--\entry {\code {setsockopt}}{407}
--\entry {\code {setstate}}{453}
--\entry {\code {settimeofday}}{491}
--\entry {\code {setuid}}{664}
--\entry {\code {setutent}}{673}
--\entry {\code {setutxent}}{677}
--\entry {\code {setvbuf}}{258}
--\entry {\code {shutdown}}{387}
--\entry {\code {sigaction}}{541}
--\entry {\code {sigaddset}}{562}
--\entry {\code {sigaltstack}}{571}
--\entry {\code {sigblock}}{573}
--\entry {\code {sigdelset}}{562}
--\entry {\code {sigemptyset}}{562}
--\entry {\code {sigfillset}}{562}
--\entry {\code {siginterrupt}}{573}
--\entry {\code {sigismember}}{562}
--\entry {\code {siglongjmp}}{526}
--\entry {\code {sigmask}}{573}
--\entry {\code {signal}}{538}
--\entry {\code {signbit}}{474}
--\entry {\code {significand}}{470}
--\entry {\code {significandf}}{470}
--\entry {\code {significandl}}{470}
--\entry {\code {sigpause}}{573}
--\entry {\code {sigpending}}{565}
--\entry {\code {sigprocmask}}{562}
--\entry {\code {sigsetjmp}}{526}
--\entry {\code {sigsetmask}}{573}
--\entry {\code {sigstack}}{571}
--\entry {\code {sigsuspend}}{569}
--\entry {\code {sigvec}}{573}
--\entry {\code {sigwait}}{739}
--\entry {\code {sin}}{440}
--\entry {\code {sincos}}{441}
--\entry {\code {sincosf}}{441}
--\entry {\code {sincosl}}{441}
--\entry {\code {sinf}}{440}
--\entry {\code {sinh}}{447}
--\entry {\code {sinhf}}{447}
--\entry {\code {sinhl}}{447}
--\entry {\code {sinl}}{440}
--\entry {\code {sleep}}{515}
--\entry {\code {snprintf}}{230}
--\entry {\code {socket}}{386}
--\entry {\code {socketpair}}{388}
--\entry {\code {sprintf}}{230}
--\entry {\code {sqrt}}{445}
--\entry {\code {sqrtf}}{445}
--\entry {\code {sqrtl}}{445}
--\entry {\code {srand}}{452}
--\entry {\code {srand48}}{454}
--\entry {\code {srand48_r}}{457}
--\entry {\code {srandom}}{452}
--\entry {\code {sscanf}}{249}
--\entry {\code {ssignal}}{540}
--\entry {\code {stat}}{340}
--\entry {\code {stat64}}{340}
--\entry {\code {stpcpy}}{75}
--\entry {\code {stpncpy}}{76}
--\entry {\code {strcasecmp}}{81}
--\entry {\code {strcat}}{77}
--\entry {\code {strchr}}{86}
--\entry {\code {strcmp}}{81}
--\entry {\code {strcoll}}{84}
--\entry {\code {strcpy}}{74}
--\entry {\code {strcspn}}{88}
--\entry {\code {strdup}}{75}
--\entry {\code {strdupa}}{76}
--\entry {\code {strerror}}{27}
--\entry {\code {strerror_r}}{27}
--\entry {\code {strfmon}}{155}
--\entry {\code {strftime}}{495}
--\entry {\code {strlen}}{72}
--\entry {\code {strncasecmp}}{82}
--\entry {\code {strncat}}{79}
--\entry {\code {strncmp}}{82}
--\entry {\code {strncpy}}{75}
--\entry {\code {strndup}}{75}
--\entry {\code {strndupa}}{77}
--\entry {\code {strnlen}}{73}
--\entry {\code {strpbrk}}{88}
--\entry {\code {strptime}}{500}
--\entry {\code {strrchr}}{87}
--\entry {\code {strsep}}{90}
--\entry {\code {strsignal}}{537}
--\entry {\code {strspn}}{88}
--\entry {\code {strstr}}{87}
--\entry {\code {strtod}}{482}
--\entry {\code {strtof}}{483}
--\entry {\code {strtok}}{88}
--\entry {\code {strtok_r}}{90}
--\entry {\code {strtol}}{480}
--\entry {\code {strtol_l}}{481}
--\entry {\code {strtold}}{483}
--\entry {\code {strtoll}}{481}
--\entry {\code {strtoll_l}}{481}
--\entry {\code {strtoq}}{481}
--\entry {\code {strtoul}}{480}
--\entry {\code {strtoul_l}}{481}
--\entry {\code {strtoull}}{481}
--\entry {\code {strtoull_l}}{481}
--\entry {\code {strtouq}}{481}
--\entry {\code {strverscmp}}{82}
--\entry {\code {strxfrm}}{84}
--\entry {\code {success}}{653}
--\entry {\code {SUN_LEN}}{370}
--\entry {\code {symlink}}{332}
--\entry {\code {sync}}{292}
--\entry {\code {sysconf}}{700}
--\entry {\code {system}}{619}
--\entry {\code {sysv_signal}}{540}
--\initial {T}
--\entry {\code {tan}}{440}
--\entry {\code {tanf}}{440}
--\entry {\code {tanh}}{447}
--\entry {\code {tanhf}}{447}
--\entry {\code {tanhl}}{447}
--\entry {\code {tanl}}{440}
--\entry {\code {tcdrain}}{431}
--\entry {\code {tcflow}}{432}
--\entry {\code {tcflush}}{431}
--\entry {\code {tcgetattr}}{414}
--\entry {\code {tcgetpgrp}}{648}
--\entry {\code {tcgetsid}}{649}
--\entry {\code {tcsendbreak}}{431}
--\entry {\code {tcsetattr}}{414}
--\entry {\code {tcsetpgrp}}{649}
--\entry {\code {tdelete}}{185}
--\entry {\code {tdestroy}}{185}
--\entry {\code {telldir}}{324}
--\entry {\code {TEMP_FAILURE_RETRY}}{555}
--\entry {\code {tempnam}}{354}
--\entry {\code {textdomain}}{172}
--\entry {\code {tfind}}{185}
--\entry {\code {tgamma}}{450}
--\entry {\code {tgammaf}}{450}
--\entry {\code {tgammal}}{450}
--\entry {\code {time}}{490}
--\entry {\code {times}}{489}
--\entry {\code {tmpfile}}{353}
--\entry {\code {tmpfile64}}{353}
--\entry {\code {tmpnam}}{354}
--\entry {\code {tmpnam_r}}{354}
--\entry {\code {toascii}}{63}
--\entry {\code {tolower}}{63}
--\entry {\code {toupper}}{63}
--\entry {\code {towctrans}}{69}
--\entry {\code {towlower}}{69}
--\entry {\code {towupper}}{69}
--\entry {\code {trunc}}{471}
--\entry {\code {truncate}}{274, 351}
--\entry {\code {truncate64}}{274}
--\entry {\code {truncf}}{471}
--\entry {\code {truncl}}{471}
--\entry {\code {tryagain}}{653}
--\entry {\code {tsearch}}{184}
--\entry {\code {ttyname}}{411}
--\entry {\code {ttyname_r}}{411}
--\entry {\code {twalk}}{186}
--\entry {\code {tzset}}{509}
--\initial {U}
--\entry {\code {umask}}{347}
--\entry {\code {uname}}{691}
--\entry {\code {unavail}}{653}
--\entry {\code {ungetc}}{220}
--\entry {\code {unlink}}{333}
--\entry {\code {unlockpt}}{435}
--\entry {\code {unsetenv}}{611}
--\entry {\code {updwtmp}}{675}
--\entry {\code {utime}}{350}
--\entry {\code {utimes}}{350}
--\entry {\code {utmpname}}{675}
--\initial {V}
--\entry {\code {va_alist}}{750}
--\entry {\code {va_arg}}{748}
--\entry {\code {va_dcl}}{750}
--\entry {\code {va_end}}{748}
--\entry {\code {va_start}}{748, 750}
--\entry {\code {valloc}}{36}
--\entry {\code {vasprintf}}{233}
--\entry {\code {versionsort}}{325}
--\entry {\code {versionsort64}}{326}
--\entry {\code {vfork}}{621}
--\entry {\code {vfprintf}}{233}
--\entry {\code {vfscanf}}{250}
--\entry {\code {vprintf}}{232}
--\entry {\code {vscanf}}{250}
--\entry {\code {vsnprintf}}{233}
--\entry {\code {vsprintf}}{233}
--\entry {\code {vsscanf}}{250}
--\initial {W}
--\entry {\code {wait}}{626}
--\entry {\code {wait3}}{628}
--\entry {\code {wait4}}{626}
--\entry {\code {waitpid}}{624}
--\entry {\code {WCOREDUMP}}{627}
--\entry {\code {wcrtomb}}{107}
--\entry {\code {wcsnrtombs}}{112}
--\entry {\code {wcsrtombs}}{111}
--\entry {\code {wcstombs}}{117}
--\entry {\code {wctob}}{105}
--\entry {\code {wctomb}}{115}
--\entry {\code {wctrans}}{68}
--\entry {\code {wctype}}{64}
--\entry {\code {WEXITSTATUS}}{627}
--\entry {\code {WIFEXITED}}{627}
--\entry {\code {WIFSIGNALED}}{627}
--\entry {\code {WIFSTOPPED}}{627}
--\entry {\code {wordexp}}{200}
--\entry {\code {wordfree}}{200}
--\entry {\code {write}}{277}
--\entry {\code {writev}}{285}
--\entry {\code {WSTOPSIG}}{627}
--\entry {\code {WTERMSIG}}{627}
--\initial {Y}
--\entry {\code {y0}}{450}
--\entry {\code {y0f}}{450}
--\entry {\code {y0l}}{450}
--\entry {\code {y1}}{451}
--\entry {\code {y1f}}{451}
--\entry {\code {y1l}}{451}
--\entry {\code {yn}}{451}
--\entry {\code {ynf}}{451}
--\entry {\code {ynl}}{451}
-diff -Naur ../glibc-2.1.3/manual/libc.info glibc-2.1.3/manual/libc.info
---- ../glibc-2.1.3/manual/libc.info 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info 1969-12-31 16:00:00.000000000 -0800
-@@ -1,752 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--Indirect:
--libc.info-1: 1298
--libc.info-2: 57716
--libc.info-3: 102744
--libc.info-4: 151031
--libc.info-5: 199987
--libc.info-6: 249921
--libc.info-7: 292606
--libc.info-8: 339721
--libc.info-9: 378119
--libc.info-10: 424741
--libc.info-11: 468204
--libc.info-12: 510493
--libc.info-13: 559332
--libc.info-14: 606451
--libc.info-15: 654088
--libc.info-16: 701144
--libc.info-17: 750430
--libc.info-18: 795650
--libc.info-19: 844918
--libc.info-20: 894777
--libc.info-21: 944407
--libc.info-22: 992882
--libc.info-23: 1042803
--libc.info-24: 1090005
--libc.info-25: 1138647
--libc.info-26: 1185928
--libc.info-27: 1232876
--libc.info-28: 1281524
--libc.info-29: 1329861
--libc.info-30: 1374966
--libc.info-31: 1420048
--libc.info-32: 1469028
--libc.info-33: 1518430
--libc.info-34: 1565374
--libc.info-35: 1614949
--libc.info-36: 1663505
--libc.info-37: 1707438
--libc.info-38: 1756967
--libc.info-39: 1806436
--libc.info-40: 1855417
--libc.info-41: 1898314
--libc.info-42: 1942337
--libc.info-43: 1989010
--libc.info-44: 2037813
--libc.info-45: 2050944
--libc.info-46: 2234131
--libc.info-47: 2277750
--libc.info-48: 2322225
--libc.info-49: 2379317
--libc.info-50: 2386726
--libc.info-51: 2457367
--libc.info-52: 2508837
--
--Tag Table:
--(Indirect)
--Node: Top1298
--Node: Introduction57716
--Node: Getting Started59065
--Node: Standards and Portability60525
--Node: ISO C61973
--Node: POSIX63490
--Node: Berkeley Unix65231
--Node: SVID65999
--Node: XPG67000
--Node: Using the Library67941
--Node: Header Files68664
--Node: Macro Definitions72616
--Node: Reserved Names74961
--Node: Feature Test Macros79644
--Node: Roadmap to the Manual90385
--Node: Error Reporting97601
--Node: Checking for Errors98529
--Node: Error Codes102744
--Node: Error Messages121761
--Node: Memory Allocation127458
--Node: Memory Concepts128350
--Node: Dynamic Allocation and C129620
--Node: Unconstrained Allocation131704
--Node: Basic Allocation133155
--Node: Malloc Examples134859
--Node: Freeing after Malloc136810
--Node: Changing Block Size138626
--Node: Allocating Cleared Space141229
--Node: Efficiency and Malloc142237
--Node: Aligned Memory Blocks143327
--Node: Malloc Tunable Parameters144707
--Node: Heap Consistency Checking146370
--Node: Hooks for Malloc151031
--Node: Statistics of Malloc155620
--Node: Summary of Malloc157553
--Node: Allocation Debugging159677
--Node: Tracing malloc160821
--Node: Using the Memory Debugger162677
--Node: Tips for the Memory Debugger164557
--Node: Interpreting the traces165892
--Node: Obstacks169485
--Node: Creating Obstacks171099
--Node: Preparing for Obstacks172998
--Node: Allocation in an Obstack175745
--Node: Freeing Obstack Objects178153
--Node: Obstack Functions179489
--Node: Growing Objects181719
--Node: Extra Fast Growing185966
--Node: Status of an Obstack189585
--Node: Obstacks Data Alignment191004
--Node: Obstack Chunks192690
--Node: Summary of Obstacks195046
--Node: Variable Size Automatic198460
--Node: Alloca Example199987
--Node: Advantages of Alloca201104
--Node: Disadvantages of Alloca202996
--Node: GNU C Variable-Size Arrays203741
--Node: Character Handling204899
--Node: Classification of Characters206365
--Node: Case Conversion210209
--Node: Classification of Wide Characters212099
--Node: Using Wide Char Classes219833
--Node: Wide Character Case Conversion222191
--Node: String and Array Utilities224957
--Node: Representation of Strings226904
--Node: String/Array Conventions229845
--Node: String Length231677
--Node: Copying and Concatenation233667
--Node: String/Array Comparison249921
--Node: Collation Functions257337
--Node: Search Functions264333
--Node: Finding Tokens in a String269779
--Node: Encode Binary Data276580
--Node: Argz and Envz Vectors281238
--Node: Argz Functions281838
--Node: Envz Functions288393
--Node: Character Set Handling291443
--Node: Extended Char Intro292606
--Node: Charset Function Overview304759
--Node: Restartable multibyte conversion305773
--Node: Selecting the Conversion307885
--Node: Keeping the state310301
--Node: Converting a Character313530
--Node: Converting Strings329668
--Node: Multibyte Conversion Example339721
--Node: Non-reentrant Conversion342707
--Node: Non-reentrant Character Conversion344342
--Node: Non-reentrant String Conversion349044
--Node: Shift State352039
--Node: Generic Charset Conversion354702
--Node: Generic Conversion Interface357830
--Node: iconv Examples367685
--Node: Other iconv Implementations372786
--Node: glibc iconv Implementation378119
--Node: Locales417363
--Node: Effects of Locale418963
--Node: Choosing Locale420898
--Node: Locale Categories422276
--Node: Setting the Locale424741
--Node: Standard Locales429033
--Node: Locale Information430326
--Node: The Lame Way to Locale Data432086
--Node: General Numeric434052
--Node: Currency Symbol436983
--Node: Sign of Money Amount441602
--Node: The Elegant and Fast Way443915
--Node: Formatting Numbers455142
--Node: Message Translation464860
--Node: Message catalogs a la X/Open466906
--Node: The catgets Functions468204
--Node: The message catalog files477313
--Node: The gencat program484269
--Node: Common Usage487408
--Node: The Uniforum approach494531
--Node: Message catalogs with gettext496025
--Node: Translation with gettext496723
--Node: Locating gettext catalog503629
--Node: Using gettextized software510493
--Node: Helper programs for gettext518829
--Node: Searching and Sorting520591
--Node: Comparison Functions521506
--Node: Array Search Function522724
--Node: Array Sort Function526068
--Node: Search/Sort Example528040
--Node: Hash Search Function531519
--Node: Tree Search Function539117
--Node: Pattern Matching545900
--Node: Wildcard Matching546702
--Node: Globbing549580
--Node: Calling Glob550444
--Node: Flags for Globbing555802
--Node: More Flags for Globbing559332
--Node: Regular Expressions565288
--Node: POSIX Regexp Compilation566272
--Node: Flags for POSIX Regexps570387
--Node: Matching POSIX Regexps571294
--Node: Regexp Subexpressions573455
--Node: Subexpression Complications575509
--Node: Regexp Cleanup577872
--Node: Word Expansion580198
--Node: Expansion Stages581553
--Node: Calling Wordexp583046
--Node: Flags for Wordexp587009
--Node: Wordexp Example588962
--Node: Tilde Expansion590758
--Node: Variable Substitution591830
--Node: I/O Overview595945
--Node: I/O Concepts597458
--Node: Streams and File Descriptors598603
--Node: File Position601694
--Node: File Names603828
--Node: Directories604714
--Node: File Name Resolution606451
--Node: File Name Errors609380
--Node: File Name Portability610920
--Node: I/O on Streams612912
--Node: Streams614935
--Node: Standard Streams616276
--Node: Opening Streams617942
--Node: Closing Streams625469
--Node: Simple Output628006
--Node: Character Input630342
--Node: Line Input633451
--Node: Unreading638439
--Node: Unreading Idea639248
--Node: How Unread640074
--Node: Block Input/Output642572
--Node: Formatted Output644801
--Node: Formatted Output Basics646568
--Node: Output Conversion Syntax649061
--Node: Table of Output Conversions654088
--Node: Integer Conversions656887
--Node: Floating-Point Conversions662228
--Node: Other Output Conversions668023
--Node: Formatted Output Functions671183
--Node: Dynamic Output675325
--Node: Variable Arguments Output676962
--Node: Parsing a Template String682496
--Node: Example of Parsing686323
--Node: Customizing Printf688611
--Node: Registering New Conversions690530
--Node: Conversion Specifier Options692521
--Node: Defining the Output Handler696274
--Node: Printf Extension Example698741
--Node: Predefined Printf Handlers701144
--Node: Formatted Input704789
--Node: Formatted Input Basics705868
--Node: Input Conversion Syntax708548
--Node: Table of Input Conversions711911
--Node: Numeric Input Conversions714208
--Node: String Input Conversions718452
--Node: Dynamic String Input722545
--Node: Other Input Conversions723735
--Node: Formatted Input Functions725387
--Node: Variable Arguments Input726953
--Node: EOF and Errors728588
--Node: Binary Streams730808
--Node: File Positioning733332
--Node: Portable Positioning740445
--Node: Stream Buffering745986
--Node: Buffering Concepts747571
--Node: Flushing Buffers748934
--Node: Controlling Buffering750430
--Node: Other Kinds of Streams754865
--Node: String Streams756154
--Node: Obstack Streams760292
--Node: Custom Streams762343
--Node: Streams and Cookies762996
--Node: Hook Functions766066
--Node: Formatted Messages768452
--Node: Printing Formatted Messages769117
--Node: Adding Severity Classes775561
--Node: Example777154
--Node: Low-Level I/O780379
--Node: Opening and Closing Files783453
--Node: Truncating Files791434
--Node: I/O Primitives795650
--Node: File Position Primitive809767
--Node: Descriptors and Streams817073
--Node: Stream/Descriptor Precautions819491
--Node: Linked Channels820697
--Node: Independent Channels821925
--Node: Cleaning Streams823828
--Node: Scatter-Gather826031
--Node: Memory-mapped I/O828620
--Node: Waiting for I/O837175
--Node: Synchronizing I/O844918
--Node: Asynchronous I/O848390
--Node: Asynchronous Reads/Writes856454
--Node: Status of AIO Operations868913
--Node: Synchronizing AIO Operations872478
--Node: Cancel AIO Operations878869
--Node: Configuration of AIO882330
--Node: Control Operations884426
--Node: Duplicating Descriptors887115
--Node: Descriptor Flags891375
--Node: File Status Flags894777
--Node: Access Modes896231
--Node: Open-time Flags898520
--Node: Operating Modes903237
--Node: Getting File Status Flags906003
--Node: File Locks908610
--Node: Interrupt Input917507
--Node: IOCTLs919939
--Node: File System Interface922015
--Node: Working Directory923544
--Node: Accessing Directories927267
--Node: Directory Entries928692
--Node: Opening a Directory931534
--Node: Reading/Closing Directory933226
--Node: Simple Directory Lister936279
--Node: Random Access Directory937298
--Node: Scanning Directory Content938800
--Node: Simple Directory Lister Mark II943286
--Node: Working on Directory Trees944407
--Node: Hard Links956252
--Node: Symbolic Links959046
--Node: Deleting Files962812
--Node: Renaming Files965742
--Node: Creating Directories969369
--Node: File Attributes971117
--Node: Attribute Meanings972667
--Node: Reading Attributes981888
--Node: Testing File Type985972
--Node: File Owner989189
--Node: Permission Bits992882
--Node: Access Permission998199
--Node: Setting Permissions999349
--Node: Testing File Access1004596
--Node: File Times1008239
--Node: File Size1012770
--Node: Making Special Files1016909
--Node: Temporary Files1018586
--Node: Pipes and FIFOs1026473
--Node: Creating a Pipe1028056
--Node: Pipe to a Subprocess1031209
--Node: FIFO Special Files1034049
--Node: Pipe Atomicity1035622
--Node: Sockets1036506
--Node: Socket Concepts1038553
--Node: Communication Styles1042803
--Node: Socket Addresses1044655
--Node: Address Formats1046694
--Node: Setting Address1049662
--Node: Reading Address1051385
--Node: Interface Naming1053146
--Node: Local Namespace1055554
--Node: Local Namespace Concepts1056214
--Node: Local Namespace Details1057821
--Node: Local Socket Example1059768
--Node: Internet Namespace1061193
--Node: Internet Address Formats1063425
--Node: Host Addresses1065580
--Node: Abstract Host Addresses1066762
--Node: Host Address Data Type1071287
--Node: Host Address Functions1074411
--Node: Host Names1078774
--Node: Ports1087967
--Node: Services Database1090005
--Node: Byte Order1092829
--Node: Protocols Database1095149
--Node: Inet Example1098690
--Node: Misc Namespaces1100700
--Node: Open/Close Sockets1101450
--Node: Creating a Socket1101948
--Node: Closing a Socket1103624
--Node: Socket Pairs1105154
--Node: Connections1107166
--Node: Connecting1108260
--Node: Listening1111099
--Node: Accepting Connections1113185
--Node: Who is Connected1116324
--Node: Transferring Data1117423
--Node: Sending Data1118533
--Node: Receiving Data1121061
--Node: Socket Data Options1122805
--Node: Byte Stream Example1123668
--Node: Server Example1125725
--Node: Out-of-Band Data1129742
--Node: Datagrams1135677
--Node: Sending Datagrams1136707
--Node: Receiving Datagrams1138647
--Node: Datagram Example1140733
--Node: Example Receiver1142748
--Node: Inetd1145316
--Node: Inetd Servers1146124
--Node: Configuring Inetd1147367
--Node: Socket Options1150041
--Node: Socket Option Functions1150749
--Node: Socket-Level Options1152314
--Node: Networks Database1155943
--Node: Low-Level Terminal Interface1158828
--Node: Is It a Terminal1160226
--Node: I/O Queues1162129
--Node: Canonical or Not1164087
--Node: Terminal Modes1165934
--Node: Mode Data Types1167210
--Node: Mode Functions1169038
--Node: Setting Modes1172970
--Node: Input Modes1174958
--Node: Output Modes1180225
--Node: Control Modes1181838
--Node: Local Modes1185928
--Node: Line Speed1192242
--Node: Special Characters1196419
--Node: Editing Characters1198333
--Node: Signal Characters1202674
--Node: Start/Stop Characters1205543
--Node: Other Special1207414
--Node: Noncanonical Input1209228
--Node: Line Control1214041
--Node: Noncanon Example1218753
--Node: Pseudo-Terminals1220973
--Node: Allocation1221885
--Node: Pseudo-Terminal Pairs1226676
--Node: Mathematics1229195
--Node: Mathematical Constants1230868
--Node: Trig Functions1232876
--Node: Inverse Trig Functions1236612
--Node: Exponents and Logarithms1240416
--Node: Hyperbolic Functions1248606
--Node: Special Functions1252646
--Node: Pseudo-Random Numbers1257155
--Node: ISO Random1259386
--Node: BSD Random1261318
--Node: SVID Random1263499
--Node: FP Function Optimizations1276673
--Node: Arithmetic1278593
--Node: Floating Point Numbers1279807
--Node: Floating Point Classes1281524
--Node: Floating Point Errors1285923
--Node: FP Exceptions1286420
--Node: Infinity and NaN1290781
--Node: Status bit operations1293856
--Node: Math Error Reporting1297118
--Node: Rounding1299444
--Node: Control Functions1303033
--Node: Arithmetic Functions1306263
--Node: Absolute Value1307131
--Node: Normalization Functions1309123
--Node: Rounding Functions1313197
--Node: Remainder Functions1317442
--Node: FP Bit Twiddling1319586
--Node: FP Comparison Functions1322699
--Node: Misc FP Arithmetic1325413
--Node: Complex Numbers1328155
--Node: Operations on Complex1329861
--Node: Integer Division1332204
--Node: Parsing of Numbers1335761
--Node: Parsing of Integers1336448
--Node: Parsing of Floats1343367
--Node: System V Number Conversion1347034
--Node: Date and Time1352350
--Node: Processor Time1353591
--Node: Basic CPU Time1354349
--Node: Detailed CPU Time1356604
--Node: Calendar Time1359069
--Node: Simple Calendar Time1360787
--Node: High-Resolution Calendar1362544
--Node: Broken-down Time1368264
--Node: Formatting Date and Time1374966
--Node: Parsing Date and Time1388408
--Node: Low-Level Time String Parsing1389243
--Node: General Time String Parsing1402603
--Node: TZ Variable1410035
--Node: Time Zone Functions1416088
--Node: Time Functions Example1418933
--Node: Precision Time1420048
--Node: Setting an Alarm1426515
--Node: Sleeping1431743
--Node: Resource Usage1435987
--Node: Limits on Resources1439498
--Node: Priority1446161
--Node: Non-Local Exits1449422
--Node: Non-Local Intro1450041
--Node: Non-Local Details1453768
--Node: Non-Local Exits and Signals1456844
--Node: Signal Handling1458315
--Node: Concepts of Signals1460350
--Node: Kinds of Signals1460914
--Node: Signal Generation1462311
--Node: Delivery of Signal1464578
--Node: Standard Signals1467435
--Node: Program Error Signals1469028
--Node: Termination Signals1476486
--Node: Alarm Signals1480324
--Node: Asynchronous I/O Signals1481564
--Node: Job Control Signals1482755
--Node: Operation Error Signals1487358
--Node: Miscellaneous Signals1489297
--Node: Signal Messages1490992
--Node: Signal Actions1492878
--Node: Basic Signal Handling1493823
--Node: Advanced Signal Handling1499892
--Node: Signal and Sigaction1502848
--Node: Sigaction Function Example1504600
--Node: Flags for Sigaction1506916
--Node: Initial Signal Actions1509294
--Node: Defining Handlers1510677
--Node: Handler Returns1512862
--Node: Termination in Handler1514912
--Node: Longjmp in Handler1516335
--Node: Signals in Handler1518430
--Node: Merged Signals1520550
--Node: Nonreentrancy1526260
--Node: Atomic Data Access1531678
--Node: Non-atomic Example1532714
--Node: Atomic Types1534485
--Node: Atomic Usage1535493
--Node: Interrupted Primitives1536963
--Node: Generating Signals1540263
--Node: Signaling Yourself1540856
--Node: Signaling Another Process1542834
--Node: Permission for kill1546210
--Node: Kill Example1548006
--Node: Blocking Signals1550350
--Node: Why Block1552122
--Node: Signal Sets1553659
--Node: Process Signal Mask1556685
--Node: Testing for Delivery1559693
--Node: Blocking for Handler1560943
--Node: Checking for Pending Signals1563362
--Node: Remembering a Signal1565374
--Node: Waiting for a Signal1568923
--Node: Using Pause1569468
--Node: Pause Problems1571092
--Node: Sigsuspend1572816
--Node: Signal Stack1575526
--Node: BSD Signal Handling1580863
--Node: BSD Handler1582137
--Node: Blocking in BSD1584571
--Node: Process Startup1586025
--Node: Program Arguments1587060
--Node: Argument Syntax1589058
--Node: Parsing Program Arguments1591735
--Node: Getopt1592840
--Node: Using Getopt1593478
--Node: Example of Getopt1596859
--Node: Getopt Long Options1599583
--Node: Getopt Long Option Example1603685
--Node: Argp1606556
--Node: Argp Global Variables1609812
--Node: Argp Parsers1611832
--Node: Argp Option Vectors1614949
--Node: Argp Option Flags1618186
--Node: Argp Parser Functions1620204
--Node: Argp Special Keys1622907
--Node: Argp Helper Functions1627998
--Node: Argp Parsing State1631059
--Node: Argp Children1634580
--Node: Argp Flags1636641
--Node: Argp Help Filtering1638958
--Node: Argp Help Filter Keys1640175
--Node: Argp Help1641049
--Node: Argp Help Flags1642238
--Node: Argp Examples1644534
--Node: Argp Example 11645004
--Node: Argp Example 21645808
--Node: Argp Example 31648753
--Node: Argp Example 41655801
--Node: Argp User Customization1663505
--Node: Suboptions1665118
--Node: Suboptions Example1667060
--Node: Environment Variables1669163
--Node: Environment Access1671036
--Node: Standard Environment1675277
--Node: Program Termination1679453
--Node: Normal Termination1680672
--Node: Exit Status1681898
--Node: Cleanups on Exit1684919
--Node: Aborting a Program1686736
--Node: Termination Internals1687635
--Node: Processes1689756
--Node: Running a Command1691779
--Node: Process Creation Concepts1693846
--Node: Process Identification1695856
--Node: Creating a Process1696780
--Node: Executing a File1700403
--Node: Process Completion1707438
--Node: Process Completion Status1713704
--Node: BSD Wait Functions1715348
--Node: Process Creation Example1717216
--Node: Job Control1719466
--Node: Concepts of Job Control1720746
--Node: Job Control is Optional1724103
--Node: Controlling Terminal1725153
--Node: Access to the Terminal1726060
--Node: Orphaned Process Groups1727664
--Node: Implementing a Shell1728656
--Node: Data Structures1729539
--Node: Initializing the Shell1732182
--Node: Launching Jobs1735918
--Node: Foreground and Background1743371
--Node: Stopped and Terminated Jobs1746480
--Node: Continuing Stopped Jobs1751662
--Node: Missing Pieces1753289
--Node: Functions for Job Control1754913
--Node: Identifying the Terminal1755393
--Node: Process Group Functions1756967
--Node: Terminal Access Functions1761978
--Node: Name Service Switch1765452
--Node: NSS Basics1766783
--Node: NSS Configuration File1768379
--Node: Services in the NSS configuration1770077
--Node: Actions in the NSS configuration1771358
--Node: Notes on NSS Configuration File1774519
--Node: NSS Module Internals1776396
--Node: NSS Module Names1777092
--Node: NSS Modules Interface1779467
--Node: Extending NSS1784266
--Node: Adding another Service to NSS1785197
--Node: NSS Module Function Internals1787423
--Node: Users and Groups1792330
--Node: User and Group IDs1794942
--Node: Process Persona1795850
--Node: Why Change Persona1797535
--Node: How Change Persona1799416
--Node: Reading Persona1801303
--Node: Setting User ID1803573
--Node: Setting Groups1806436
--Node: Enable/Disable Setuid1810538
--Node: Setuid Program Example1812572
--Node: Tips for Setuid1816026
--Node: Who Logged In1818543
--Node: User Accounting Database1820924
--Node: Manipulating the Database1822108
--Node: XPG Functions1834434
--Node: Logging In and Out1838097
--Node: User Database1840213
--Node: User Data Structure1840875
--Node: Lookup User1842132
--Node: Scanning All Users1844695
--Node: Writing a User Entry1847649
--Node: Group Database1848548
--Node: Group Data Structure1849124
--Node: Lookup Group1849887
--Node: Scanning All Groups1852387
--Node: Database Example1855417
--Node: Netgroup Database1857614
--Node: Netgroup Data1858025
--Node: Lookup Netgroup1859542
--Node: Netgroup Membership1862954
--Node: System Information1864284
--Node: Host Identification1864948
--Node: Hardware/Software Type ID1868167
--Node: Filesystem handling1870894
--Node: System Configuration1886625
--Node: General Limits1888198
--Node: System Options1891837
--Node: Version Supported1895169
--Node: Sysconf1897006
--Node: Sysconf Definition1897642
--Node: Constants for Sysconf1898314
--Node: Examples of Sysconf1910834
--Node: Minimums1911827
--Node: Limits for Files1914538
--Node: Options for Files1917540
--Node: File Minimums1919829
--Node: Pathconf1921608
--Node: Utility Limits1924562
--Node: Utility Minimums1926492
--Node: String Parameters1928244
--Node: Cryptographic Functions1932152
--Node: Legal Problems1934274
--Node: getpass1936419
--Node: crypt1937323
--Node: DES Encryption1942337
--Node: POSIX Threads1948750
--Node: Basic Thread Operations1950127
--Node: Thread Attributes1954713
--Node: Cancellation1960007
--Node: Cleanup Handlers1964059
--Node: Mutexes1969197
--Node: Condition Variables1977752
--Node: POSIX Semaphores1985128
--Node: Thread-Specific Data1989010
--Node: Threads and Signal Handling1993643
--Node: Miscellaneous Thread Functions1997347
--Node: Language Features2004706
--Node: Consistency Checking2005630
--Node: Variadic Functions2010268
--Node: Why Variadic2011340
--Node: How Variadic2013305
--Node: Variadic Prototypes2014594
--Node: Receiving Arguments2015752
--Node: How Many Arguments2018466
--Node: Calling Variadics2020137
--Node: Argument Macros2022274
--Node: Variadic Example2025044
--Node: Old Varargs2026196
--Node: Null Pointer Constant2027871
--Node: Important Data Types2028956
--Node: Data Type Measurements2031522
--Node: Width of Type2032379
--Node: Range of Type2033285
--Node: Floating Type Macros2036553
--Node: Floating Point Concepts2037813
--Node: Floating Point Parameters2041548
--Node: IEEE Floating Point2048496
--Node: Structure Measurement2050249
--Node: Library Summary2050944
--Node: Installation2234131
--Node: Configuring and compiling2236199
--Node: Running make install2243896
--Node: Tools for Compilation2247584
--Node: Supported Configurations2251078
--Node: Linux2253073
--Node: Reporting Bugs2255216
--Node: Maintenance2258061
--Node: Source Layout2258444
--Node: Porting2262377
--Node: Hierarchy Conventions2270678
--Node: Porting to Unix2275735
--Node: Contributors2277750
--Node: Copying2295328
--Node: Concept Index2322225
--Node: Type Index2379317
--Node: Function Index2386726
--Node: Variable Index2457367
--Node: File Index2508837
--
--End Tag Table
-diff -Naur ../glibc-2.1.3/manual/libc.info-1 glibc-2.1.3/manual/libc.info-1
---- ../glibc-2.1.3/manual/libc.info-1 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-1 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1258 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir)
--
--Main Menu
--*********
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta of the GNU C Library.
--
--* Menu:
--
--* Introduction:: Purpose of the GNU C Library.
--* Error Reporting:: How library functions report errors.
--* Memory Allocation:: Allocating memory dynamically and
-- manipulating it via pointers.
--* Character Handling:: Character testing and conversion functions.
--* String and Array Utilities:: Utilities for copying and comparing strings
-- and arrays.
--* Character Set Handling:: Support for extended character sets.
--* Locales:: The country and language can affect the
-- behavior of library functions.
--* Message Translation:: How to make the program speak the user's
-- language.
--* Searching and Sorting:: General searching and sorting functions.
--* Pattern Matching:: Matching shell "globs" and regular
-- expressions.
--* I/O Overview:: Introduction to the I/O facilities.
--* I/O on Streams:: High-level, portable I/O facilities.
--* Low-Level I/O:: Low-level, less portable I/O.
--* File System Interface:: Functions for manipulating files.
--* Pipes and FIFOs:: A simple interprocess communication
-- mechanism.
--* Sockets:: A more complicated IPC mechanism, with
-- networking support.
--* Low-Level Terminal Interface:: How to change the characteristics of a
-- terminal device.
--* Mathematics:: Math functions, useful constants, random
-- numbers.
--* Arithmetic:: Low level arithmetic functions.
--* Date and Time:: Functions for getting the date and time and
-- formatting them nicely.
--* Non-Local Exits:: Jumping out of nested function calls.
--* Signal Handling:: How to send, block, and handle signals.
--* Process Startup:: Writing the beginning and end of your
-- program.
--* Processes:: How to create processes and run other
-- programs.
--* Job Control:: All about process groups and sessions.
--* Name Service Switch:: Accessing system databases.
--* Users and Groups:: How users are identified and classified.
--* System Information:: Getting information about the hardware and
-- operating system.
--* System Configuration:: Parameters describing operating system
-- limits.
--
--Add-ons
--
--* Cryptographic Functions:: DES encryption and password handling.
--* POSIX Threads:: The standard threads library.
--
--Appendices
--
--* Language Features:: C language features provided by the library.
--* Library Summary:: A summary showing the syntax, header file,
-- and derivation of each library feature.
--* Installation:: How to install the GNU C library.
--* Maintenance:: How to enhance and port the GNU C Library.
--* Contributors:: Who wrote what parts of the GNU C library.
--* Copying:: The GNU Library General Public License says
-- how you can copy and share the GNU C Library.
--
--Indices
--
--* Concept Index:: Index of concepts and names.
--* Type Index:: Index of types and type qualifiers.
--* Function Index:: Index of functions and function-like macros.
--* Variable Index:: Index of variables and variable-like macros.
--* File Index:: Index of programs and files.
--
-- -- The Detailed Node Listing --
--
--Introduction
--
--* Getting Started:: What this manual is for and how to use it.
--* Standards and Portability:: Standards and sources upon which the GNU
-- C library is based.
--* Using the Library:: Some practical uses for the library.
--* Roadmap to the Manual:: Overview of the remaining chapters in
-- this manual.
--
--Standards and Portability
--
--* ISO C:: The international standard for the C
-- programming language.
--* POSIX:: The ISO/IEC 9945 (aka IEEE 1003) standards
-- for operating systems.
--* Berkeley Unix:: BSD and SunOS.
--* SVID:: The System V Interface Description.
--* XPG:: The X/Open Portability Guide.
--
--Using the Library
--
--* Header Files:: How to include the header files in your
-- programs.
--* Macro Definitions:: Some functions in the library may really
-- be implemented as macros.
--* Reserved Names:: The C standard reserves some names for
-- the library, and some for users.
--* Feature Test Macros:: How to control what names are defined.
--
--Error Reporting
--
--* Checking for Errors:: How errors are reported by library functions.
--* Error Codes:: Error code macros; all of these expand
-- into integer constant values.
--* Error Messages:: Mapping error codes onto error messages.
--
--Memory Allocation
--
--* Memory Concepts:: An introduction to concepts and terminology.
--* Dynamic Allocation and C:: How to get different kinds of allocation in C.
--* Unconstrained Allocation:: The `malloc' facility allows fully general
-- dynamic allocation.
--* Allocation Debugging:: Finding memory leaks and not freed memory.
--* Obstacks:: Obstacks are less general than malloc
-- but more efficient and convenient.
--* Variable Size Automatic:: Allocation of variable-sized blocks
-- of automatic storage that are freed when the
-- calling function returns.
--
--Unconstrained Allocation
--
--* Basic Allocation:: Simple use of `malloc'.
--* Malloc Examples:: Examples of `malloc'. `xmalloc'.
--* Freeing after Malloc:: Use `free' to free a block you
-- got with `malloc'.
--* Changing Block Size:: Use `realloc' to make a block
-- bigger or smaller.
--* Allocating Cleared Space:: Use `calloc' to allocate a
-- block and clear it.
--* Efficiency and Malloc:: Efficiency considerations in use of
-- these functions.
--* Aligned Memory Blocks:: Allocating specially aligned memory:
-- `memalign' and `valloc'.
--* Malloc Tunable Parameters:: Use `mallopt' to adjust allocation
-- parameters.
--* Heap Consistency Checking:: Automatic checking for errors.
--* Hooks for Malloc:: You can use these hooks for debugging
-- programs that use `malloc'.
--* Statistics of Malloc:: Getting information about how much
-- memory your program is using.
--* Summary of Malloc:: Summary of `malloc' and related functions.
--
--Allocation Debugging
--
--* Tracing malloc:: How to install the tracing functionality.
--* Using the Memory Debugger:: Example programs excerpts.
--* Tips for the Memory Debugger:: Some more or less clever ideas.
--* Interpreting the traces:: What do all these lines mean?
--
--Obstacks
--
--* Creating Obstacks:: How to declare an obstack in your program.
--* Preparing for Obstacks:: Preparations needed before you can
-- use obstacks.
--* Allocation in an Obstack:: Allocating objects in an obstack.
--* Freeing Obstack Objects:: Freeing objects in an obstack.
--* Obstack Functions:: The obstack functions are both
-- functions and macros.
--* Growing Objects:: Making an object bigger by stages.
--* Extra Fast Growing:: Extra-high-efficiency (though more
-- complicated) growing objects.
--* Status of an Obstack:: Inquiries about the status of an obstack.
--* Obstacks Data Alignment:: Controlling alignment of objects in obstacks.
--* Obstack Chunks:: How obstacks obtain and release chunks;
-- efficiency considerations.
--* Summary of Obstacks::
--
--Variable Size Automatic
--
--* Alloca Example:: Example of using `alloca'.
--* Advantages of Alloca:: Reasons to use `alloca'.
--* Disadvantages of Alloca:: Reasons to avoid `alloca'.
--* GNU C Variable-Size Arrays:: Only in GNU C, here is an alternative
-- method of allocating dynamically and
-- freeing automatically.
--
--Character Handling
--
--* Classification of Characters:: Testing whether characters are
-- letters, digits, punctuation, etc.
--
--* Case Conversion:: Case mapping, and the like.
--* Classification of Wide Characters:: Character class determination for
-- wide characters.
--* Using Wide Char Classes:: Notes on using the wide character
-- classes.
--* Wide Character Case Conversion:: Mapping of wide characters.
--
--String and Array Utilities
--
--* Representation of Strings:: Introduction to basic concepts.
--* String/Array Conventions:: Whether to use a string function or an
-- arbitrary array function.
--* String Length:: Determining the length of a string.
--* Copying and Concatenation:: Functions to copy the contents of strings
-- and arrays.
--* String/Array Comparison:: Functions for byte-wise and character-wise
-- comparison.
--* Collation Functions:: Functions for collating strings.
--* Search Functions:: Searching for a specific element or substring.
--* Finding Tokens in a String:: Splitting a string into tokens by looking
-- for delimiters.
--* Encode Binary Data:: Encoding and Decoding of Binary Data.
--* Argz and Envz Vectors:: Null-separated string vectors.
--
--Argz and Envz Vectors
--
--* Argz Functions:: Operations on argz vectors.
--* Envz Functions:: Additional operations on environment vectors.
--
--Character Set Handling
--
--* Extended Char Intro:: Introduction to Extended Characters.
--* Charset Function Overview:: Overview about Character Handling
-- Functions.
--* Restartable multibyte conversion:: Restartable multibyte conversion
-- Functions.
--* Non-reentrant Conversion:: Non-reentrant Conversion Function.
--* Generic Charset Conversion:: Generic Charset Conversion.
--
--Restartable multibyte conversion
--
--* Selecting the Conversion:: Selecting the conversion and its properties.
--* Keeping the state:: Representing the state of the conversion.
--* Converting a Character:: Converting Single Characters.
--* Converting Strings:: Converting Multibyte and Wide Character
-- Strings.
--* Multibyte Conversion Example:: A Complete Multibyte Conversion Example.
--
--Non-reentrant Conversion
--
--* Non-reentrant Character Conversion:: Non-reentrant Conversion of Single
-- Characters.
--* Non-reentrant String Conversion:: Non-reentrant Conversion of Strings.
--* Shift State:: States in Non-reentrant Functions.
--
--Generic Charset Conversion
--
--* Generic Conversion Interface:: Generic Character Set Conversion Interface.
--* iconv Examples:: A complete `iconv' example.
--* Other iconv Implementations:: Some Details about other `iconv'
-- Implementations.
--* glibc iconv Implementation:: The `iconv' Implementation in the GNU C
-- library.
--
--Locales
--
--* Effects of Locale:: Actions affected by the choice of
-- locale.
--* Choosing Locale:: How the user specifies a locale.
--* Locale Categories:: Different purposes for which you can
-- select a locale.
--* Setting the Locale:: How a program specifies the locale
-- with library functions.
--* Standard Locales:: Locale names available on all systems.
--* Locale Information:: How to access the information for the locale.
--* Formatting Numbers:: A dedicated function to format numbers.
--
--Locale Information
--
--* The Lame Way to Locale Data:: ISO C's `localeconv'.
--* The Elegant and Fast Way:: X/Open's `nl_langinfo'.
--
--The Lame Way to Locale Data
--
--* General Numeric:: Parameters for formatting numbers and
-- currency amounts.
--* Currency Symbol:: How to print the symbol that identifies an
-- amount of money (e.g. `$').
--* Sign of Money Amount:: How to print the (positive or negative) sign
-- for a monetary amount, if one exists.
--
--Message Translation
--
--* Message catalogs a la X/Open:: The `catgets' family of functions.
--* The Uniforum approach:: The `gettext' family of functions.
--
--Message catalogs a la X/Open
--
--* The catgets Functions:: The `catgets' function family.
--* The message catalog files:: Format of the message catalog files.
--* The gencat program:: How to generate message catalogs files which
-- can be used by the functions.
--* Common Usage:: How to use the `catgets' interface.
--
--The Uniforum approach
--
--* Message catalogs with gettext:: The `gettext' family of functions.
--* Helper programs for gettext:: Programs to handle message catalogs
-- for `gettext'.
--
--Message catalogs with gettext
--
--* Translation with gettext:: What has to be done to translate a message.
--* Locating gettext catalog:: How to determine which catalog to be used.
--* Using gettextized software:: The possibilities of the user to influence
-- the way `gettext' works.
--
--Searching and Sorting
--
--* Comparison Functions:: Defining how to compare two objects.
-- Since the sort and search facilities
-- are general, you have to specify the
-- ordering.
--* Array Search Function:: The `bsearch' function.
--* Array Sort Function:: The `qsort' function.
--* Search/Sort Example:: An example program.
--* Hash Search Function:: The `hsearch' function.
--* Tree Search Function:: The `tsearch' function.
--
--Pattern Matching
--
--* Wildcard Matching:: Matching a wildcard pattern against a single string.
--* Globbing:: Finding the files that match a wildcard pattern.
--* Regular Expressions:: Matching regular expressions against strings.
--* Word Expansion:: Expanding shell variables, nested commands,
-- arithmetic, and wildcards.
-- This is what the shell does with shell commands.
--
--Globbing
--
--* Calling Glob:: Basic use of `glob'.
--* Flags for Globbing:: Flags that enable various options in `glob'.
--* More Flags for Globbing:: GNU specific extensions to `glob'.
--
--Regular Expressions
--
--* POSIX Regexp Compilation:: Using `regcomp' to prepare to match.
--* Flags for POSIX Regexps:: Syntax variations for `regcomp'.
--* Matching POSIX Regexps:: Using `regexec' to match the compiled
-- pattern that you get from `regcomp'.
--* Regexp Subexpressions:: Finding which parts of the string were matched.
--* Subexpression Complications:: Find points of which parts were matched.
--* Regexp Cleanup:: Freeing storage; reporting errors.
--
--Word Expansion
--
--* Expansion Stages:: What word expansion does to a string.
--* Calling Wordexp:: How to call `wordexp'.
--* Flags for Wordexp:: Options you can enable in `wordexp'.
--* Wordexp Example:: A sample program that does word expansion.
--* Tilde Expansion:: Details of how tilde expansion works.
--* Variable Substitution:: Different types of variable substitution.
--
--I/O Overview
--
--* I/O Concepts:: Some basic information and terminology.
--* File Names:: How to refer to a file.
--
--I/O Concepts
--
--* Streams and File Descriptors:: The GNU Library provides two ways
-- to access the contents of files.
--* File Position:: The number of bytes from the
-- beginning of the file.
--
--File Names
--
--* Directories:: Directories contain entries for files.
--* File Name Resolution:: A file name specifies how to look up a file.
--* File Name Errors:: Error conditions relating to file names.
--* File Name Portability:: File name portability and syntax issues.
--
--I/O on Streams
--
--* Streams:: About the data type representing a stream.
--* Standard Streams:: Streams to the standard input and output
-- devices are created for you.
--* Opening Streams:: How to create a stream to talk to a file.
--* Closing Streams:: Close a stream when you are finished with it.
--* Simple Output:: Unformatted output by characters and lines.
--* Character Input:: Unformatted input by characters and words.
--* Line Input:: Reading a line or a record from a stream.
--* Unreading:: Peeking ahead/pushing back input just read.
--* Block Input/Output:: Input and output operations on blocks of data.
--* Formatted Output:: `printf' and related functions.
--* Customizing Printf:: You can define new conversion specifiers for
-- `printf' and friends.
--* Formatted Input:: `scanf' and related functions.
--* EOF and Errors:: How you can tell if an I/O error happens.
--* Binary Streams:: Some systems distinguish between text files
-- and binary files.
--* File Positioning:: About random-access streams.
--* Portable Positioning:: Random access on peculiar ISO C systems.
--* Stream Buffering:: How to control buffering of streams.
--* Other Kinds of Streams:: Streams that do not necessarily correspond
-- to an open file.
--* Formatted Messages:: Print strictly formatted messages.
--
--Unreading
--
--* Unreading Idea:: An explanation of unreading with pictures.
--* How Unread:: How to call `ungetc' to do unreading.
--
--Formatted Output
--
--* Formatted Output Basics:: Some examples to get you started.
--* Output Conversion Syntax:: General syntax of conversion
-- specifications.
--* Table of Output Conversions:: Summary of output conversions and
-- what they do.
--* Integer Conversions:: Details about formatting of integers.
--* Floating-Point Conversions:: Details about formatting of
-- floating-point numbers.
--* Other Output Conversions:: Details about formatting of strings,
-- characters, pointers, and the like.
--* Formatted Output Functions:: Descriptions of the actual functions.
--* Dynamic Output:: Functions that allocate memory for the output.
--* Variable Arguments Output:: `vprintf' and friends.
--* Parsing a Template String:: What kinds of args does a given template
-- call for?
--* Example of Parsing:: Sample program using `parse_printf_format'.
--
--Customizing Printf
--
--* Registering New Conversions:: Using `register_printf_function'
-- to register a new output conversion.
--* Conversion Specifier Options:: The handler must be able to get
-- the options specified in the
-- template when it is called.
--* Defining the Output Handler:: Defining the handler and arginfo
-- functions that are passed as arguments
-- to `register_printf_function'.
--* Printf Extension Example:: How to define a `printf'
-- handler function.
--* Predefined Printf Handlers:: Predefined `printf' handlers.
--
--Formatted Input
--
--* Formatted Input Basics:: Some basics to get you started.
--* Input Conversion Syntax:: Syntax of conversion specifications.
--* Table of Input Conversions:: Summary of input conversions and what they do.
--* Numeric Input Conversions:: Details of conversions for reading numbers.
--* String Input Conversions:: Details of conversions for reading strings.
--* Dynamic String Input:: String conversions that `malloc' the buffer.
--* Other Input Conversions:: Details of miscellaneous other conversions.
--* Formatted Input Functions:: Descriptions of the actual functions.
--* Variable Arguments Input:: `vscanf' and friends.
--
--Stream Buffering
--
--* Buffering Concepts:: Terminology is defined here.
--* Flushing Buffers:: How to ensure that output buffers are flushed.
--* Controlling Buffering:: How to specify what kind of buffering to use.
--
--Other Kinds of Streams
--
--* String Streams:: Streams that get data from or put data in
-- a string or memory buffer.
--* Obstack Streams:: Streams that store data in an obstack.
--* Custom Streams:: Defining your own streams with an arbitrary
-- input data source and/or output data sink.
--
--Custom Streams
--
--* Streams and Cookies:: The "cookie" records where to fetch or
-- store data that is read or written.
--* Hook Functions:: How you should define the four "hook
-- functions" that a custom stream needs.
--
--Formatted Messages
--
--* Printing Formatted Messages:: The `fmtmsg' function.
--* Adding Severity Classes:: Add more severity classes.
--* Example:: How to use `fmtmsg' and `addseverity'.
--
--Low-Level I/O
--
--* Opening and Closing Files:: How to open and close file
-- descriptors.
--* Truncating Files:: Change the size of a file.
--* I/O Primitives:: Reading and writing data.
--* File Position Primitive:: Setting a descriptor's file
-- position.
--* Descriptors and Streams:: Converting descriptor to stream
-- or vice-versa.
--* Stream/Descriptor Precautions:: Precautions needed if you use both
-- descriptors and streams.
--* Scatter-Gather:: Fast I/O to discontinous buffers.
--* Memory-mapped I/O:: Using files like memory.
--* Waiting for I/O:: How to check for input or output
-- on multiple file descriptors.
--* Synchronizing I/O:: Making sure all I/O actions completed.
--* Asynchronous I/O:: Perform I/O in parallel.
--* Control Operations:: Various other operations on file
-- descriptors.
--* Duplicating Descriptors:: Fcntl commands for duplicating
-- file descriptors.
--* Descriptor Flags:: Fcntl commands for manipulating
-- flags associated with file
-- descriptors.
--* File Status Flags:: Fcntl commands for manipulating
-- flags associated with open files.
--* File Locks:: Fcntl commands for implementing
-- file locking.
--* Interrupt Input:: Getting an asynchronous signal when
-- input arrives.
--* IOCTLs:: Generic I/O Control operations.
--
--Stream/Descriptor Precautions
--
--* Linked Channels:: Dealing with channels sharing a file position.
--* Independent Channels:: Dealing with separately opened, unlinked channels.
--* Cleaning Streams:: Cleaning a stream makes it safe to use
-- another channel.
--
--Asynchronous I/O
--
--* Asynchronous Reads/Writes:: Asynchronous Read and Write Operations.
--* Status of AIO Operations:: Getting the Status of AIO Operations.
--* Synchronizing AIO Operations:: Getting into a consistent state.
--* Cancel AIO Operations:: Cancelation of AIO Operations.
--* Configuration of AIO:: How to optimize the AIO implementation.
--
--File Status Flags
--
--* Access Modes:: Whether the descriptor can read or write.
--* Open-time Flags:: Details of `open'.
--* Operating Modes:: Special modes to control I/O operations.
--* Getting File Status Flags:: Fetching and changing these flags.
--
--File System Interface
--
--* Working Directory:: This is used to resolve relative
-- file names.
--* Accessing Directories:: Finding out what files a directory
-- contains.
--* Working on Directory Trees:: Apply actions to all files or a selectable
-- subset of a directory hierarchy.
--* Hard Links:: Adding alternate names to a file.
--* Symbolic Links:: A file that "points to" a file name.
--* Deleting Files:: How to delete a file, and what that means.
--* Renaming Files:: Changing a file's name.
--* Creating Directories:: A system call just for creating a directory.
--* File Attributes:: Attributes of individual files.
--* Making Special Files:: How to create special files.
--* Temporary Files:: Naming and creating temporary files.
--
--Accessing Directories
--
--* Directory Entries:: Format of one directory entry.
--* Opening a Directory:: How to open a directory stream.
--* Reading/Closing Directory:: How to read directory entries from the stream.
--* Simple Directory Lister:: A very simple directory listing program.
--* Random Access Directory:: Rereading part of the directory
-- already read with the same stream.
--* Scanning Directory Content:: Get entries for user selected subset of
-- contents in given directory.
--* Simple Directory Lister Mark II:: Revised version of the program.
--
--File Attributes
--
--* Attribute Meanings:: The names of the file attributes,
-- and what their values mean.
--* Reading Attributes:: How to read the attributes of a file.
--* Testing File Type:: Distinguishing ordinary files,
-- directories, links...
--* File Owner:: How ownership for new files is determined,
-- and how to change it.
--* Permission Bits:: How information about a file's access
-- mode is stored.
--* Access Permission:: How the system decides who can access a file.
--* Setting Permissions:: How permissions for new files are assigned,
-- and how to change them.
--* Testing File Access:: How to find out if your process can
-- access a file.
--* File Times:: About the time attributes of a file.
--* File Size:: Manually changing the size of a file.
--
--Pipes and FIFOs
--
--* Creating a Pipe:: Making a pipe with the `pipe' function.
--* Pipe to a Subprocess:: Using a pipe to communicate with a
-- child process.
--* FIFO Special Files:: Making a FIFO special file.
--* Pipe Atomicity:: When pipe (or FIFO) I/O is atomic.
--
--Sockets
--
--* Socket Concepts:: Basic concepts you need to know about.
--* Communication Styles::Stream communication, datagrams, and other styles.
--* Socket Addresses:: How socket names ("addresses") work.
--* Interface Naming:: Identifying specific network interfaces.
--* Local Namespace:: Details about the local namespace.
--* Internet Namespace:: Details about the Internet namespace.
--* Misc Namespaces:: Other namespaces not documented fully here.
--* Open/Close Sockets:: Creating sockets and destroying them.
--* Connections:: Operations on sockets with connection state.
--* Datagrams:: Operations on datagram sockets.
--* Inetd:: Inetd is a daemon that starts servers on request.
-- The most convenient way to write a server
-- is to make it work with Inetd.
--* Socket Options:: Miscellaneous low-level socket options.
--* Networks Database:: Accessing the database of network names.
--
--Socket Addresses
--
--* Address Formats:: About `struct sockaddr'.
--* Setting Address:: Binding an address to a socket.
--* Reading Address:: Reading the address of a socket.
--
--Local Namespace
--
--* Concepts: Local Namespace Concepts. What you need to understand.
--* Details: Local Namespace Details. Address format, symbolic names, etc.
--* Example: Local Socket Example. Example of creating a socket.
--
--Internet Namespace
--
--* Internet Address Formats:: How socket addresses are specified in the
-- Internet namespace.
--* Host Addresses:: All about host addresses of internet host.
--* Protocols Database:: Referring to protocols by name.
--* Ports:: Internet port numbers.
--* Services Database:: Ports may have symbolic names.
--* Byte Order:: Different hosts may use different byte
-- ordering conventions; you need to
-- canonicalize host address and port number.
--* Inet Example:: Putting it all together.
--
--Host Addresses
--
--* Abstract Host Addresses:: What a host number consists of.
--* Data type: Host Address Data Type. Data type for a host number.
--* Functions: Host Address Functions. Functions to operate on them.
--* Names: Host Names. Translating host names to host numbers.
--
--Open/Close Sockets
--
--* Creating a Socket:: How to open a socket.
--* Closing a Socket:: How to close a socket.
--* Socket Pairs:: These are created like pipes.
--
--Connections
--
--* Connecting:: What the client program must do.
--* Listening:: How a server program waits for requests.
--* Accepting Connections:: What the server does when it gets a request.
--* Who is Connected:: Getting the address of the
-- other side of a connection.
--* Transferring Data:: How to send and receive data.
--* Byte Stream Example:: An example program: a client for communicating
-- over a byte stream socket in the Internet namespace.
--* Server Example:: A corresponding server program.
--* Out-of-Band Data:: This is an advanced feature.
--
--Transferring Data
--
--* Sending Data:: Sending data with `send'.
--* Receiving Data:: Reading data with `recv'.
--* Socket Data Options:: Using `send' and `recv'.
--
--Datagrams
--
--* Sending Datagrams:: Sending packets on a datagram socket.
--* Receiving Datagrams:: Receiving packets on a datagram socket.
--* Datagram Example:: An example program: packets sent over a
-- datagram socket in the local namespace.
--* Example Receiver:: Another program, that receives those packets.
--
--Inetd
--
--* Inetd Servers::
--* Configuring Inetd::
--
--Socket Options
--
--* Socket Option Functions:: The basic functions for setting and getting
-- socket options.
--* Socket-Level Options:: Details of the options at the socket level.
--
--Low-Level Terminal Interface
--
--* Is It a Terminal:: How to determine if a file is a terminal
-- device, and what its name is.
--* I/O Queues:: About flow control and typeahead.
--* Canonical or Not:: Two basic styles of input processing.
--* Terminal Modes:: How to examine and modify flags controlling
-- details of terminal I/O: echoing,
-- signals, editing.
--* Line Control:: Sending break sequences, clearing
-- terminal buffers ...
--* Noncanon Example:: How to read single characters without echo.
--* Pseudo-Terminals:: How to open a pseudo-terminal.
--
--Terminal Modes
--
--* Mode Data Types:: The data type `struct termios' and
-- related types.
--* Mode Functions:: Functions to read and set the terminal
-- attributes.
--* Setting Modes:: The right way to set terminal attributes
-- reliably.
--* Input Modes:: Flags controlling low-level input handling.
--* Output Modes:: Flags controlling low-level output handling.
--* Control Modes:: Flags controlling serial port behavior.
--* Local Modes:: Flags controlling high-level input handling.
--* Line Speed:: How to read and set the terminal line speed.
--* Special Characters:: Characters that have special effects,
-- and how to change them.
--* Noncanonical Input:: Controlling how long to wait for input.
--
--Special Characters
--
--* Editing Characters:: Special characters that terminate lines and
-- delete text, and other editing functions.
--* Signal Characters:: Special characters that send or raise signals
-- to or for certain classes of processes.
--* Start/Stop Characters:: Special characters that suspend or resume
-- suspended output.
--* Other Special:: Other special characters for BSD systems:
-- they can discard output, and print status.
--
--Pseudo-Terminals
--
--* Allocation:: Allocating a pseudo terminal.
--* Pseudo-Terminal Pairs:: How to open both sides of a
-- pseudo-terminal in a single operation.
--
--Mathematics
--
--* Mathematical Constants:: Precise numeric values for often-used
-- constants.
--* Trig Functions:: Sine, cosine, tangent, and friends.
--* Inverse Trig Functions:: Arcsine, arccosine, etc.
--* Exponents and Logarithms:: Also pow and sqrt.
--* Hyperbolic Functions:: sinh, cosh, tanh, etc.
--* Special Functions:: Bessel, gamma, erf.
--* Pseudo-Random Numbers:: Functions for generating pseudo-random
-- numbers.
--* FP Function Optimizations:: Fast code or small code.
--
--Pseudo-Random Numbers
--
--* ISO Random:: `rand' and friends.
--* BSD Random:: `random' and friends.
--* SVID Random:: `drand48' and friends.
--
--Arithmetic
--
--* Floating Point Numbers:: Basic concepts. IEEE 754.
--* Floating Point Classes:: The five kinds of floating-point number.
--* Floating Point Errors:: When something goes wrong in a calculation.
--* Rounding:: Controlling how results are rounded.
--* Control Functions:: Saving and restoring the FPU's state.
--* Arithmetic Functions:: Fundamental operations provided by the library.
--* Complex Numbers:: The types. Writing complex constants.
--* Operations on Complex:: Projection, conjugation, decomposition.
--* Integer Division:: Integer division with guaranteed rounding.
--* Parsing of Numbers:: Converting strings to numbers.
--* System V Number Conversion:: An archaic way to convert numbers to strings.
--
--Floating Point Errors
--
--* FP Exceptions:: IEEE 754 math exceptions and how to detect them.
--* Infinity and NaN:: Special values returned by calculations.
--* Status bit operations:: Checking for exceptions after the fact.
--* Math Error Reporting:: How the math functions report errors.
--
--Arithmetic Functions
--
--* Absolute Value:: Absolute values of integers and floats.
--* Normalization Functions:: Extracting exponents and putting them back.
--* Rounding Functions:: Rounding floats to integers.
--* Remainder Functions:: Remainders on division, precisely defined.
--* FP Bit Twiddling:: Sign bit adjustment. Adding epsilon.
--* FP Comparison Functions:: Comparisons without risk of exceptions.
--* Misc FP Arithmetic:: Max, min, positive difference, multiply-add.
--
--Parsing of Numbers
--
--* Parsing of Integers:: Functions for conversion of integer values.
--* Parsing of Floats:: Functions for conversion of floating-point
-- values.
--
--Date and Time
--
--* Processor Time:: Measures processor time used by a program.
--* Calendar Time:: Manipulation of "real" dates and times.
--* Precision Time:: Manipulation and monitoring of high accuracy
-- time.
--* Setting an Alarm:: Sending a signal after a specified time.
--* Sleeping:: Waiting for a period of time.
--* Resource Usage:: Measuring various resources used.
--* Limits on Resources:: Specifying limits on resource usage.
--* Priority:: Reading or setting process run priority.
--
--Processor Time
--
--* Basic CPU Time:: The `clock' function.
--* Detailed CPU Time:: The `times' function.
--
--Calendar Time
--
--* Simple Calendar Time:: Facilities for manipulating calendar time.
--* High-Resolution Calendar:: A time representation with greater precision.
--* Broken-down Time:: Facilities for manipulating local time.
--* Formatting Date and Time:: Converting times to strings.
--* Parsing Date and Time:: Convert textual time and date information back
-- into broken-down time values.
--* TZ Variable:: How users specify the time zone.
--* Time Zone Functions:: Functions to examine or specify the time zone.
--* Time Functions Example:: An example program showing use of some of
-- the time functions.
--
--Parsing Date and Time
--
--* Low-Level Time String Parsing:: Interpret string according to given format.
--* General Time String Parsing:: User-friendly function to parse data and
-- time strings.
--
--Non-Local Exits
--
--* Intro: Non-Local Intro. When and how to use these facilities.
--* Details: Non-Local Details. Functions for nonlocal exits.
--* Non-Local Exits and Signals:: Portability issues.
--
--Signal Handling
--
--* Concepts of Signals:: Introduction to the signal facilities.
--* Standard Signals:: Particular kinds of signals with
-- standard names and meanings.
--* Signal Actions:: Specifying what happens when a
-- particular signal is delivered.
--* Defining Handlers:: How to write a signal handler function.
--* Interrupted Primitives:: Signal handlers affect use of `open',
-- `read', `write' and other functions.
--* Generating Signals:: How to send a signal to a process.
--* Blocking Signals:: Making the system hold signals temporarily.
--* Waiting for a Signal:: Suspending your program until a signal
-- arrives.
--* Signal Stack:: Using a Separate Signal Stack.
--* BSD Signal Handling:: Additional functions for backward
-- compatibility with BSD.
--
--Concepts of Signals
--
--* Kinds of Signals:: Some examples of what can cause a signal.
--* Signal Generation:: Concepts of why and how signals occur.
--* Delivery of Signal:: Concepts of what a signal does to the
-- process.
--
--Standard Signals
--
--* Program Error Signals:: Used to report serious program errors.
--* Termination Signals:: Used to interrupt and/or terminate the
-- program.
--* Alarm Signals:: Used to indicate expiration of timers.
--* Asynchronous I/O Signals:: Used to indicate input is available.
--* Job Control Signals:: Signals used to support job control.
--* Operation Error Signals:: Used to report operational system errors.
--* Miscellaneous Signals:: Miscellaneous Signals.
--* Signal Messages:: Printing a message describing a signal.
--
--Signal Actions
--
--* Basic Signal Handling:: The simple `signal' function.
--* Advanced Signal Handling:: The more powerful `sigaction' function.
--* Signal and Sigaction:: How those two functions interact.
--* Sigaction Function Example:: An example of using the sigaction function.
--* Flags for Sigaction:: Specifying options for signal handling.
--* Initial Signal Actions:: How programs inherit signal actions.
--
--Defining Handlers
--
--* Handler Returns:: Handlers that return normally, and what
-- this means.
--* Termination in Handler:: How handler functions terminate a program.
--* Longjmp in Handler:: Nonlocal transfer of control out of a
-- signal handler.
--* Signals in Handler:: What happens when signals arrive while
-- the handler is already occupied.
--* Merged Signals:: When a second signal arrives before the
-- first is handled.
--* Nonreentrancy:: Do not call any functions unless you know they
-- are reentrant with respect to signals.
--* Atomic Data Access:: A single handler can run in the middle of
-- reading or writing a single object.
--
--Atomic Data Access
--
--* Non-atomic Example:: A program illustrating interrupted access.
--* Types: Atomic Types. Data types that guarantee no interruption.
--* Usage: Atomic Usage. Proving that interruption is harmless.
--
--Generating Signals
--
--* Signaling Yourself:: A process can send a signal to itself.
--* Signaling Another Process:: Send a signal to another process.
--* Permission for kill:: Permission for using `kill'.
--* Kill Example:: Using `kill' for Communication.
--
--Blocking Signals
--
--* Why Block:: The purpose of blocking signals.
--* Signal Sets:: How to specify which signals to
-- block.
--* Process Signal Mask:: Blocking delivery of signals to your
-- process during normal execution.
--* Testing for Delivery:: Blocking to Test for Delivery of
-- a Signal.
--* Blocking for Handler:: Blocking additional signals while a
-- handler is being run.
--* Checking for Pending Signals:: Checking for Pending Signals
--* Remembering a Signal:: How you can get almost the same
-- effect as blocking a signal, by
-- handling it and setting a flag
-- to be tested later.
--
--Waiting for a Signal
--
--* Using Pause:: The simple way, using `pause'.
--* Pause Problems:: Why the simple way is often not very good.
--* Sigsuspend:: Reliably waiting for a specific signal.
--
--BSD Signal Handling
--
--* BSD Handler:: BSD Function to Establish a Handler.
--* Blocking in BSD:: BSD Functions for Blocking Signals.
--
--Process Startup
--
--* Program Arguments:: Parsing your program's command-line arguments.
--* Environment Variables:: How to access parameters inherited from
-- a parent process.
--* Program Termination:: How to cause a process to terminate and
-- return status information to its parent.
--
--Program Arguments
--
--* Argument Syntax:: By convention, options start with a hyphen.
--* Parsing Program Arguments:: Ways to parse program options and arguments.
--
--Parsing Program Arguments
--
--* Getopt:: Parsing program options using `getopt'.
--* Argp:: Parsing program options using `argp_parse'.
--* Suboptions:: Some programs need more detailed options.
--* Suboptions Example:: This shows how it could be done for `mount'.
--
--Environment Variables
--
--* Environment Access:: How to get and set the values of
-- environment variables.
--* Standard Environment:: These environment variables have
-- standard interpretations.
--
--Program Termination
--
--* Normal Termination:: If a program calls `exit', a
-- process terminates normally.
--* Exit Status:: The `exit status' provides information
-- about why the process terminated.
--* Cleanups on Exit:: A process can run its own cleanup
-- functions upon normal termination.
--* Aborting a Program:: The `abort' function causes
-- abnormal program termination.
--* Termination Internals:: What happens when a process terminates.
--
--Processes
--
--* Running a Command:: The easy way to run another program.
--* Process Creation Concepts:: An overview of the hard way to do it.
--* Process Identification:: How to get the process ID of a process.
--* Creating a Process:: How to fork a child process.
--* Executing a File:: How to make a process execute another program.
--* Process Completion:: How to tell when a child process has completed.
--* Process Completion Status:: How to interpret the status value
-- returned from a child process.
--* BSD Wait Functions:: More functions, for backward compatibility.
--* Process Creation Example:: A complete example program.
--
--Job Control
--
--* Concepts of Job Control:: Jobs can be controlled by a shell.
--* Job Control is Optional:: Not all POSIX systems support job control.
--* Controlling Terminal:: How a process gets its controlling terminal.
--* Access to the Terminal:: How processes share the controlling terminal.
--* Orphaned Process Groups:: Jobs left after the user logs out.
--* Implementing a Shell:: What a shell must do to implement job control.
--* Functions for Job Control:: Functions to control process groups.
--
--Implementing a Shell
--
--* Data Structures:: Introduction to the sample shell.
--* Initializing the Shell:: What the shell must do to take
-- responsibility for job control.
--* Launching Jobs:: Creating jobs to execute commands.
--* Foreground and Background:: Putting a job in foreground of background.
--* Stopped and Terminated Jobs:: Reporting job status.
--* Continuing Stopped Jobs:: How to continue a stopped job in
-- the foreground or background.
--* Missing Pieces:: Other parts of the shell.
--
--Functions for Job Control
--
--* Identifying the Terminal:: Determining the controlling terminal's name.
--* Process Group Functions:: Functions for manipulating process groups.
--* Terminal Access Functions:: Functions for controlling terminal access.
--
--Name Service Switch
--
--* NSS Basics:: What is this NSS good for.
--* NSS Configuration File:: Configuring NSS.
--* NSS Module Internals:: How does it work internally.
--* Extending NSS:: What to do to add services or databases.
--
--NSS Configuration File
--
--* Services in the NSS configuration:: Service names in the NSS configuration.
--* Actions in the NSS configuration:: React appropriately to the lookup result.
--* Notes on NSS Configuration File:: Things to take care about while
-- configuring NSS.
--
--NSS Module Internals
--
--* NSS Module Names:: Construction of the interface function of
-- the NSS modules.
--* NSS Modules Interface:: Programming interface in the NSS module
-- functions.
--
--Extending NSS
--
--* Adding another Service to NSS:: What is to do to add a new service.
--* NSS Module Function Internals:: Guidelines for writing new NSS
-- service functions.
--
--Users and Groups
--
--* User and Group IDs:: Each user has a unique numeric ID;
-- likewise for groups.
--* Process Persona:: The user IDs and group IDs of a process.
--* Why Change Persona:: Why a program might need to change
-- its user and/or group IDs.
--* How Change Persona:: Changing the user and group IDs.
--* Reading Persona:: How to examine the user and group IDs.
--
--* Setting User ID:: Functions for setting the user ID.
--* Setting Groups:: Functions for setting the group IDs.
--
--* Enable/Disable Setuid:: Turning setuid access on and off.
--* Setuid Program Example:: The pertinent parts of one sample program.
--* Tips for Setuid:: How to avoid granting unlimited access.
--
--* Who Logged In:: Getting the name of the user who logged in,
-- or of the real user ID of the current process.
--
--* User Accounting Database:: Keeping information about users and various
-- actions in databases.
--
--* User Database:: Functions and data structures for
-- accessing the user database.
--* Group Database:: Functions and data structures for
-- accessing the group database.
--* Database Example:: Example program showing the use of database
-- inquiry functions.
--* Netgroup Database:: Functions for accessing the netgroup database.
--
--User Accounting Database
--
--* Manipulating the Database:: Scanning and modifying the user
-- accounting database.
--* XPG Functions:: A standardized way for doing the same thing.
--* Logging In and Out:: Functions from BSD that modify the user
-- accounting database.
--
--User Database
--
--* User Data Structure:: What each user record contains.
--* Lookup User:: How to look for a particular user.
--* Scanning All Users:: Scanning the list of all users, one by one.
--* Writing a User Entry:: How a program can rewrite a user's record.
--
--Group Database
--
--* Group Data Structure:: What each group record contains.
--* Lookup Group:: How to look for a particular group.
--* Scanning All Groups:: Scanning the list of all groups.
--
--Netgroup Database
--
--* Netgroup Data:: Data in the Netgroup database and where
-- it comes from.
--* Lookup Netgroup:: How to look for a particular netgroup.
--* Netgroup Membership:: How to test for netgroup membership.
--
--System Information
--
--* Host Identification:: Determining the name of the machine.
--* Hardware/Software Type ID:: Determining the hardware type of the
-- machine and what operating system it is
-- running.
--* Filesystem handling:: Which is mounted and/or available?
--
--System Configuration
--
--* General Limits:: Constants and functions that describe
-- various process-related limits that have
-- one uniform value for any given machine.
--* System Options:: Optional POSIX features.
--* Version Supported:: Version numbers of POSIX.1 and POSIX.2.
--* Sysconf:: Getting specific configuration values
-- of general limits and system options.
--* Minimums:: Minimum values for general limits.
--
--* Limits for Files:: Size limitations that pertain to individual files.
-- These can vary between file systems
-- or even from file to file.
--* Options for Files:: Optional features that some files may support.
--* File Minimums:: Minimum values for file limits.
--* Pathconf:: Getting the limit values for a particular file.
--
--* Utility Limits:: Capacity limits of some POSIX.2 utility programs.
--* Utility Minimums:: Minimum allowable values of those limits.
--
--* String Parameters:: Getting the default search path.
--
--Sysconf
--
--* Sysconf Definition:: Detailed specifications of `sysconf'.
--* Constants for Sysconf:: The list of parameters `sysconf' can read.
--* Examples of Sysconf:: How to use `sysconf' and the parameter
-- macros properly together.
--
--Cryptographic Functions
--
--* Legal Problems:: This software can get you locked up, or worse.
--* getpass:: Prompting the user for a password.
--* crypt:: A one-way function for UNIX passwords.
--* DES Encryption:: Routines for DES encryption.
--
--POSIX Threads
--
--* Basic Thread Operations:: Creating, terminating, and waiting for threads.
--* Thread Attributes:: Tuning thread scheduling.
--* Cancellation:: Stopping a thread before it's done.
--* Cleanup Handlers:: Deallocating resources when a thread is
-- cancelled.
--* Mutexes:: One way to synchronize threads.
--* Condition Variables:: Another way.
--* POSIX Semaphores:: And a third way.
--* Thread-Specific Data:: Variables with different values in
-- different threads.
--* Threads and Signal Handling:: Why you should avoid mixing the two, and
-- how to do it if you must.
--* Miscellaneous Thread Functions:: A grab bag of utility routines.
--
--Language Features
--
--* Consistency Checking:: Using `assert' to abort if
-- something "impossible" happens.
--* Variadic Functions:: Defining functions with varying numbers
-- of args.
--* Null Pointer Constant:: The macro `NULL'.
--* Important Data Types:: Data types for object sizes.
--* Data Type Measurements:: Parameters of data type representations.
--
--Variadic Functions
--
--* Why Variadic:: Reasons for making functions take
-- variable arguments.
--* How Variadic:: How to define and call variadic functions.
--* Variadic Example:: A complete example.
--
--How Variadic
--
--* Variadic Prototypes:: How to make a prototype for a function
-- with variable arguments.
--* Receiving Arguments:: Steps you must follow to access the
-- optional argument values.
--* How Many Arguments:: How to decide whether there are more arguments.
--* Calling Variadics:: Things you need to know about calling
-- variable arguments functions.
--* Argument Macros:: Detailed specification of the macros
-- for accessing variable arguments.
--* Old Varargs:: The pre-ISO way of defining variadic functions.
--
--Data Type Measurements
--
--* Width of Type:: How many bits does an integer type hold?
--* Range of Type:: What are the largest and smallest values
-- that an integer type can hold?
--* Floating Type Macros:: Parameters that measure the floating point types.
--* Structure Measurement:: Getting measurements on structure types.
--
--Floating Type Macros
--
--* Floating Point Concepts:: Definitions of terminology.
--* Floating Point Parameters:: Details of specific macros.
--* IEEE Floating Point:: The measurements for one common
-- representation.
--
--Installation
--
--* Configuring and compiling:: How to compile and test GNU libc.
--* Running make install:: How to install it once you've got it compiled.
--* Tools for Compilation:: You'll need these first.
--* Supported Configurations:: What it runs on, what it doesn't.
--* Linux:: Specific advice for Linux systems.
--* Reporting Bugs:: So they'll get fixed.
--
--Maintenance
--
--* Source Layout:: How to add new functions or header files
-- to the GNU C library.
--* Porting:: How to port the GNU C library to
-- a new machine or operating system.
--
--Porting
--
--* Hierarchy Conventions:: The layout of the `sysdeps' hierarchy.
--* Porting to Unix:: Porting the library to an average
-- Unix-like system.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-10 glibc-2.1.3/manual/libc.info-10
---- ../glibc-2.1.3/manual/libc.info-10 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-10 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1071 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Setting the Locale, Next: Standard Locales, Prev: Locale Categories, Up: Locales
--
--How Programs Set the Locale
--===========================
--
-- A C program inherits its locale environment variables when it starts
--up. This happens automatically. However, these variables do not
--automatically control the locale used by the library functions, because
--ISO C says that all programs start by default in the standard `C'
--locale. To use the locales specified by the environment, you must call
--`setlocale'. Call it as follows:
--
-- setlocale (LC_ALL, "");
--
--to select a locale based on the user choice of the appropriate
--environment variables.
--
-- You can also use `setlocale' to specify a particular locale, for
--general use or for a specific category.
--
-- The symbols in this section are defined in the header file
--`locale.h'.
--
-- - Function: char * setlocale (int CATEGORY, const char *LOCALE)
-- The function `setlocale' sets the current locale for category
-- CATEGORY to LOCALE.
--
-- If CATEGORY is `LC_ALL', this specifies the locale for all
-- purposes. The other possible values of CATEGORY specify an
-- individual purpose (*note Locale Categories::.).
--
-- You can also use this function to find out the current locale by
-- passing a null pointer as the LOCALE argument. In this case,
-- `setlocale' returns a string that is the name of the locale
-- currently selected for category CATEGORY.
--
-- The string returned by `setlocale' can be overwritten by subsequent
-- calls, so you should make a copy of the string (*note Copying and
-- Concatenation::.) if you want to save it past any further calls to
-- `setlocale'. (The standard library is guaranteed never to call
-- `setlocale' itself.)
--
-- You should not modify the string returned by `setlocale'. It
-- might be the same string that was passed as an argument in a
-- previous call to `setlocale'.
--
-- When you read the current locale for category `LC_ALL', the value
-- encodes the entire combination of selected locales for all
-- categories. In this case, the value is not just a single locale
-- name. In fact, we don't make any promises about what it looks
-- like. But if you specify the same "locale name" with `LC_ALL' in
-- a subsequent call to `setlocale', it restores the same combination
-- of locale selections.
--
-- To ensure to be able to use the string encoding the currently
-- selected locale at a later time one has to make a copy of the
-- string. It is not guaranteed that the return value stays valid
-- all the time.
--
-- When the LOCALE argument is not a null pointer, the string returned
-- by `setlocale' reflects the newly modified locale.
--
-- If you specify an empty string for LOCALE, this means to read the
-- appropriate environment variable and use its value to select the
-- locale for CATEGORY.
--
-- If a nonempty string is given for LOCALE the locale with this name
-- is used, if this is possible.
--
-- If you specify an invalid locale name, `setlocale' returns a null
-- pointer and leaves the current locale unchanged.
--
-- Here is an example showing how you might use `setlocale' to
--temporarily switch to a new locale.
--
-- #include <stddef.h>
-- #include <locale.h>
-- #include <stdlib.h>
-- #include <string.h>
--
-- void
-- with_other_locale (char *new_locale,
-- void (*subroutine) (int),
-- int argument)
-- {
-- char *old_locale, *saved_locale;
--
-- /* Get the name of the current locale. */
-- old_locale = setlocale (LC_ALL, NULL);
--
-- /* Copy the name so it won't be clobbered by `setlocale'. */
-- saved_locale = strdup (old_locale);
-- if (saved_locale == NULL)
-- fatal ("Out of memory");
--
-- /* Now change the locale and do some stuff with it. */
-- setlocale (LC_ALL, new_locale);
-- (*subroutine) (argument);
--
-- /* Restore the original locale. */
-- setlocale (LC_ALL, saved_locale);
-- free (saved_locale);
-- }
--
-- *Portability Note:* Some ISO C systems may define additional locale
--categories and future versions of the library will do so. For
--portability, assume that any symbol beginning with `LC_' might be
--defined in `locale.h'.
--
--
--File: libc.info, Node: Standard Locales, Next: Locale Information, Prev: Setting the Locale, Up: Locales
--
--Standard Locales
--================
--
-- The only locale names you can count on finding on all operating
--systems are these three standard ones:
--
--`"C"'
-- This is the standard C locale. The attributes and behavior it
-- provides are specified in the ISO C standard. When your program
-- starts up, it initially uses this locale by default.
--
--`"POSIX"'
-- This is the standard POSIX locale. Currently, it is an alias for
-- the standard C locale.
--
--`""'
-- The empty name says to select a locale based on environment
-- variables. *Note Locale Categories::.
--
-- Defining and installing named locales is normally a responsibility of
--the system administrator at your site (or the person who installed the
--GNU C library). It is also possible for the user to create private
--locales. All this will be discussed later when describing the tool to
--do so XXX.
--
-- If your program needs to use something other than the `C' locale, it
--will be more portable if you use whatever locale the user specifies
--with the environment, rather than trying to specify some non-standard
--locale explicitly by name. Remember, different machines might have
--different sets of locales installed.
--
--
--File: libc.info, Node: Locale Information, Next: Formatting Numbers, Prev: Standard Locales, Up: Locales
--
--Accessing the Locale Information
--================================
--
-- There are several ways to access the locale information. The
--simplest way is to let the C library itself do the work. Several of the
--functions in this library access implicitly the locale data and use
--what information is available in the currently selected locale. This is
--how the locale model is meant to work normally.
--
-- As an example take the `strftime' function which is meant to nicely
--format date and time information (*note Formatting Date and Time::.).
--Part of the standard information contained in the `LC_TIME' category
--are, e.g., the names of the months. Instead of requiring the
--programmer to take care of providing the translations the `strftime'
--function does this all by itself. When using `%A' in the format string
--this will be replaced by the appropriate weekday name of the locale
--currently selected for `LC_TIME'. This is the easy part and wherever
--possible functions do things automatically as in this case.
--
-- But there are quite often situations when there is simply no
--functions to perform the task or it is simply not possible to do the
--work automatically. For these cases it is necessary to access the
--information in the locale directly. To do this the C library provides
--two functions: `localeconv' and `nl_langinfo'. The former is part of
--ISO C and therefore portable, but has a brain-damaged interface. The
--second is part of the Unix interface and is portable in as far as the
--system follows the Unix standards.
--
--* Menu:
--
--* The Lame Way to Locale Data:: ISO C's `localeconv'.
--* The Elegant and Fast Way:: X/Open's `nl_langinfo'.
--
--
--File: libc.info, Node: The Lame Way to Locale Data, Next: The Elegant and Fast Way, Up: Locale Information
--
--`localeconv': It is portable but ...
--------------------------------------
--
-- Together with the `setlocale' function the ISO C people invented
--`localeconv' function. It is a masterpiece of misdesign. It is
--expensive to use, it is not extendable, and is not generally usable as
--it provides access only to the `LC_MONETARY' and `LC_NUMERIC' related
--information. If it is applicable for a certain situation it should
--nevertheless be used since it is very portable. In general it is
--better to use the function `strfmon' which can be used to format
--monetary amounts correctly according to the selected locale by
--implicitly using this information.
--
-- - Function: struct lconv * localeconv (void)
-- The `localeconv' function returns a pointer to a structure whose
-- components contain information about how numeric and monetary
-- values should be formatted in the current locale.
--
-- You should not modify the structure or its contents. The
-- structure might be overwritten by subsequent calls to
-- `localeconv', or by calls to `setlocale', but no other function in
-- the library overwrites this value.
--
-- - Data Type: struct lconv
-- This is the data type of the value returned by `localeconv'. Its
-- elements are described in the following subsections.
--
-- If a member of the structure `struct lconv' has type `char', and the
--value is `CHAR_MAX', it means that the current locale has no value for
--that parameter.
--
--* Menu:
--
--* General Numeric:: Parameters for formatting numbers and
-- currency amounts.
--* Currency Symbol:: How to print the symbol that identifies an
-- amount of money (e.g. `$').
--* Sign of Money Amount:: How to print the (positive or negative) sign
-- for a monetary amount, if one exists.
--
--
--File: libc.info, Node: General Numeric, Next: Currency Symbol, Up: The Lame Way to Locale Data
--
--Generic Numeric Formatting Parameters
--.....................................
--
-- These are the standard members of `struct lconv'; there may be
--others.
--
--`char *decimal_point'
--`char *mon_decimal_point'
-- These are the decimal-point separators used in formatting
-- non-monetary and monetary quantities, respectively. In the `C'
-- locale, the value of `decimal_point' is `"."', and the value of
-- `mon_decimal_point' is `""'.
--
--`char *thousands_sep'
--`char *mon_thousands_sep'
-- These are the separators used to delimit groups of digits to the
-- left of the decimal point in formatting non-monetary and monetary
-- quantities, respectively. In the `C' locale, both members have a
-- value of `""' (the empty string).
--
--`char *grouping'
--`char *mon_grouping'
-- These are strings that specify how to group the digits to the left
-- of the decimal point. `grouping' applies to non-monetary
-- quantities and `mon_grouping' applies to monetary quantities. Use
-- either `thousands_sep' or `mon_thousands_sep' to separate the digit
-- groups.
--
-- Each string is made up of decimal numbers separated by semicolons.
-- Successive numbers (from left to right) give the sizes of
-- successive groups (from right to left, starting at the decimal
-- point). The last number in the string is used over and over for
-- all the remaining groups.
--
-- If the last integer is `-1', it means that there is no more
-- grouping--or, put another way, any remaining digits form one large
-- group without separators.
--
-- For example, if `grouping' is `"4;3;2"', the correct grouping for
-- the number `123456787654321' is `12', `34', `56', `78', `765',
-- `4321'. This uses a group of 4 digits at the end, preceded by a
-- group of 3 digits, preceded by groups of 2 digits (as many as
-- needed). With a separator of `,', the number would be printed as
-- `12,34,56,78,765,4321'.
--
-- A value of `"3"' indicates repeated groups of three digits, as
-- normally used in the U.S.
--
-- In the standard `C' locale, both `grouping' and `mon_grouping'
-- have a value of `""'. This value specifies no grouping at all.
--
--`char int_frac_digits'
--`char frac_digits'
-- These are small integers indicating how many fractional digits (to
-- the right of the decimal point) should be displayed in a monetary
-- value in international and local formats, respectively. (Most
-- often, both members have the same value.)
--
-- In the standard `C' locale, both of these members have the value
-- `CHAR_MAX', meaning "unspecified". The ISO standard doesn't say
-- what to do when you find this the value; we recommend printing no
-- fractional digits. (This locale also specifies the empty string
-- for `mon_decimal_point', so printing any fractional digits would be
-- confusing!)
--
--
--File: libc.info, Node: Currency Symbol, Next: Sign of Money Amount, Prev: General Numeric, Up: The Lame Way to Locale Data
--
--Printing the Currency Symbol
--............................
--
-- These members of the `struct lconv' structure specify how to print
--the symbol to identify a monetary value--the international analog of
--`$' for US dollars.
--
-- Each country has two standard currency symbols. The "local currency
--symbol" is used commonly within the country, while the "international
--currency symbol" is used internationally to refer to that country's
--currency when it is necessary to indicate the country unambiguously.
--
-- For example, many countries use the dollar as their monetary unit,
--and when dealing with international currencies it's important to specify
--that one is dealing with (say) Canadian dollars instead of U.S. dollars
--or Australian dollars. But when the context is known to be Canada,
--there is no need to make this explicit--dollar amounts are implicitly
--assumed to be in Canadian dollars.
--
--`char *currency_symbol'
-- The local currency symbol for the selected locale.
--
-- In the standard `C' locale, this member has a value of `""' (the
-- empty string), meaning "unspecified". The ISO standard doesn't
-- say what to do when you find this value; we recommend you simply
-- print the empty string as you would print any other string found
-- in the appropriate member.
--
--`char *int_curr_symbol'
-- The international currency symbol for the selected locale.
--
-- The value of `int_curr_symbol' should normally consist of a
-- three-letter abbreviation determined by the international standard
-- `ISO 4217 Codes for the Representation of Currency and Funds',
-- followed by a one-character separator (often a space).
--
-- In the standard `C' locale, this member has a value of `""' (the
-- empty string), meaning "unspecified". We recommend you simply
-- print the empty string as you would print any other string found
-- in the appropriate member.
--
--`char p_cs_precedes'
--`char n_cs_precedes'
-- These members are `1' if the `currency_symbol' string should
-- precede the value of a monetary amount, or `0' if the string should
-- follow the value. The `p_cs_precedes' member applies to positive
-- amounts (or zero), and the `n_cs_precedes' member applies to
-- negative amounts.
--
-- In the standard `C' locale, both of these members have a value of
-- `CHAR_MAX', meaning "unspecified". The ISO standard doesn't say
-- what to do when you find this value, but we recommend printing the
-- currency symbol before the amount. That's right for most
-- countries. In other words, treat all nonzero values alike in
-- these members.
--
-- The POSIX standard says that these two members apply to the
-- `int_curr_symbol' as well as the `currency_symbol'. The ISO C
-- standard seems to imply that they should apply only to the
-- `currency_symbol'--so the `int_curr_symbol' should always precede
-- the amount.
--
-- We can only guess which of these (if either) matches the usual
-- conventions for printing international currency symbols. Our
-- guess is that they should always precede the amount. If we find
-- out a reliable answer, we will put it here.
--
--`char p_sep_by_space'
--`char n_sep_by_space'
-- These members are `1' if a space should appear between the
-- `currency_symbol' string and the amount, or `0' if no space should
-- appear. The `p_sep_by_space' member applies to positive amounts
-- (or zero), and the `n_sep_by_space' member applies to negative
-- amounts.
--
-- In the standard `C' locale, both of these members have a value of
-- `CHAR_MAX', meaning "unspecified". The ISO standard doesn't say
-- what you should do when you find this value; we suggest you treat
-- it as one (print a space). In other words, treat all nonzero
-- values alike in these members.
--
-- These members apply only to `currency_symbol'. When you use
-- `int_curr_symbol', you never print an additional space, because
-- `int_curr_symbol' itself contains the appropriate separator.
--
-- The POSIX standard says that these two members apply to the
-- `int_curr_symbol' as well as the `currency_symbol'. But an
-- example in the ISO C standard clearly implies that they should
-- apply only to the `currency_symbol'--that the `int_curr_symbol'
-- contains any appropriate separator, so you should never print an
-- additional space.
--
-- Based on what we know now, we recommend you ignore these members
-- when printing international currency symbols, and print no extra
-- space.
--
--
--File: libc.info, Node: Sign of Money Amount, Prev: Currency Symbol, Up: The Lame Way to Locale Data
--
--Printing the Sign of an Amount of Money
--.......................................
--
-- These members of the `struct lconv' structure specify how to print
--the sign (if any) in a monetary value.
--
--`char *positive_sign'
--`char *negative_sign'
-- These are strings used to indicate positive (or zero) and negative
-- (respectively) monetary quantities.
--
-- In the standard `C' locale, both of these members have a value of
-- `""' (the empty string), meaning "unspecified".
--
-- The ISO standard doesn't say what to do when you find this value;
-- we recommend printing `positive_sign' as you find it, even if it is
-- empty. For a negative value, print `negative_sign' as you find it
-- unless both it and `positive_sign' are empty, in which case print
-- `-' instead. (Failing to indicate the sign at all seems rather
-- unreasonable.)
--
--`char p_sign_posn'
--`char n_sign_posn'
-- These members have values that are small integers indicating how to
-- position the sign for nonnegative and negative monetary quantities,
-- respectively. (The string used by the sign is what was specified
-- with `positive_sign' or `negative_sign'.) The possible values are
-- as follows:
--
-- `0'
-- The currency symbol and quantity should be surrounded by
-- parentheses.
--
-- `1'
-- Print the sign string before the quantity and currency symbol.
--
-- `2'
-- Print the sign string after the quantity and currency symbol.
--
-- `3'
-- Print the sign string right before the currency symbol.
--
-- `4'
-- Print the sign string right after the currency symbol.
--
-- `CHAR_MAX'
-- "Unspecified". Both members have this value in the standard
-- `C' locale.
--
-- The ISO standard doesn't say what you should do when the value is
-- `CHAR_MAX'. We recommend you print the sign after the currency
-- symbol.
--
-- It is not clear whether you should let these members apply to the
--international currency format or not. POSIX says you should, but
--intuition plus the examples in the ISO C standard suggest you should
--not. We hope that someone who knows well the conventions for formatting
--monetary quantities will tell us what we should recommend.
--
--
--File: libc.info, Node: The Elegant and Fast Way, Prev: The Lame Way to Locale Data, Up: Locale Information
--
--Pinpoint Access to Locale Data
--------------------------------
--
-- When writing the X/Open Portability Guide the authors realized that
--the `localeconv' function is not enough to provide reasonable access to
--the locale information. The information which was meant to be available
--in the locale (as later specified in the POSIX.1 standard) requires more
--possibilities to access it. Therefore the `nl_langinfo' function was
--introduced.
--
-- - Function: char * nl_langinfo (nl_item ITEM)
-- The `nl_langinfo' function can be used to access individual
-- elements of the locale categories. I.e., unlike the `localeconv'
-- function which always returns all the information `nl_langinfo'
-- lets the caller select what information is necessary. This is very
-- fast and it is no problem to call this function multiple times.
--
-- The second advantage is that not only the numeric and monetary
-- formatting information is available. Also the information of the
-- `LC_TIME' and `LC_MESSAGES' categories is available.
--
-- The type `nl_type' is defined in `nl_types.h'. The argument ITEM
-- is a numeric values which must be one of the values defined in the
-- header `langinfo.h'. The X/Open standard defines the following
-- values:
--
-- `ABDAY_1'
-- `ABDAY_2'
-- `ABDAY_3'
-- `ABDAY_4'
-- `ABDAY_5'
-- `ABDAY_6'
-- `ABDAY_7'
-- `nl_langinfo' returns the abbreviated weekday name. `ABDAY_1'
-- corresponds to Sunday.
--
-- `DAY_1'
-- `DAY_2'
-- `DAY_3'
-- `DAY_4'
-- `DAY_5'
-- `DAY_6'
-- `DAY_7'
-- Similar to `ABDAY_1' etc, but here the return value is the
-- unabbreviated weekday name.
--
-- `ABMON_1'
-- `ABMON_2'
-- `ABMON_3'
-- `ABMON_4'
-- `ABMON_5'
-- `ABMON_6'
-- `ABMON_7'
-- `ABMON_8'
-- `ABMON_9'
-- `ABMON_10'
-- `ABMON_11'
-- `ABMON_12'
-- The return value is abbreviated name for the month names.
-- `ABMON_1' corresponds to January.
--
-- `MON_1'
-- `MON_2'
-- `MON_3'
-- `MON_4'
-- `MON_5'
-- `MON_6'
-- `MON_7'
-- `MON_8'
-- `MON_9'
-- `MON_10'
-- `MON_11'
-- `MON_12'
-- Similar to `ABMON_1' etc but here the month names are not
-- abbreviated. Here the first value `MON_1' also corresponds
-- to January.
--
-- `AM_STR'
-- `PM_STR'
-- The return values are strings which can be used in the time
-- representation which uses to American 1 to 12 hours plus
-- am/pm representation.
--
-- Please note that in locales which do not know this time
-- representation these strings actually might be empty and
-- therefore the am/pm format cannot be used at all.
--
-- `D_T_FMT'
-- The return value can be used as a format string for
-- `strftime' to represent time and date in a locale specific
-- way.
--
-- `D_FMT'
-- The return value can be used as a format string for
-- `strftime' to represent a date in a locale specific way.
--
-- `T_FMT'
-- The return value can be used as a format string for
-- `strftime' to represent time in a locale specific way.
--
-- `T_FMT_AMPM'
-- The return value can be used as a format string for
-- `strftime' to represent time using the American-style am/pm
-- format.
--
-- Please note that if the am/pm format does not make any sense
-- for the selected locale the returned value might be the same
-- as the one for `T_FMT'.
--
-- `ERA'
-- The return value is value representing the eras of time used
-- in the current locale.
--
-- Most locales do not define this value. An example for a
-- locale which does define this value is the Japanese. Here
-- the traditional data representation is based on the eras
-- measured by the reigns of the emperors.
--
-- Normally it should not be necessary to use this value
-- directly. Using the `E' modifier for its formats the
-- `strftime' functions can be made to use this information.
-- The format of the returned string is not specified and
-- therefore one should not generalize the knowledge about the
-- representation on one system.
--
-- `ERA_YEAR'
-- The return value describes the name years for the eras of
-- this locale. As for `ERA' it should not be necessary to use
-- this value directly.
--
-- `ERA_D_T_FMT'
-- This return value can be used as a format string for
-- `strftime' to represent time and date using the era
-- representation in a locale specific way.
--
-- `ERA_D_FMT'
-- This return value can be used as a format string for
-- `strftime' to represent a date using the era representation
-- in a locale specific way.
--
-- `ERA_T_FMT'
-- This return value can be used as a format string for
-- `strftime' to represent time using the era representation in
-- a locale specific way.
--
-- `ALT_DIGITS'
-- The return value is a representation of up to 100 values used
-- to represent the values 0 to 99. As for `ERA' this value is
-- not intended to be used directly, but instead indirectly
-- through the `strftime' function. When the modifier `O' is
-- used for format which would use numerals to represent hours,
-- minutes, seconds, weekdays, months, or weeks the appropriate
-- value for this locale values is used instead of the number.
--
-- `INT_CURR_SYMBOL'
-- This value is the same as returned by `localeconv' in the
-- `int_curr_symbol' element of the `struct lconv'.
--
-- `CURRENCY_SYMBOL'
-- `CRNCYSTR'
-- This value is the same as returned by `localeconv' in the
-- `currency_symbol' element of the `struct lconv'.
--
-- `CRNCYSTR' is a deprecated alias, still required by Unix98.
--
-- `MON_DECIMAL_POINT'
-- This value is the same as returned by `localeconv' in the
-- `mon_decimal_point' element of the `struct lconv'.
--
-- `MON_THOUSANDS_SEP'
-- This value is the same as returned by `localeconv' in the
-- `mon_thousands_sep' element of the `struct lconv'.
--
-- `MON_GROUPING'
-- This value is the same as returned by `localeconv' in the
-- `mon_grouping' element of the `struct lconv'.
--
-- `POSITIVE_SIGN'
-- This value is the same as returned by `localeconv' in the
-- `positive_sign' element of the `struct lconv'.
--
-- `NEGATIVE_SIGN'
-- This value is the same as returned by `localeconv' in the
-- `negative_sign' element of the `struct lconv'.
--
-- `INT_FRAC_DIGITS'
-- This value is the same as returned by `localeconv' in the
-- `int_frac_digits' element of the `struct lconv'.
--
-- `FRAC_DIGITS'
-- This value is the same as returned by `localeconv' in the
-- `frac_digits' element of the `struct lconv'.
--
-- `P_CS_PRECEDES'
-- This value is the same as returned by `localeconv' in the
-- `p_cs_precedes' element of the `struct lconv'.
--
-- `P_SEP_BY_SPACE'
-- This value is the same as returned by `localeconv' in the
-- `p_sep_by_space' element of the `struct lconv'.
--
-- `N_CS_PRECEDES'
-- This value is the same as returned by `localeconv' in the
-- `n_cs_precedes' element of the `struct lconv'.
--
-- `N_SEP_BY_SPACE'
-- This value is the same as returned by `localeconv' in the
-- `n_sep_by_space' element of the `struct lconv'.
--
-- `P_SIGN_POSN'
-- This value is the same as returned by `localeconv' in the
-- `p_sign_posn' element of the `struct lconv'.
--
-- `N_SIGN_POSN'
-- This value is the same as returned by `localeconv' in the
-- `n_sign_posn' element of the `struct lconv'.
--
-- `DECIMAL_POINT'
-- `RADIXCHAR'
-- This value is the same as returned by `localeconv' in the
-- `decimal_point' element of the `struct lconv'.
--
-- The name `RADIXCHAR' is a deprecated alias still used in
-- Unix98.
--
-- `THOUSANDS_SEP'
-- `THOUSEP'
-- This value is the same as returned by `localeconv' in the
-- `thousands_sep' element of the `struct lconv'.
--
-- The name `THOUSEP' is a deprecated alias still used in Unix98.
--
-- `GROUPING'
-- This value is the same as returned by `localeconv' in the
-- `grouping' element of the `struct lconv'.
--
-- `YESEXPR'
-- The return value is a regular expression which can be used
-- with the `regex' function to recognize a positive response to
-- a yes/no question.
--
-- `NOEXPR'
-- The return value is a regular expression which can be used
-- with the `regex' function to recognize a negative response to
-- a yes/no question.
--
-- `YESSTR'
-- The return value is a locale specific translation of the
-- positive response to a yes/no question.
--
-- Using this value is deprecated since it is a very special
-- case of message translation and this better can be handled
-- using the message translation functions (*note Message
-- Translation::.).
--
-- `NOSTR'
-- The return value is a locale specific translation of the
-- negative response to a yes/no question. What is said for
-- `YESSTR' is also true here.
--
-- The file `langinfo.h' defines a lot more symbols but none of them
-- is official. Using them is completely unportable and the format
-- of the return values might change. Therefore it is highly
-- requested to not use them in any situation.
--
-- Please note that the return value for any valid argument can be
-- used for in all situations (with the possible exception of the
-- am/pm time format related values). If the user has not selected
-- any locale for the appropriate category `nl_langinfo' returns the
-- information from the `"C"' locale. It is therefore possible to
-- use this function as shown in the example below.
--
-- If the argument ITEM is not valid the global variable ERRNO is set
-- to `EINVAL' and a `NULL' pointer is returned.
--
-- An example for the use of `nl_langinfo' is a function which has to
--print a given date and time in the locale specific way. At first one
--might think the since `strftime' internally uses the locale information
--writing something like the following is enough:
--
-- size_t
-- i18n_time_n_data (char *s, size_t len, const struct tm *tp)
-- {
-- return strftime (s, len, "%X %D", tp);
-- }
--
-- The format contains no weekday or month names and therefore is
--internationally usable. Wrong! The output produced is something like
--`"hh:mm:ss MM/DD/YY"'. This format is only recognizable in the USA.
--Other countries use different formats. Therefore the function should
--be rewritten like this:
--
-- size_t
-- i18n_time_n_data (char *s, size_t len, const struct tm *tp)
-- {
-- return strftime (s, len, nl_langinfo (D_T_FMT), tp);
-- }
--
-- Now the date and time format which is explicitly selected for the
--locale in place when the program runs is used. If the user selects the
--locale correctly there should never be a misunderstanding over the time
--and date format.
--
--
--File: libc.info, Node: Formatting Numbers, Prev: Locale Information, Up: Locales
--
--A dedicated function to format numbers
--======================================
--
-- We have seen that the structure returned by `localeconv' as well as
--the values given to `nl_langinfo' allow to retrieve the various pieces
--of locale specific information to format numbers and monetary amounts.
--But we have also seen that the rules underlying this information are
--quite complex.
--
-- Therefore the X/Open standards introduce a function which uses this
--information from the locale and so makes it is for the user to format
--numbers according to these rules.
--
-- - Function: ssize_t strfmon (char *S, size_t MAXSIZE, const char
-- *FORMAT, ...)
-- The `strfmon' function is similar to the `strftime' function in
-- that it takes a description of a buffer (with size), a format
-- string and values to write into a buffer a textual representation
-- of the values according to the format string. As for `strftime'
-- the function also returns the number of bytes written into the
-- buffer.
--
-- There are two difference: `strfmon' can take more than one argument
-- and of course the format specification is different. The format
-- string consists as for `strftime' of normal text which is simply
-- printed and format specifiers, which here are also introduced
-- using `%'. Following the `%' the function allows similar to
-- `printf' a sequence of flags and other specifications before the
-- format character:
--
-- * Immediately following the `%' there can be one or more of the
-- following flags:
-- `=F'
-- The single byte character F is used for this field as
-- the numeric fill character. By default this character
-- is a space character. Filling with this character is
-- only performed if a left precision is specified. It is
-- not just to fill to the given field width.
--
-- `^'
-- The number is printed without grouping the digits using
-- the rules of the current locale. By default grouping is
-- enabled.
--
-- `+', `('
-- At most one of these flags must be used. They select
-- which format to represent the sign of currency amount is
-- used. By default and if `+' is used the locale
-- equivalent to +/- is used. If `(' is used negative
-- amounts are enclosed in parentheses. The exact format
-- is determined by the values of the `LC_MONETARY'
-- category of the locale selected at program runtime.
--
-- `!'
-- The output will not contain the currency symbol.
--
-- `-'
-- The output will be formatted right-justified instead
-- left-justified if the output does not fill the entire
-- field width.
--
-- The next part of a specification is an, again optional,
-- specification of the field width. The width is given by digits
-- following the flags. If no width is specified it is assumed to be
-- 0. The width value is used after it is determined how much space
-- the printed result needs. If it does not require fewer characters
-- than specified by the width value nothing happens. Otherwise the
-- output is extended to use as many characters as the width says by
-- filling with spaces. At which side depends on whether the `-'
-- flag was given or not. If it was given, the spaces are added at
-- the right, making the output right-justified and vice versa.
--
-- So far the format looks familiar as it is similar to `printf' or
-- `strftime' formats. But the next two fields introduce something
-- new. The first one, if available, is introduced by a `#' character
-- which is followed by a decimal digit string. The value of the
-- digit string specifies the width the formatted digits left to the
-- radix character. This does *not* include the grouping character
-- needed if the `^' flag is not given. If the space needed to print
-- the number does not fill the whole width the field is padded at
-- the left side with the fill character which can be selected using
-- the `=' flag and which by default is a space. For example, if the
-- field width is selected as 6 and the number is 123, the fill
-- character is `*' the result will be `***123'.
--
-- The next field is introduced by a `.' (period) and consists of
-- another decimal digit string. Its value describes the number of
-- characters printed after the radix character. The default is
-- selected from the current locale (`frac_digits',
-- `int_frac_digits', see *note General Numeric::.). If the exact
-- representation needs more digits than those specified by the field
-- width the displayed value is rounded. In case the number of
-- fractional digits is selected to be zero, no radix character is
-- printed.
--
-- As a GNU extension the `strfmon' implementation in the GNU libc
-- allows as the next field an optional `L' as a format modifier. If
-- this modifier is given the argument is expected to be a `long
-- double' instead of a `double' value.
--
-- Finally as the last component of the format there must come a
-- format specifying. There are three specifiers defined:
--
-- `i'
-- The argument is formatted according to the locale's rules to
-- format an international currency value.
--
-- `n'
-- The argument is formatted according to the locale's rules to
-- format an national currency value.
--
-- `%'
-- Creates a `%' in the output. There must be no flag, width
-- specifier or modifier given, only `%%' is allowed.
--
-- As it is done for `printf', the function reads the format string
-- from left to right and uses the values passed to the function
-- following the format string. The values are expected to be either
-- of type `double' or `long double', depending on the presence of the
-- modifier `L'. The result is stored in the buffer pointed to by S.
-- At most MAXSIZE characters are stored.
--
-- The return value of the function is the number of characters
-- stored in S, including the terminating NUL byte. If the number of
-- characters stored would exceed MAXSIZE the function returns -1 and
-- the content of the buffer S is unspecified. In this case `errno'
-- is set to `E2BIG'.
--
-- A few examples should make it clear how to use this function. It is
--assumed that all the following pieces of code are executed in a program
--which uses the locale valid for the USA (`en_US'). The simplest form
--of the format is this:
--
-- strfmon (buf, 100, "@%n@%n@%n@", 123.45, -567.89, 12345.678);
--
--The output produced is
-- "@$123.45@-$567.89@$12,345.68@"
--
-- We can notice several things here. First, the width for all formats
--is different. We have not specified a width in the format string and so
--this is no wonder. Second, the third number is printed using thousands
--separators. The thousands separator for the `en_US' locale is a comma.
--Beside this the number is rounded. The .678 are rounded to .68 since
--the format does not specify a precision and the default value in the
--locale is 2. A last thing is that the national currency symbol is
--printed since `%n' was used, not `i'. The next example shows how we
--can align the output.
--
-- strfmon (buf, 100, "@%=*11n@%=*11n@%=*11n@", 123.45, -567.89, 12345.678);
--
--The output this time is:
--
-- "@ $123.45@ -$567.89@ $12,345.68@"
--
-- Two things stand out. First, all fields have the same width (eleven
--characters) since this is the width given in the format and since no
--number required more characters to be printed. The second important
--point is that the fill character is not used. This is correct since the
--white space was not used to fill the space specified by the right
--precision, but instead it is used to fill to the given width. The
--difference becomes obvious if we now add a right width specification.
--
-- strfmon (buf, 100, "@%=*11#5n@%=*11#5n@%=*11#5n@",
-- 123.45, -567.89, 12345.678);
--
--The output is
--
-- "@ $***123.45@-$***567.89@ $12,456.68@"
--
-- Here we can see that all the currency symbols are now aligned and the
--space between the currency sign and the number is filled with the
--selected fill character. Please note that although the right precision
--is selected to be 5 and 123.45 has three characters right of the radix
--character, the space is filled with three asterisks. This is correct
--since as explained above, the right precision does not count the
--characters used for the thousands separators in. One last example
--should explain the remaining functionality.
--
-- strfmon (buf, 100, "@%=0(16#5.3i@%=0(16#5.3i@%=0(16#5.3i@",
-- 123.45, -567.89, 12345.678);
--
--This rather complex format string produces the following output:
--
-- "@ USD 000123,450 @(USD 000567.890)@ USD 12,345.678 @"
--
-- The most noticeable change is the use of the alternative style to
--represent negative numbers. In financial circles it is often done using
--parentheses and this is what the `(' flag selected. The fill character
--is now `0'. Please note that this `0' character is not regarded as a
--numeric zero and therefore the first and second number are not printed
--using a thousands separator. Since we use in the format the specifier
--`i' instead of `n' now the international form of the currency symbol is
--used. This is a four letter string, in this case `"USD "'. The last
--point is that since the left precision is selected to be three the
--first and second number are printed with an extra zero at the end and
--the third number is printed unrounded.
--
--
--File: libc.info, Node: Message Translation, Next: Searching and Sorting, Prev: Locales, Up: Top
--
--Message Translation
--*******************
--
-- The program's interface with the human should be designed in a way to
--ease the human the task. One of the possibilities is to use messages in
--whatever language the user prefers.
--
-- Printing messages in different languages can be implemented in
--different ways. One could add all the different languages in the
--source code and add among the variants every time a message has to be
--printed. This is certainly no good solution since extending the set of
--languages is difficult (the code must be changed) and the code itself
--can become really big with dozens of message sets.
--
-- A better solution is to keep the message sets for each language are
--kept in separate files which are loaded at runtime depending on the
--language selection of the user.
--
-- The GNU C Library provides two different sets of functions to support
--message translation. The problem is that neither of the interfaces is
--officially defined by the POSIX standard. The `catgets' family of
--functions is defined in the X/Open standard but this is derived from
--industry decisions and therefore not necessarily based on reasonable
--decisions.
--
-- As mentioned above the message catalog handling provides easy
--extendibility by using external data files which contain the message
--translations. I.e., these files contain for each of the messages used
--in the program a translation for the appropriate language. So the tasks
--of the message handling functions are
--
-- * locate the external data file with the appropriate translations.
--
-- * load the data and make it possible to address the messages
--
-- * map a given key to the translated message
--
-- The two approaches mainly differ in the implementation of this last
--step. The design decisions made for this influences the whole rest.
--
--* Menu:
--
--* Message catalogs a la X/Open:: The `catgets' family of functions.
--* The Uniforum approach:: The `gettext' family of functions.
--
--
--File: libc.info, Node: Message catalogs a la X/Open, Next: The Uniforum approach, Up: Message Translation
--
--X/Open Message Catalog Handling
--===============================
--
-- The `catgets' functions are based on the simple scheme:
--
-- Associate every message to translate in the source code with a
-- unique identifier. To retrieve a message from a catalog file
-- solely the identifier is used.
--
-- This means for the author of the program that s/he will have to make
--sure the meaning of the identifier in the program code and in the
--message catalogs are always the same.
--
-- Before a message can be translated the catalog file must be located.
--The user of the program must be able to guide the responsible function
--to find whatever catalog the user wants. This is separated from what
--the programmer had in mind.
--
-- All the types, constants and functions for the `catgets' functions
--are defined/declared in the `nl_types.h' header file.
--
--* Menu:
--
--* The catgets Functions:: The `catgets' function family.
--* The message catalog files:: Format of the message catalog files.
--* The gencat program:: How to generate message catalogs files which
-- can be used by the functions.
--* Common Usage:: How to use the `catgets' interface.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-11 glibc-2.1.3/manual/libc.info-11
---- ../glibc-2.1.3/manual/libc.info-11 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-11 1969-12-31 16:00:00.000000000 -0800
-@@ -1,949 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: The catgets Functions, Next: The message catalog files, Up: Message catalogs a la X/Open
--
--The `catgets' function family
-------------------------------
--
-- - Function: nl_catd catopen (const char *CAT_NAME, int FLAG)
-- The `catgets' function tries to locate the message data file names
-- CAT_NAME and loads it when found. The return value is of an
-- opaque type and can be used in calls to the other functions to
-- refer to this loaded catalog.
--
-- The return value is `(nl_catd) -1' in case the function failed and
-- no catalog was loaded. The global variable ERRNO contains a code
-- for the error causing the failure. But even if the function call
-- succeeded this does not mean that all messages can be translated.
--
-- Locating the catalog file must happen in a way which lets the user
-- of the program influence the decision. It is up to the user to
-- decide about the language to use and sometimes it is useful to use
-- alternate catalog files. All this can be specified by the user by
-- setting some environment variables.
--
-- The first problem is to find out where all the message catalogs are
-- stored. Every program could have its own place to keep all the
-- different files but usually the catalog files are grouped by
-- languages and the catalogs for all programs are kept in the same
-- place.
--
-- To tell the `catopen' function where the catalog for the program
-- can be found the user can set the environment variable `NLSPATH' to
-- a value which describes her/his choice. Since this value must be
-- usable for different languages and locales it cannot be a simple
-- string. Instead it is a format string (similar to `printf''s).
-- An example is
--
-- /usr/share/locale/%L/%N:/usr/share/locale/%L/LC_MESSAGES/%N
--
-- First one can see that more than one directory can be specified
-- (with the usual syntax of separating them by colons). The next
-- things to observe are the format string, `%L' and `%N' in this
-- case. The `catopen' function knows about several of them and the
-- replacement for all of them is of course different.
--
-- `%N'
-- This format element is substituted with the name of the
-- catalog file. This is the value of the CAT_NAME argument
-- given to `catgets'.
--
-- `%L'
-- This format element is substituted with the name of the
-- currently selected locale for translating messages. How this
-- is determined is explained below.
--
-- `%l'
-- (This is the lowercase ell.) This format element is
-- substituted with the language element of the locale name.
-- The string describing the selected locale is expected to have
-- the form `LANG[_TERR[.CODESET]]' and this format uses the
-- first part LANG.
--
-- `%t'
-- This format element is substituted by the territory part TERR
-- of the name of the currently selected locale. See the
-- explanation of the format above.
--
-- `%c'
-- This format element is substituted by the codeset part
-- CODESET of the name of the currently selected locale. See
-- the explanation of the format above.
--
-- `%%'
-- Since `%' is used in a meta character there must be a way to
-- express the `%' character in the result itself. Using `%%'
-- does this just like it works for `printf'.
--
-- Using `NLSPATH' allows to specify arbitrary directories to be
-- searched for message catalogs while still allowing different
-- languages to be used. If the `NLSPATH' environment variable is
-- not set the default value is
--
-- PREFIX/share/locale/%L/%N:PREFIX/share/locale/%L/LC_MESSAGES/%N
--
-- where PREFIX is given to `configure' while installing the GNU C
-- Library (this value is in many cases `/usr' or the empty string).
--
-- The remaining problem is to decide which must be used. The value
-- decides about the substitution of the format elements mentioned
-- above. First of all the user can specify a path in the message
-- catalog name (i.e., the name contains a slash character). In this
-- situation the `NLSPATH' environment variable is not used. The
-- catalog must exist as specified in the program, perhaps relative
-- to the current working directory. This situation in not desirable
-- and catalogs names never should be written this way. Beside this,
-- this behaviour is not portable to all other platforms providing
-- the `catgets' interface.
--
-- Otherwise the values of environment variables from the standard
-- environment are examined (*note Standard Environment::.). Which
-- variables are examined is decided by the FLAG parameter of
-- `catopen'. If the value is `NL_CAT_LOCALE' (which is defined in
-- `nl_types.h') then the `catopen' function examines the environment
-- variable `LC_ALL', `LC_MESSAGES', and `LANG' in this order. The
-- first variable which is set in the current environment will be
-- used.
--
-- If FLAG is zero only the `LANG' environment variable is examined.
-- This is a left-over from the early days of this function where the
-- other environment variable were not known.
--
-- In any case the environment variable should have a value of the
-- form `LANG[_TERR[.CODESET]]' as explained above. If no
-- environment variable is set the `"C"' locale is used which
-- prevents any translation.
--
-- The return value of the function is in any case a valid string.
-- Either it is a translation from a message catalog or it is the
-- same as the STRING parameter. So a piece of code to decide
-- whether a translation actually happened must look like this:
--
-- {
-- char *trans = catgets (desc, set, msg, input_string);
-- if (trans == input_string)
-- {
-- /* Something went wrong. */
-- }
-- }
--
-- When an error occured the global variable ERRNO is set to
--
-- EBADF
-- The catalog does not exist.
--
-- ENOMSG
-- The set/message ttuple does not name an existing element in
-- the message catalog.
--
-- While it sometimes can be useful to test for errors programs
-- normally will avoid any test. If the translation is not available
-- it is no big problem if the original, untranslated message is
-- printed. Either the user understands this as well or s/he will
-- look for the reason why the messages are not translated.
--
-- Please note that the currently selected locale does not depend on a
--call to the `setlocale' function. It is not necessary that the locale
--data files for this locale exist and calling `setlocale' succeeds. The
--`catopen' function directly reads the values of the environment
--variables.
--
-- - Function: char * catgets (nl_catd CATALOG_DESC, int SET, int
-- MESSAGE, const char *STRING)
-- The function `catgets' has to be used to access the massage catalog
-- previously opened using the `catopen' function. The CATALOG_DESC
-- parameter must be a value previously returned by `catopen'.
--
-- The next two parameters, SET and MESSAGE, reflect the internal
-- organization of the message catalog files. This will be explained
-- in detail below. For now it is interesting to know that a catalog
-- can consists of several set and the messages in each thread are
-- individually numbered using numbers. Neither the set number nor
-- the message number must be consecutive. They can be arbitrarily
-- chosen. But each message (unless equal to another one) must have
-- its own unique pair of set and message number.
--
-- Since it is not guaranteed that the message catalog for the
-- language selected by the user exists the last parameter STRING
-- helps to handle this case gracefully. If no matching string can
-- be found STRING is returned. This means for the programmer that
--
-- * the STRING parameters should contain reasonable text (this
-- also helps to understand the program seems otherwise there
-- would be no hint on the string which is expected to be
-- returned.
--
-- * all STRING arguments should be written in the same language.
--
-- It is somewhat uncomfortable to write a program using the `catgets'
--functions if no supporting functionality is available. Since each
--set/message number tuple must be unique the programmer must keep lists
--of the messages at the same time the code is written. And the work
--between several people working on the same project must be coordinated.
--We will see some how these problems can be relaxed a bit (*note Common
--Usage::.).
--
-- - Function: int catclose (nl_catd CATALOG_DESC)
-- The `catclose' function can be used to free the resources
-- associated with a message catalog which previously was opened by a
-- call to `catopen'. If the resources can be successfully freed the
-- function returns `0'. Otherwise it return `-1' and the global
-- variable ERRNO is set. Errors can occur if the catalog descriptor
-- CATALOG_DESC is not valid in which case ERRNO is set to `EBADF'.
--
--
--File: libc.info, Node: The message catalog files, Next: The gencat program, Prev: The catgets Functions, Up: Message catalogs a la X/Open
--
--Format of the message catalog files
-------------------------------------
--
-- The only reasonable way the translate all the messages of a function
--and store the result in a message catalog file which can be read by the
--`catopen' function is to write all the message text to the translator
--and let her/him translate them all. I.e., we must have a file with
--entries which associate the set/message tuple with a specific
--translation. This file format is specified in the X/Open standard and
--is as follows:
--
-- * Lines containing only whitespace characters or empty lines are
-- ignored.
--
-- * Lines which contain as the first non-whitespace character a `$'
-- followed by a whitespace character are comment and are also
-- ignored.
--
-- * If a line contains as the first non-whitespace characters the
-- sequence `$set' followed by a whitespace character an additional
-- argument is required to follow. This argument can either be:
--
-- - a number. In this case the value of this number determines
-- the set to which the following messages are added.
--
-- - an identifier consisting of alphanumeric characters plus the
-- underscore character. In this case the set get automatically
-- a number assigned. This value is one added to the largest
-- set number which so far appeared.
--
-- How to use the symbolic names is explained in section *Note
-- Common Usage::.
--
-- It is an error if a symbol name appears more than once. All
-- following messages are placed in a set with this number.
--
-- * If a line contains as the first non-whitespace characters the
-- sequence `$delset' followed by a whitespace character an
-- additional argument is required to follow. This argument can
-- either be:
--
-- - a number. In this case the value of this number determines
-- the set which will be deleted.
--
-- - an identifier consisting of alphanumeric characters plus the
-- underscore character. This symbolic identifier must match a
-- name for a set which previously was defined. It is an error
-- if the name is unknown.
--
-- In both cases all messages in the specified set will be removed.
-- They will not appear in the output. But if this set is later
-- again selected with a `$set' command again messages could be added
-- and these messages will appear in the output.
--
-- * If a line contains after leading whitespaces the sequence
-- `$quote', the quoting character used for this input file is
-- changed to the first non-whitespace character following the
-- `$quote'. If no non-whitespace character is present before the
-- line ends quoting is disable.
--
-- By default no quoting character is used. In this mode strings are
-- terminated with the first unescaped line break. If there is a
-- `$quote' sequence present newline need not be escaped. Instead a
-- string is terminated with the first unescaped appearance of the
-- quote character.
--
-- A common usage of this feature would be to set the quote character
-- to `"'. Then any appearance of the `"' in the strings must be
-- escaped using the backslash (i.e., `\"' must be written).
--
-- * Any other line must start with a number or an alphanumeric
-- identifier (with the underscore character included). The
-- following characters (starting at the first non-whitespace
-- character) will form the string which gets associated with the
-- currently selected set and the message number represented by the
-- number and identifier respectively.
--
-- If the start of the line is a number the message number is
-- obvious. It is an error if the same message number already
-- appeared for this set.
--
-- If the leading token was an identifier the message number gets
-- automatically assigned. The value is the current maximum messages
-- number for this set plus one. It is an error if the identifier was
-- already used for a message in this set. It is ok to reuse the
-- identifier for a message in another thread. How to use the
-- symbolic identifiers will be explained below (*note Common
-- Usage::.). There is one limitation with the identifier: it must
-- not be `Set'. The reason will be explained below.
--
-- Please note that you must use a quoting character if a message
-- contains leading whitespace. Since one cannot guarantee this
-- never happens it is probably a good idea to always use quoting.
--
-- The text of the messages can contain escape characters. The usual
-- bunch of characters known from the ISO C language are recognized
-- (`\n', `\t', `\v', `\b', `\r', `\f', `\\', and `\NNN', where NNN
-- is the octal coding of a character code).
--
-- *Important:* The handling of identifiers instead of numbers for the
--set and messages is a GNU extension. Systems strictly following the
--X/Open specification do not have this feature. An example for a message
--catalog file is this:
--
-- $ This is a leading comment.
-- $quote "
--
-- $set SetOne
-- 1 Message with ID 1.
-- two " Message with ID \"two\", which gets the value 2 assigned"
--
-- $set SetTwo
-- $ Since the last set got the number 1 assigned this set has number 2.
-- 4000 "The numbers can be arbitrary, they need not start at one."
--
-- This small example shows various aspects:
-- * Lines 1 and 9 are comments since they start with `$' followed by a
-- whitespace.
--
-- * The quoting character is set to `"'. Otherwise the quotes in the
-- message definition would have to be left away and in this case the
-- message with the identifier `two' would loose its leading
-- whitespace.
--
-- * Mixing numbered messages with message having symbolic names is no
-- problem and the numbering happens automatically.
--
-- While this file format is pretty easy it is not the best possible for
--use in a running program. The `catopen' function would have to parser
--the file and handle syntactic errors gracefully. This is not so easy
--and the whole process is pretty slow. Therefore the `catgets'
--functions expect the data in another more compact and ready-to-use file
--format. There is a special program `gencat' which is explained in
--detail in the next section.
--
-- Files in this other format are not human readable. To be easy to
--use by programs it is a binary file. But the format is byte order
--independent so translation files can be shared by systems of arbitrary
--architecture (as long as they use the GNU C Library).
--
-- Details about the binary file format are not important to know since
--these files are always created by the `gencat' program. The sources of
--the GNU C Library also provide the sources for the `gencat' program and
--so the interested reader can look through these source files to learn
--about the file format.
--
--
--File: libc.info, Node: The gencat program, Next: Common Usage, Prev: The message catalog files, Up: Message catalogs a la X/Open
--
--Generate Message Catalogs files
---------------------------------
--
-- The `gencat' program is specified in the X/Open standard and the GNU
--implementation follows this specification and so allows to process all
--correctly formed input files. Additionally some extension are
--implemented which help to work in a more reasonable way with the
--`catgets' functions.
--
-- The `gencat' program can be invoked in two ways:
--
-- `gencat [OPTION]... [OUTPUT-FILE [INPUT-FILE]...]`
--
-- This is the interface defined in the X/Open standard. If no
--INPUT-FILE parameter is given input will be read from standard input.
--Multiple input files will be read as if they are concatenated. If
--OUTPUT-FILE is also missing, the output will be written to standard
--output. To provide the interface one is used from other programs a
--second interface is provided.
--
-- `gencat [OPTION]... -o OUTPUT-FILE [INPUT-FILE]...`
--
-- The option `-o' is used to specify the output file and all file
--arguments are used as input files.
--
-- Beside this one can use `-' or `/dev/stdin' for INPUT-FILE to denote
--the standard input. Corresponding one can use `-' and `/dev/stdout'
--for OUTPUT-FILE to denote standard output. Using `-' as a file name is
--allowed in X/Open while using the device names is a GNU extension.
--
-- The `gencat' program works by concatenating all input files and then
--*merge* the resulting collection of message sets with a possibly
--existing output file. This is done by removing all messages with
--set/message number tuples matching any of the generated messages from
--the output file and then adding all the new messages. To regenerate a
--catalog file while ignoring the old contents therefore requires to
--remove the output file if it exists. If the output is written to
--standard output no merging takes place.
--
--The following table shows the options understood by the `gencat'
--program. The X/Open standard does not specify any option for the
--program so all of these are GNU extensions.
--
--`-V'
--`--version'
-- Print the version information and exit.
--
--`-h'
--`--help'
-- Print a usage message listing all available options, then exit
-- successfully.
--
--`--new'
-- Do never merge the new messages from the input files with the old
-- content of the output files. The old content of the output file
-- is discarded.
--
--`-H'
--`--header=name'
-- This option is used to emit the symbolic names given to sets and
-- messages in the input files for use in the program. Details about
-- how to use this are given in the next section. The NAME parameter
-- to this option specifies the name of the output file. It will
-- contain a number of C preprocessor `#define's to associate a name
-- with a number.
--
-- Please note that the generated file only contains the symbols from
-- the input files. If the output is merged with the previous
-- content of the output file the possibly existing symbols from the
-- file(s) which generated the old output files are not in the
-- generated header file.
--
--
--File: libc.info, Node: Common Usage, Prev: The gencat program, Up: Message catalogs a la X/Open
--
--How to use the `catgets' interface
------------------------------------
--
-- The `catgets' functions can be used in two different ways. By
--following slavishly the X/Open specs and not relying on the extension
--and by using the GNU extensions. We will take a look at the former
--method first to understand the benefits of extensions.
--
--Not using symbolic names
--........................
--
-- Since the X/Open format of the message catalog files does not allow
--symbol names we have to work with numbers all the time. When we start
--writing a program we have to replace all appearances of translatable
--strings with something like
--
-- catgets (catdesc, set, msg, "string")
--
--CATGETS is retrieved from a call to `catopen' which is normally done
--once at the program start. The `"string"' is the string we want to
--translate. The problems start with the set and message numbers.
--
-- In a bigger program several programmers usually work at the same
--time on the program and so coordinating the number allocation is
--crucial. Though no two different strings must be indexed by the same
--tuple of numbers it is highly desirable to reuse the numbers for equal
--strings with equal translations (please note that there might be
--strings which are equal in one language but have different translations
--due to difference contexts).
--
-- The allocation process can be relaxed a bit by different set numbers
--for different parts of the program. So the number of developers who
--have to coordinate the allocation can be reduced. But still lists must
--be keep track of the allocation and errors can easily happen. These
--errors cannot be discovered by the compiler or the `catgets' functions.
--Only the user of the program might see wrong messages printed. In the
--worst cases the messages are so irritating that they cannot be
--recognized as wrong. Think about the translations for `"true"' and
--`"false"' being exchanged. This could result in a disaster.
--
--Using symbolic names
--....................
--
-- The problems mentioned in the last section derive from the fact that:
--
-- 1. the numbers are allocated once and due to the possibly frequent
-- use of them it is difficult to change a number later.
--
-- 2. the numbers do not allow to guess anything about the string and
-- therefore collisions can easily happen.
--
-- By constantly using symbolic names and by providing a method which
--maps the string content to a symbolic name (however this will happen)
--one can prevent both problems above. The cost of this is that the
--programmer has to write a complete message catalog file while s/he is
--writing the program itself.
--
-- This is necessary since the symbolic names must be mapped to numbers
--before the program sources can be compiled. In the last section it was
--described how to generate a header containing the mapping of the names.
--E.g., for the example message file given in the last section we could
--call the `gencat' program as follow (assume `ex.msg' contains the
--sources).
--
-- gencat -H ex.h -o ex.cat ex.msg
--
--This generates a header file with the following content:
--
-- #define SetTwoSet 0x2 /* u.msg:8 */
--
-- #define SetOneSet 0x1 /* u.msg:4 */
-- #define SetOnetwo 0x2 /* u.msg:6 */
--
-- As can be seen the various symbols given in the source file are
--mangled to generate unique identifiers and these identifiers get numbers
--assigned. Reading the source file and knowing about the rules will
--allow to predict the content of the header file (it is deterministic)
--but this is not necessary. The `gencat' program can take care for
--everything. All the programmer has to do is to put the generated header
--file in the dependency list of the source files of her/his project and
--to add a rules to regenerate the header of any of the input files
--change.
--
-- One word about the symbol mangling. Every symbol consists of two
--parts: the name of the message set plus the name of the message or the
--special string `Set'. So `SetOnetwo' means this macro can be used to
--access the translation with identifier `two' in the message set
--`SetOne'.
--
-- The other names denote the names of the message sets. The special
--string `Set' is used in the place of the message identifier.
--
-- If in the code the second string of the set `SetOne' is used the C
--code should look like this:
--
-- catgets (catdesc, SetOneSet, SetOnetwo,
-- " Message with ID \"two\", which gets the value 2 assigned")
--
-- Writing the function this way will allow to change the message number
--and even the set number without requiring any change in the C source
--code. (The text of the string is normally not the same; this is only
--for this example.)
--
--How does to this allow to develop
--.................................
--
-- To illustrate the usual way to work with the symbolic version numbers
--here is a little example. Assume we want to write the very complex and
--famous greeting program. We start by writing the code as usual:
--
-- #include <stdio.h>
-- int
-- main (void)
-- {
-- printf ("Hello, world!\n");
-- return 0;
-- }
--
-- Now we want to internationalize the message and therefore replace the
--message with whatever the user wants.
--
-- #include <nl_types.h>
-- #include <stdio.h>
-- #include "msgnrs.h"
-- int
-- main (void)
-- {
-- nl_catd catdesc = catopen ("hello.cat", NL_CAT_LOCALE);
-- printf (catgets (catdesc, SetMainSet, SetMainHello,
-- "Hello, world!\n"));
-- catclose (catdesc);
-- return 0;
-- }
--
-- We see how the catalog object is opened and the returned descriptor
--used in the other function calls. It is not really necessary to check
--for failure of any of the functions since even in these situations the
--functions will behave reasonable. They simply will be return a
--translation.
--
-- What remains unspecified here are the constants `SetMainSet' and
--`SetMainHello'. These are the symbolic names describing the message.
--To get the actual definitions which match the information in the
--catalog file we have to create the message catalog source file and
--process it using the `gencat' program.
--
-- $ Messages for the famous greeting program.
-- $quote "
--
-- $set Main
-- Hello "Hallo, Welt!\n"
--
-- Now we can start building the program (assume the message catalog
--source file is named `hello.msg' and the program source file `hello.c'):
--
-- % gencat -H msgnrs.h -o hello.cat hello.msg
-- % cat msgnrs.h
-- #define MainSet 0x1 /* hello.msg:4 */
-- #define MainHello 0x1 /* hello.msg:5 */
-- % gcc -o hello hello.c -I.
-- % cp hello.cat /usr/share/locale/de/LC_MESSAGES
-- % echo $LC_ALL
-- de
-- % ./hello
-- Hallo, Welt!
-- %
--
-- The call of the `gencat' program creates the missing header file
--`msgnrs.h' as well as the message catalog binary. The former is used
--in the compilation of `hello.c' while the later is placed in a
--directory in which the `catopen' function will try to locate it.
--Please check the `LC_ALL' environment variable and the default path for
--`catopen' presented in the description above.
--
--
--File: libc.info, Node: The Uniforum approach, Prev: Message catalogs a la X/Open, Up: Message Translation
--
--The Uniforum approach to Message Translation
--============================================
--
-- Sun Microsystems tried to standardize a different approach to message
--translation in the Uniforum group. There never was a real standard
--defined but still the interface was used in Sun's operation systems.
--Since this approach fits better in the development process of free
--software it is also used throughout the GNU package and the GNU
--`gettext' package provides support for this outside the GNU C Library.
--
-- The code of the `libintl' from GNU `gettext' is the same as the code
--in the GNU C Library. So the documentation in the GNU `gettext' manual
--is also valid for the functionality here. The following text will
--describe the library functions in detail. But the numerous helper
--programs are not described in this manual. Instead people should read
--the GNU `gettext' manual (*note GNU gettext utilities: (gettext)Top.).
--We will only give a short overview.
--
-- Though the `catgets' functions are available by default on more
--systems the `gettext' interface is at least as portable as the former.
--The GNU `gettext' package can be used wherever the functions are not
--available.
--
--* Menu:
--
--* Message catalogs with gettext:: The `gettext' family of functions.
--* Helper programs for gettext:: Programs to handle message catalogs
-- for `gettext'.
--
--
--File: libc.info, Node: Message catalogs with gettext, Next: Helper programs for gettext, Up: The Uniforum approach
--
--The `gettext' family of functions
-----------------------------------
--
-- The paradigms underlying the `gettext' approach to message
--translations is different from that of the `catgets' functions the
--basic functionally is equivalent. There are functions of the following
--categories:
--
--* Menu:
--
--* Translation with gettext:: What has to be done to translate a message.
--* Locating gettext catalog:: How to determine which catalog to be used.
--* Using gettextized software:: The possibilities of the user to influence
-- the way `gettext' works.
--
--
--File: libc.info, Node: Translation with gettext, Next: Locating gettext catalog, Up: Message catalogs with gettext
--
--What has to be done to translate a message?
--...........................................
--
-- The `gettext' functions have a very simple interface. The most
--basic function just takes the string which shall be translated as the
--argument and it returns the translation. This is fundamentally
--different from the `catgets' approach where an extra key is necessary
--and the original string is only used for the error case.
--
-- If the string which has to be translated is the only argument this of
--course means the string itself is the key. I.e., the translation will
--be selected based on the original string. The message catalogs must
--therefore contain the original strings plus one translation for any such
--string. The task of the `gettext' function is it to compare the
--argument string with the available strings in the catalog and return the
--appropriate translation. Of course this process is optimized so that
--this process is not more expensive than an access using an atomic key
--like in `catgets'.
--
-- The `gettext' approach has some advantages but also some
--disadvantages. Please see the GNU `gettext' manual for a detailed
--discussion of the pros and cons.
--
-- All the definitions and declarations for `gettext' can be found in
--the `libintl.h' header file. On systems where these functions are not
--part of the C library they can be found in a separate library named
--`libintl.a' (or accordingly different for shared libraries).
--
-- - Function: char * gettext (const char *MSGID)
-- The `gettext' function searches the currently selected message
-- catalogs for a string which is equal to MSGID. If there is such a
-- string available it is returned. Otherwise the argument string
-- MSGID is returned.
--
-- Please note that all though the return value is `char *' the
-- returned string must not be changed. This broken type results
-- from the history of the function and does not reflect the way the
-- function should be used.
--
-- Please note that above we wrote "message catalogs" (plural). This
-- is a speciality of the GNU implementation of these functions and
-- we will say more about this when we talk about the ways message
-- catalogs are selected (*note Locating gettext catalog::.).
--
-- The `gettext' function does not modify the value of the global
-- ERRNO variable. This is necessary to make it possible to write
-- something like
--
-- printf (gettext ("Operation failed: %m\n"));
--
-- Here the ERRNO value is used in the `printf' function while
-- processing the `%m' format element and if the `gettext' function
-- would change this value (it is called before `printf' is called)
-- we would get a wrong message.
--
-- So there is no easy way to detect a missing message catalog beside
-- comparing the argument string with the result. But it is normally
-- the task of the user to react on missing catalogs. The program
-- cannot guess when a message catalog is really necessary since for
-- a user who s peaks the language the program was developed in does
-- not need any translation.
--
-- The remaining two functions to access the message catalog add some
--functionality to select a message catalog which is not the default one.
--This is important if parts of the program are developed independently.
--Every part can have its own message catalog and all of them can be used
--at the same time. The C library itself is an example: internally it
--uses the `gettext' functions but since it must not depend on a
--currently selected default message catalog it must specify all ambiguous
--information.
--
-- - Function: char * dgettext (const char *DOMAINNAME, const char *MSGID)
-- The `dgettext' functions acts just like the `gettext' function.
-- It only takes an additional first argument DOMAINNAME which guides
-- the selection of the message catalogs which are searched for the
-- translation. If the DOMAINNAME parameter is the null pointer the
-- `dgettext' function is exactly equivalent to `gettext' since the
-- default value for the domain name is used.
--
-- As for `gettext' the return value type is `char *' which is an
-- anachronism. The returned string must never be modified.
--
-- - Function: char * dcgettext (const char *DOMAINNAME, const char
-- *MSGID, int CATEGORY)
-- The `dcgettext' adds another argument to those which `dgettext'
-- takes. This argument CATEGORY specifies the last piece of
-- information needed to localize the message catalog. I.e., the
-- domain name and the locale category exactly specify which message
-- catalog has to be used (relative to a given directory, see below).
--
-- The `dgettext' function can be expressed in terms of `dcgettext'
-- by using
--
-- dcgettext (domain, string, LC_MESSAGES)
--
-- instead of
--
-- dgettext (domain, string)
--
-- This also shows which values are expected for the third parameter.
-- One has to use the available selectors for the categories
-- available in `locale.h'. Normally the available values are
-- `LC_CTYPE', `LC_COLLATE', `LC_MESSAGES', `LC_MONETARY',
-- `LC_NUMERIC', and `LC_TIME'. Please note that `LC_ALL' must not
-- be used and even though the names might suggest this, there is no
-- relation to the environments variables of this name.
--
-- The `dcgettext' function is only implemented for compatibility with
-- other systems which have `gettext' functions. There is not really
-- any situation where it is necessary (or useful) to use a different
-- value but `LC_MESSAGES' in for the CATEGORY parameter. We are
-- dealing with messages here and any other choice can only be
-- irritating.
--
-- As for `gettext' the return value type is `char *' which is an
-- anachronism. The returned string must never be modified.
--
-- When using the three functions above in a program it is a frequent
--case that the MSGID argument is a constant string. So it is worth to
--optimize this case. Thinking shortly about this one will realize that
--as long as no new message catalog is loaded the translation of a message
--will not change. I.e., the algorithm to determine the translation is
--deterministic.
--
-- Exactly this is what the optimizations implemented in the
--`libintl.h' header will use. Whenever a program is compiler with the
--GNU C compiler, optimization is selected and the MSGID argument to
--`gettext', `dgettext' or `dcgettext' is a constant string the actual
--function call will only be done the first time the message is used and
--then always only if any new message catalog was loaded and so the
--result of the translation lookup might be different. See the
--`libintl.h' header file for details. For the user it is only important
--to know that the result is always the same, independent of the compiler
--or compiler options in use.
--
--
--File: libc.info, Node: Locating gettext catalog, Next: Using gettextized software, Prev: Translation with gettext, Up: Message catalogs with gettext
--
--How to determine which catalog to be used
--.........................................
--
-- The functions to retrieve the translations for a given message have a
--remarkable simple interface. But to provide the user of the program
--still the opportunity to select exactly the translation s/he wants and
--also to provide the programmer the possibility to influence the way to
--locate the search for catalogs files there is a quite complicated
--underlying mechanism which controls all this. The code is complicated
--the use is easy.
--
-- Basically we have two different tasks to perform which can also be
--performed by the `catgets' functions:
--
-- 1. Locate the set of message catalogs. There are a number of files
-- for different languages and which all belong to the package.
-- Usually they are all stored in the filesystem below a certain
-- directory.
--
-- There can be arbitrary many packages installed and they can follow
-- different guidelines for the placement of their files.
--
-- 2. Relative to the location specified by the package the actual
-- translation files must be searched, based on the wishes of the
-- user. I.e., for each language the user selects the program should
-- be able to locate the appropriate file.
--
-- This is the functionality required by the specifications for
--`gettext' and this is also what the `catgets' functions are able to do.
--But there are some problems unresolved:
--
-- * The language to be used can be specified in several different ways.
-- There is no generally accepted standard for this and the user
-- always expects the program understand what s/he means. E.g., to
-- select the German translation one could write `de', `german', or
-- `deutsch' and the program should always react the same.
--
-- * Sometimes the specification of the user is too detailed. If s/he,
-- e.g., specifies `de_DE.ISO-8859-1' which means German, spoken in
-- Germany, coded using the ISO 8859-1 character set there is the
-- possibility that a message catalog matching this exactly is not
-- available. But there could be a catalog matching `de' and if the
-- character set used on the machine is always ISO 8859-1 there is no
-- reason why this later message catalog should not be used. (We
-- call this "message inheritance".)
--
-- * If a catalog for a wanted language is not available it is not
-- always the second best choice to fall back on the language of the
-- developer and simply not translate any message. Instead a user
-- might be better able to read the messages in another language and
-- so the user of the program should be able to define an precedence
-- order of languages.
--
-- We can divide the configuration actions in two parts: the one is
--performed by the programmer, the other by the user. We will start with
--the functions the programmer can use since the user configuration will
--be based on this.
--
-- As the functions described in the last sections already mention
--separate sets of messages can be selected by a "domain name". This is a
--simple string which should be unique for each program part with uses a
--separate domain. It is possible to use in one program arbitrary many
--domains at the same time. E.g., the GNU C Library itself uses a domain
--named `libc' while the program using the C Library could use a domain
--named `foo'. The important point is that at any time exactly one
--domain is active. This is controlled with the following function.
--
-- - Function: char * textdomain (const char *DOMAINNAME)
-- The `textdomain' function sets the default domain, which is used in
-- all future `gettext' calls, to DOMAINNAME. Please note that
-- `dgettext' and `dcgettext' calls are not influenced if the
-- DOMAINNAME parameter of these functions is not the null pointer.
--
-- Before the first call to `textdomain' the default domain is
-- `messages'. This is the name specified in the specification of
-- the `gettext' API. This name is as good as any other name. No
-- program should ever really use a domain with this name since this
-- can only lead to problems.
--
-- The function returns the value which is from now on taken as the
-- default domain. If the system went out of memory the returned
-- value is `NULL' and the global variable ERRNO is set to `ENOMEM'.
-- Despite the return value type being `char *' the return string must
-- not be changed. It is allocated internally by the `textdomain'
-- function.
--
-- If the DOMAINNAME parameter is the null pointer no new default
-- domain is set. Instead the currently selected default domain is
-- returned.
--
-- If the DOMAINNAME parameter is the empty string the default domain
-- is reset to its initial value, the domain with the name `messages'.
-- This possibility is questionable to use since the domain `messages'
-- really never should be used.
--
-- - Function: char * bindtextdomain (const char *DOMAINNAME, const char
-- *DIRNAME)
-- The `bindtextdomain' function can be used to specify the directly
-- which contains the message catalogs for domain DOMAINNAME for the
-- different languages. To be correct, this is the directory where
-- the hierarchy of directories is expected. Details are explained
-- below.
--
-- For the programmer it is important to note that the translations
-- which come with the program have be placed in a directory
-- hierarchy starting at, say, `/foo/bar'. Then the program should
-- make a `bindtextdomain' call to bind the domain for the current
-- program to this directory. So it is made sure the catalogs are
-- found. A correctly running program does not depend on the user
-- setting an environment variable.
--
-- The `bindtextdomain' function can be used several times and if the
-- DOMAINNAME argument is different the previously bounded domains
-- will not be overwritten.
--
-- If the program which wish to use `bindtextdomain' at some point of
-- time use the `chdir' function to change the current working
-- directory it is important that the DIRNAME strings ought to be an
-- absolute pathname. Otherwise the addressed directory might vary
-- with the time.
--
-- If the DIRNAME parameter is the null pointer `bindtextdomain'
-- returns the currently selected directory for the domain with the
-- name DOMAINNAME.
--
-- the `bindtextdomain' function returns a pointer to a string
-- containing the name of the selected directory name. The string is
-- allocated internally in the function and must not be changed by the
-- user. If the system went out of core during the execution of
-- `bindtextdomain' the return value is `NULL' and the global
-- variable ERRNO is set accordingly.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-12 glibc-2.1.3/manual/libc.info-12
---- ../glibc-2.1.3/manual/libc.info-12 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-12 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1187 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Using gettextized software, Prev: Locating gettext catalog, Up: Message catalogs with gettext
--
--User influence on `gettext'
--...........................
--
-- The last sections described what the programmer can do to
--internationalize the messages of the program. But it is finally up to
--the user to select the message s/he wants to see. S/He must understand
--them.
--
-- The POSIX locale model uses the environment variables `LC_COLLATE',
--`LC_CTYPE', `LC_MESSAGES', `LC_MONETARY', `NUMERIC', and `LC_TIME' to
--select the locale which is to be used. This way the user can influence
--lots of functions. As we mentioned above the `gettext' functions also
--take advantage of this.
--
-- To understand how this happens it is necessary to take a look at the
--various components of the filename which gets computed to locate a
--message catalog. It is composed as follows:
--
-- DIR_NAME/LOCALE/LC_CATEGORY/DOMAIN_NAME.mo
--
-- The default value for DIR_NAME is system specific. It is computed
--from the value given as the prefix while configuring the C library.
--This value normally is `/usr' or `/'. For the former the complete
--DIR_NAME is:
--
-- /usr/share/locale
--
-- We can use `/usr/share' since the `.mo' files containing the message
--catalogs are system independent, all systems can use the same files.
--If the program executed the `bindtextdomain' function for the message
--domain that is currently handled the `dir_name' component is the
--exactly the value which was given to the function as the second
--parameter. I.e., `bindtextdomain' allows to overwrite the only system
--dependent and fixed value to make it possible to address file
--everywhere in the filesystem.
--
-- The CATEGORY is the name of the locale category which was selected
--in the program code. For `gettext' and `dgettext' this is always
--`LC_MESSAGES', for `dcgettext' this is selected by the value of the
--third parameter. As said above it should be avoided to ever use a
--category other than `LC_MESSAGES'.
--
-- The LOCALE component is computed based on the category used. Just
--like for the `setlocale' function here comes the user selection into
--the play. Some environment variables are examined in a fixed order and
--the first environment variable set determines the return value of the
--lookup process. In detail, for the category `LC_xxx' the following
--variables in this order are examined:
--
--`LANGUAGE'
--
--`LC_ALL'
--
--`LC_xxx'
--
--`LANG'
-- This looks very familiar. With the exception of the `LANGUAGE'
--environment variable this is exactly the lookup order the `setlocale'
--function uses. But why introducing the `LANGUAGE' variable?
--
-- The reason is that the syntax of the values these variables can have
--is different to what is expected by the `setlocale' function. If we
--would set `LC_ALL' to a value following the extended syntax that would
--mean the `setlocale' function will never be able to use the value of
--this variable as well. An additional variable removes this problem
--plus we can select the language independently of the locale setting
--which sometimes is useful.
--
-- While for the `LC_xxx' variables the value should consist of exactly
--one specification of a locale the `LANGUAGE' variable's value can
--consist of a colon separated list of locale names. The attentive
--reader will realize that this is the way we manage to implement one of
--our additional demands above: we want to be able to specify an ordered
--list of language.
--
-- Back to the constructed filename we have only one component missing.
--The DOMAIN_NAME part is the name which was either registered using the
--`textdomain' function or which was given to `dgettext' or `dcgettext'
--as the first parameter. Now it becomes obvious that a good choice for
--the domain name in the program code is a string which is closely
--related to the program/package name. E.g., for the GNU C Library the
--domain name is `libc'.
--
--A limit piece of example code should show how the programmer is supposed
--to work:
--
-- {
-- textdomain ("test-package");
-- bindtextdomain ("test-package", "/usr/local/share/locale");
-- puts (gettext ("Hello, world!");
-- }
--
-- At the program start the default domain is `messages'. The
--`textdomain' call changes this to `test-package'. The `bindtextdomain'
--call specifies that the message catalogs for the domain `test-package'
--can be found below the directory `/usr/local/share/locale'.
--
-- If now the user set in her/his environment the variable `LANGUAGE'
--to `de' the `gettext' function will try to use the translations from
--the file
--
-- /usr/local/share/locale/de/LC_MESSAGES/test-package.mo
--
-- From the above descriptions it should be clear which component of
--this filename is determined by which source.
--
-- In the above example we assumed that the `LANGUAGE' environment
--variable to `de'. This might be an appropriate selection but what
--happens if the user wants to use `LC_ALL' because of the wider
--usability and here the required value is `de_DE.ISO-8859-1'? We
--already mentioned above that a situation like this is not infrequent.
--E.g., a person might prefer reading a dialect and if this is not
--available fall back on the standard language.
--
-- The `gettext' functions know about situations like this and can
--handle them gracefully. The functions recognize the format of the value
--of the environment variable. It can split the value is different pieces
--and by leaving out the only or the other part it can construct new
--values. This happens of course in a predictable way. To understand
--this one must know the format of the environment variable value. There
--are to more or less standardized forms:
--
--*X/Open Format*
-- `language[_territory[.codeset]][@modifier]'
--
--*CEN Format (European Community Standard)*
-- `language[_territory][+audience][+special][,[sponsor][_revision]]'
--
-- The functions will automatically recognize which format is used.
--Less specific locale names will be stripped of in the order of the
--following list:
--
-- 1. `revision'
--
-- 2. `sponsor'
--
-- 3. `special'
--
-- 4. `codeset'
--
-- 5. `normalized codeset'
--
-- 6. `territory'
--
-- 7. `audience'/`modifier'
--
-- From the last entry one can see that the meaning of the `modifier'
--field in the X/Open format and the `audience' format have the same
--meaning. Beside one can see that the `language' field for obvious
--reasons never will be dropped.
--
-- The only new thing is the `normalized codeset' entry. This is
--another goodie which is introduced to help reducing the chaos which
--derives from the inability of the people to standardize the names of
--character sets. Instead of ISO-8859-1 one can often see 8859-1, 88591,
--iso8859-1, or iso_8859-1. The `normalized codeset' value is generated
--from the user-provided character set name by applying the following
--rules:
--
-- 1. Remove all characters beside numbers and letters.
--
-- 2. Fold letters to lowercase.
--
-- 3. If the same only contains digits prepend the string `"iso"'.
--
--So all of the above name will be normalized to `iso88591'. This allows
--the program user much more freely choosing the locale name.
--
-- Even this extended functionality still does not help to solve the
--problem that completely different names can be used to denote the same
--locale (e.g., `de' and `german'). To be of help in this situation the
--locale implementation and also the `gettext' functions know about
--aliases.
--
-- The file `/usr/share/locale/locale.alias' (replace `/usr' with
--whatever prefix you used for configuring the C library) contains a
--mapping of alternative names to more regular names. The system manager
--is free to add new entries to fill her/his own needs. The selected
--locale from the environment is compared with the entries in the first
--column of this file ignoring the case. If they match the value of the
--second column is used instead for the further handling.
--
-- In the description of the format of the environment variables we
--already mentioned the character set as a factor in the selection of the
--message catalog. In fact, only catalogs which contain text written
--using the character set of the system/program can be used (directly;
--there will come a solution for this some day). This means for the user
--that s/he will always have to take care for this. If in the collection
--of the message catalogs there are files for the same language but coded
--using different character sets the user has to be careful.
--
--
--File: libc.info, Node: Helper programs for gettext, Prev: Message catalogs with gettext, Up: The Uniforum approach
--
--Programs to handle message catalogs for `gettext'
---------------------------------------------------
--
-- The GNU C Library does not contain the source code for the programs
--to handle message catalogs for the `gettext' functions. As part of the
--GNU project the GNU gettext package contains everything the developer
--needs. The functionality provided by the tools in this package by far
--exceeds the abilities of the `gencat' program described above for the
--`catgets' functions.
--
-- There is a program `msgfmt' which is the equivalent program to the
--`gencat' program. It generates from the human-readable and -editable
--form of the message catalog a binary file which can be used by the
--`gettext' functions. But there are several more programs available.
--
-- The `xgettext' program can be used to automatically extract the
--translatable messages from a source file. I.e., the programmer need not
--take care for the translations and the list of messages which have to be
--translated. S/He will simply wrap the translatable string in calls to
--`gettext' et.al and the rest will be done by `xgettext'. This program
--has a lot of option which help to customize the output or do help to
--understand the input better.
--
-- Other programs help to manage development cycle when new messages
--appear in the source files or when a new translation of the messages
--appear. here it should only be noted that using all the tools in GNU
--gettext it is possible to *completely* automize the handling of message
--catalog. Beside marking the translatable string in the source code and
--generating the translations the developers do not have anything to do
--themself.
--
--
--File: libc.info, Node: Searching and Sorting, Next: Pattern Matching, Prev: Message Translation, Up: Top
--
--Searching and Sorting
--*********************
--
-- This chapter describes functions for searching and sorting arrays of
--arbitrary objects. You pass the appropriate comparison function to be
--applied as an argument, along with the size of the objects in the array
--and the total number of elements.
--
--* Menu:
--
--* Comparison Functions:: Defining how to compare two objects.
-- Since the sort and search facilities
-- are general, you have to specify the
-- ordering.
--* Array Search Function:: The `bsearch' function.
--* Array Sort Function:: The `qsort' function.
--* Search/Sort Example:: An example program.
--* Hash Search Function:: The `hsearch' function.
--* Tree Search Function:: The `tsearch' function.
--
--
--File: libc.info, Node: Comparison Functions, Next: Array Search Function, Up: Searching and Sorting
--
--Defining the Comparison Function
--================================
--
-- In order to use the sorted array library functions, you have to
--describe how to compare the elements of the array.
--
-- To do this, you supply a comparison function to compare two elements
--of the array. The library will call this function, passing as arguments
--pointers to two array elements to be compared. Your comparison function
--should return a value the way `strcmp' (*note String/Array
--Comparison::.) does: negative if the first argument is "less" than the
--second, zero if they are "equal", and positive if the first argument is
--"greater".
--
-- Here is an example of a comparison function which works with an
--array of numbers of type `double':
--
-- int
-- compare_doubles (const void *a, const void *b)
-- {
-- const double *da = (const double *) a;
-- const double *db = (const double *) b;
--
-- return (*da > *db) - (*da < *db);
-- }
--
-- The header file `stdlib.h' defines a name for the data type of
--comparison functions. This type is a GNU extension.
--
-- int comparison_fn_t (const void *, const void *);
--
--
--File: libc.info, Node: Array Search Function, Next: Array Sort Function, Prev: Comparison Functions, Up: Searching and Sorting
--
--Array Search Function
--=====================
--
-- Generally searching for a specific element in an array means that
--potentially all elements must be checked. The GNU C library contains
--functions to perform linear search. The prototypes for the following
--two functions can be found in `search.h'.
--
-- - Function: void * lfind (const void *KEY, void *BASE, size_t *NMEMB,
-- size_t SIZE, comparison_fn_t COMPAR)
-- The `lfind' function searches in the array with `*NMEMB' elements
-- of SIZE bytes pointed to by BASE for an element which matches the
-- one pointed to by KEY. The function pointed to by COMPAR is used
-- decide whether two elements match.
--
-- The return value is a pointer to the matching element in the array
-- starting at BASE if it is found. If no matching element is
-- available `NULL' is returned.
--
-- The mean runtime of this function is `*NMEMB'/2. This function
-- should only be used elements often get added to or deleted from
-- the array in which case it might not be useful to sort the array
-- before searching.
--
-- - Function: void * lsearch (const void *KEY, void *BASE, size_t
-- *NMEMB, size_t SIZE, comparison_fn_t COMPAR)
-- The `lsearch' function is similar to the `lfind' function. It
-- searches the given array for an element and returns it if found.
-- The difference is that if no matching element is found the
-- `lsearch' function adds the object pointed to by KEY (with a size
-- of SIZE bytes) at the end of the array and it increments the value
-- of `*NMEMB' to reflect this addition.
--
-- This means for the caller that if it is not sure that the array
-- contains the element one is searching for the memory allocated for
-- the array starting at BASE must have room for at least SIZE more
-- bytes. If one is sure the element is in the array it is better to
-- use `lfind' so having more room in the array is always necessary
-- when calling `lsearch'.
--
-- To search a sorted array for an element matching the key, use the
--`bsearch' function. The prototype for this function is in the header
--file `stdlib.h'.
--
-- - Function: void * bsearch (const void *KEY, const void *ARRAY, size_t
-- COUNT, size_t SIZE, comparison_fn_t COMPARE)
-- The `bsearch' function searches the sorted array ARRAY for an
-- object that is equivalent to KEY. The array contains COUNT
-- elements, each of which is of size SIZE bytes.
--
-- The COMPARE function is used to perform the comparison. This
-- function is called with two pointer arguments and should return an
-- integer less than, equal to, or greater than zero corresponding to
-- whether its first argument is considered less than, equal to, or
-- greater than its second argument. The elements of the ARRAY must
-- already be sorted in ascending order according to this comparison
-- function.
--
-- The return value is a pointer to the matching array element, or a
-- null pointer if no match is found. If the array contains more
-- than one element that matches, the one that is returned is
-- unspecified.
--
-- This function derives its name from the fact that it is implemented
-- using the binary search algorithm.
--
--
--File: libc.info, Node: Array Sort Function, Next: Search/Sort Example, Prev: Array Search Function, Up: Searching and Sorting
--
--Array Sort Function
--===================
--
-- To sort an array using an arbitrary comparison function, use the
--`qsort' function. The prototype for this function is in `stdlib.h'.
--
-- - Function: void qsort (void *ARRAY, size_t COUNT, size_t SIZE,
-- comparison_fn_t COMPARE)
-- The QSORT function sorts the array ARRAY. The array contains
-- COUNT elements, each of which is of size SIZE.
--
-- The COMPARE function is used to perform the comparison on the
-- array elements. This function is called with two pointer
-- arguments and should return an integer less than, equal to, or
-- greater than zero corresponding to whether its first argument is
-- considered less than, equal to, or greater than its second
-- argument.
--
-- *Warning:* If two objects compare as equal, their order after
-- sorting is unpredictable. That is to say, the sorting is not
-- stable. This can make a difference when the comparison considers
-- only part of the elements. Two elements with the same sort key
-- may differ in other respects.
--
-- If you want the effect of a stable sort, you can get this result by
-- writing the comparison function so that, lacking other reason
-- distinguish between two elements, it compares them by their
-- addresses. Note that doing this may make the sorting algorithm
-- less efficient, so do it only if necessary.
--
-- Here is a simple example of sorting an array of doubles in
-- numerical order, using the comparison function defined above
-- (*note Comparison Functions::.):
--
-- {
-- double *array;
-- int size;
-- ...
-- qsort (array, size, sizeof (double), compare_doubles);
-- }
--
-- The `qsort' function derives its name from the fact that it was
-- originally implemented using the "quick sort" algorithm.
--
--
--File: libc.info, Node: Search/Sort Example, Next: Hash Search Function, Prev: Array Sort Function, Up: Searching and Sorting
--
--Searching and Sorting Example
--=============================
--
-- Here is an example showing the use of `qsort' and `bsearch' with an
--array of structures. The objects in the array are sorted by comparing
--their `name' fields with the `strcmp' function. Then, we can look up
--individual objects based on their names.
--
-- #include <stdlib.h>
-- #include <stdio.h>
-- #include <string.h>
--
-- /* Define an array of critters to sort. */
--
-- struct critter
-- {
-- const char *name;
-- const char *species;
-- };
--
-- struct critter muppets[] =
-- {
-- {"Kermit", "frog"},
-- {"Piggy", "pig"},
-- {"Gonzo", "whatever"},
-- {"Fozzie", "bear"},
-- {"Sam", "eagle"},
-- {"Robin", "frog"},
-- {"Animal", "animal"},
-- {"Camilla", "chicken"},
-- {"Sweetums", "monster"},
-- {"Dr. Strangepork", "pig"},
-- {"Link Hogthrob", "pig"},
-- {"Zoot", "human"},
-- {"Dr. Bunsen Honeydew", "human"},
-- {"Beaker", "human"},
-- {"Swedish Chef", "human"}
-- };
--
-- int count = sizeof (muppets) / sizeof (struct critter);
--
--
--
-- /* This is the comparison function used for sorting and searching. */
--
-- int
-- critter_cmp (const struct critter *c1, const struct critter *c2)
-- {
-- return strcmp (c1->name, c2->name);
-- }
--
--
-- /* Print information about a critter. */
--
-- void
-- print_critter (const struct critter *c)
-- {
-- printf ("%s, the %s\n", c->name, c->species);
-- }
-- /* Do the lookup into the sorted array. */
--
-- void
-- find_critter (const char *name)
-- {
-- struct critter target, *result;
-- target.name = name;
-- result = bsearch (&target, muppets, count, sizeof (struct critter),
-- critter_cmp);
-- if (result)
-- print_critter (result);
-- else
-- printf ("Couldn't find %s.\n", name);
-- }
--
-- /* Main program. */
--
-- int
-- main (void)
-- {
-- int i;
--
-- for (i = 0; i < count; i++)
-- print_critter (&muppets[i]);
-- printf ("\n");
--
-- qsort (muppets, count, sizeof (struct critter), critter_cmp);
--
-- for (i = 0; i < count; i++)
-- print_critter (&muppets[i]);
-- printf ("\n");
--
-- find_critter ("Kermit");
-- find_critter ("Gonzo");
-- find_critter ("Janice");
--
-- return 0;
-- }
--
-- The output from this program looks like:
--
-- Kermit, the frog
-- Piggy, the pig
-- Gonzo, the whatever
-- Fozzie, the bear
-- Sam, the eagle
-- Robin, the frog
-- Animal, the animal
-- Camilla, the chicken
-- Sweetums, the monster
-- Dr. Strangepork, the pig
-- Link Hogthrob, the pig
-- Zoot, the human
-- Dr. Bunsen Honeydew, the human
-- Beaker, the human
-- Swedish Chef, the human
--
-- Animal, the animal
-- Beaker, the human
-- Camilla, the chicken
-- Dr. Bunsen Honeydew, the human
-- Dr. Strangepork, the pig
-- Fozzie, the bear
-- Gonzo, the whatever
-- Kermit, the frog
-- Link Hogthrob, the pig
-- Piggy, the pig
-- Robin, the frog
-- Sam, the eagle
-- Swedish Chef, the human
-- Sweetums, the monster
-- Zoot, the human
--
-- Kermit, the frog
-- Gonzo, the whatever
-- Couldn't find Janice.
--
--
--File: libc.info, Node: Hash Search Function, Next: Tree Search Function, Prev: Search/Sort Example, Up: Searching and Sorting
--
--The `hsearch' function.
--=======================
--
-- The functions mentioned so far in this chapter are searching in a
--sorted or unsorted array. There are other methods to organize
--information which later should be searched. The costs of insert,
--delete and search differ. One possible implementation is using hashing
--tables.
--
-- - Function: int hcreate (size_t NEL)
-- The `hcreate' function creates a hashing table which can contain at
-- least NEL elements. There is no possibility to grow this table so
-- it is necessary to choose the value for NEL wisely. The used
-- methods to implement this function might make it necessary to make
-- the number of elements in the hashing table larger than the
-- expected maximal number of elements. Hashing tables usually work
-- inefficient if they are filled 80% or more. The constant access
-- time guaranteed by hashing can only be achieved if few collisions
-- exist. See Knuth's "The Art of Computer Programming, Part 3:
-- Searching and Sorting" for more information.
--
-- The weakest aspect of this function is that there can be at most
-- one hashing table used through the whole program. The table is
-- allocated in local memory out of control of the programmer. As an
-- extension the GNU C library provides an additional set of
-- functions with an reentrant interface which provide a similar
-- interface but which allow to keep arbitrary many hashing tables.
--
-- It is possible to use more than one hashing table in the program
-- run if the former table is first destroyed by a call to `hdestroy'.
--
-- The function returns a non-zero value if successful. If it return
-- zero something went wrong. This could either mean there is
-- already a hashing table in use or the program runs out of memory.
--
-- - Function: void hdestroy (void)
-- The `hdestroy' function can be used to free all the resources
-- allocated in a previous call of `hcreate'. After a call to this
-- function it is again possible to call `hcreate' and allocate a new
-- table with possibly different size.
--
-- It is important to remember that the elements contained in the
-- hashing table at the time `hdestroy' is called are *not* freed by
-- this function. It is the responsibility of the program code to
-- free those strings (if necessary at all). Freeing all the element
-- memory is not possible without extra, separately kept information
-- since there is no function to iterate through all available
-- elements in the hashing table. If it is really necessary to free
-- a table and all elements the programmer has to keep a list of all
-- table elements and before calling `hdestroy' s/he has to free all
-- element's data using this list. This is a very unpleasant
-- mechanism and it also shows that this kind of hashing tables is
-- mainly meant for tables which are created once and used until the
-- end of the program run.
--
-- Entries of the hashing table and keys for the search are defined
--using this type:
--
-- - Data type: struct ENTRY
-- Both elements of this structure are pointers to zero-terminated
-- strings. This is a limiting restriction of the functionality of
-- the `hsearch' functions. They can only be used for data sets
-- which use the NUL character always and solely to terminate the
-- records. It is not possible to handle general binary data.
--
-- `char *key'
-- Pointer to a zero-terminated string of characters describing
-- the key for the search or the element in the hashing table.
--
-- `char *data'
-- Pointer to a zero-terminated string of characters describing
-- the data. If the functions will be called only for searching
-- an existing entry this element might stay undefined since it
-- is not used.
--
-- - Function: ENTRY * hsearch (ENTRY ITEM, ACTION ACTION)
-- To search in a hashing table created using `hcreate' the `hsearch'
-- function must be used. This function can perform simple search
-- for an element (if ACTION has the `FIND') or it can alternatively
-- insert the key element into the hashing table, possibly replacing
-- a previous value (if ACTION is `ENTER').
--
-- The key is denoted by a pointer to an object of type `ENTRY'. For
-- locating the corresponding position in the hashing table only the
-- `key' element of the structure is used.
--
-- The return value depends on the ACTION parameter value. If it is
-- `FIND' the value is a pointer to the matching element in the
-- hashing table or `NULL' if no matching element exists. If ACTION
-- is `ENTER' the return value is only `NULL' if the programs runs
-- out of memory while adding the new element to the table.
-- Otherwise the return value is a pointer to the element in the
-- hashing table which contains newly added element based on the data
-- in KEY.
--
-- As mentioned before the hashing table used by the functions
--described so far is global and there can be at any time at most one
--hashing table in the program. A solution is to use the following
--functions which are a GNU extension. All have in common that they
--operate on a hashing table which is described by the content of an
--object of the type `struct hsearch_data'. This type should be treated
--as opaque, none of its members should be changed directly.
--
-- - Function: int hcreate_r (size_t NEL, struct hsearch_data *HTAB)
-- The `hcreate_r' function initializes the object pointed to by HTAB
-- to contain a hashing table with at least NEL elements. So this
-- function is equivalent to the `hcreate' function except that the
-- initialized data structure is controlled by the user.
--
-- This allows to have more than once hashing table at one time. The
-- memory necessary for the `struct hsearch_data' object can be
-- allocated dynamically.
--
-- The return value is non-zero if the operation were successful. if
-- the return value is zero something went wrong which probably means
-- the programs runs out of memory.
--
-- - Function: void hdestroy_r (struct hsearch_data *HTAB)
-- The `hdestroy_r' function frees all resources allocated by the
-- `hcreate_r' function for this very same object HTAB. As for
-- `hdestroy' it is the programs responsibility to free the strings
-- for the elements of the table.
--
-- - Function: int hsearch_r (ENTRY ITEM, ACTION ACTION, ENTRY **RETVAL,
-- struct hsearch_data *HTAB)
-- The `hsearch_r' function is equivalent to `hsearch'. The meaning
-- of the first two arguments is identical. But instead of operating
-- on a single global hashing table the function works on the table
-- described by the object pointed to by HTAB (which is initialized
-- by a call to `hcreate_r').
--
-- Another difference to `hcreate' is that the pointer to the found
-- entry in the table is not the return value of the functions. It is
-- returned by storing it in a pointer variables pointed to by the
-- RETVAL parameter. The return value of the function is an integer
-- value indicating success if it is non-zero and failure if it is
-- zero. In the later case the global variable ERRNO signals the
-- reason for the failure.
--
-- `ENOMEM'
-- The table is filled and `hsearch_r' was called with an so far
-- unknown key and ACTION set to `ENTER'.
--
-- `ESRCH'
-- The ACTION parameter is `FIND' and no corresponding element
-- is found in the table.
--
--
--File: libc.info, Node: Tree Search Function, Prev: Hash Search Function, Up: Searching and Sorting
--
--The `tsearch' function.
--=======================
--
-- Another common form to organize data for efficient search is to use
--trees. The `tsearch' function family provides a nice interface to
--functions to organize possibly large amounts of data by providing a mean
--access time proportional to the logarithm of the number of elements.
--The GNU C library implementation even guarantees that this bound is
--never exceeded even for input data which cause problems for simple
--binary tree implementations.
--
-- The functions described in the chapter are all described in the
--System V and X/Open specifications and are therefore quite portable.
--
-- In contrast to the `hsearch' functions the `tsearch' functions can
--be used with arbitrary data and not only zero-terminated strings.
--
-- The `tsearch' functions have the advantage that no function to
--initialize data structures is necessary. A simple pointer of type
--`void *' initialized to `NULL' is a valid tree and can be extended or
--searched.
--
-- - Function: void * tsearch (const void *KEY, void **ROOTP,
-- comparison_fn_t COMPAR)
-- The `tsearch' function searches in the tree pointed to by `*ROOTP'
-- for an element matching KEY. The function pointed to by COMPAR is
-- used to determine whether two elements match. *Note Comparison
-- Functions::, for a specification of the functions which can be
-- used for the COMPAR parameter.
--
-- If the tree does not contain a matching entry the KEY value will
-- be added to the tree. `tsearch' does not make a copy of the object
-- pointed to by KEY (how could it since the size is unknown).
-- Instead it adds a reference to this object which means the object
-- must be available as long as the tree data structure is used.
--
-- The tree is represented by a pointer to a pointer since it is
-- sometimes necessary to change the root node of the tree. So it
-- must not be assumed that the variable pointed to by ROOTP has the
-- same value after the call. This also shows that it is not safe to
-- call the `tsearch' function more than once at the same time using
-- the same tree. It is no problem to run it more than once at a
-- time on different trees.
--
-- The return value is a pointer to the matching element in the tree.
-- If a new element was created the pointer points to the new data
-- (which is in fact KEY). If an entry had to be created and the
-- program ran out of space `NULL' is returned.
--
-- - Function: void * tfind (const void *KEY, void *const *ROOTP,
-- comparison_fn_t COMPAR)
-- The `tfind' function is similar to the `tsearch' function. It
-- locates an element matching the one pointed to by KEY and returns
-- a pointer to this element. But if no matching element is
-- available no new element is entered (note that the ROOTP parameter
-- points to a constant pointer). Instead the function returns
-- `NULL'.
--
-- Another advantage of the `tsearch' function in contrast to the
--`hsearch' functions is that there is an easy way to remove elements.
--
-- - Function: void * tdelete (const void *KEY, void **ROOTP,
-- comparison_fn_t COMPAR)
-- To remove a specific element matching KEY from the tree `tdelete'
-- can be used. It locates the matching element using the same
-- method as `tfind'. The corresponding element is then removed and
-- the data if this tree node is returned by the function. If there
-- is no matching entry in the tree nothing can be deleted and the
-- function returns `NULL'.
--
-- - Function: void tdestroy (void *VROOT, __free_fn_t FREEFCT)
-- If the complete search tree has to be removed one can use
-- `tdestroy'. It frees all resources allocated by the `tsearch'
-- function to generate the tree pointed to by VROOT.
--
-- For the data in each tree node the function FREEFCT is called.
-- The pointer to the data is passed as the argument to the function.
-- If no such work is necessary FREEFCT must point to a function
-- doing nothing. It is called in any case.
--
-- This function is a GNU extension and not covered by the System V or
-- X/Open specifications.
--
-- In addition to the function to create and destroy the tree data
--structure there is another function which allows to apply a function on
--all elements of the tree. The function must have this type:
--
-- void __action_fn_t (const void *nodep, VISIT value, int level);
--
-- The NODEP is the data value of the current node (once given as the
--KEY argument to `tsearch'). LEVEL is a numeric value which corresponds
--to the depth of the current node in the tree. The root node has the
--depth 0 and its children have a depth of 1 and so on. The `VISIT' type
--is an enumeration type.
--
-- - Data Type: VISIT
-- The `VISIT' value indicates the status of the current node in the
-- tree and how the function is called. The status of a node is
-- either `leaf' or `internal node'. For each leaf node the function
-- is called exactly once, for each internal node it is called three
-- times: before the first child is processed, after the first child
-- is processed and after both children are processed. This makes it
-- possible to handle all three methods of tree traversal (or even a
-- combination of them).
--
-- `preorder'
-- The current node is an internal node and the function is
-- called before the first child was processed.
--
-- `endorder'
-- The current node is an internal node and the function is
-- called after the first child was processed.
--
-- `postorder'
-- The current node is an internal node and the function is
-- called after the second child was processed.
--
-- `leaf'
-- The current node is a leaf.
--
-- - Function: void twalk (const void *ROOT, __action_fn_t ACTION)
-- For each node in the tree with a node pointed to by ROOT the
-- `twalk' function calls the function provided by the parameter
-- ACTION. For leaf nodes the function is called exactly once with
-- VALUE set to `leaf'. For internal nodes the function is called
-- three times, setting the VALUE parameter or ACTION to the
-- appropriate value. The LEVEL argument for the ACTION function is
-- computed while descending the tree with increasing the value by
-- one for the descend to a child, starting with the value 0 for the
-- root node.
--
-- Since the functions used for the ACTION parameter to `twalk' must
-- not modify the tree data it is safe to run `twalk' is more than
-- one thread at the same time working on the same tree. It is also
-- safe to call `tfind' in parallel. Functions which modify the tree
-- must not be used. Otherwise the behaviour is undefined.
--
--
--File: libc.info, Node: Pattern Matching, Next: I/O Overview, Prev: Searching and Sorting, Up: Top
--
--Pattern Matching
--****************
--
-- The GNU C Library provides pattern matching facilities for two kinds
--of patterns: regular expressions and file-name wildcards. The library
--also provides a facility for expanding variable and command references
--and parsing text into words in the way the shell does.
--
--* Menu:
--
--* Wildcard Matching:: Matching a wildcard pattern against a single string.
--* Globbing:: Finding the files that match a wildcard pattern.
--* Regular Expressions:: Matching regular expressions against strings.
--* Word Expansion:: Expanding shell variables, nested commands,
-- arithmetic, and wildcards.
-- This is what the shell does with shell commands.
--
--
--File: libc.info, Node: Wildcard Matching, Next: Globbing, Up: Pattern Matching
--
--Wildcard Matching
--=================
--
-- This section describes how to match a wildcard pattern against a
--particular string. The result is a yes or no answer: does the string
--fit the pattern or not. The symbols described here are all declared in
--`fnmatch.h'.
--
-- - Function: int fnmatch (const char *PATTERN, const char *STRING, int
-- FLAGS)
-- This function tests whether the string STRING matches the pattern
-- PATTERN. It returns `0' if they do match; otherwise, it returns
-- the nonzero value `FNM_NOMATCH'. The arguments PATTERN and STRING
-- are both strings.
--
-- The argument FLAGS is a combination of flag bits that alter the
-- details of matching. See below for a list of the defined flags.
--
-- In the GNU C Library, `fnmatch' cannot experience an "error"--it
-- always returns an answer for whether the match succeeds. However,
-- other implementations of `fnmatch' might sometimes report "errors".
-- They would do so by returning nonzero values that are not equal to
-- `FNM_NOMATCH'.
--
-- These are the available flags for the FLAGS argument:
--
--`FNM_FILE_NAME'
-- Treat the `/' character specially, for matching file names. If
-- this flag is set, wildcard constructs in PATTERN cannot match `/'
-- in STRING. Thus, the only way to match `/' is with an explicit
-- `/' in PATTERN.
--
--`FNM_PATHNAME'
-- This is an alias for `FNM_FILE_NAME'; it comes from POSIX.2. We
-- don't recommend this name because we don't use the term "pathname"
-- for file names.
--
--`FNM_PERIOD'
-- Treat the `.' character specially if it appears at the beginning of
-- STRING. If this flag is set, wildcard constructs in PATTERN
-- cannot match `.' as the first character of STRING.
--
-- If you set both `FNM_PERIOD' and `FNM_FILE_NAME', then the special
-- treatment applies to `.' following `/' as well as to `.' at the
-- beginning of STRING. (The shell uses the `FNM_PERIOD' and
-- `FNM_FILE_NAME' flags together for matching file names.)
--
--`FNM_NOESCAPE'
-- Don't treat the `\' character specially in patterns. Normally,
-- `\' quotes the following character, turning off its special meaning
-- (if any) so that it matches only itself. When quoting is enabled,
-- the pattern `\?' matches only the string `?', because the question
-- mark in the pattern acts like an ordinary character.
--
-- If you use `FNM_NOESCAPE', then `\' is an ordinary character.
--
--`FNM_LEADING_DIR'
-- Ignore a trailing sequence of characters starting with a `/' in
-- STRING; that is to say, test whether STRING starts with a
-- directory name that PATTERN matches.
--
-- If this flag is set, either `foo*' or `foobar' as a pattern would
-- match the string `foobar/frobozz'.
--
--`FNM_CASEFOLD'
-- Ignore case in comparing STRING to PATTERN.
--
--
--File: libc.info, Node: Globbing, Next: Regular Expressions, Prev: Wildcard Matching, Up: Pattern Matching
--
--Globbing
--========
--
-- The archetypal use of wildcards is for matching against the files in
--a directory, and making a list of all the matches. This is called
--"globbing".
--
-- You could do this using `fnmatch', by reading the directory entries
--one by one and testing each one with `fnmatch'. But that would be slow
--(and complex, since you would have to handle subdirectories by hand).
--
-- The library provides a function `glob' to make this particular use
--of wildcards convenient. `glob' and the other symbols in this section
--are declared in `glob.h'.
--
--* Menu:
--
--* Calling Glob:: Basic use of `glob'.
--* Flags for Globbing:: Flags that enable various options in `glob'.
--* More Flags for Globbing:: GNU specific extensions to `glob'.
--
--
--File: libc.info, Node: Calling Glob, Next: Flags for Globbing, Up: Globbing
--
--Calling `glob'
----------------
--
-- The result of globbing is a vector of file names (strings). To
--return this vector, `glob' uses a special data type, `glob_t', which is
--a structure. You pass `glob' the address of the structure, and it
--fills in the structure's fields to tell you about the results.
--
-- - Data Type: glob_t
-- This data type holds a pointer to a word vector. More precisely,
-- it records both the address of the word vector and its size. The
-- GNU implementation contains some more fields which are non-standard
-- extensions.
--
-- `gl_pathc'
-- The number of elements in the vector.
--
-- `gl_pathv'
-- The address of the vector. This field has type `char **'.
--
-- `gl_offs'
-- The offset of the first real element of the vector, from its
-- nominal address in the `gl_pathv' field. Unlike the other
-- fields, this is always an input to `glob', rather than an
-- output from it.
--
-- If you use a nonzero offset, then that many elements at the
-- beginning of the vector are left empty. (The `glob' function
-- fills them with null pointers.)
--
-- The `gl_offs' field is meaningful only if you use the
-- `GLOB_DOOFFS' flag. Otherwise, the offset is always zero
-- regardless of what is in this field, and the first real
-- element comes at the beginning of the vector.
--
-- `gl_closedir'
-- The address of an alternative implementation of the `closedir'
-- function. It is used if the `GLOB_ALTDIRFUNC' bit is set in
-- the flag parameter. The type of this field is
-- `void (*) (void *)'.
--
-- This is a GNU extension.
--
-- `gl_readdir'
-- The address of an alternative implementation of the `readdir'
-- function used to read the contents of a directory. It is
-- used if the `GLOB_ALTDIRFUNC' bit is set in the flag
-- parameter. The type of this field is
-- `struct dirent *(*) (void *)'.
--
-- This is a GNU extension.
--
-- `gl_opendir'
-- The address of an alternative implementation of the `opendir'
-- function. It is used if the `GLOB_ALTDIRFUNC' bit is set in
-- the flag parameter. The type of this field is
-- `void *(*) (const char *)'.
--
-- This is a GNU extension.
--
-- `gl_stat'
-- The address of an alternative implementation of the `stat'
-- function to get information about an object in the
-- filesystem. It is used if the `GLOB_ALTDIRFUNC' bit is set
-- in the flag parameter. The type of this field is
-- `int (*) (const char *, struct stat *)'.
--
-- This is a GNU extension.
--
-- `gl_lstat'
-- The address of an alternative implementation of the `lstat'
-- function to get information about an object in the
-- filesystems, not following symbolic links. It is used if the
-- `GLOB_ALTDIRFUNC' bit is set in the flag parameter. The type
-- of this field is `int (*) (const char *, struct stat *)'.
--
-- This is a GNU extension.
--
-- - Function: int glob (const char *PATTERN, int FLAGS, int (*ERRFUNC)
-- (const char *FILENAME, int ERROR-CODE), glob_t *VECTOR-PTR)
-- The function `glob' does globbing using the pattern PATTERN in the
-- current directory. It puts the result in a newly allocated
-- vector, and stores the size and address of this vector into
-- `*VECTOR-PTR'. The argument FLAGS is a combination of bit flags;
-- see *Note Flags for Globbing::, for details of the flags.
--
-- The result of globbing is a sequence of file names. The function
-- `glob' allocates a string for each resulting word, then allocates
-- a vector of type `char **' to store the addresses of these
-- strings. The last element of the vector is a null pointer. This
-- vector is called the "word vector".
--
-- To return this vector, `glob' stores both its address and its
-- length (number of elements, not counting the terminating null
-- pointer) into `*VECTOR-PTR'.
--
-- Normally, `glob' sorts the file names alphabetically before
-- returning them. You can turn this off with the flag `GLOB_NOSORT'
-- if you want to get the information as fast as possible. Usually
-- it's a good idea to let `glob' sort them--if you process the files
-- in alphabetical order, the users will have a feel for the rate of
-- progress that your application is making.
--
-- If `glob' succeeds, it returns 0. Otherwise, it returns one of
-- these error codes:
--
-- `GLOB_ABORTED'
-- There was an error opening a directory, and you used the flag
-- `GLOB_ERR' or your specified ERRFUNC returned a nonzero value.
-- *Note Flags for Globbing::, for an explanation of the
-- `GLOB_ERR' flag and ERRFUNC.
--
-- `GLOB_NOMATCH'
-- The pattern didn't match any existing files. If you use the
-- `GLOB_NOCHECK' flag, then you never get this error code,
-- because that flag tells `glob' to *pretend* that the pattern
-- matched at least one file.
--
-- `GLOB_NOSPACE'
-- It was impossible to allocate memory to hold the result.
--
-- In the event of an error, `glob' stores information in
-- `*VECTOR-PTR' about all the matches it has found so far.
--
--
--File: libc.info, Node: Flags for Globbing, Next: More Flags for Globbing, Prev: Calling Glob, Up: Globbing
--
--Flags for Globbing
--------------------
--
-- This section describes the flags that you can specify in the FLAGS
--argument to `glob'. Choose the flags you want, and combine them with
--the C bitwise OR operator `|'.
--
--`GLOB_APPEND'
-- Append the words from this expansion to the vector of words
-- produced by previous calls to `glob'. This way you can
-- effectively expand several words as if they were concatenated with
-- spaces between them.
--
-- In order for appending to work, you must not modify the contents
-- of the word vector structure between calls to `glob'. And, if you
-- set `GLOB_DOOFFS' in the first call to `glob', you must also set
-- it when you append to the results.
--
-- Note that the pointer stored in `gl_pathv' may no longer be valid
-- after you call `glob' the second time, because `glob' might have
-- relocated the vector. So always fetch `gl_pathv' from the
-- `glob_t' structure after each `glob' call; *never* save the
-- pointer across calls.
--
--`GLOB_DOOFFS'
-- Leave blank slots at the beginning of the vector of words. The
-- `gl_offs' field says how many slots to leave. The blank slots
-- contain null pointers.
--
--`GLOB_ERR'
-- Give up right away and report an error if there is any difficulty
-- reading the directories that must be read in order to expand
-- PATTERN fully. Such difficulties might include a directory in
-- which you don't have the requisite access. Normally, `glob' tries
-- its best to keep on going despite any errors, reading whatever
-- directories it can.
--
-- You can exercise even more control than this by specifying an
-- error-handler function ERRFUNC when you call `glob'. If ERRFUNC
-- is not a null pointer, then `glob' doesn't give up right away when
-- it can't read a directory; instead, it calls ERRFUNC with two
-- arguments, like this:
--
-- (*ERRFUNC) (FILENAME, ERROR-CODE)
--
-- The argument FILENAME is the name of the directory that `glob'
-- couldn't open or couldn't read, and ERROR-CODE is the `errno'
-- value that was reported to `glob'.
--
-- If the error handler function returns nonzero, then `glob' gives up
-- right away. Otherwise, it continues.
--
--`GLOB_MARK'
-- If the pattern matches the name of a directory, append `/' to the
-- directory's name when returning it.
--
--`GLOB_NOCHECK'
-- If the pattern doesn't match any file names, return the pattern
-- itself as if it were a file name that had been matched.
-- (Normally, when the pattern doesn't match anything, `glob' returns
-- that there were no matches.)
--
--`GLOB_NOSORT'
-- Don't sort the file names; return them in no particular order.
-- (In practice, the order will depend on the order of the entries in
-- the directory.) The only reason *not* to sort is to save time.
--
--`GLOB_NOESCAPE'
-- Don't treat the `\' character specially in patterns. Normally,
-- `\' quotes the following character, turning off its special meaning
-- (if any) so that it matches only itself. When quoting is enabled,
-- the pattern `\?' matches only the string `?', because the question
-- mark in the pattern acts like an ordinary character.
--
-- If you use `GLOB_NOESCAPE', then `\' is an ordinary character.
--
-- `glob' does its work by calling the function `fnmatch' repeatedly.
-- It handles the flag `GLOB_NOESCAPE' by turning on the
-- `FNM_NOESCAPE' flag in calls to `fnmatch'.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-13 glibc-2.1.3/manual/libc.info-13
---- ../glibc-2.1.3/manual/libc.info-13 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-13 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1154 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: More Flags for Globbing, Prev: Flags for Globbing, Up: Globbing
--
--More Flags for Globbing
-------------------------
--
-- Beside the flags described in the last section, the GNU
--implementation of `glob' allows a few more flags which are also defined
--in the `glob.h' file. Some of the extensions implement functionality
--which is available in modern shell implementations.
--
--`GLOB_PERIOD'
-- The `.' character (period) is treated special. It cannot be
-- matched by wildcards. *Note Wildcard Matching::, `FNM_PERIOD'.
--
--`GLOB_MAGCHAR'
-- The `GLOB_MAGCHAR' value is not to be given to `glob' in the FLAGS
-- parameter. Instead, `glob' sets this bit in the GL_FLAGS element
-- of the GLOB_T structure provided as the result if the pattern used
-- for matching contains any wildcard character.
--
--`GLOB_ALTDIRFUNC'
-- Instead of the using the using the normal functions for accessing
-- the filesystem the `glob' implementation uses the user-supplied
-- functions specified in the structure pointed to by PGLOB
-- parameter. For more information about the functions refer to the
-- sections about directory handling see *Note Accessing
-- Directories::, and *Note Reading Attributes::.
--
--`GLOB_BRACE'
-- If this flag is given the handling of braces in the pattern is
-- changed. It is now required that braces appear correctly grouped.
-- I.e., for each opening brace there must be a closing one. Braces
-- can be used recursively. So it is possible to define one brace
-- expression in another one. It is important to note that the range
-- of each brace expression is completely contained in the outer
-- brace expression (if there is one).
--
-- The string between the matching braces is separated into single
-- expressions by splitting at `,' (comma) characters. The commas
-- themself are discarded. Please note what we said above about
-- recursive brace expressions. The commas used to separate the
-- subexpressions must be at the same level. Commas in brace
-- subexpressions are not matched. They are used during expansion of
-- the brace expression of the deeper level. The example below shows
-- this
--
-- glob ("{foo/{,bar,biz},baz}", GLOB_BRACE, NULL, &result)
--
-- is equivalent to the sequence
--
-- glob ("foo/", GLOB_BRACE, NULL, &result)
-- glob ("foo/bar", GLOB_BRACE|GLOB_APPEND, NULL, &result)
-- glob ("foo/biz", GLOB_BRACE|GLOB_APPEND, NULL, &result)
-- glob ("baz", GLOB_BRACE|GLOB_APPEND, NULL, &result)
--
-- if we leave aside error handling.
--
--`GLOB_NOMAGIC'
-- If the pattern contains no wildcard constructs (it is a literal
-- file name), return it as the sole "matching" word, even if no file
-- exists by that name.
--
--`GLOB_TILDE'
-- If this flag is used the character `~' (tilde) is handled special
-- if it appears at the beginning of the pattern. Instead of being
-- taken verbatim it is used to represent the home directory of a
-- known user.
--
-- If `~' is the only character in pattern or it is followed by a `/'
-- (slash), the home directory of the process owner is substituted.
-- Using `getlogin' and `getpwnam' the information is read from the
-- system databases. As an example take user `bart' with his home
-- directory at `/home/bart'. For him a call like
--
-- glob ("~/bin/*", GLOB_TILDE, NULL, &result)
--
-- would return the contents of the directory `/home/bart/bin'.
-- Instead of referring to the own home directory it is also possible
-- to name the home directory of other users. To do so one has to
-- append the user name after the tilde character. So the contents
-- of user `homer''s `bin' directory can be retrieved by
--
-- glob ("~homer/bin/*", GLOB_TILDE, NULL, &result)
--
-- If the user name is not valid or the home directory cannot be
-- determined for some reason the pattern is left untouched and
-- itself used as the result. I.e., if in the last example `home' is
-- not available the tilde expansion yields to `"~homer/bin/*"' and
-- `glob' is not looking for a directory named `~homer'.
--
-- This functionality is equivalent to what is available in C-shells
-- if the `nonomatch' flag is set.
--
--`GLOB_TILDE_CHECK'
-- If this flag is used `glob' behaves like as if `GLOB_TILDE' is
-- given. The only difference is that if the user name is not
-- available or the home directory cannot be determined for other
-- reasons this leads to an error. `glob' will return `GLOB_NOMATCH'
-- instead of using the pattern itself as the name.
--
-- This functionality is equivalent to what is available in C-shells
-- if `nonomatch' flag is not set.
--
--`GLOB_ONLYDIR'
-- If this flag is used the globbing function takes this as a *hint*
-- that the caller is only interested in directories matching the
-- pattern. If the information about the type of the file is easily
-- available non-directories will be rejected but no extra work will
-- be done to determine the information for each file. I.e., the
-- caller must still be able to filter directories out.
--
-- This functionality is only available with the GNU `glob'
-- implementation. It is mainly used internally to increase the
-- performance but might be useful for a user as well and therefore is
-- documented here.
--
-- Calling `glob' will in most cases allocate resources which are used
--to represent the result of the function call. If the same object of
--type `glob_t' is used in multiple call to `glob' the resources are
--freed or reused so that no leaks appear. But this does not include the
--time when all `glob' calls are done.
--
-- - Function: void globfree (glob_t *PGLOB)
-- The `globfree' function frees all resources allocated by previous
-- calls to `glob' associated with the object pointed to by PGLOB.
-- This function should be called whenever the currently used
-- `glob_t' typed object isn't used anymore.
--
--
--File: libc.info, Node: Regular Expressions, Next: Word Expansion, Prev: Globbing, Up: Pattern Matching
--
--Regular Expression Matching
--===========================
--
-- The GNU C library supports two interfaces for matching regular
--expressions. One is the standard POSIX.2 interface, and the other is
--what the GNU system has had for many years.
--
-- Both interfaces are declared in the header file `regex.h'. If you
--define `_POSIX_C_SOURCE', then only the POSIX.2 functions, structures,
--and constants are declared.
--
--* Menu:
--
--* POSIX Regexp Compilation:: Using `regcomp' to prepare to match.
--* Flags for POSIX Regexps:: Syntax variations for `regcomp'.
--* Matching POSIX Regexps:: Using `regexec' to match the compiled
-- pattern that you get from `regcomp'.
--* Regexp Subexpressions:: Finding which parts of the string were matched.
--* Subexpression Complications:: Find points of which parts were matched.
--* Regexp Cleanup:: Freeing storage; reporting errors.
--
--
--File: libc.info, Node: POSIX Regexp Compilation, Next: Flags for POSIX Regexps, Up: Regular Expressions
--
--POSIX Regular Expression Compilation
--------------------------------------
--
-- Before you can actually match a regular expression, you must
--"compile" it. This is not true compilation--it produces a special data
--structure, not machine instructions. But it is like ordinary
--compilation in that its purpose is to enable you to "execute" the
--pattern fast. (*Note Matching POSIX Regexps::, for how to use the
--compiled regular expression for matching.)
--
-- There is a special data type for compiled regular expressions:
--
-- - Data Type: regex_t
-- This type of object holds a compiled regular expression. It is
-- actually a structure. It has just one field that your programs
-- should look at:
--
-- `re_nsub'
-- This field holds the number of parenthetical subexpressions
-- in the regular expression that was compiled.
--
-- There are several other fields, but we don't describe them here,
-- because only the functions in the library should use them.
--
-- After you create a `regex_t' object, you can compile a regular
--expression into it by calling `regcomp'.
--
-- - Function: int regcomp (regex_t *COMPILED, const char *PATTERN, int
-- CFLAGS)
-- The function `regcomp' "compiles" a regular expression into a data
-- structure that you can use with `regexec' to match against a
-- string. The compiled regular expression format is designed for
-- efficient matching. `regcomp' stores it into `*COMPILED'.
--
-- It's up to you to allocate an object of type `regex_t' and pass its
-- address to `regcomp'.
--
-- The argument CFLAGS lets you specify various options that control
-- the syntax and semantics of regular expressions. *Note Flags for
-- POSIX Regexps::.
--
-- If you use the flag `REG_NOSUB', then `regcomp' omits from the
-- compiled regular expression the information necessary to record
-- how subexpressions actually match. In this case, you might as well
-- pass `0' for the MATCHPTR and NMATCH arguments when you call
-- `regexec'.
--
-- If you don't use `REG_NOSUB', then the compiled regular expression
-- does have the capacity to record how subexpressions match. Also,
-- `regcomp' tells you how many subexpressions PATTERN has, by
-- storing the number in `COMPILED->re_nsub'. You can use that value
-- to decide how long an array to allocate to hold information about
-- subexpression matches.
--
-- `regcomp' returns `0' if it succeeds in compiling the regular
-- expression; otherwise, it returns a nonzero error code (see the
-- table below). You can use `regerror' to produce an error message
-- string describing the reason for a nonzero value; see *Note Regexp
-- Cleanup::.
--
--
-- Here are the possible nonzero values that `regcomp' can return:
--
--`REG_BADBR'
-- There was an invalid `\{...\}' construct in the regular
-- expression. A valid `\{...\}' construct must contain either a
-- single number, or two numbers in increasing order separated by a
-- comma.
--
--`REG_BADPAT'
-- There was a syntax error in the regular expression.
--
--`REG_BADRPT'
-- A repetition operator such as `?' or `*' appeared in a bad
-- position (with no preceding subexpression to act on).
--
--`REG_ECOLLATE'
-- The regular expression referred to an invalid collating element
-- (one not defined in the current locale for string collation).
-- *Note Locale Categories::.
--
--`REG_ECTYPE'
-- The regular expression referred to an invalid character class name.
--
--`REG_EESCAPE'
-- The regular expression ended with `\'.
--
--`REG_ESUBREG'
-- There was an invalid number in the `\DIGIT' construct.
--
--`REG_EBRACK'
-- There were unbalanced square brackets in the regular expression.
--
--`REG_EPAREN'
-- An extended regular expression had unbalanced parentheses, or a
-- basic regular expression had unbalanced `\(' and `\)'.
--
--`REG_EBRACE'
-- The regular expression had unbalanced `\{' and `\}'.
--
--`REG_ERANGE'
-- One of the endpoints in a range expression was invalid.
--
--`REG_ESPACE'
-- `regcomp' ran out of memory.
--
--
--File: libc.info, Node: Flags for POSIX Regexps, Next: Matching POSIX Regexps, Prev: POSIX Regexp Compilation, Up: Regular Expressions
--
--Flags for POSIX Regular Expressions
-------------------------------------
--
-- These are the bit flags that you can use in the CFLAGS operand when
--compiling a regular expression with `regcomp'.
--
--`REG_EXTENDED'
-- Treat the pattern as an extended regular expression, rather than
-- as a basic regular expression.
--
--`REG_ICASE'
-- Ignore case when matching letters.
--
--`REG_NOSUB'
-- Don't bother storing the contents of the MATCHES-PTR array.
--
--`REG_NEWLINE'
-- Treat a newline in STRING as dividing STRING into multiple lines,
-- so that `$' can match before the newline and `^' can match after.
-- Also, don't permit `.' to match a newline, and don't permit
-- `[^...]' to match a newline.
--
-- Otherwise, newline acts like any other ordinary character.
--
--
--File: libc.info, Node: Matching POSIX Regexps, Next: Regexp Subexpressions, Prev: Flags for POSIX Regexps, Up: Regular Expressions
--
--Matching a Compiled POSIX Regular Expression
----------------------------------------------
--
-- Once you have compiled a regular expression, as described in *Note
--POSIX Regexp Compilation::, you can match it against strings using
--`regexec'. A match anywhere inside the string counts as success,
--unless the regular expression contains anchor characters (`^' or `$').
--
-- - Function: int regexec (regex_t *COMPILED, char *STRING, size_t
-- NMATCH, regmatch_t MATCHPTR [], int EFLAGS)
-- This function tries to match the compiled regular expression
-- `*COMPILED' against STRING.
--
-- `regexec' returns `0' if the regular expression matches;
-- otherwise, it returns a nonzero value. See the table below for
-- what nonzero values mean. You can use `regerror' to produce an
-- error message string describing the reason for a nonzero value;
-- see *Note Regexp Cleanup::.
--
-- The argument EFLAGS is a word of bit flags that enable various
-- options.
--
-- If you want to get information about what part of STRING actually
-- matched the regular expression or its subexpressions, use the
-- arguments MATCHPTR and NMATCH. Otherwise, pass `0' for NMATCH,
-- and `NULL' for MATCHPTR. *Note Regexp Subexpressions::.
--
-- You must match the regular expression with the same set of current
--locales that were in effect when you compiled the regular expression.
--
-- The function `regexec' accepts the following flags in the EFLAGS
--argument:
--
--`REG_NOTBOL'
-- Do not regard the beginning of the specified string as the
-- beginning of a line; more generally, don't make any assumptions
-- about what text might precede it.
--
--`REG_NOTEOL'
-- Do not regard the end of the specified string as the end of a
-- line; more generally, don't make any assumptions about what text
-- might follow it.
--
-- Here are the possible nonzero values that `regexec' can return:
--
--`REG_NOMATCH'
-- The pattern didn't match the string. This isn't really an error.
--
--`REG_ESPACE'
-- `regexec' ran out of memory.
--
--
--File: libc.info, Node: Regexp Subexpressions, Next: Subexpression Complications, Prev: Matching POSIX Regexps, Up: Regular Expressions
--
--Match Results with Subexpressions
-----------------------------------
--
-- When `regexec' matches parenthetical subexpressions of PATTERN, it
--records which parts of STRING they match. It returns that information
--by storing the offsets into an array whose elements are structures of
--type `regmatch_t'. The first element of the array (index `0') records
--the part of the string that matched the entire regular expression.
--Each other element of the array records the beginning and end of the
--part that matched a single parenthetical subexpression.
--
-- - Data Type: regmatch_t
-- This is the data type of the MATCHARRAY array that you pass to
-- `regexec'. It contains two structure fields, as follows:
--
-- `rm_so'
-- The offset in STRING of the beginning of a substring. Add
-- this value to STRING to get the address of that part.
--
-- `rm_eo'
-- The offset in STRING of the end of the substring.
--
-- - Data Type: regoff_t
-- `regoff_t' is an alias for another signed integer type. The
-- fields of `regmatch_t' have type `regoff_t'.
--
-- The `regmatch_t' elements correspond to subexpressions positionally;
--the first element (index `1') records where the first subexpression
--matched, the second element records the second subexpression, and so
--on. The order of the subexpressions is the order in which they begin.
--
-- When you call `regexec', you specify how long the MATCHPTR array is,
--with the NMATCH argument. This tells `regexec' how many elements to
--store. If the actual regular expression has more than NMATCH
--subexpressions, then you won't get offset information about the rest of
--them. But this doesn't alter whether the pattern matches a particular
--string or not.
--
-- If you don't want `regexec' to return any information about where
--the subexpressions matched, you can either supply `0' for NMATCH, or
--use the flag `REG_NOSUB' when you compile the pattern with `regcomp'.
--
--
--File: libc.info, Node: Subexpression Complications, Next: Regexp Cleanup, Prev: Regexp Subexpressions, Up: Regular Expressions
--
--Complications in Subexpression Matching
-----------------------------------------
--
-- Sometimes a subexpression matches a substring of no characters. This
--happens when `f\(o*\)' matches the string `fum'. (It really matches
--just the `f'.) In this case, both of the offsets identify the point in
--the string where the null substring was found. In this example, the
--offsets are both `1'.
--
-- Sometimes the entire regular expression can match without using some
--of its subexpressions at all--for example, when `ba\(na\)*' matches the
--string `ba', the parenthetical subexpression is not used. When this
--happens, `regexec' stores `-1' in both fields of the element for that
--subexpression.
--
-- Sometimes matching the entire regular expression can match a
--particular subexpression more than once--for example, when `ba\(na\)*'
--matches the string `bananana', the parenthetical subexpression matches
--three times. When this happens, `regexec' usually stores the offsets
--of the last part of the string that matched the subexpression. In the
--case of `bananana', these offsets are `6' and `8'.
--
-- But the last match is not always the one that is chosen. It's more
--accurate to say that the last *opportunity* to match is the one that
--takes precedence. What this means is that when one subexpression
--appears within another, then the results reported for the inner
--subexpression reflect whatever happened on the last match of the outer
--subexpression. For an example, consider `\(ba\(na\)*s \)*' matching
--the string `bananas bas '. The last time the inner expression actually
--matches is near the end of the first word. But it is *considered*
--again in the second word, and fails to match there. `regexec' reports
--nonuse of the "na" subexpression.
--
-- Another place where this rule applies is when the regular expression
-- \(ba\(na\)*s \|nefer\(ti\)* \)*
--
--matches `bananas nefertiti'. The "na" subexpression does match in the
--first word, but it doesn't match in the second word because the other
--alternative is used there. Once again, the second repetition of the
--outer subexpression overrides the first, and within that second
--repetition, the "na" subexpression is not used. So `regexec' reports
--nonuse of the "na" subexpression.
--
--
--File: libc.info, Node: Regexp Cleanup, Prev: Subexpression Complications, Up: Regular Expressions
--
--POSIX Regexp Matching Cleanup
-------------------------------
--
-- When you are finished using a compiled regular expression, you can
--free the storage it uses by calling `regfree'.
--
-- - Function: void regfree (regex_t *COMPILED)
-- Calling `regfree' frees all the storage that `*COMPILED' points
-- to. This includes various internal fields of the `regex_t'
-- structure that aren't documented in this manual.
--
-- `regfree' does not free the object `*COMPILED' itself.
--
-- You should always free the space in a `regex_t' structure with
--`regfree' before using the structure to compile another regular
--expression.
--
-- When `regcomp' or `regexec' reports an error, you can use the
--function `regerror' to turn it into an error message string.
--
-- - Function: size_t regerror (int ERRCODE, regex_t *COMPILED, char
-- *BUFFER, size_t LENGTH)
-- This function produces an error message string for the error code
-- ERRCODE, and stores the string in LENGTH bytes of memory starting
-- at BUFFER. For the COMPILED argument, supply the same compiled
-- regular expression structure that `regcomp' or `regexec' was
-- working with when it got the error. Alternatively, you can supply
-- `NULL' for COMPILED; you will still get a meaningful error
-- message, but it might not be as detailed.
--
-- If the error message can't fit in LENGTH bytes (including a
-- terminating null character), then `regerror' truncates it. The
-- string that `regerror' stores is always null-terminated even if it
-- has been truncated.
--
-- The return value of `regerror' is the minimum length needed to
-- store the entire error message. If this is less than LENGTH, then
-- the error message was not truncated, and you can use it.
-- Otherwise, you should call `regerror' again with a larger buffer.
--
-- Here is a function which uses `regerror', but always dynamically
-- allocates a buffer for the error message:
--
-- char *get_regerror (int errcode, regex_t *compiled)
-- {
-- size_t length = regerror (errcode, compiled, NULL, 0);
-- char *buffer = xmalloc (length);
-- (void) regerror (errcode, compiled, buffer, length);
-- return buffer;
-- }
--
--
--File: libc.info, Node: Word Expansion, Prev: Regular Expressions, Up: Pattern Matching
--
--Shell-Style Word Expansion
--==========================
--
-- "Word expansion" means the process of splitting a string into
--"words" and substituting for variables, commands, and wildcards just as
--the shell does.
--
-- For example, when you write `ls -l foo.c', this string is split into
--three separate words--`ls', `-l' and `foo.c'. This is the most basic
--function of word expansion.
--
-- When you write `ls *.c', this can become many words, because the
--word `*.c' can be replaced with any number of file names. This is
--called "wildcard expansion", and it is also a part of word expansion.
--
-- When you use `echo $PATH' to print your path, you are taking
--advantage of "variable substitution", which is also part of word
--expansion.
--
-- Ordinary programs can perform word expansion just like the shell by
--calling the library function `wordexp'.
--
--* Menu:
--
--* Expansion Stages:: What word expansion does to a string.
--* Calling Wordexp:: How to call `wordexp'.
--* Flags for Wordexp:: Options you can enable in `wordexp'.
--* Wordexp Example:: A sample program that does word expansion.
--* Tilde Expansion:: Details of how tilde expansion works.
--* Variable Substitution:: Different types of variable substitution.
--
--
--File: libc.info, Node: Expansion Stages, Next: Calling Wordexp, Up: Word Expansion
--
--The Stages of Word Expansion
------------------------------
--
-- When word expansion is applied to a sequence of words, it performs
--the following transformations in the order shown here:
--
-- 1. "Tilde expansion": Replacement of `~foo' with the name of the home
-- directory of `foo'.
--
-- 2. Next, three different transformations are applied in the same step,
-- from left to right:
--
-- * "Variable substitution": Environment variables are
-- substituted for references such as `$foo'.
--
-- * "Command substitution": Constructs such as ``cat foo`' and
-- the equivalent `$(cat foo)' are replaced with the output from
-- the inner command.
--
-- * "Arithmetic expansion": Constructs such as `$(($x-1))' are
-- replaced with the result of the arithmetic computation.
--
-- 3. "Field splitting": subdivision of the text into "words".
--
-- 4. "Wildcard expansion": The replacement of a construct such as `*.c'
-- with a list of `.c' file names. Wildcard expansion applies to an
-- entire word at a time, and replaces that word with 0 or more file
-- names that are themselves words.
--
-- 5. "Quote removal": The deletion of string-quotes, now that they have
-- done their job by inhibiting the above transformations when
-- appropriate.
--
-- For the details of these transformations, and how to write the
--constructs that use them, see `The BASH Manual' (to appear).
--
--
--File: libc.info, Node: Calling Wordexp, Next: Flags for Wordexp, Prev: Expansion Stages, Up: Word Expansion
--
--Calling `wordexp'
-------------------
--
-- All the functions, constants and data types for word expansion are
--declared in the header file `wordexp.h'.
--
-- Word expansion produces a vector of words (strings). To return this
--vector, `wordexp' uses a special data type, `wordexp_t', which is a
--structure. You pass `wordexp' the address of the structure, and it
--fills in the structure's fields to tell you about the results.
--
-- - Data Type: wordexp_t
-- This data type holds a pointer to a word vector. More precisely,
-- it records both the address of the word vector and its size.
--
-- `we_wordc'
-- The number of elements in the vector.
--
-- `we_wordv'
-- The address of the vector. This field has type `char **'.
--
-- `we_offs'
-- The offset of the first real element of the vector, from its
-- nominal address in the `we_wordv' field. Unlike the other
-- fields, this is always an input to `wordexp', rather than an
-- output from it.
--
-- If you use a nonzero offset, then that many elements at the
-- beginning of the vector are left empty. (The `wordexp'
-- function fills them with null pointers.)
--
-- The `we_offs' field is meaningful only if you use the
-- `WRDE_DOOFFS' flag. Otherwise, the offset is always zero
-- regardless of what is in this field, and the first real
-- element comes at the beginning of the vector.
--
-- - Function: int wordexp (const char *WORDS, wordexp_t
-- *WORD-VECTOR-PTR, int FLAGS)
-- Perform word expansion on the string WORDS, putting the result in
-- a newly allocated vector, and store the size and address of this
-- vector into `*WORD-VECTOR-PTR'. The argument FLAGS is a
-- combination of bit flags; see *Note Flags for Wordexp::, for
-- details of the flags.
--
-- You shouldn't use any of the characters `|&;<>' in the string
-- WORDS unless they are quoted; likewise for newline. If you use
-- these characters unquoted, you will get the `WRDE_BADCHAR' error
-- code. Don't use parentheses or braces unless they are quoted or
-- part of a word expansion construct. If you use quotation
-- characters `'"`', they should come in pairs that balance.
--
-- The results of word expansion are a sequence of words. The
-- function `wordexp' allocates a string for each resulting word, then
-- allocates a vector of type `char **' to store the addresses of
-- these strings. The last element of the vector is a null pointer.
-- This vector is called the "word vector".
--
-- To return this vector, `wordexp' stores both its address and its
-- length (number of elements, not counting the terminating null
-- pointer) into `*WORD-VECTOR-PTR'.
--
-- If `wordexp' succeeds, it returns 0. Otherwise, it returns one of
-- these error codes:
--
-- `WRDE_BADCHAR'
-- The input string WORDS contains an unquoted invalid character
-- such as `|'.
--
-- `WRDE_BADVAL'
-- The input string refers to an undefined shell variable, and
-- you used the flag `WRDE_UNDEF' to forbid such references.
--
-- `WRDE_CMDSUB'
-- The input string uses command substitution, and you used the
-- flag `WRDE_NOCMD' to forbid command substitution.
--
-- `WRDE_NOSPACE'
-- It was impossible to allocate memory to hold the result. In
-- this case, `wordexp' can store part of the results--as much
-- as it could allocate room for.
--
-- `WRDE_SYNTAX'
-- There was a syntax error in the input string. For example,
-- an unmatched quoting character is a syntax error.
--
-- - Function: void wordfree (wordexp_t *WORD-VECTOR-PTR)
-- Free the storage used for the word-strings and vector that
-- `*WORD-VECTOR-PTR' points to. This does not free the structure
-- `*WORD-VECTOR-PTR' itself--only the other data it points to.
--
--
--File: libc.info, Node: Flags for Wordexp, Next: Wordexp Example, Prev: Calling Wordexp, Up: Word Expansion
--
--Flags for Word Expansion
--------------------------
--
-- This section describes the flags that you can specify in the FLAGS
--argument to `wordexp'. Choose the flags you want, and combine them
--with the C operator `|'.
--
--`WRDE_APPEND'
-- Append the words from this expansion to the vector of words
-- produced by previous calls to `wordexp'. This way you can
-- effectively expand several words as if they were concatenated with
-- spaces between them.
--
-- In order for appending to work, you must not modify the contents
-- of the word vector structure between calls to `wordexp'. And, if
-- you set `WRDE_DOOFFS' in the first call to `wordexp', you must also
-- set it when you append to the results.
--
--`WRDE_DOOFFS'
-- Leave blank slots at the beginning of the vector of words. The
-- `we_offs' field says how many slots to leave. The blank slots
-- contain null pointers.
--
--`WRDE_NOCMD'
-- Don't do command substitution; if the input requests command
-- substitution, report an error.
--
--`WRDE_REUSE'
-- Reuse a word vector made by a previous call to `wordexp'. Instead
-- of allocating a new vector of words, this call to `wordexp' will
-- use the vector that already exists (making it larger if necessary).
--
-- Note that the vector may move, so it is not safe to save an old
-- pointer and use it again after calling `wordexp'. You must fetch
-- `we_pathv' anew after each call.
--
--`WRDE_SHOWERR'
-- Do show any error messages printed by commands run by command
-- substitution. More precisely, allow these commands to inherit the
-- standard error output stream of the current process. By default,
-- `wordexp' gives these commands a standard error stream that
-- discards all output.
--
--`WRDE_UNDEF'
-- If the input refers to a shell variable that is not defined,
-- report an error.
--
--
--File: libc.info, Node: Wordexp Example, Next: Tilde Expansion, Prev: Flags for Wordexp, Up: Word Expansion
--
--`wordexp' Example
-------------------
--
-- Here is an example of using `wordexp' to expand several strings and
--use the results to run a shell command. It also shows the use of
--`WRDE_APPEND' to concatenate the expansions and of `wordfree' to free
--the space allocated by `wordexp'.
--
-- int
-- expand_and_execute (const char *program, const char *options)
-- {
-- wordexp_t result;
-- pid_t pid
-- int status, i;
--
-- /* Expand the string for the program to run. */
-- switch (wordexp (program, &result, 0))
-- {
-- case 0: /* Successful. */
-- break;
-- case WRDE_NOSPACE:
-- /* If the error was `WRDE_NOSPACE',
-- then perhaps part of the result was allocated. */
-- wordfree (&result);
-- default: /* Some other error. */
-- return -1;
-- }
--
-- /* Expand the strings specified for the arguments. */
-- for (i = 0; args[i]; i++)
-- {
-- if (wordexp (options, &result, WRDE_APPEND))
-- {
-- wordfree (&result);
-- return -1;
-- }
-- }
--
-- pid = fork ();
-- if (pid == 0)
-- {
-- /* This is the child process. Execute the command. */
-- execv (result.we_wordv[0], result.we_wordv);
-- exit (EXIT_FAILURE);
-- }
-- else if (pid < 0)
-- /* The fork failed. Report failure. */
-- status = -1;
-- else
-- /* This is the parent process. Wait for the child to complete. */
-- if (waitpid (pid, &status, 0) != pid)
-- status = -1;
--
-- wordfree (&result);
-- return status;
-- }
--
--
--File: libc.info, Node: Tilde Expansion, Next: Variable Substitution, Prev: Wordexp Example, Up: Word Expansion
--
--Details of Tilde Expansion
----------------------------
--
-- It's a standard part of shell syntax that you can use `~' at the
--beginning of a file name to stand for your own home directory. You can
--use `~USER' to stand for USER's home directory.
--
-- "Tilde expansion" is the process of converting these abbreviations
--to the directory names that they stand for.
--
-- Tilde expansion applies to the `~' plus all following characters up
--to whitespace or a slash. It takes place only at the beginning of a
--word, and only if none of the characters to be transformed is quoted in
--any way.
--
-- Plain `~' uses the value of the environment variable `HOME' as the
--proper home directory name. `~' followed by a user name uses
--`getpwname' to look up that user in the user database, and uses
--whatever directory is recorded there. Thus, `~' followed by your own
--name can give different results from plain `~', if the value of `HOME'
--is not really your home directory.
--
--
--File: libc.info, Node: Variable Substitution, Prev: Tilde Expansion, Up: Word Expansion
--
--Details of Variable Substitution
----------------------------------
--
-- Part of ordinary shell syntax is the use of `$VARIABLE' to
--substitute the value of a shell variable into a command. This is called
--"variable substitution", and it is one part of doing word expansion.
--
-- There are two basic ways you can write a variable reference for
--substitution:
--
--`${VARIABLE}'
-- If you write braces around the variable name, then it is completely
-- unambiguous where the variable name ends. You can concatenate
-- additional letters onto the end of the variable value by writing
-- them immediately after the close brace. For example, `${foo}s'
-- expands into `tractors'.
--
--`$VARIABLE'
-- If you do not put braces around the variable name, then the
-- variable name consists of all the alphanumeric characters and
-- underscores that follow the `$'. The next punctuation character
-- ends the variable name. Thus, `$foo-bar' refers to the variable
-- `foo' and expands into `tractor-bar'.
--
-- When you use braces, you can also use various constructs to modify
--the value that is substituted, or test it in various ways.
--
--`${VARIABLE:-DEFAULT}'
-- Substitute the value of VARIABLE, but if that is empty or
-- undefined, use DEFAULT instead.
--
--`${VARIABLE:=DEFAULT}'
-- Substitute the value of VARIABLE, but if that is empty or
-- undefined, use DEFAULT instead and set the variable to DEFAULT.
--
--`${VARIABLE:?MESSAGE}'
-- If VARIABLE is defined and not empty, substitute its value.
--
-- Otherwise, print MESSAGE as an error message on the standard error
-- stream, and consider word expansion a failure.
--
--`${VARIABLE:+REPLACEMENT}'
-- Substitute REPLACEMENT, but only if VARIABLE is defined and
-- nonempty. Otherwise, substitute nothing for this construct.
--
--`${#VARIABLE}'
-- Substitute a numeral which expresses in base ten the number of
-- characters in the value of VARIABLE. `${#foo}' stands for `7',
-- because `tractor' is seven characters.
--
-- These variants of variable substitution let you remove part of the
--variable's value before substituting it. The PREFIX and SUFFIX are not
--mere strings; they are wildcard patterns, just like the patterns that
--you use to match multiple file names. But in this context, they match
--against parts of the variable value rather than against file names.
--
--`${VARIABLE%%SUFFIX}'
-- Substitute the value of VARIABLE, but first discard from that
-- variable any portion at the end that matches the pattern SUFFIX.
--
-- If there is more than one alternative for how to match against
-- SUFFIX, this construct uses the longest possible match.
--
-- Thus, `${foo%%r*}' substitutes `t', because the largest match for
-- `r*' at the end of `tractor' is `ractor'.
--
--`${VARIABLE%SUFFIX}'
-- Substitute the value of VARIABLE, but first discard from that
-- variable any portion at the end that matches the pattern SUFFIX.
--
-- If there is more than one alternative for how to match against
-- SUFFIX, this construct uses the shortest possible alternative.
--
-- Thus, `${foo%%r*}' substitutes `tracto', because the shortest
-- match for `r*' at the end of `tractor' is just `r'.
--
--`${VARIABLE##PREFIX}'
-- Substitute the value of VARIABLE, but first discard from that
-- variable any portion at the beginning that matches the pattern
-- PREFIX.
--
-- If there is more than one alternative for how to match against
-- PREFIX, this construct uses the longest possible match.
--
-- Thus, `${foo%%r*}' substitutes `t', because the largest match for
-- `r*' at the end of `tractor' is `ractor'.
--
--`${VARIABLE#PREFIX}'
-- Substitute the value of VARIABLE, but first discard from that
-- variable any portion at the beginning that matches the pattern
-- PREFIX.
--
-- If there is more than one alternative for how to match against
-- PREFIX, this construct uses the shortest possible alternative.
--
-- Thus, `${foo%%r*}' substitutes `tracto', because the shortest
-- match for `r*' at the end of `tractor' is just `r'.
--
--
--File: libc.info, Node: I/O Overview, Next: I/O on Streams, Prev: Pattern Matching, Up: Top
--
--Input/Output Overview
--*********************
--
-- Most programs need to do either input (reading data) or output
--(writing data), or most frequently both, in order to do anything
--useful. The GNU C library provides such a large selection of input and
--output functions that the hardest part is often deciding which function
--is most appropriate!
--
-- This chapter introduces concepts and terminology relating to input
--and output. Other chapters relating to the GNU I/O facilities are:
--
-- * *Note I/O on Streams::, which covers the high-level functions that
-- operate on streams, including formatted input and output.
--
-- * *Note Low-Level I/O::, which covers the basic I/O and control
-- functions on file descriptors.
--
-- * *Note File System Interface::, which covers functions for
-- operating on directories and for manipulating file attributes such
-- as access modes and ownership.
--
-- * *Note Pipes and FIFOs::, which includes information on the basic
-- interprocess communication facilities.
--
-- * *Note Sockets::, which covers a more complicated interprocess
-- communication facility with support for networking.
--
-- * *Note Low-Level Terminal Interface::, which covers functions for
-- changing how input and output to terminal or other serial devices
-- are processed.
--
--* Menu:
--
--* I/O Concepts:: Some basic information and terminology.
--* File Names:: How to refer to a file.
--
--
--File: libc.info, Node: I/O Concepts, Next: File Names, Up: I/O Overview
--
--Input/Output Concepts
--=====================
--
-- Before you can read or write the contents of a file, you must
--establish a connection or communications channel to the file. This
--process is called "opening" the file. You can open a file for reading,
--writing, or both.
--
-- The connection to an open file is represented either as a stream or
--as a file descriptor. You pass this as an argument to the functions
--that do the actual read or write operations, to tell them which file to
--operate on. Certain functions expect streams, and others are designed
--to operate on file descriptors.
--
-- When you have finished reading to or writing from the file, you can
--terminate the connection by "closing" the file. Once you have closed a
--stream or file descriptor, you cannot do any more input or output
--operations on it.
--
--* Menu:
--
--* Streams and File Descriptors:: The GNU Library provides two ways
-- to access the contents of files.
--* File Position:: The number of bytes from the
-- beginning of the file.
--
--
--File: libc.info, Node: Streams and File Descriptors, Next: File Position, Up: I/O Concepts
--
--Streams and File Descriptors
------------------------------
--
-- When you want to do input or output to a file, you have a choice of
--two basic mechanisms for representing the connection between your
--program and the file: file descriptors and streams. File descriptors
--are represented as objects of type `int', while streams are represented
--as `FILE *' objects.
--
-- File descriptors provide a primitive, low-level interface to input
--and output operations. Both file descriptors and streams can represent
--a connection to a device (such as a terminal), or a pipe or socket for
--communicating with another process, as well as a normal file. But, if
--you want to do control operations that are specific to a particular kind
--of device, you must use a file descriptor; there are no facilities to
--use streams in this way. You must also use file descriptors if your
--program needs to do input or output in special modes, such as
--nonblocking (or polled) input (*note File Status Flags::.).
--
-- Streams provide a higher-level interface, layered on top of the
--primitive file descriptor facilities. The stream interface treats all
--kinds of files pretty much alike--the sole exception being the three
--styles of buffering that you can choose (*note Stream Buffering::.).
--
-- The main advantage of using the stream interface is that the set of
--functions for performing actual input and output operations (as opposed
--to control operations) on streams is much richer and more powerful than
--the corresponding facilities for file descriptors. The file descriptor
--interface provides only simple functions for transferring blocks of
--characters, but the stream interface also provides powerful formatted
--input and output functions (`printf' and `scanf') as well as functions
--for character- and line-oriented input and output.
--
-- Since streams are implemented in terms of file descriptors, you can
--extract the file descriptor from a stream and perform low-level
--operations directly on the file descriptor. You can also initially open
--a connection as a file descriptor and then make a stream associated with
--that file descriptor.
--
-- In general, you should stick with using streams rather than file
--descriptors, unless there is some specific operation you want to do that
--can only be done on a file descriptor. If you are a beginning
--programmer and aren't sure what functions to use, we suggest that you
--concentrate on the formatted input functions (*note Formatted Input::.)
--and formatted output functions (*note Formatted Output::.).
--
-- If you are concerned about portability of your programs to systems
--other than GNU, you should also be aware that file descriptors are not
--as portable as streams. You can expect any system running ISO C to
--support streams, but non-GNU systems may not support file descriptors at
--all, or may only implement a subset of the GNU functions that operate on
--file descriptors. Most of the file descriptor functions in the GNU
--library are included in the POSIX.1 standard, however.
--
--
--File: libc.info, Node: File Position, Prev: Streams and File Descriptors, Up: I/O Concepts
--
--File Position
---------------
--
-- One of the attributes of an open file is its "file position" that
--keeps track of where in the file the next character is to be read or
--written. In the GNU system, and all POSIX.1 systems, the file position
--is simply an integer representing the number of bytes from the beginning
--of the file.
--
-- The file position is normally set to the beginning of the file when
--it is opened, and each time a character is read or written, the file
--position is incremented. In other words, access to the file is normally
--"sequential".
--
-- Ordinary files permit read or write operations at any position within
--the file. Some other kinds of files may also permit this. Files which
--do permit this are sometimes referred to as "random-access" files. You
--can change the file position using the `fseek' function on a stream
--(*note File Positioning::.) or the `lseek' function on a file
--descriptor (*note I/O Primitives::.). If you try to change the file
--position on a file that doesn't support random access, you get the
--`ESPIPE' error.
--
-- Streams and descriptors that are opened for "append access" are
--treated specially for output: output to such files is *always* appended
--sequentially to the *end* of the file, regardless of the file position.
--However, the file position is still used to control where in the file
--reading is done.
--
-- If you think about it, you'll realize that several programs can read
--a given file at the same time. In order for each program to be able to
--read the file at its own pace, each program must have its own file
--pointer, which is not affected by anything the other programs do.
--
-- In fact, each opening of a file creates a separate file position.
--Thus, if you open a file twice even in the same program, you get two
--streams or descriptors with independent file positions.
--
-- By contrast, if you open a descriptor and then duplicate it to get
--another descriptor, these two descriptors share the same file position:
--changing the file position of one descriptor will affect the other.
--
--
--File: libc.info, Node: File Names, Prev: I/O Concepts, Up: I/O Overview
--
--File Names
--==========
--
-- In order to open a connection to a file, or to perform other
--operations such as deleting a file, you need some way to refer to the
--file. Nearly all files have names that are strings--even files which
--are actually devices such as tape drives or terminals. These strings
--are called "file names". You specify the file name to say which file
--you want to open or operate on.
--
-- This section describes the conventions for file names and how the
--operating system works with them.
--
--* Menu:
--
--* Directories:: Directories contain entries for files.
--* File Name Resolution:: A file name specifies how to look up a file.
--* File Name Errors:: Error conditions relating to file names.
--* File Name Portability:: File name portability and syntax issues.
--
--
--File: libc.info, Node: Directories, Next: File Name Resolution, Up: File Names
--
--Directories
-------------
--
-- In order to understand the syntax of file names, you need to
--understand how the file system is organized into a hierarchy of
--directories.
--
-- A "directory" is a file that contains information to associate other
--files with names; these associations are called "links" or "directory
--entries". Sometimes, people speak of "files in a directory", but in
--reality, a directory only contains pointers to files, not the files
--themselves.
--
-- The name of a file contained in a directory entry is called a "file
--name component". In general, a file name consists of a sequence of one
--or more such components, separated by the slash character (`/'). A
--file name which is just one component names a file with respect to its
--directory. A file name with multiple components names a directory, and
--then a file in that directory, and so on.
--
-- Some other documents, such as the POSIX standard, use the term
--"pathname" for what we call a file name, and either "filename" or
--"pathname component" for what this manual calls a file name component.
--We don't use this terminology because a "path" is something completely
--different (a list of directories to search), and we think that
--"pathname" used for something else will confuse users. We always use
--"file name" and "file name component" (or sometimes just "component",
--where the context is obvious) in GNU documentation. Some macros use
--the POSIX terminology in their names, such as `PATH_MAX'. These macros
--are defined by the POSIX standard, so we cannot change their names.
--
-- You can find more detailed information about operations on
--directories in *Note File System Interface::.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-14 glibc-2.1.3/manual/libc.info-14
---- ../glibc-2.1.3/manual/libc.info-14 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-14 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1114 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: File Name Resolution, Next: File Name Errors, Prev: Directories, Up: File Names
--
--File Name Resolution
----------------------
--
-- A file name consists of file name components separated by slash
--(`/') characters. On the systems that the GNU C library supports,
--multiple successive `/' characters are equivalent to a single `/'
--character.
--
-- The process of determining what file a file name refers to is called
--"file name resolution". This is performed by examining the components
--that make up a file name in left-to-right order, and locating each
--successive component in the directory named by the previous component.
--Of course, each of the files that are referenced as directories must
--actually exist, be directories instead of regular files, and have the
--appropriate permissions to be accessible by the process; otherwise the
--file name resolution fails.
--
-- If a file name begins with a `/', the first component in the file
--name is located in the "root directory" of the process (usually all
--processes on the system have the same root directory). Such a file name
--is called an "absolute file name".
--
-- Otherwise, the first component in the file name is located in the
--current working directory (*note Working Directory::.). This kind of
--file name is called a "relative file name".
--
-- The file name components `.' ("dot") and `..' ("dot-dot") have
--special meanings. Every directory has entries for these file name
--components. The file name component `.' refers to the directory
--itself, while the file name component `..' refers to its "parent
--directory" (the directory that contains the link for the directory in
--question). As a special case, `..' in the root directory refers to the
--root directory itself, since it has no parent; thus `/..' is the same
--as `/'.
--
-- Here are some examples of file names:
--
--`/a'
-- The file named `a', in the root directory.
--
--`/a/b'
-- The file named `b', in the directory named `a' in the root
-- directory.
--
--`a'
-- The file named `a', in the current working directory.
--
--`/a/./b'
-- This is the same as `/a/b'.
--
--`./a'
-- The file named `a', in the current working directory.
--
--`../a'
-- The file named `a', in the parent directory of the current working
-- directory.
--
-- A file name that names a directory may optionally end in a `/'. You
--can specify a file name of `/' to refer to the root directory, but the
--empty string is not a meaningful file name. If you want to refer to
--the current working directory, use a file name of `.' or `./'.
--
-- Unlike some other operating systems, the GNU system doesn't have any
--built-in support for file types (or extensions) or file versions as part
--of its file name syntax. Many programs and utilities use conventions
--for file names--for example, files containing C source code usually
--have names suffixed with `.c'--but there is nothing in the file system
--itself that enforces this kind of convention.
--
--
--File: libc.info, Node: File Name Errors, Next: File Name Portability, Prev: File Name Resolution, Up: File Names
--
--File Name Errors
------------------
--
-- Functions that accept file name arguments usually detect these
--`errno' error conditions relating to the file name syntax or trouble
--finding the named file. These errors are referred to throughout this
--manual as the "usual file name errors".
--
--`EACCES'
-- The process does not have search permission for a directory
-- component of the file name.
--
--`ENAMETOOLONG'
-- This error is used when either the total length of a file name is
-- greater than `PATH_MAX', or when an individual file name component
-- has a length greater than `NAME_MAX'. *Note Limits for Files::.
--
-- In the GNU system, there is no imposed limit on overall file name
-- length, but some file systems may place limits on the length of a
-- component.
--
--`ENOENT'
-- This error is reported when a file referenced as a directory
-- component in the file name doesn't exist, or when a component is a
-- symbolic link whose target file does not exist. *Note Symbolic
-- Links::.
--
--`ENOTDIR'
-- A file that is referenced as a directory component in the file name
-- exists, but it isn't a directory.
--
--`ELOOP'
-- Too many symbolic links were resolved while trying to look up the
-- file name. The system has an arbitrary limit on the number of
-- symbolic links that may be resolved in looking up a single file
-- name, as a primitive way to detect loops. *Note Symbolic Links::.
--
--
--File: libc.info, Node: File Name Portability, Prev: File Name Errors, Up: File Names
--
--Portability of File Names
---------------------------
--
-- The rules for the syntax of file names discussed in *Note File
--Names::, are the rules normally used by the GNU system and by other
--POSIX systems. However, other operating systems may use other
--conventions.
--
-- There are two reasons why it can be important for you to be aware of
--file name portability issues:
--
-- * If your program makes assumptions about file name syntax, or
-- contains embedded literal file name strings, it is more difficult
-- to get it to run under other operating systems that use different
-- syntax conventions.
--
-- * Even if you are not concerned about running your program on
-- machines that run other operating systems, it may still be
-- possible to access files that use different naming conventions.
-- For example, you may be able to access file systems on another
-- computer running a different operating system over a network, or
-- read and write disks in formats used by other operating systems.
--
-- The ISO C standard says very little about file name syntax, only that
--file names are strings. In addition to varying restrictions on the
--length of file names and what characters can validly appear in a file
--name, different operating systems use different conventions and syntax
--for concepts such as structured directories and file types or
--extensions. Some concepts such as file versions might be supported in
--some operating systems and not by others.
--
-- The POSIX.1 standard allows implementations to put additional
--restrictions on file name syntax, concerning what characters are
--permitted in file names and on the length of file name and file name
--component strings. However, in the GNU system, you do not need to worry
--about these restrictions; any character except the null character is
--permitted in a file name string, and there are no limits on the length
--of file name strings.
--
--
--File: libc.info, Node: I/O on Streams, Next: Low-Level I/O, Prev: I/O Overview, Up: Top
--
--Input/Output on Streams
--***********************
--
-- This chapter describes the functions for creating streams and
--performing input and output operations on them. As discussed in *Note
--I/O Overview::, a stream is a fairly abstract, high-level concept
--representing a communications channel to a file, device, or process.
--
--* Menu:
--
--* Streams:: About the data type representing a stream.
--* Standard Streams:: Streams to the standard input and output
-- devices are created for you.
--* Opening Streams:: How to create a stream to talk to a file.
--* Closing Streams:: Close a stream when you are finished with it.
--* Simple Output:: Unformatted output by characters and lines.
--* Character Input:: Unformatted input by characters and words.
--* Line Input:: Reading a line or a record from a stream.
--* Unreading:: Peeking ahead/pushing back input just read.
--* Block Input/Output:: Input and output operations on blocks of data.
--* Formatted Output:: `printf' and related functions.
--* Customizing Printf:: You can define new conversion specifiers for
-- `printf' and friends.
--* Formatted Input:: `scanf' and related functions.
--* EOF and Errors:: How you can tell if an I/O error happens.
--* Binary Streams:: Some systems distinguish between text files
-- and binary files.
--* File Positioning:: About random-access streams.
--* Portable Positioning:: Random access on peculiar ISO C systems.
--* Stream Buffering:: How to control buffering of streams.
--* Other Kinds of Streams:: Streams that do not necessarily correspond
-- to an open file.
--* Formatted Messages:: Print strictly formatted messages.
--
--
--File: libc.info, Node: Streams, Next: Standard Streams, Up: I/O on Streams
--
--Streams
--=======
--
-- For historical reasons, the type of the C data structure that
--represents a stream is called `FILE' rather than "stream". Since most
--of the library functions deal with objects of type `FILE *', sometimes
--the term "file pointer" is also used to mean "stream". This leads to
--unfortunate confusion over terminology in many books on C. This
--manual, however, is careful to use the terms "file" and "stream" only
--in the technical sense.
--
-- The `FILE' type is declared in the header file `stdio.h'.
--
-- - Data Type: FILE
-- This is the data type used to represent stream objects. A `FILE'
-- object holds all of the internal state information about the
-- connection to the associated file, including such things as the
-- file position indicator and buffering information. Each stream
-- also has error and end-of-file status indicators that can be
-- tested with the `ferror' and `feof' functions; see *Note EOF and
-- Errors::.
--
-- `FILE' objects are allocated and managed internally by the
--input/output library functions. Don't try to create your own objects of
--type `FILE'; let the library do it. Your programs should deal only
--with pointers to these objects (that is, `FILE *' values) rather than
--the objects themselves.
--
--
--File: libc.info, Node: Standard Streams, Next: Opening Streams, Prev: Streams, Up: I/O on Streams
--
--Standard Streams
--================
--
-- When the `main' function of your program is invoked, it already has
--three predefined streams open and available for use. These represent
--the "standard" input and output channels that have been established for
--the process.
--
-- These streams are declared in the header file `stdio.h'.
--
-- - Variable: FILE * stdin
-- The "standard input" stream, which is the normal source of input
-- for the program.
--
-- - Variable: FILE * stdout
-- The "standard output" stream, which is used for normal output from
-- the program.
--
-- - Variable: FILE * stderr
-- The "standard error" stream, which is used for error messages and
-- diagnostics issued by the program.
--
-- In the GNU system, you can specify what files or processes
--correspond to these streams using the pipe and redirection facilities
--provided by the shell. (The primitives shells use to implement these
--facilities are described in *Note File System Interface::.) Most other
--operating systems provide similar mechanisms, but the details of how to
--use them can vary.
--
-- In the GNU C library, `stdin', `stdout', and `stderr' are normal
--variables which you can set just like any others. For example, to
--redirect the standard output to a file, you could do:
--
-- fclose (stdout);
-- stdout = fopen ("standard-output-file", "w");
--
-- Note however, that in other systems `stdin', `stdout', and `stderr'
--are macros that you cannot assign to in the normal way. But you can
--use `freopen' to get the effect of closing one and reopening it. *Note
--Opening Streams::.
--
--
--File: libc.info, Node: Opening Streams, Next: Closing Streams, Prev: Standard Streams, Up: I/O on Streams
--
--Opening Streams
--===============
--
-- Opening a file with the `fopen' function creates a new stream and
--establishes a connection between the stream and a file. This may
--involve creating a new file.
--
-- Everything described in this section is declared in the header file
--`stdio.h'.
--
-- - Function: FILE * fopen (const char *FILENAME, const char *OPENTYPE)
-- The `fopen' function opens a stream for I/O to the file FILENAME,
-- and returns a pointer to the stream.
--
-- The OPENTYPE argument is a string that controls how the file is
-- opened and specifies attributes of the resulting stream. It must
-- begin with one of the following sequences of characters:
--
-- `r'
-- Open an existing file for reading only.
--
-- `w'
-- Open the file for writing only. If the file already exists,
-- it is truncated to zero length. Otherwise a new file is
-- created.
--
-- `a'
-- Open a file for append access; that is, writing at the end of
-- file only. If the file already exists, its initial contents
-- are unchanged and output to the stream is appended to the end
-- of the file. Otherwise, a new, empty file is created.
--
-- `r+'
-- Open an existing file for both reading and writing. The
-- initial contents of the file are unchanged and the initial
-- file position is at the beginning of the file.
--
-- `w+'
-- Open a file for both reading and writing. If the file
-- already exists, it is truncated to zero length. Otherwise, a
-- new file is created.
--
-- `a+'
-- Open or create file for both reading and appending. If the
-- file exists, its initial contents are unchanged. Otherwise,
-- a new file is created. The initial file position for reading
-- is at the beginning of the file, but output is always
-- appended to the end of the file.
--
-- As you can see, `+' requests a stream that can do both input and
-- output. The ISO standard says that when using such a stream, you
-- must call `fflush' (*note Stream Buffering::.) or a file
-- positioning function such as `fseek' (*note File Positioning::.)
-- when switching from reading to writing or vice versa. Otherwise,
-- internal buffers might not be emptied properly. The GNU C library
-- does not have this limitation; you can do arbitrary reading and
-- writing operations on a stream in whatever order.
--
-- Additional characters may appear after these to specify flags for
-- the call. Always put the mode (`r', `w+', etc.) first; that is
-- the only part you are guaranteed will be understood by all systems.
--
-- The GNU C library defines one additional character for use in
-- OPENTYPE: the character `x' insists on creating a new file--if a
-- file FILENAME already exists, `fopen' fails rather than opening
-- it. If you use `x' you can are guaranteed that you will not
-- clobber an existing file. This is equivalent to the `O_EXCL'
-- option to the `open' function (*note Opening and Closing Files::.).
--
-- The character `b' in OPENTYPE has a standard meaning; it requests
-- a binary stream rather than a text stream. But this makes no
-- difference in POSIX systems (including the GNU system). If both
-- `+' and `b' are specified, they can appear in either order. *Note
-- Binary Streams::.
--
-- Any other characters in OPENTYPE are simply ignored. They may be
-- meaningful in other systems.
--
-- If the open fails, `fopen' returns a null pointer.
--
-- When the sources are compiling with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits machine this function is in fact `fopen64' since the LFS
-- interface replaces transparently the old interface.
--
-- You can have multiple streams (or file descriptors) pointing to the
--same file open at the same time. If you do only input, this works
--straightforwardly, but you must be careful if any output streams are
--included. *Note Stream/Descriptor Precautions::. This is equally true
--whether the streams are in one program (not usual) or in several
--programs (which can easily happen). It may be advantageous to use the
--file locking facilities to avoid simultaneous access. *Note File
--Locks::.
--
-- - Function: FILE * fopen64 (const char *FILENAME, const char *OPENTYPE)
-- This function is similar to `fopen' but the stream it returns a
-- pointer for is opened using `open64'. Therefore this stream can be
-- used even on files larger then 2^31 bytes on 32 bits machines.
--
-- Please note that the return type is still `FILE *'. There is no
-- special `FILE' type for the LFS interface.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' on a 32
-- bits machine this function is available under the name `fopen' and
-- so transparently replaces the old interface.
--
-- - Macro: int FOPEN_MAX
-- The value of this macro is an integer constant expression that
-- represents the minimum number of streams that the implementation
-- guarantees can be open simultaneously. You might be able to open
-- more than this many streams, but that is not guaranteed. The
-- value of this constant is at least eight, which includes the three
-- standard streams `stdin', `stdout', and `stderr'. In POSIX.1
-- systems this value is determined by the `OPEN_MAX' parameter;
-- *note General Limits::.. In BSD and GNU, it is controlled by the
-- `RLIMIT_NOFILE' resource limit; *note Limits on Resources::..
--
-- - Function: FILE * freopen (const char *FILENAME, const char
-- *OPENTYPE, FILE *STREAM)
-- This function is like a combination of `fclose' and `fopen'. It
-- first closes the stream referred to by STREAM, ignoring any errors
-- that are detected in the process. (Because errors are ignored,
-- you should not use `freopen' on an output stream if you have
-- actually done any output using the stream.) Then the file named by
-- FILENAME is opened with mode OPENTYPE as for `fopen', and
-- associated with the same stream object STREAM.
--
-- If the operation fails, a null pointer is returned; otherwise,
-- `freopen' returns STREAM.
--
-- `freopen' has traditionally been used to connect a standard stream
-- such as `stdin' with a file of your own choice. This is useful in
-- programs in which use of a standard stream for certain purposes is
-- hard-coded. In the GNU C library, you can simply close the
-- standard streams and open new ones with `fopen'. But other
-- systems lack this ability, so using `freopen' is more portable.
--
-- When the sources are compiling with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits machine this function is in fact `freopen64' since the LFS
-- interface replaces transparently the old interface.
--
-- - Function: FILE * freopen64 (const char *FILENAME, const char
-- *OPENTYPE, FILE *STREAM)
-- This function is similar to `freopen'. The only difference is that
-- on 32 bits machine the stream returned is able to read beyond the
-- 2^31 bytes limits imposed by the normal interface. It should be
-- noted that the stream pointed to by STREAM need not be opened
-- using `fopen64' or `freopen64' since its mode is not important for
-- this function.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' on a 32
-- bits machine this function is available under the name `freopen'
-- and so transparently replaces the old interface.
--
--
--File: libc.info, Node: Closing Streams, Next: Simple Output, Prev: Opening Streams, Up: I/O on Streams
--
--Closing Streams
--===============
--
-- When a stream is closed with `fclose', the connection between the
--stream and the file is cancelled. After you have closed a stream, you
--cannot perform any additional operations on it.
--
-- - Function: int fclose (FILE *STREAM)
-- This function causes STREAM to be closed and the connection to the
-- corresponding file to be broken. Any buffered output is written
-- and any buffered input is discarded. The `fclose' function returns
-- a value of `0' if the file was closed successfully, and `EOF' if
-- an error was detected.
--
-- It is important to check for errors when you call `fclose' to close
-- an output stream, because real, everyday errors can be detected at
-- this time. For example, when `fclose' writes the remaining
-- buffered output, it might get an error because the disk is full.
-- Even if you know the buffer is empty, errors can still occur when
-- closing a file if you are using NFS.
--
-- The function `fclose' is declared in `stdio.h'.
--
-- To close all streams currently available the GNU C Library provides
--another function.
--
-- - Function: int fcloseall (void)
-- This function causes all open streams of the process to be closed
-- and the connection to corresponding files to be broken. All
-- buffered data is written and any buffered input is discarded. The
-- `fcloseall' function returns a value of `0' if all the files were
-- closed successfully, and `EOF' if an error was detected.
--
-- This function should be used only in special situation, e.g., when
-- an error occurred and the program must be aborted. Normally each
-- single stream should be closed separately so that problems with
-- one stream can be identified. It is also problematic since the
-- standard streams (*note Standard Streams::.) will also be closed.
--
-- The function `fcloseall' is declared in `stdio.h'.
--
-- If the `main' function to your program returns, or if you call the
--`exit' function (*note Normal Termination::.), all open streams are
--automatically closed properly. If your program terminates in any other
--manner, such as by calling the `abort' function (*note Aborting a
--Program::.) or from a fatal signal (*note Signal Handling::.), open
--streams might not be closed properly. Buffered output might not be
--flushed and files may be incomplete. For more information on buffering
--of streams, see *Note Stream Buffering::.
--
--
--File: libc.info, Node: Simple Output, Next: Character Input, Prev: Closing Streams, Up: I/O on Streams
--
--Simple Output by Characters or Lines
--====================================
--
-- This section describes functions for performing character- and
--line-oriented output.
--
-- These functions are declared in the header file `stdio.h'.
--
-- - Function: int fputc (int C, FILE *STREAM)
-- The `fputc' function converts the character C to type `unsigned
-- char', and writes it to the stream STREAM. `EOF' is returned if a
-- write error occurs; otherwise the character C is returned.
--
-- - Function: int putc (int C, FILE *STREAM)
-- This is just like `fputc', except that most systems implement it as
-- a macro, making it faster. One consequence is that it may
-- evaluate the STREAM argument more than once, which is an exception
-- to the general rule for macros. `putc' is usually the best
-- function to use for writing a single character.
--
-- - Function: int putchar (int C)
-- The `putchar' function is equivalent to `putc' with `stdout' as
-- the value of the STREAM argument.
--
-- - Function: int fputs (const char *S, FILE *STREAM)
-- The function `fputs' writes the string S to the stream STREAM.
-- The terminating null character is not written. This function does
-- *not* add a newline character, either. It outputs only the
-- characters in the string.
--
-- This function returns `EOF' if a write error occurs, and otherwise
-- a non-negative value.
--
-- For example:
--
-- fputs ("Are ", stdout);
-- fputs ("you ", stdout);
-- fputs ("hungry?\n", stdout);
--
-- outputs the text `Are you hungry?' followed by a newline.
--
-- - Function: int puts (const char *S)
-- The `puts' function writes the string S to the stream `stdout'
-- followed by a newline. The terminating null character of the
-- string is not written. (Note that `fputs' does *not* write a
-- newline as this function does.)
--
-- `puts' is the most convenient function for printing simple
-- messages. For example:
--
-- puts ("This is a message.");
--
-- - Function: int putw (int W, FILE *STREAM)
-- This function writes the word W (that is, an `int') to STREAM. It
-- is provided for compatibility with SVID, but we recommend you use
-- `fwrite' instead (*note Block Input/Output::.).
--
--
--File: libc.info, Node: Character Input, Next: Line Input, Prev: Simple Output, Up: I/O on Streams
--
--Character Input
--===============
--
-- This section describes functions for performing character-oriented
--input. These functions are declared in the header file `stdio.h'.
--
-- These functions return an `int' value that is either a character of
--input, or the special value `EOF' (usually -1). It is important to
--store the result of these functions in a variable of type `int' instead
--of `char', even when you plan to use it only as a character. Storing
--`EOF' in a `char' variable truncates its value to the size of a
--character, so that it is no longer distinguishable from the valid
--character `(char) -1'. So always use an `int' for the result of `getc'
--and friends, and check for `EOF' after the call; once you've verified
--that the result is not `EOF', you can be sure that it will fit in a
--`char' variable without loss of information.
--
-- - Function: int fgetc (FILE *STREAM)
-- This function reads the next character as an `unsigned char' from
-- the stream STREAM and returns its value, converted to an `int'.
-- If an end-of-file condition or read error occurs, `EOF' is
-- returned instead.
--
-- - Function: int getc (FILE *STREAM)
-- This is just like `fgetc', except that it is permissible (and
-- typical) for it to be implemented as a macro that evaluates the
-- STREAM argument more than once. `getc' is often highly optimized,
-- so it is usually the best function to use to read a single
-- character.
--
-- - Function: int getchar (void)
-- The `getchar' function is equivalent to `getc' with `stdin' as the
-- value of the STREAM argument.
--
-- Here is an example of a function that does input using `fgetc'. It
--would work just as well using `getc' instead, or using `getchar ()'
--instead of `fgetc (stdin)'.
--
-- int
-- y_or_n_p (const char *question)
-- {
-- fputs (question, stdout);
-- while (1)
-- {
-- int c, answer;
-- /* Write a space to separate answer from question. */
-- fputc (' ', stdout);
-- /* Read the first character of the line.
-- This should be the answer character, but might not be. */
-- c = tolower (fgetc (stdin));
-- answer = c;
-- /* Discard rest of input line. */
-- while (c != '\n' && c != EOF)
-- c = fgetc (stdin);
-- /* Obey the answer if it was valid. */
-- if (answer == 'y')
-- return 1;
-- if (answer == 'n')
-- return 0;
-- /* Answer was invalid: ask for valid answer. */
-- fputs ("Please answer y or n:", stdout);
-- }
-- }
--
-- - Function: int getw (FILE *STREAM)
-- This function reads a word (that is, an `int') from STREAM. It's
-- provided for compatibility with SVID. We recommend you use
-- `fread' instead (*note Block Input/Output::.). Unlike `getc', any
-- `int' value could be a valid result. `getw' returns `EOF' when it
-- encounters end-of-file or an error, but there is no way to
-- distinguish this from an input word with value -1.
--
--
--File: libc.info, Node: Line Input, Next: Unreading, Prev: Character Input, Up: I/O on Streams
--
--Line-Oriented Input
--===================
--
-- Since many programs interpret input on the basis of lines, it's
--convenient to have functions to read a line of text from a stream.
--
-- Standard C has functions to do this, but they aren't very safe: null
--characters and even (for `gets') long lines can confuse them. So the
--GNU library provides the nonstandard `getline' function that makes it
--easy to read lines reliably.
--
-- Another GNU extension, `getdelim', generalizes `getline'. It reads
--a delimited record, defined as everything through the next occurrence
--of a specified delimiter character.
--
-- All these functions are declared in `stdio.h'.
--
-- - Function: ssize_t getline (char **LINEPTR, size_t *N, FILE *STREAM)
-- This function reads an entire line from STREAM, storing the text
-- (including the newline and a terminating null character) in a
-- buffer and storing the buffer address in `*LINEPTR'.
--
-- Before calling `getline', you should place in `*LINEPTR' the
-- address of a buffer `*N' bytes long, allocated with `malloc'. If
-- this buffer is long enough to hold the line, `getline' stores the
-- line in this buffer. Otherwise, `getline' makes the buffer bigger
-- using `realloc', storing the new buffer address back in `*LINEPTR'
-- and the increased size back in `*N'. *Note Unconstrained
-- Allocation::.
--
-- If you set `*LINEPTR' to a null pointer, and `*N' to zero, before
-- the call, then `getline' allocates the initial buffer for you by
-- calling `malloc'.
--
-- In either case, when `getline' returns, `*LINEPTR' is a `char *'
-- which points to the text of the line.
--
-- When `getline' is successful, it returns the number of characters
-- read (including the newline, but not including the terminating
-- null). This value enables you to distinguish null characters that
-- are part of the line from the null character inserted as a
-- terminator.
--
-- This function is a GNU extension, but it is the recommended way to
-- read lines from a stream. The alternative standard functions are
-- unreliable.
--
-- If an error occurs or end of file is reached, `getline' returns
-- `-1'.
--
-- - Function: ssize_t getdelim (char **LINEPTR, size_t *N, int
-- DELIMITER, FILE *STREAM)
-- This function is like `getline' except that the character which
-- tells it to stop reading is not necessarily newline. The argument
-- DELIMITER specifies the delimiter character; `getdelim' keeps
-- reading until it sees that character (or end of file).
--
-- The text is stored in LINEPTR, including the delimiter character
-- and a terminating null. Like `getline', `getdelim' makes LINEPTR
-- bigger if it isn't big enough.
--
-- `getline' is in fact implemented in terms of `getdelim', just like
-- this:
--
-- ssize_t
-- getline (char **lineptr, size_t *n, FILE *stream)
-- {
-- return getdelim (lineptr, n, '\n', stream);
-- }
--
-- - Function: char * fgets (char *S, int COUNT, FILE *STREAM)
-- The `fgets' function reads characters from the stream STREAM up to
-- and including a newline character and stores them in the string S,
-- adding a null character to mark the end of the string. You must
-- supply COUNT characters worth of space in S, but the number of
-- characters read is at most COUNT - 1. The extra character space
-- is used to hold the null character at the end of the string.
--
-- If the system is already at end of file when you call `fgets', then
-- the contents of the array S are unchanged and a null pointer is
-- returned. A null pointer is also returned if a read error occurs.
-- Otherwise, the return value is the pointer S.
--
-- *Warning:* If the input data has a null character, you can't tell.
-- So don't use `fgets' unless you know the data cannot contain a
-- null. Don't use it to read files edited by the user because, if
-- the user inserts a null character, you should either handle it
-- properly or print a clear error message. We recommend using
-- `getline' instead of `fgets'.
--
-- - Deprecated function: char * gets (char *S)
-- The function `gets' reads characters from the stream `stdin' up to
-- the next newline character, and stores them in the string S. The
-- newline character is discarded (note that this differs from the
-- behavior of `fgets', which copies the newline character into the
-- string). If `gets' encounters a read error or end-of-file, it
-- returns a null pointer; otherwise it returns S.
--
-- *Warning:* The `gets' function is *very dangerous* because it
-- provides no protection against overflowing the string S. The GNU
-- library includes it for compatibility only. You should *always*
-- use `fgets' or `getline' instead. To remind you of this, the
-- linker (if using GNU `ld') will issue a warning whenever you use
-- `gets'.
--
--
--File: libc.info, Node: Unreading, Next: Block Input/Output, Prev: Line Input, Up: I/O on Streams
--
--Unreading
--=========
--
-- In parser programs it is often useful to examine the next character
--in the input stream without removing it from the stream. This is called
--"peeking ahead" at the input because your program gets a glimpse of the
--input it will read next.
--
-- Using stream I/O, you can peek ahead at input by first reading it and
--then "unreading" it (also called "pushing it back" on the stream).
--Unreading a character makes it available to be input again from the
--stream, by the next call to `fgetc' or other input function on that
--stream.
--
--* Menu:
--
--* Unreading Idea:: An explanation of unreading with pictures.
--* How Unread:: How to call `ungetc' to do unreading.
--
--
--File: libc.info, Node: Unreading Idea, Next: How Unread, Up: Unreading
--
--What Unreading Means
----------------------
--
-- Here is a pictorial explanation of unreading. Suppose you have a
--stream reading a file that contains just six characters, the letters
--`foobar'. Suppose you have read three characters so far. The
--situation looks like this:
--
-- f o o b a r
-- ^
--
--so the next input character will be `b'.
--
-- If instead of reading `b' you unread the letter `o', you get a
--situation like this:
--
-- f o o b a r
-- |
-- o--
-- ^
--
--so that the next input characters will be `o' and `b'.
--
-- If you unread `9' instead of `o', you get this situation:
--
-- f o o b a r
-- |
-- 9--
-- ^
--
--so that the next input characters will be `9' and `b'.
--
--
--File: libc.info, Node: How Unread, Prev: Unreading Idea, Up: Unreading
--
--Using `ungetc' To Do Unreading
--------------------------------
--
-- The function to unread a character is called `ungetc', because it
--reverses the action of `getc'.
--
-- - Function: int ungetc (int C, FILE *STREAM)
-- The `ungetc' function pushes back the character C onto the input
-- stream STREAM. So the next input from STREAM will read C before
-- anything else.
--
-- If C is `EOF', `ungetc' does nothing and just returns `EOF'. This
-- lets you call `ungetc' with the return value of `getc' without
-- needing to check for an error from `getc'.
--
-- The character that you push back doesn't have to be the same as
-- the last character that was actually read from the stream. In
-- fact, it isn't necessary to actually read any characters from the
-- stream before unreading them with `ungetc'! But that is a strange
-- way to write a program; usually `ungetc' is used only to unread a
-- character that was just read from the same stream.
--
-- The GNU C library only supports one character of pushback--in other
-- words, it does not work to call `ungetc' twice without doing input
-- in between. Other systems might let you push back multiple
-- characters; then reading from the stream retrieves the characters
-- in the reverse order that they were pushed.
--
-- Pushing back characters doesn't alter the file; only the internal
-- buffering for the stream is affected. If a file positioning
-- function (such as `fseek', `fseeko' or `rewind'; *note File
-- Positioning::.) is called, any pending pushed-back characters are
-- discarded.
--
-- Unreading a character on a stream that is at end of file clears the
-- end-of-file indicator for the stream, because it makes the
-- character of input available. After you read that character,
-- trying to read again will encounter end of file.
--
-- Here is an example showing the use of `getc' and `ungetc' to skip
--over whitespace characters. When this function reaches a
--non-whitespace character, it unreads that character to be seen again on
--the next read operation on the stream.
--
-- #include <stdio.h>
-- #include <ctype.h>
--
-- void
-- skip_whitespace (FILE *stream)
-- {
-- int c;
-- do
-- /* No need to check for `EOF' because it is not
-- `isspace', and `ungetc' ignores `EOF'. */
-- c = getc (stream);
-- while (isspace (c));
-- ungetc (c, stream);
-- }
--
--
--File: libc.info, Node: Block Input/Output, Next: Formatted Output, Prev: Unreading, Up: I/O on Streams
--
--Block Input/Output
--==================
--
-- This section describes how to do input and output operations on
--blocks of data. You can use these functions to read and write binary
--data, as well as to read and write text in fixed-size blocks instead of
--by characters or lines.
--
-- Binary files are typically used to read and write blocks of data in
--the same format as is used to represent the data in a running program.
--In other words, arbitrary blocks of memory--not just character or string
--objects--can be written to a binary file, and meaningfully read in
--again by the same program.
--
-- Storing data in binary form is often considerably more efficient than
--using the formatted I/O functions. Also, for floating-point numbers,
--the binary form avoids possible loss of precision in the conversion
--process. On the other hand, binary files can't be examined or modified
--easily using many standard file utilities (such as text editors), and
--are not portable between different implementations of the language, or
--different kinds of computers.
--
-- These functions are declared in `stdio.h'.
--
-- - Function: size_t fread (void *DATA, size_t SIZE, size_t COUNT, FILE
-- *STREAM)
-- This function reads up to COUNT objects of size SIZE into the
-- array DATA, from the stream STREAM. It returns the number of
-- objects actually read, which might be less than COUNT if a read
-- error occurs or the end of the file is reached. This function
-- returns a value of zero (and doesn't read anything) if either SIZE
-- or COUNT is zero.
--
-- If `fread' encounters end of file in the middle of an object, it
-- returns the number of complete objects read, and discards the
-- partial object. Therefore, the stream remains at the actual end
-- of the file.
--
-- - Function: size_t fwrite (const void *DATA, size_t SIZE, size_t
-- COUNT, FILE *STREAM)
-- This function writes up to COUNT objects of size SIZE from the
-- array DATA, to the stream STREAM. The return value is normally
-- COUNT, if the call succeeds. Any other value indicates some sort
-- of error, such as running out of space.
--
--
--File: libc.info, Node: Formatted Output, Next: Customizing Printf, Prev: Block Input/Output, Up: I/O on Streams
--
--Formatted Output
--================
--
-- The functions described in this section (`printf' and related
--functions) provide a convenient way to perform formatted output. You
--call `printf' with a "format string" or "template string" that
--specifies how to format the values of the remaining arguments.
--
-- Unless your program is a filter that specifically performs line- or
--character-oriented processing, using `printf' or one of the other
--related functions described in this section is usually the easiest and
--most concise way to perform output. These functions are especially
--useful for printing error messages, tables of data, and the like.
--
--* Menu:
--
--* Formatted Output Basics:: Some examples to get you started.
--* Output Conversion Syntax:: General syntax of conversion
-- specifications.
--* Table of Output Conversions:: Summary of output conversions and
-- what they do.
--* Integer Conversions:: Details about formatting of integers.
--* Floating-Point Conversions:: Details about formatting of
-- floating-point numbers.
--* Other Output Conversions:: Details about formatting of strings,
-- characters, pointers, and the like.
--* Formatted Output Functions:: Descriptions of the actual functions.
--* Dynamic Output:: Functions that allocate memory for the output.
--* Variable Arguments Output:: `vprintf' and friends.
--* Parsing a Template String:: What kinds of args does a given template
-- call for?
--* Example of Parsing:: Sample program using `parse_printf_format'.
--
--
--File: libc.info, Node: Formatted Output Basics, Next: Output Conversion Syntax, Up: Formatted Output
--
--Formatted Output Basics
-------------------------
--
-- The `printf' function can be used to print any number of arguments.
--The template string argument you supply in a call provides information
--not only about the number of additional arguments, but also about their
--types and what style should be used for printing them.
--
-- Ordinary characters in the template string are simply written to the
--output stream as-is, while "conversion specifications" introduced by a
--`%' character in the template cause subsequent arguments to be
--formatted and written to the output stream. For example,
--
-- int pct = 37;
-- char filename[] = "foo.txt";
-- printf ("Processing of `%s' is %d%% finished.\nPlease be patient.\n",
-- filename, pct);
--
--produces output like
--
-- Processing of `foo.txt' is 37% finished.
-- Please be patient.
--
-- This example shows the use of the `%d' conversion to specify that an
--`int' argument should be printed in decimal notation, the `%s'
--conversion to specify printing of a string argument, and the `%%'
--conversion to print a literal `%' character.
--
-- There are also conversions for printing an integer argument as an
--unsigned value in octal, decimal, or hexadecimal radix (`%o', `%u', or
--`%x', respectively); or as a character value (`%c').
--
-- Floating-point numbers can be printed in normal, fixed-point notation
--using the `%f' conversion or in exponential notation using the `%e'
--conversion. The `%g' conversion uses either `%e' or `%f' format,
--depending on what is more appropriate for the magnitude of the
--particular number.
--
-- You can control formatting more precisely by writing "modifiers"
--between the `%' and the character that indicates which conversion to
--apply. These slightly alter the ordinary behavior of the conversion.
--For example, most conversion specifications permit you to specify a
--minimum field width and a flag indicating whether you want the result
--left- or right-justified within the field.
--
-- The specific flags and modifiers that are permitted and their
--interpretation vary depending on the particular conversion. They're all
--described in more detail in the following sections. Don't worry if this
--all seems excessively complicated at first; you can almost always get
--reasonable free-format output without using any of the modifiers at all.
--The modifiers are mostly used to make the output look "prettier" in
--tables.
--
--
--File: libc.info, Node: Output Conversion Syntax, Next: Table of Output Conversions, Prev: Formatted Output Basics, Up: Formatted Output
--
--Output Conversion Syntax
--------------------------
--
-- This section provides details about the precise syntax of conversion
--specifications that can appear in a `printf' template string.
--
-- Characters in the template string that are not part of a conversion
--specification are printed as-is to the output stream. Multibyte
--character sequences (*note Character Set Handling::.) are permitted in a
--template string.
--
-- The conversion specifications in a `printf' template string have the
--general form:
--
-- % [ PARAM-NO $] FLAGS WIDTH [ . PRECISION ] TYPE CONVERSION
--
-- For example, in the conversion specifier `%-10.8ld', the `-' is a
--flag, `10' specifies the field width, the precision is `8', the letter
--`l' is a type modifier, and `d' specifies the conversion style. (This
--particular type specifier says to print a `long int' argument in
--decimal notation, with a minimum of 8 digits left-justified in a field
--at least 10 characters wide.)
--
-- In more detail, output conversion specifications consist of an
--initial `%' character followed in sequence by:
--
-- * An optional specification of the parameter used for this format.
-- Normally the parameters to the `printf' function a assigned to the
-- formats in the order of appearance in the format string. But in
-- some situations (such as message translation) this is not
-- desirable and this extension allows to specify and explicit
-- parameter to be used.
--
-- The PARAM-NO part of the format must be an integer in the range of
-- 1 to the maximum number of arguments present to the function call.
-- Some implementations limit this number to a certainly upper
-- bound. The exact limit can be retrieved by the following constant.
--
-- - Macro: NL_ARGMAX
-- The value of `ARGMAX' is the maximum value allowed for the
-- specification of an positional parameter in a `printf' call.
-- The actual value in effect at runtime can be retrieved by
-- using `sysconf' using the `_SC_NL_ARGMAX' parameter *note
-- Sysconf Definition::..
--
-- Some system have a quite low limit such as 9 for System V
-- systems. The GNU C library has no real limit.
--
-- If any of the formats has a specification for the parameter
-- position all of them in the format string shall have one.
-- Otherwise the behaviour is undefined.
--
-- * Zero or more "flag characters" that modify the normal behavior of
-- the conversion specification.
--
-- * An optional decimal integer specifying the "minimum field width".
-- If the normal conversion produces fewer characters than this, the
-- field is padded with spaces to the specified width. This is a
-- *minimum* value; if the normal conversion produces more characters
-- than this, the field is *not* truncated. Normally, the output is
-- right-justified within the field.
--
-- You can also specify a field width of `*'. This means that the
-- next argument in the argument list (before the actual value to be
-- printed) is used as the field width. The value must be an `int'.
-- If the value is negative, this means to set the `-' flag (see
-- below) and to use the absolute value as the field width.
--
-- * An optional "precision" to specify the number of digits to be
-- written for the numeric conversions. If the precision is
-- specified, it consists of a period (`.') followed optionally by a
-- decimal integer (which defaults to zero if omitted).
--
-- You can also specify a precision of `*'. This means that the next
-- argument in the argument list (before the actual value to be
-- printed) is used as the precision. The value must be an `int',
-- and is ignored if it is negative. If you specify `*' for both the
-- field width and precision, the field width argument precedes the
-- precision argument. Other C library versions may not recognize
-- this syntax.
--
-- * An optional "type modifier character", which is used to specify the
-- data type of the corresponding argument if it differs from the
-- default type. (For example, the integer conversions assume a type
-- of `int', but you can specify `h', `l', or `L' for other integer
-- types.)
--
-- * A character that specifies the conversion to be applied.
--
-- The exact options that are permitted and how they are interpreted
--vary between the different conversion specifiers. See the descriptions
--of the individual conversions for information about the particular
--options that they use.
--
-- With the `-Wformat' option, the GNU C compiler checks calls to
--`printf' and related functions. It examines the format string and
--verifies that the correct number and types of arguments are supplied.
--There is also a GNU C syntax to tell the compiler that a function you
--write uses a `printf'-style format string. *Note Declaring Attributes
--of Functions: (gcc.info)Function Attributes, for more information.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-15 glibc-2.1.3/manual/libc.info-15
---- ../glibc-2.1.3/manual/libc.info-15 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-15 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1211 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Table of Output Conversions, Next: Integer Conversions, Prev: Output Conversion Syntax, Up: Formatted Output
--
--Table of Output Conversions
-----------------------------
--
-- Here is a table summarizing what all the different conversions do:
--
--`%d', `%i'
-- Print an integer as a signed decimal number. *Note Integer
-- Conversions::, for details. `%d' and `%i' are synonymous for
-- output, but are different when used with `scanf' for input (*note
-- Table of Input Conversions::.).
--
--`%o'
-- Print an integer as an unsigned octal number. *Note Integer
-- Conversions::, for details.
--
--`%u'
-- Print an integer as an unsigned decimal number. *Note Integer
-- Conversions::, for details.
--
--`%x', `%X'
-- Print an integer as an unsigned hexadecimal number. `%x' uses
-- lower-case letters and `%X' uses upper-case. *Note Integer
-- Conversions::, for details.
--
--`%f'
-- Print a floating-point number in normal (fixed-point) notation.
-- *Note Floating-Point Conversions::, for details.
--
--`%e', `%E'
-- Print a floating-point number in exponential notation. `%e' uses
-- lower-case letters and `%E' uses upper-case. *Note Floating-Point
-- Conversions::, for details.
--
--`%g', `%G'
-- Print a floating-point number in either normal or exponential
-- notation, whichever is more appropriate for its magnitude. `%g'
-- uses lower-case letters and `%G' uses upper-case. *Note
-- Floating-Point Conversions::, for details.
--
--`%a', `%A'
-- Print a floating-point number in a hexadecimal fractional notation
-- which the exponent to base 2 represented in decimal digits. `%a'
-- uses lower-case letters and `%A' uses upper-case. *Note
-- Floating-Point Conversions::, for details.
--
--`%c'
-- Print a single character. *Note Other Output Conversions::.
--
--`%s'
-- Print a string. *Note Other Output Conversions::.
--
--`%p'
-- Print the value of a pointer. *Note Other Output Conversions::.
--
--`%n'
-- Get the number of characters printed so far. *Note Other Output
-- Conversions::. Note that this conversion specification never
-- produces any output.
--
--`%m'
-- Print the string corresponding to the value of `errno'. (This is
-- a GNU extension.) *Note Other Output Conversions::.
--
--`%%'
-- Print a literal `%' character. *Note Other Output Conversions::.
--
-- If the syntax of a conversion specification is invalid, unpredictable
--things will happen, so don't do this. If there aren't enough function
--arguments provided to supply values for all the conversion
--specifications in the template string, or if the arguments are not of
--the correct types, the results are unpredictable. If you supply more
--arguments than conversion specifications, the extra argument values are
--simply ignored; this is sometimes useful.
--
--
--File: libc.info, Node: Integer Conversions, Next: Floating-Point Conversions, Prev: Table of Output Conversions, Up: Formatted Output
--
--Integer Conversions
---------------------
--
-- This section describes the options for the `%d', `%i', `%o', `%u',
--`%x', and `%X' conversion specifications. These conversions print
--integers in various formats.
--
-- The `%d' and `%i' conversion specifications both print an `int'
--argument as a signed decimal number; while `%o', `%u', and `%x' print
--the argument as an unsigned octal, decimal, or hexadecimal number
--(respectively). The `%X' conversion specification is just like `%x'
--except that it uses the characters `ABCDEF' as digits instead of
--`abcdef'.
--
-- The following flags are meaningful:
--
--`-'
-- Left-justify the result in the field (instead of the normal
-- right-justification).
--
--`+'
-- For the signed `%d' and `%i' conversions, print a plus sign if the
-- value is positive.
--
--` '
-- For the signed `%d' and `%i' conversions, if the result doesn't
-- start with a plus or minus sign, prefix it with a space character
-- instead. Since the `+' flag ensures that the result includes a
-- sign, this flag is ignored if you supply both of them.
--
--`#'
-- For the `%o' conversion, this forces the leading digit to be `0',
-- as if by increasing the precision. For `%x' or `%X', this
-- prefixes a leading `0x' or `0X' (respectively) to the result.
-- This doesn't do anything useful for the `%d', `%i', or `%u'
-- conversions. Using this flag produces output which can be parsed
-- by the `strtoul' function (*note Parsing of Integers::.) and
-- `scanf' with the `%i' conversion (*note Numeric Input
-- Conversions::.).
--
--`''
-- Separate the digits into groups as specified by the locale
-- specified for the `LC_NUMERIC' category; *note General Numeric::..
-- This flag is a GNU extension.
--
--`0'
-- Pad the field with zeros instead of spaces. The zeros are placed
-- after any indication of sign or base. This flag is ignored if the
-- `-' flag is also specified, or if a precision is specified.
--
-- If a precision is supplied, it specifies the minimum number of
--digits to appear; leading zeros are produced if necessary. If you
--don't specify a precision, the number is printed with as many digits as
--it needs. If you convert a value of zero with an explicit precision of
--zero, then no characters at all are produced.
--
-- Without a type modifier, the corresponding argument is treated as an
--`int' (for the signed conversions `%i' and `%d') or `unsigned int' (for
--the unsigned conversions `%o', `%u', `%x', and `%X'). Recall that
--since `printf' and friends are variadic, any `char' and `short'
--arguments are automatically converted to `int' by the default argument
--promotions. For arguments of other integer types, you can use these
--modifiers:
--
--`hh'
-- Specifies that the argument is a `signed char' or `unsigned char',
-- as appropriate. A `char' argument is converted to an `int' or
-- `unsigned int' by the default argument promotions anyway, but the
-- `h' modifier says to convert it back to a `char' again.
--
-- This modifier was introduced in ISO C 9x.
--
--`h'
-- Specifies that the argument is a `short int' or `unsigned short
-- int', as appropriate. A `short' argument is converted to an `int'
-- or `unsigned int' by the default argument promotions anyway, but
-- the `h' modifier says to convert it back to a `short' again.
--
--`j'
-- Specifies that the argument is a `intmax_t' or `uintmax_t', as
-- appropriate.
--
-- This modifier was introduced in ISO C 9x.
--
--`l'
-- Specifies that the argument is a `long int' or `unsigned long
-- int', as appropriate. Two `l' characters is like the `L'
-- modifier, below.
--
--`L'
--`ll'
--`q'
-- Specifies that the argument is a `long long int'. (This type is
-- an extension supported by the GNU C compiler. On systems that
-- don't support extra-long integers, this is the same as `long int'.)
--
-- The `q' modifier is another name for the same thing, which comes
-- from 4.4 BSD; a `long long int' is sometimes called a "quad" `int'.
--
--`t'
-- Specifies that the argument is a `ptrdiff_t'.
--
-- This modifier was introduced in ISO C 9x.
--
--`z'
--`Z'
-- Specifies that the argument is a `size_t'.
--
-- `z' was introduced in ISO C 9x. `Z' is a GNU extension predating
-- this addition and should not be used anymore in new code.
--
-- Here is an example. Using the template string:
--
-- "|%5d|%-5d|%+5d|%+-5d|% 5d|%05d|%5.0d|%5.2d|%d|\n"
--
--to print numbers using the different options for the `%d' conversion
--gives results like:
--
-- | 0|0 | +0|+0 | 0|00000| | 00|0|
-- | 1|1 | +1|+1 | 1|00001| 1| 01|1|
-- | -1|-1 | -1|-1 | -1|-0001| -1| -01|-1|
-- |100000|100000|+100000| 100000|100000|100000|100000|100000|
--
-- In particular, notice what happens in the last case where the number
--is too large to fit in the minimum field width specified.
--
-- Here are some more examples showing how unsigned integers print under
--various format options, using the template string:
--
-- "|%5u|%5o|%5x|%5X|%#5o|%#5x|%#5X|%#10.8x|\n"
--
-- | 0| 0| 0| 0| 0| 0x0| 0X0|0x00000000|
-- | 1| 1| 1| 1| 01| 0x1| 0X1|0x00000001|
-- |100000|303240|186a0|186A0|0303240|0x186a0|0X186A0|0x000186a0|
--
--
--File: libc.info, Node: Floating-Point Conversions, Next: Other Output Conversions, Prev: Integer Conversions, Up: Formatted Output
--
--Floating-Point Conversions
----------------------------
--
-- This section discusses the conversion specifications for
--floating-point numbers: the `%f', `%e', `%E', `%g', and `%G'
--conversions.
--
-- The `%f' conversion prints its argument in fixed-point notation,
--producing output of the form [`-']DDD`.'DDD, where the number of digits
--following the decimal point is controlled by the precision you specify.
--
-- The `%e' conversion prints its argument in exponential notation,
--producing output of the form [`-']D`.'DDD`e'[`+'|`-']DD. Again, the
--number of digits following the decimal point is controlled by the
--precision. The exponent always contains at least two digits. The `%E'
--conversion is similar but the exponent is marked with the letter `E'
--instead of `e'.
--
-- The `%g' and `%G' conversions print the argument in the style of
--`%e' or `%E' (respectively) if the exponent would be less than -4 or
--greater than or equal to the precision; otherwise they use the `%f'
--style. Trailing zeros are removed from the fractional portion of the
--result and a decimal-point character appears only if it is followed by
--a digit.
--
-- The `%a' and `%A' conversions are meant for representing
--floating-point number exactly in textual form so that they can be
--exchanged as texts between different programs and/or machines. The
--numbers are represented is the form [`-']`0x'H`.'HHH`p'[`+'|`-']DD. At
--the left of the decimal-point character exactly one digit is print.
--This character is only `0' if the number is denormalized. Otherwise
--the value is unspecified; it is implemention dependent how many bits
--are used. The number of hexadecimal digits on the right side of the
--decimal-point character is equal to the precision. If the precision is
--zero it is determined to be large enough to provide an exact
--representation of the number (or it is large enough to distinguish two
--adjacent values if the `FLT_RADIX' is not a power of 2, *note Floating
--Point Parameters::.). For the `%a' conversion lower-case characters
--are used to represent the hexadecimal number and the prefix and
--exponent sign are printed as `0x' and `p' respectively. Otherwise
--upper-case characters are used and `0X' and `P' are used for the
--representation of prefix and exponent string. The exponent to the base
--of two is printed as a decimal number using at least one digit but at
--most as many digits as necessary to represent the value exactly.
--
-- If the value to be printed represents infinity or a NaN, the output
--is [`-']`inf' or `nan' respectively if the conversion specifier is
--`%a', `%e', `%f', or `%g' and it is [`-']`INF' or `NAN' respectively if
--the conversion is `%A', `%E', or `%G'.
--
-- The following flags can be used to modify the behavior:
--
--`-'
-- Left-justify the result in the field. Normally the result is
-- right-justified.
--
--`+'
-- Always include a plus or minus sign in the result.
--
--` '
-- If the result doesn't start with a plus or minus sign, prefix it
-- with a space instead. Since the `+' flag ensures that the result
-- includes a sign, this flag is ignored if you supply both of them.
--
--`#'
-- Specifies that the result should always include a decimal point,
-- even if no digits follow it. For the `%g' and `%G' conversions,
-- this also forces trailing zeros after the decimal point to be left
-- in place where they would otherwise be removed.
--
--`''
-- Separate the digits of the integer part of the result into groups
-- as specified by the locale specified for the `LC_NUMERIC' category;
-- *note General Numeric::.. This flag is a GNU extension.
--
--`0'
-- Pad the field with zeros instead of spaces; the zeros are placed
-- after any sign. This flag is ignored if the `-' flag is also
-- specified.
--
-- The precision specifies how many digits follow the decimal-point
--character for the `%f', `%e', and `%E' conversions. For these
--conversions, the default precision is `6'. If the precision is
--explicitly `0', this suppresses the decimal point character entirely.
--For the `%g' and `%G' conversions, the precision specifies how many
--significant digits to print. Significant digits are the first digit
--before the decimal point, and all the digits after it. If the
--precision is `0' or not specified for `%g' or `%G', it is treated like
--a value of `1'. If the value being printed cannot be expressed
--accurately in the specified number of digits, the value is rounded to
--the nearest number that fits.
--
-- Without a type modifier, the floating-point conversions use an
--argument of type `double'. (By the default argument promotions, any
--`float' arguments are automatically converted to `double'.) The
--following type modifier is supported:
--
--`L'
-- An uppercase `L' specifies that the argument is a `long double'.
--
-- Here are some examples showing how numbers print using the various
--floating-point conversions. All of the numbers were printed using this
--template string:
--
-- "|%13.4a|%13.4f|%13.4e|%13.4g|\n"
--
-- Here is the output:
--
-- | 0x0.0000p+0| 0.0000| 0.0000e+00| 0|
-- | 0x1.0000p-1| 0.5000| 5.0000e-01| 0.5|
-- | 0x1.0000p+0| 1.0000| 1.0000e+00| 1|
-- | -0x1.0000p+0| -1.0000| -1.0000e+00| -1|
-- | 0x1.9000p+6| 100.0000| 1.0000e+02| 100|
-- | 0x1.f400p+9| 1000.0000| 1.0000e+03| 1000|
-- | 0x1.3880p+13| 10000.0000| 1.0000e+04| 1e+04|
-- | 0x1.81c8p+13| 12345.0000| 1.2345e+04| 1.234e+04|
-- | 0x1.86a0p+16| 100000.0000| 1.0000e+05| 1e+05|
-- | 0x1.e240p+16| 123456.0000| 1.2346e+05| 1.235e+05|
--
-- Notice how the `%g' conversion drops trailing zeros.
--
--
--File: libc.info, Node: Other Output Conversions, Next: Formatted Output Functions, Prev: Floating-Point Conversions, Up: Formatted Output
--
--Other Output Conversions
--------------------------
--
-- This section describes miscellaneous conversions for `printf'.
--
-- The `%c' conversion prints a single character. The `int' argument
--is first converted to an `unsigned char'. The `-' flag can be used to
--specify left-justification in the field, but no other flags are
--defined, and no precision or type modifier can be given. For example:
--
-- printf ("%c%c%c%c%c", 'h', 'e', 'l', 'l', 'o');
--
--prints `hello'.
--
-- The `%s' conversion prints a string. The corresponding argument
--must be of type `char *' (or `const char *'). A precision can be
--specified to indicate the maximum number of characters to write;
--otherwise characters in the string up to but not including the
--terminating null character are written to the output stream. The `-'
--flag can be used to specify left-justification in the field, but no
--other flags or type modifiers are defined for this conversion. For
--example:
--
-- printf ("%3s%-6s", "no", "where");
--
--prints ` nowhere '.
--
-- If you accidentally pass a null pointer as the argument for a `%s'
--conversion, the GNU library prints it as `(null)'. We think this is
--more useful than crashing. But it's not good practice to pass a null
--argument intentionally.
--
-- The `%m' conversion prints the string corresponding to the error
--code in `errno'. *Note Error Messages::. Thus:
--
-- fprintf (stderr, "can't open `%s': %m\n", filename);
--
--is equivalent to:
--
-- fprintf (stderr, "can't open `%s': %s\n", filename, strerror (errno));
--
--The `%m' conversion is a GNU C library extension.
--
-- The `%p' conversion prints a pointer value. The corresponding
--argument must be of type `void *'. In practice, you can use any type
--of pointer.
--
-- In the GNU system, non-null pointers are printed as unsigned
--integers, as if a `%#x' conversion were used. Null pointers print as
--`(nil)'. (Pointers might print differently in other systems.)
--
-- For example:
--
-- printf ("%p", "testing");
--
--prints `0x' followed by a hexadecimal number--the address of the string
--constant `"testing"'. It does not print the word `testing'.
--
-- You can supply the `-' flag with the `%p' conversion to specify
--left-justification, but no other flags, precision, or type modifiers
--are defined.
--
-- The `%n' conversion is unlike any of the other output conversions.
--It uses an argument which must be a pointer to an `int', but instead of
--printing anything it stores the number of characters printed so far by
--this call at that location. The `h' and `l' type modifiers are
--permitted to specify that the argument is of type `short int *' or
--`long int *' instead of `int *', but no flags, field width, or
--precision are permitted.
--
-- For example,
--
-- int nchar;
-- printf ("%d %s%n\n", 3, "bears", &nchar);
--
--prints:
--
-- 3 bears
--
--and sets `nchar' to `7', because `3 bears' is seven characters.
--
-- The `%%' conversion prints a literal `%' character. This conversion
--doesn't use an argument, and no flags, field width, precision, or type
--modifiers are permitted.
--
--
--File: libc.info, Node: Formatted Output Functions, Next: Dynamic Output, Prev: Other Output Conversions, Up: Formatted Output
--
--Formatted Output Functions
----------------------------
--
-- This section describes how to call `printf' and related functions.
--Prototypes for these functions are in the header file `stdio.h'.
--Because these functions take a variable number of arguments, you *must*
--declare prototypes for them before using them. Of course, the easiest
--way to make sure you have all the right prototypes is to just include
--`stdio.h'.
--
-- - Function: int printf (const char *TEMPLATE, ...)
-- The `printf' function prints the optional arguments under the
-- control of the template string TEMPLATE to the stream `stdout'.
-- It returns the number of characters printed, or a negative value
-- if there was an output error.
--
-- - Function: int fprintf (FILE *STREAM, const char *TEMPLATE, ...)
-- This function is just like `printf', except that the output is
-- written to the stream STREAM instead of `stdout'.
--
-- - Function: int sprintf (char *S, const char *TEMPLATE, ...)
-- This is like `printf', except that the output is stored in the
-- character array S instead of written to a stream. A null
-- character is written to mark the end of the string.
--
-- The `sprintf' function returns the number of characters stored in
-- the array S, not including the terminating null character.
--
-- The behavior of this function is undefined if copying takes place
-- between objects that overlap--for example, if S is also given as
-- an argument to be printed under control of the `%s' conversion.
-- *Note Copying and Concatenation::.
--
-- *Warning:* The `sprintf' function can be *dangerous* because it
-- can potentially output more characters than can fit in the
-- allocation size of the string S. Remember that the field width
-- given in a conversion specification is only a *minimum* value.
--
-- To avoid this problem, you can use `snprintf' or `asprintf',
-- described below.
--
-- - Function: int snprintf (char *S, size_t SIZE, const char *TEMPLATE,
-- ...)
-- The `snprintf' function is similar to `sprintf', except that the
-- SIZE argument specifies the maximum number of characters to
-- produce. The trailing null character is counted towards this
-- limit, so you should allocate at least SIZE characters for the
-- string S.
--
-- The return value is the number of characters which would be
-- generated for the given input, excluding the trailing null. If
-- this value is greater or equal to SIZE, not all characters from
-- the result have been stored in S. You should try again with a
-- bigger output string. Here is an example of doing this:
--
-- /* Construct a message describing the value of a variable
-- whose name is NAME and whose value is VALUE. */
-- char *
-- make_message (char *name, char *value)
-- {
-- /* Guess we need no more than 100 chars of space. */
-- int size = 100;
-- char *buffer = (char *) xmalloc (size);
-- int nchars;
--
-- /* Try to print in the allocated space. */
-- nchars = snprintf (buffer, size, "value of %s is %s",
-- name, value);
--
-- if (nchars >= size)
-- {
-- /* Reallocate buffer now that we know
-- how much space is needed. */
-- buffer = (char *) xrealloc (buffer, nchars + 1);
--
-- /* Try again. */
-- snprintf (buffer, size, "value of %s is %s",
-- name, value);
-- }
-- /* The last call worked, return the string. */
-- return buffer;
-- }
--
-- In practice, it is often easier just to use `asprintf', below.
--
-- *Attention:* In the GNU C library version 2.0 the return value is
-- the number of characters stored, not including the terminating
-- null. If this value equals `SIZE - 1', then there was not enough
-- space in S for all the output. This change was necessary with the
-- adoption of snprintf by ISO C9x.
--
--
--File: libc.info, Node: Dynamic Output, Next: Variable Arguments Output, Prev: Formatted Output Functions, Up: Formatted Output
--
--Dynamically Allocating Formatted Output
-----------------------------------------
--
-- The functions in this section do formatted output and place the
--results in dynamically allocated memory.
--
-- - Function: int asprintf (char **PTR, const char *TEMPLATE, ...)
-- This function is similar to `sprintf', except that it dynamically
-- allocates a string (as with `malloc'; *note Unconstrained
-- Allocation::.) to hold the output, instead of putting the output
-- in a buffer you allocate in advance. The PTR argument should be
-- the address of a `char *' object, and `asprintf' stores a pointer
-- to the newly allocated string at that location.
--
-- Here is how to use `asprintf' to get the same result as the
-- `snprintf' example, but more easily:
--
-- /* Construct a message describing the value of a variable
-- whose name is NAME and whose value is VALUE. */
-- char *
-- make_message (char *name, char *value)
-- {
-- char *result;
-- asprintf (&result, "value of %s is %s", name, value);
-- return result;
-- }
--
-- - Function: int obstack_printf (struct obstack *OBSTACK, const char
-- *TEMPLATE, ...)
-- This function is similar to `asprintf', except that it uses the
-- obstack OBSTACK to allocate the space. *Note Obstacks::.
--
-- The characters are written onto the end of the current object. To
-- get at them, you must finish the object with `obstack_finish'
-- (*note Growing Objects::.).
--
--
--File: libc.info, Node: Variable Arguments Output, Next: Parsing a Template String, Prev: Dynamic Output, Up: Formatted Output
--
--Variable Arguments Output Functions
-------------------------------------
--
-- The functions `vprintf' and friends are provided so that you can
--define your own variadic `printf'-like functions that make use of the
--same internals as the built-in formatted output functions.
--
-- The most natural way to define such functions would be to use a
--language construct to say, "Call `printf' and pass this template plus
--all of my arguments after the first five." But there is no way to do
--this in C, and it would be hard to provide a way, since at the C
--language level there is no way to tell how many arguments your function
--received.
--
-- Since that method is impossible, we provide alternative functions,
--the `vprintf' series, which lets you pass a `va_list' to describe "all
--of my arguments after the first five."
--
-- When it is sufficient to define a macro rather than a real function,
--the GNU C compiler provides a way to do this much more easily with
--macros. For example:
--
-- #define myprintf(a, b, c, d, e, rest...) \
-- printf (mytemplate , ## rest...)
--
--*Note Macros with Variable Numbers of Arguments: (gcc.info)Macro
--Varargs, for details. But this is limited to macros, and does not
--apply to real functions at all.
--
-- Before calling `vprintf' or the other functions listed in this
--section, you *must* call `va_start' (*note Variadic Functions::.) to
--initialize a pointer to the variable arguments. Then you can call
--`va_arg' to fetch the arguments that you want to handle yourself. This
--advances the pointer past those arguments.
--
-- Once your `va_list' pointer is pointing at the argument of your
--choice, you are ready to call `vprintf'. That argument and all
--subsequent arguments that were passed to your function are used by
--`vprintf' along with the template that you specified separately.
--
-- In some other systems, the `va_list' pointer may become invalid
--after the call to `vprintf', so you must not use `va_arg' after you
--call `vprintf'. Instead, you should call `va_end' to retire the
--pointer from service. However, you can safely call `va_start' on
--another pointer variable and begin fetching the arguments again through
--that pointer. Calling `vprintf' does not destroy the argument list of
--your function, merely the particular pointer that you passed to it.
--
-- GNU C does not have such restrictions. You can safely continue to
--fetch arguments from a `va_list' pointer after passing it to `vprintf',
--and `va_end' is a no-op. (Note, however, that subsequent `va_arg'
--calls will fetch the same arguments which `vprintf' previously used.)
--
-- Prototypes for these functions are declared in `stdio.h'.
--
-- - Function: int vprintf (const char *TEMPLATE, va_list AP)
-- This function is similar to `printf' except that, instead of taking
-- a variable number of arguments directly, it takes an argument list
-- pointer AP.
--
-- - Function: int vfprintf (FILE *STREAM, const char *TEMPLATE, va_list
-- AP)
-- This is the equivalent of `fprintf' with the variable argument list
-- specified directly as for `vprintf'.
--
-- - Function: int vsprintf (char *S, const char *TEMPLATE, va_list AP)
-- This is the equivalent of `sprintf' with the variable argument list
-- specified directly as for `vprintf'.
--
-- - Function: int vsnprintf (char *S, size_t SIZE, const char *TEMPLATE,
-- va_list AP)
-- This is the equivalent of `snprintf' with the variable argument
-- list specified directly as for `vprintf'.
--
-- - Function: int vasprintf (char **PTR, const char *TEMPLATE, va_list
-- AP)
-- The `vasprintf' function is the equivalent of `asprintf' with the
-- variable argument list specified directly as for `vprintf'.
--
-- - Function: int obstack_vprintf (struct obstack *OBSTACK, const char
-- *TEMPLATE, va_list AP)
-- The `obstack_vprintf' function is the equivalent of
-- `obstack_printf' with the variable argument list specified directly
-- as for `vprintf'.
--
-- Here's an example showing how you might use `vfprintf'. This is a
--function that prints error messages to the stream `stderr', along with
--a prefix indicating the name of the program (*note Error Messages::.,
--for a description of `program_invocation_short_name').
--
-- #include <stdio.h>
-- #include <stdarg.h>
--
-- void
-- eprintf (const char *template, ...)
-- {
-- va_list ap;
-- extern char *program_invocation_short_name;
--
-- fprintf (stderr, "%s: ", program_invocation_short_name);
-- va_start (ap, template);
-- vfprintf (stderr, template, ap);
-- va_end (ap);
-- }
--
--You could call `eprintf' like this:
--
-- eprintf ("file `%s' does not exist\n", filename);
--
-- In GNU C, there is a special construct you can use to let the
--compiler know that a function uses a `printf'-style format string.
--Then it can check the number and types of arguments in each call to the
--function, and warn you when they do not match the format string. For
--example, take this declaration of `eprintf':
--
-- void eprintf (const char *template, ...)
-- __attribute__ ((format (printf, 1, 2)));
--
--This tells the compiler that `eprintf' uses a format string like
--`printf' (as opposed to `scanf'; *note Formatted Input::.); the format
--string appears as the first argument; and the arguments to satisfy the
--format begin with the second. *Note Declaring Attributes of Functions:
--(gcc.info)Function Attributes, for more information.
--
--
--File: libc.info, Node: Parsing a Template String, Next: Example of Parsing, Prev: Variable Arguments Output, Up: Formatted Output
--
--Parsing a Template String
---------------------------
--
-- You can use the function `parse_printf_format' to obtain information
--about the number and types of arguments that are expected by a given
--template string. This function permits interpreters that provide
--interfaces to `printf' to avoid passing along invalid arguments from
--the user's program, which could cause a crash.
--
-- All the symbols described in this section are declared in the header
--file `printf.h'.
--
-- - Function: size_t parse_printf_format (const char *TEMPLATE, size_t
-- N, int *ARGTYPES)
-- This function returns information about the number and types of
-- arguments expected by the `printf' template string TEMPLATE. The
-- information is stored in the array ARGTYPES; each element of this
-- array describes one argument. This information is encoded using
-- the various `PA_' macros, listed below.
--
-- The N argument specifies the number of elements in the array
-- ARGTYPES. This is the most elements that `parse_printf_format'
-- will try to write.
--
-- `parse_printf_format' returns the total number of arguments
-- required by TEMPLATE. If this number is greater than N, then the
-- information returned describes only the first N arguments. If you
-- want information about more than that many arguments, allocate a
-- bigger array and call `parse_printf_format' again.
--
-- The argument types are encoded as a combination of a basic type and
--modifier flag bits.
--
-- - Macro: int PA_FLAG_MASK
-- This macro is a bitmask for the type modifier flag bits. You can
-- write the expression `(argtypes[i] & PA_FLAG_MASK)' to extract
-- just the flag bits for an argument, or `(argtypes[i] &
-- ~PA_FLAG_MASK)' to extract just the basic type code.
--
-- Here are symbolic constants that represent the basic types; they
--stand for integer values.
--
--`PA_INT'
-- This specifies that the base type is `int'.
--
--`PA_CHAR'
-- This specifies that the base type is `int', cast to `char'.
--
--`PA_STRING'
-- This specifies that the base type is `char *', a null-terminated
-- string.
--
--`PA_POINTER'
-- This specifies that the base type is `void *', an arbitrary
-- pointer.
--
--`PA_FLOAT'
-- This specifies that the base type is `float'.
--
--`PA_DOUBLE'
-- This specifies that the base type is `double'.
--
--`PA_LAST'
-- You can define additional base types for your own programs as
-- offsets from `PA_LAST'. For example, if you have data types `foo'
-- and `bar' with their own specialized `printf' conversions, you
-- could define encodings for these types as:
--
-- #define PA_FOO PA_LAST
-- #define PA_BAR (PA_LAST + 1)
--
-- Here are the flag bits that modify a basic type. They are combined
--with the code for the basic type using inclusive-or.
--
--`PA_FLAG_PTR'
-- If this bit is set, it indicates that the encoded type is a
-- pointer to the base type, rather than an immediate value. For
-- example, `PA_INT|PA_FLAG_PTR' represents the type `int *'.
--
--`PA_FLAG_SHORT'
-- If this bit is set, it indicates that the base type is modified
-- with `short'. (This corresponds to the `h' type modifier.)
--
--`PA_FLAG_LONG'
-- If this bit is set, it indicates that the base type is modified
-- with `long'. (This corresponds to the `l' type modifier.)
--
--`PA_FLAG_LONG_LONG'
-- If this bit is set, it indicates that the base type is modified
-- with `long long'. (This corresponds to the `L' type modifier.)
--
--`PA_FLAG_LONG_DOUBLE'
-- This is a synonym for `PA_FLAG_LONG_LONG', used by convention with
-- a base type of `PA_DOUBLE' to indicate a type of `long double'.
--
-- For an example of using these facilities, see *Note Example of
--Parsing::.
--
--
--File: libc.info, Node: Example of Parsing, Prev: Parsing a Template String, Up: Formatted Output
--
--Example of Parsing a Template String
--------------------------------------
--
-- Here is an example of decoding argument types for a format string.
--We assume this is part of an interpreter which contains arguments of
--type `NUMBER', `CHAR', `STRING' and `STRUCTURE' (and perhaps others
--which are not valid here).
--
-- /* Test whether the NARGS specified objects
-- in the vector ARGS are valid
-- for the format string FORMAT:
-- if so, return 1.
-- If not, return 0 after printing an error message. */
--
-- int
-- validate_args (char *format, int nargs, OBJECT *args)
-- {
-- int *argtypes;
-- int nwanted;
--
-- /* Get the information about the arguments.
-- Each conversion specification must be at least two characters
-- long, so there cannot be more specifications than half the
-- length of the string. */
--
-- argtypes = (int *) alloca (strlen (format) / 2 * sizeof (int));
-- nwanted = parse_printf_format (string, nelts, argtypes);
--
-- /* Check the number of arguments. */
-- if (nwanted > nargs)
-- {
-- error ("too few arguments (at least %d required)", nwanted);
-- return 0;
-- }
--
-- /* Check the C type wanted for each argument
-- and see if the object given is suitable. */
-- for (i = 0; i < nwanted; i++)
-- {
-- int wanted;
--
-- if (argtypes[i] & PA_FLAG_PTR)
-- wanted = STRUCTURE;
-- else
-- switch (argtypes[i] & ~PA_FLAG_MASK)
-- {
-- case PA_INT:
-- case PA_FLOAT:
-- case PA_DOUBLE:
-- wanted = NUMBER;
-- break;
-- case PA_CHAR:
-- wanted = CHAR;
-- break;
-- case PA_STRING:
-- wanted = STRING;
-- break;
-- case PA_POINTER:
-- wanted = STRUCTURE;
-- break;
-- }
-- if (TYPE (args[i]) != wanted)
-- {
-- error ("type mismatch for arg number %d", i);
-- return 0;
-- }
-- }
-- return 1;
-- }
--
--
--File: libc.info, Node: Customizing Printf, Next: Formatted Input, Prev: Formatted Output, Up: I/O on Streams
--
--Customizing `printf'
--====================
--
-- The GNU C library lets you define your own custom conversion
--specifiers for `printf' template strings, to teach `printf' clever ways
--to print the important data structures of your program.
--
-- The way you do this is by registering the conversion with the
--function `register_printf_function'; see *Note Registering New
--Conversions::. One of the arguments you pass to this function is a
--pointer to a handler function that produces the actual output; see
--*Note Defining the Output Handler::, for information on how to write
--this function.
--
-- You can also install a function that just returns information about
--the number and type of arguments expected by the conversion specifier.
--*Note Parsing a Template String::, for information about this.
--
-- The facilities of this section are declared in the header file
--`printf.h'.
--
--* Menu:
--
--* Registering New Conversions:: Using `register_printf_function'
-- to register a new output conversion.
--* Conversion Specifier Options:: The handler must be able to get
-- the options specified in the
-- template when it is called.
--* Defining the Output Handler:: Defining the handler and arginfo
-- functions that are passed as arguments
-- to `register_printf_function'.
--* Printf Extension Example:: How to define a `printf'
-- handler function.
--* Predefined Printf Handlers:: Predefined `printf' handlers.
--
-- *Portability Note:* The ability to extend the syntax of `printf'
--template strings is a GNU extension. ISO standard C has nothing
--similar.
--
--
--File: libc.info, Node: Registering New Conversions, Next: Conversion Specifier Options, Up: Customizing Printf
--
--Registering New Conversions
-----------------------------
--
-- The function to register a new output conversion is
--`register_printf_function', declared in `printf.h'.
--
-- - Function: int register_printf_function (int SPEC, printf_function
-- HANDLER-FUNCTION, printf_arginfo_function ARGINFO-FUNCTION)
-- This function defines the conversion specifier character SPEC.
-- Thus, if SPEC is `'z'', it defines the conversion `%z'. You can
-- redefine the built-in conversions like `%s', but flag characters
-- like `#' and type modifiers like `l' can never be used as
-- conversions; calling `register_printf_function' for those
-- characters has no effect.
--
-- The HANDLER-FUNCTION is the function called by `printf' and
-- friends when this conversion appears in a template string. *Note
-- Defining the Output Handler::, for information about how to define
-- a function to pass as this argument. If you specify a null
-- pointer, any existing handler function for SPEC is removed.
--
-- The ARGINFO-FUNCTION is the function called by
-- `parse_printf_format' when this conversion appears in a template
-- string. *Note Parsing a Template String::, for information about
-- this.
--
-- *Attention:* In the GNU C library version before 2.0 the
-- ARGINFO-FUNCTION function did not need to be installed unless the
-- user uses the `parse_printf_format' function. This changed. Now
-- a call to any of the `printf' functions will call this function
-- when this format specifier appears in the format string.
--
-- The return value is `0' on success, and `-1' on failure (which
-- occurs if SPEC is out of range).
--
-- You can redefine the standard output conversions, but this is
-- probably not a good idea because of the potential for confusion.
-- Library routines written by other people could break if you do
-- this.
--
--
--File: libc.info, Node: Conversion Specifier Options, Next: Defining the Output Handler, Prev: Registering New Conversions, Up: Customizing Printf
--
--Conversion Specifier Options
------------------------------
--
-- If you define a meaning for `%A', what if the template contains
--`%+23A' or `%-#A'? To implement a sensible meaning for these, the
--handler when called needs to be able to get the options specified in
--the template.
--
-- Both the HANDLER-FUNCTION and ARGINFO-FUNCTION accept an argument
--that points to a `struct printf_info', which contains information about
--the options appearing in an instance of the conversion specifier. This
--data type is declared in the header file `printf.h'.
--
-- - Type: struct printf_info
-- This structure is used to pass information about the options
-- appearing in an instance of a conversion specifier in a `printf'
-- template string to the handler and arginfo functions for that
-- specifier. It contains the following members:
--
-- `int prec'
-- This is the precision specified. The value is `-1' if no
-- precision was specified. If the precision was given as `*',
-- the `printf_info' structure passed to the handler function
-- contains the actual value retrieved from the argument list.
-- But the structure passed to the arginfo function contains a
-- value of `INT_MIN', since the actual value is not known.
--
-- `int width'
-- This is the minimum field width specified. The value is `0'
-- if no width was specified. If the field width was given as
-- `*', the `printf_info' structure passed to the handler
-- function contains the actual value retrieved from the
-- argument list. But the structure passed to the arginfo
-- function contains a value of `INT_MIN', since the actual
-- value is not known.
--
-- `wchar_t spec'
-- This is the conversion specifier character specified. It's
-- stored in the structure so that you can register the same
-- handler function for multiple characters, but still have a
-- way to tell them apart when the handler function is called.
--
-- `unsigned int is_long_double'
-- This is a boolean that is true if the `L', `ll', or `q' type
-- modifier was specified. For integer conversions, this
-- indicates `long long int', as opposed to `long double' for
-- floating point conversions.
--
-- `unsigned int is_char'
-- This is a boolean that is true if the `hh' type modifier was
-- specified.
--
-- `unsigned int is_short'
-- This is a boolean that is true if the `h' type modifier was
-- specified.
--
-- `unsigned int is_long'
-- This is a boolean that is true if the `l' type modifier was
-- specified.
--
-- `unsigned int alt'
-- This is a boolean that is true if the `#' flag was specified.
--
-- `unsigned int space'
-- This is a boolean that is true if the ` ' flag was specified.
--
-- `unsigned int left'
-- This is a boolean that is true if the `-' flag was specified.
--
-- `unsigned int showsign'
-- This is a boolean that is true if the `+' flag was specified.
--
-- `unsigned int group'
-- This is a boolean that is true if the `'' flag was specified.
--
-- `unsigned int extra'
-- This flag has a special meaning depending on the context. It
-- could be used freely by the user-defined handlers but when
-- called from the `printf' function this variable always
-- contains the value `0'.
--
-- `wchar_t pad'
-- This is the character to use for padding the output to the
-- minimum field width. The value is `'0'' if the `0' flag was
-- specified, and `' '' otherwise.
--
--
--File: libc.info, Node: Defining the Output Handler, Next: Printf Extension Example, Prev: Conversion Specifier Options, Up: Customizing Printf
--
--Defining the Output Handler
-----------------------------
--
-- Now let's look at how to define the handler and arginfo functions
--which are passed as arguments to `register_printf_function'.
--
-- *Compatibility Note:* The interface changed in the GNU libc version
--2.0. Previously the third argument was of type `va_list *'.
--
-- You should define your handler functions with a prototype like:
--
-- int FUNCTION (FILE *stream, const struct printf_info *info,
-- const void *const *args)
--
-- The STREAM argument passed to the handler function is the stream to
--which it should write output.
--
-- The INFO argument is a pointer to a structure that contains
--information about the various options that were included with the
--conversion in the template string. You should not modify this structure
--inside your handler function. *Note Conversion Specifier Options::, for
--a description of this data structure.
--
-- The ARGS is a vector of pointers to the arguments data. The number
--of arguments were determined by calling the argument information
--function provided by the user.
--
-- Your handler function should return a value just like `printf' does:
--it should return the number of characters it has written, or a negative
--value to indicate an error.
--
-- - Data Type: printf_function
-- This is the data type that a handler function should have.
--
-- If you are going to use `parse_printf_format' in your application,
--you must also define a function to pass as the ARGINFO-FUNCTION
--argument for each new conversion you install with
--`register_printf_function'.
--
-- You have to define these functions with a prototype like:
--
-- int FUNCTION (const struct printf_info *info,
-- size_t n, int *argtypes)
--
-- The return value from the function should be the number of arguments
--the conversion expects. The function should also fill in no more than
--N elements of the ARGTYPES array with information about the types of
--each of these arguments. This information is encoded using the various
--`PA_' macros. (You will notice that this is the same calling
--convention `parse_printf_format' itself uses.)
--
-- - Data Type: printf_arginfo_function
-- This type is used to describe functions that return information
-- about the number and type of arguments used by a conversion
-- specifier.
--
--
--File: libc.info, Node: Printf Extension Example, Next: Predefined Printf Handlers, Prev: Defining the Output Handler, Up: Customizing Printf
--
--`printf' Extension Example
----------------------------
--
-- Here is an example showing how to define a `printf' handler function.
--This program defines a data structure called a `Widget' and defines the
--`%W' conversion to print information about `Widget *' arguments,
--including the pointer value and the name stored in the data structure.
--The `%W' conversion supports the minimum field width and
--left-justification options, but ignores everything else.
--
-- #include <stdio.h>
-- #include <stdlib.h>
-- #include <printf.h>
-- typedef struct
-- {
-- char *name;
-- }
-- Widget;
--
-- int
-- print_widget (FILE *stream,
-- const struct printf_info *info,
-- const void *const *args)
-- {
-- const Widget *w;
-- char *buffer;
-- int len;
--
-- /* Format the output into a string. */
-- w = *((const Widget **) (args[0]));
-- len = asprintf (&buffer, "<Widget %p: %s>", w, w->name);
-- if (len == -1)
-- return -1;
--
-- /* Pad to the minimum field width and print to the stream. */
-- len = fprintf (stream, "%*s",
-- (info->left ? -info->width : info->width),
-- buffer);
--
-- /* Clean up and return. */
-- free (buffer);
-- return len;
-- }
--
--
-- int
-- print_widget_arginfo (const struct printf_info *info, size_t n,
-- int *argtypes)
-- {
-- /* We always take exactly one argument and this is a pointer to the
-- structure.. */
-- if (n > 0)
-- argtypes[0] = PA_POINTER;
-- return 1;
-- }
--
--
-- int
-- main (void)
-- {
-- /* Make a widget to print. */
-- Widget mywidget;
-- mywidget.name = "mywidget";
--
-- /* Register the print function for widgets. */
-- register_printf_function ('W', print_widget, print_widget_arginfo);
--
-- /* Now print the widget. */
-- printf ("|%W|\n", &mywidget);
-- printf ("|%35W|\n", &mywidget);
-- printf ("|%-35W|\n", &mywidget);
--
-- return 0;
-- }
--
-- The output produced by this program looks like:
--
-- |<Widget 0xffeffb7c: mywidget>|
-- | <Widget 0xffeffb7c: mywidget>|
-- |<Widget 0xffeffb7c: mywidget> |
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-16 glibc-2.1.3/manual/libc.info-16
---- ../glibc-2.1.3/manual/libc.info-16 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-16 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1155 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Predefined Printf Handlers, Prev: Printf Extension Example, Up: Customizing Printf
--
--Predefined `printf' Handlers
------------------------------
--
-- The GNU libc also contains a concrete and useful application of the
--`printf' handler extension. There are two functions available which
--implement a special way to print floating-point numbers.
--
-- - Function: int printf_size (FILE *FP, const struct printf_info *INFO,
-- const void *const *ARGS)
-- Print a given floating point number as for the format `%f' except
-- that there is a postfix character indicating the divisor for the
-- number to make this less than 1000. There are two possible
-- divisors: powers of 1024 or powers to 1000. Which one is used
-- depends on the format character specified while registered this
-- handler. If the character is of lower case, 1024 is used. For
-- upper case characters, 1000 is used.
--
-- The postfix tag corresponds to bytes, kilobytes, megabytes,
-- gigabytes, etc. The full table is:
--
-- +-----+-------------+-------+-------+--------------+
-- |low |Multiplier |From |Upper |Multiplier |
-- +-----+-------------+-------+-------+--------------+
-- |' ' |1 | |' ' |1 |
-- +-----+-------------+-------+-------+--------------+
-- |k |2^10 (1024) |kilo |K |10^3 (1000) |
-- +-----+-------------+-------+-------+--------------+
-- |m |2^20 |mega |M |10^6 |
-- +-----+-------------+-------+-------+--------------+
-- |g |2^30 |giga |G |10^9 |
-- +-----+-------------+-------+-------+--------------+
-- |t |2^40 |tera |T |10^12 |
-- +-----+-------------+-------+-------+--------------+
-- |p |2^50 |peta |P |10^15 |
-- +-----+-------------+-------+-------+--------------+
-- |e |2^60 |exa |E |10^18 |
-- +-----+-------------+-------+-------+--------------+
-- |z |2^70 |zetta |Z |10^21 |
-- +-----+-------------+-------+-------+--------------+
-- |y |2^80 |yotta |Y |10^24 |
-- +-----+-------------+-------+-------+--------------+
--
-- The default precision is 3, i.e., 1024 is printed with a lower-case
-- format character as if it were `%.3fk' and will yield `1.000k'.
--
-- Due to the requirements of `register_printf_function' we must also
--provide the function which return information about the arguments.
--
-- - Function: int printf_size_info (const struct printf_info *INFO,
-- size_t N, int *ARGTYPES)
-- This function will return in ARGTYPES the information about the
-- used parameters in the way the `vfprintf' implementation expects
-- it. The format always takes one argument.
--
-- To use these functions both functions must be registered with a call
--like
--
-- register_printf_function ('B', printf_size, printf_size_info);
--
-- Here we register the functions to print numbers as powers of 1000
--since the format character `'B'' is an upper-case character. If we
--would additionally use `'b'' in a line like
--
-- register_printf_function ('b', printf_size, printf_size_info);
--
--we could also print using power of 1024. Please note that all what is
--different in these both lines in the format specifier. The
--`printf_size' function knows about the difference of low and upper case
--format specifiers.
--
-- The use of `'B'' and `'b'' is no coincidence. Rather it is the
--preferred way to use this functionality since it is available on some
--other systems also available using the format specifiers.
--
--
--File: libc.info, Node: Formatted Input, Next: EOF and Errors, Prev: Customizing Printf, Up: I/O on Streams
--
--Formatted Input
--===============
--
-- The functions described in this section (`scanf' and related
--functions) provide facilities for formatted input analogous to the
--formatted output facilities. These functions provide a mechanism for
--reading arbitrary values under the control of a "format string" or
--"template string".
--
--* Menu:
--
--* Formatted Input Basics:: Some basics to get you started.
--* Input Conversion Syntax:: Syntax of conversion specifications.
--* Table of Input Conversions:: Summary of input conversions and what they do.
--* Numeric Input Conversions:: Details of conversions for reading numbers.
--* String Input Conversions:: Details of conversions for reading strings.
--* Dynamic String Input:: String conversions that `malloc' the buffer.
--* Other Input Conversions:: Details of miscellaneous other conversions.
--* Formatted Input Functions:: Descriptions of the actual functions.
--* Variable Arguments Input:: `vscanf' and friends.
--
--
--File: libc.info, Node: Formatted Input Basics, Next: Input Conversion Syntax, Up: Formatted Input
--
--Formatted Input Basics
------------------------
--
-- Calls to `scanf' are superficially similar to calls to `printf' in
--that arbitrary arguments are read under the control of a template
--string. While the syntax of the conversion specifications in the
--template is very similar to that for `printf', the interpretation of
--the template is oriented more towards free-format input and simple
--pattern matching, rather than fixed-field formatting. For example,
--most `scanf' conversions skip over any amount of "white space"
--(including spaces, tabs, and newlines) in the input file, and there is
--no concept of precision for the numeric input conversions as there is
--for the corresponding output conversions. Ordinarily, non-whitespace
--characters in the template are expected to match characters in the
--input stream exactly, but a matching failure is distinct from an input
--error on the stream.
--
-- Another area of difference between `scanf' and `printf' is that you
--must remember to supply pointers rather than immediate values as the
--optional arguments to `scanf'; the values that are read are stored in
--the objects that the pointers point to. Even experienced programmers
--tend to forget this occasionally, so if your program is getting strange
--errors that seem to be related to `scanf', you might want to
--double-check this.
--
-- When a "matching failure" occurs, `scanf' returns immediately,
--leaving the first non-matching character as the next character to be
--read from the stream. The normal return value from `scanf' is the
--number of values that were assigned, so you can use this to determine if
--a matching error happened before all the expected values were read.
--
-- The `scanf' function is typically used for things like reading in
--the contents of tables. For example, here is a function that uses
--`scanf' to initialize an array of `double':
--
-- void
-- readarray (double *array, int n)
-- {
-- int i;
-- for (i=0; i<n; i++)
-- if (scanf (" %lf", &(array[i])) != 1)
-- invalid_input_error ();
-- }
--
-- The formatted input functions are not used as frequently as the
--formatted output functions. Partly, this is because it takes some care
--to use them properly. Another reason is that it is difficult to recover
--from a matching error.
--
-- If you are trying to read input that doesn't match a single, fixed
--pattern, you may be better off using a tool such as Flex to generate a
--lexical scanner, or Bison to generate a parser, rather than using
--`scanf'. For more information about these tools, see *Note :
--(flex.info), and *Note : (bison.info).
--
--
--File: libc.info, Node: Input Conversion Syntax, Next: Table of Input Conversions, Prev: Formatted Input Basics, Up: Formatted Input
--
--Input Conversion Syntax
-------------------------
--
-- A `scanf' template string is a string that contains ordinary
--multibyte characters interspersed with conversion specifications that
--start with `%'.
--
-- Any whitespace character (as defined by the `isspace' function;
--*note Classification of Characters::.) in the template causes any number
--of whitespace characters in the input stream to be read and discarded.
--The whitespace characters that are matched need not be exactly the same
--whitespace characters that appear in the template string. For example,
--write ` , ' in the template to recognize a comma with optional
--whitespace before and after.
--
-- Other characters in the template string that are not part of
--conversion specifications must match characters in the input stream
--exactly; if this is not the case, a matching failure occurs.
--
-- The conversion specifications in a `scanf' template string have the
--general form:
--
-- % FLAGS WIDTH TYPE CONVERSION
--
-- In more detail, an input conversion specification consists of an
--initial `%' character followed in sequence by:
--
-- * An optional "flag character" `*', which says to ignore the text
-- read for this specification. When `scanf' finds a conversion
-- specification that uses this flag, it reads input as directed by
-- the rest of the conversion specification, but it discards this
-- input, does not use a pointer argument, and does not increment the
-- count of successful assignments.
--
-- * An optional flag character `a' (valid with string conversions only)
-- which requests allocation of a buffer long enough to store the
-- string in. (This is a GNU extension.) *Note Dynamic String
-- Input::.
--
-- * An optional decimal integer that specifies the "maximum field
-- width". Reading of characters from the input stream stops either
-- when this maximum is reached or when a non-matching character is
-- found, whichever happens first. Most conversions discard initial
-- whitespace characters (those that don't are explicitly
-- documented), and these discarded characters don't count towards
-- the maximum field width. String input conversions store a null
-- character to mark the end of the input; the maximum field width
-- does not include this terminator.
--
-- * An optional "type modifier character". For example, you can
-- specify a type modifier of `l' with integer conversions such as
-- `%d' to specify that the argument is a pointer to a `long int'
-- rather than a pointer to an `int'.
--
-- * A character that specifies the conversion to be applied.
--
-- The exact options that are permitted and how they are interpreted
--vary between the different conversion specifiers. See the descriptions
--of the individual conversions for information about the particular
--options that they allow.
--
-- With the `-Wformat' option, the GNU C compiler checks calls to
--`scanf' and related functions. It examines the format string and
--verifies that the correct number and types of arguments are supplied.
--There is also a GNU C syntax to tell the compiler that a function you
--write uses a `scanf'-style format string. *Note Declaring Attributes
--of Functions: (gcc.info)Function Attributes, for more information.
--
--
--File: libc.info, Node: Table of Input Conversions, Next: Numeric Input Conversions, Prev: Input Conversion Syntax, Up: Formatted Input
--
--Table of Input Conversions
----------------------------
--
-- Here is a table that summarizes the various conversion
--specifications:
--
--`%d'
-- Matches an optionally signed integer written in decimal. *Note
-- Numeric Input Conversions::.
--
--`%i'
-- Matches an optionally signed integer in any of the formats that
-- the C language defines for specifying an integer constant. *Note
-- Numeric Input Conversions::.
--
--`%o'
-- Matches an unsigned integer written in octal radix. *Note Numeric
-- Input Conversions::.
--
--`%u'
-- Matches an unsigned integer written in decimal radix. *Note
-- Numeric Input Conversions::.
--
--`%x', `%X'
-- Matches an unsigned integer written in hexadecimal radix. *Note
-- Numeric Input Conversions::.
--
--`%e', `%f', `%g', `%E', `%G'
-- Matches an optionally signed floating-point number. *Note Numeric
-- Input Conversions::.
--
--`%s'
-- Matches a string containing only non-whitespace characters. *Note
-- String Input Conversions::.
--
--`%['
-- Matches a string of characters that belong to a specified set.
-- *Note String Input Conversions::.
--
--`%c'
-- Matches a string of one or more characters; the number of
-- characters read is controlled by the maximum field width given for
-- the conversion. *Note String Input Conversions::.
--
--`%p'
-- Matches a pointer value in the same implementation-defined format
-- used by the `%p' output conversion for `printf'. *Note Other
-- Input Conversions::.
--
--`%n'
-- This conversion doesn't read any characters; it records the number
-- of characters read so far by this call. *Note Other Input
-- Conversions::.
--
--`%%'
-- This matches a literal `%' character in the input stream. No
-- corresponding argument is used. *Note Other Input Conversions::.
--
-- If the syntax of a conversion specification is invalid, the behavior
--is undefined. If there aren't enough function arguments provided to
--supply addresses for all the conversion specifications in the template
--strings that perform assignments, or if the arguments are not of the
--correct types, the behavior is also undefined. On the other hand, extra
--arguments are simply ignored.
--
--
--File: libc.info, Node: Numeric Input Conversions, Next: String Input Conversions, Prev: Table of Input Conversions, Up: Formatted Input
--
--Numeric Input Conversions
---------------------------
--
-- This section describes the `scanf' conversions for reading numeric
--values.
--
-- The `%d' conversion matches an optionally signed integer in decimal
--radix. The syntax that is recognized is the same as that for the
--`strtol' function (*note Parsing of Integers::.) with the value `10'
--for the BASE argument.
--
-- The `%i' conversion matches an optionally signed integer in any of
--the formats that the C language defines for specifying an integer
--constant. The syntax that is recognized is the same as that for the
--`strtol' function (*note Parsing of Integers::.) with the value `0' for
--the BASE argument. (You can print integers in this syntax with
--`printf' by using the `#' flag character with the `%x', `%o', or `%d'
--conversion. *Note Integer Conversions::.)
--
-- For example, any of the strings `10', `0xa', or `012' could be read
--in as integers under the `%i' conversion. Each of these specifies a
--number with decimal value `10'.
--
-- The `%o', `%u', and `%x' conversions match unsigned integers in
--octal, decimal, and hexadecimal radices, respectively. The syntax that
--is recognized is the same as that for the `strtoul' function (*note
--Parsing of Integers::.) with the appropriate value (`8', `10', or `16')
--for the BASE argument.
--
-- The `%X' conversion is identical to the `%x' conversion. They both
--permit either uppercase or lowercase letters to be used as digits.
--
-- The default type of the corresponding argument for the `%d' and `%i'
--conversions is `int *', and `unsigned int *' for the other integer
--conversions. You can use the following type modifiers to specify other
--sizes of integer:
--
--`hh'
-- Specifies that the argument is a `signed char *' or `unsigned char
-- *'.
--
-- This modifier was introduced in ISO C 9x.
--
--`h'
-- Specifies that the argument is a `short int *' or `unsigned short
-- int *'.
--
--`j'
-- Specifies that the argument is a `intmax_t *' or `uintmax_t *'.
--
-- This modifier was introduced in ISO C 9x.
--
--`l'
-- Specifies that the argument is a `long int *' or `unsigned long
-- int *'. Two `l' characters is like the `L' modifier, below.
--
--`ll'
--`L'
--`q'
-- Specifies that the argument is a `long long int *' or `unsigned
-- long long int *'. (The `long long' type is an extension supported
-- by the GNU C compiler. For systems that don't provide extra-long
-- integers, this is the same as `long int'.)
--
-- The `q' modifier is another name for the same thing, which comes
-- from 4.4 BSD; a `long long int' is sometimes called a "quad" `int'.
--
--`t'
-- Specifies that the argument is a `ptrdiff_t *'.
--
-- This modifier was introduced in ISO C 9x.
--
--`z'
-- Specifies that the argument is a `size_t *'.
--
-- This modifier was introduced in ISO C 9x.
--
-- All of the `%e', `%f', `%g', `%E', and `%G' input conversions are
--interchangeable. They all match an optionally signed floating point
--number, in the same syntax as for the `strtod' function (*note Parsing
--of Floats::.).
--
-- For the floating-point input conversions, the default argument type
--is `float *'. (This is different from the corresponding output
--conversions, where the default type is `double'; remember that `float'
--arguments to `printf' are converted to `double' by the default argument
--promotions, but `float *' arguments are not promoted to `double *'.)
--You can specify other sizes of float using these type modifiers:
--
--`l'
-- Specifies that the argument is of type `double *'.
--
--`L'
-- Specifies that the argument is of type `long double *'.
--
-- For all the above number parsing formats there is an additional
--optional flag `''. When this flag is given the `scanf' function
--expects the number represented in the input string to be formatted
--according to the grouping rules of the currently selected locale (*note
--General Numeric::.).
--
-- If the `"C"' or `"POSIX"' locale is selected there is no difference.
--But for a locale which specifies values for the appropriate fields in
--the locale the input must have the correct form in the input.
--Otherwise the longest prefix with a correct form is processed.
--
--
--File: libc.info, Node: String Input Conversions, Next: Dynamic String Input, Prev: Numeric Input Conversions, Up: Formatted Input
--
--String Input Conversions
--------------------------
--
-- This section describes the `scanf' input conversions for reading
--string and character values: `%s', `%[', and `%c'.
--
-- You have two options for how to receive the input from these
--conversions:
--
-- * Provide a buffer to store it in. This is the default. You should
-- provide an argument of type `char *'.
--
-- *Warning:* To make a robust program, you must make sure that the
-- input (plus its terminating null) cannot possibly exceed the size
-- of the buffer you provide. In general, the only way to do this is
-- to specify a maximum field width one less than the buffer size.
-- *If you provide the buffer, always specify a maximum field width
-- to prevent overflow.*
--
-- * Ask `scanf' to allocate a big enough buffer, by specifying the `a'
-- flag character. This is a GNU extension. You should provide an
-- argument of type `char **' for the buffer address to be stored in.
-- *Note Dynamic String Input::.
--
-- The `%c' conversion is the simplest: it matches a fixed number of
--characters, always. The maximum field with says how many characters to
--read; if you don't specify the maximum, the default is 1. This
--conversion doesn't append a null character to the end of the text it
--reads. It also does not skip over initial whitespace characters. It
--reads precisely the next N characters, and fails if it cannot get that
--many. Since there is always a maximum field width with `%c' (whether
--specified, or 1 by default), you can always prevent overflow by making
--the buffer long enough.
--
-- The `%s' conversion matches a string of non-whitespace characters.
--It skips and discards initial whitespace, but stops when it encounters
--more whitespace after having read something. It stores a null character
--at the end of the text that it reads.
--
-- For example, reading the input:
--
-- hello, world
--
--with the conversion `%10c' produces `" hello, wo"', but reading the
--same input with the conversion `%10s' produces `"hello,"'.
--
-- *Warning:* If you do not specify a field width for `%s', then the
--number of characters read is limited only by where the next whitespace
--character appears. This almost certainly means that invalid input can
--make your program crash--which is a bug.
--
-- To read in characters that belong to an arbitrary set of your choice,
--use the `%[' conversion. You specify the set between the `[' character
--and a following `]' character, using the same syntax used in regular
--expressions. As special cases:
--
-- * A literal `]' character can be specified as the first character of
-- the set.
--
-- * An embedded `-' character (that is, one that is not the first or
-- last character of the set) is used to specify a range of
-- characters.
--
-- * If a caret character `^' immediately follows the initial `[', then
-- the set of allowed input characters is the everything *except* the
-- characters listed.
--
-- The `%[' conversion does not skip over initial whitespace characters.
--
-- Here are some examples of `%[' conversions and what they mean:
--
--`%25[1234567890]'
-- Matches a string of up to 25 digits.
--
--`%25[][]'
-- Matches a string of up to 25 square brackets.
--
--`%25[^ \f\n\r\t\v]'
-- Matches a string up to 25 characters long that doesn't contain any
-- of the standard whitespace characters. This is slightly different
-- from `%s', because if the input begins with a whitespace character,
-- `%[' reports a matching failure while `%s' simply discards the
-- initial whitespace.
--
--`%25[a-z]'
-- Matches up to 25 lowercase characters.
--
-- One more reminder: the `%s' and `%[' conversions are *dangerous* if
--you don't specify a maximum width or use the `a' flag, because input
--too long would overflow whatever buffer you have provided for it. No
--matter how long your buffer is, a user could supply input that is
--longer. A well-written program reports invalid input with a
--comprehensible error message, not with a crash.
--
--
--File: libc.info, Node: Dynamic String Input, Next: Other Input Conversions, Prev: String Input Conversions, Up: Formatted Input
--
--Dynamically Allocating String Conversions
-------------------------------------------
--
-- A GNU extension to formatted input lets you safely read a string
--with no maximum size. Using this feature, you don't supply a buffer;
--instead, `scanf' allocates a buffer big enough to hold the data and
--gives you its address. To use this feature, write `a' as a flag
--character, as in `%as' or `%a[0-9a-z]'.
--
-- The pointer argument you supply for where to store the input should
--have type `char **'. The `scanf' function allocates a buffer and
--stores its address in the word that the argument points to. You should
--free the buffer with `free' when you no longer need it.
--
-- Here is an example of using the `a' flag with the `%[...]'
--conversion specification to read a "variable assignment" of the form
--`VARIABLE = VALUE'.
--
-- {
-- char *variable, *value;
--
-- if (2 > scanf ("%a[a-zA-Z0-9] = %a[^\n]\n",
-- &variable, &value))
-- {
-- invalid_input_error ();
-- return 0;
-- }
--
-- ...
-- }
--
--
--File: libc.info, Node: Other Input Conversions, Next: Formatted Input Functions, Prev: Dynamic String Input, Up: Formatted Input
--
--Other Input Conversions
-------------------------
--
-- This section describes the miscellaneous input conversions.
--
-- The `%p' conversion is used to read a pointer value. It recognizes
--the same syntax as is used by the `%p' output conversion for `printf'
--(*note Other Output Conversions::.); that is, a hexadecimal number just
--as the `%x' conversion accepts. The corresponding argument should be
--of type `void **'; that is, the address of a place to store a pointer.
--
-- The resulting pointer value is not guaranteed to be valid if it was
--not originally written during the same program execution that reads it
--in.
--
-- The `%n' conversion produces the number of characters read so far by
--this call. The corresponding argument should be of type `int *'. This
--conversion works in the same way as the `%n' conversion for `printf';
--see *Note Other Output Conversions::, for an example.
--
-- The `%n' conversion is the only mechanism for determining the
--success of literal matches or conversions with suppressed assignments.
--If the `%n' follows the locus of a matching failure, then no value is
--stored for it since `scanf' returns before processing the `%n'. If you
--store `-1' in that argument slot before calling `scanf', the presence
--of `-1' after `scanf' indicates an error occurred before the `%n' was
--reached.
--
-- Finally, the `%%' conversion matches a literal `%' character in the
--input stream, without using an argument. This conversion does not
--permit any flags, field width, or type modifier to be specified.
--
--
--File: libc.info, Node: Formatted Input Functions, Next: Variable Arguments Input, Prev: Other Input Conversions, Up: Formatted Input
--
--Formatted Input Functions
---------------------------
--
-- Here are the descriptions of the functions for performing formatted
--input. Prototypes for these functions are in the header file `stdio.h'.
--
-- - Function: int scanf (const char *TEMPLATE, ...)
-- The `scanf' function reads formatted input from the stream `stdin'
-- under the control of the template string TEMPLATE. The optional
-- arguments are pointers to the places which receive the resulting
-- values.
--
-- The return value is normally the number of successful assignments.
-- If an end-of-file condition is detected before any matches are
-- performed (including matches against whitespace and literal
-- characters in the template), then `EOF' is returned.
--
-- - Function: int fscanf (FILE *STREAM, const char *TEMPLATE, ...)
-- This function is just like `scanf', except that the input is read
-- from the stream STREAM instead of `stdin'.
--
-- - Function: int sscanf (const char *S, const char *TEMPLATE, ...)
-- This is like `scanf', except that the characters are taken from the
-- null-terminated string S instead of from a stream. Reaching the
-- end of the string is treated as an end-of-file condition.
--
-- The behavior of this function is undefined if copying takes place
-- between objects that overlap--for example, if S is also given as
-- an argument to receive a string read under control of the `%s'
-- conversion.
--
--
--File: libc.info, Node: Variable Arguments Input, Prev: Formatted Input Functions, Up: Formatted Input
--
--Variable Arguments Input Functions
------------------------------------
--
-- The functions `vscanf' and friends are provided so that you can
--define your own variadic `scanf'-like functions that make use of the
--same internals as the built-in formatted output functions. These
--functions are analogous to the `vprintf' series of output functions.
--*Note Variable Arguments Output::, for important information on how to
--use them.
--
-- *Portability Note:* The functions listed in this section are GNU
--extensions.
--
-- - Function: int vscanf (const char *TEMPLATE, va_list AP)
-- This function is similar to `scanf' except that, instead of taking
-- a variable number of arguments directly, it takes an argument list
-- pointer AP of type `va_list' (*note Variadic Functions::.).
--
-- - Function: int vfscanf (FILE *STREAM, const char *TEMPLATE, va_list
-- AP)
-- This is the equivalent of `fscanf' with the variable argument list
-- specified directly as for `vscanf'.
--
-- - Function: int vsscanf (const char *S, const char *TEMPLATE, va_list
-- AP)
-- This is the equivalent of `sscanf' with the variable argument list
-- specified directly as for `vscanf'.
--
-- In GNU C, there is a special construct you can use to let the
--compiler know that a function uses a `scanf'-style format string. Then
--it can check the number and types of arguments in each call to the
--function, and warn you when they do not match the format string. *Note
--Declaring Attributes of Functions: (gcc.info)Function Attributes, for
--details.
--
--
--File: libc.info, Node: EOF and Errors, Next: Binary Streams, Prev: Formatted Input, Up: I/O on Streams
--
--End-Of-File and Errors
--======================
--
-- Many of the functions described in this chapter return the value of
--the macro `EOF' to indicate unsuccessful completion of the operation.
--Since `EOF' is used to report both end of file and random errors, it's
--often better to use the `feof' function to check explicitly for end of
--file and `ferror' to check for errors. These functions check
--indicators that are part of the internal state of the stream object,
--indicators set if the appropriate condition was detected by a previous
--I/O operation on that stream.
--
-- These symbols are declared in the header file `stdio.h'.
--
-- - Macro: int EOF
-- This macro is an integer value that is returned by a number of
-- functions to indicate an end-of-file condition, or some other
-- error situation. With the GNU library, `EOF' is `-1'. In other
-- libraries, its value may be some other negative number.
--
-- - Function: void clearerr (FILE *STREAM)
-- This function clears the end-of-file and error indicators for the
-- stream STREAM.
--
-- The file positioning functions (*note File Positioning::.) also
-- clear the end-of-file indicator for the stream.
--
-- - Function: int feof (FILE *STREAM)
-- The `feof' function returns nonzero if and only if the end-of-file
-- indicator for the stream STREAM is set.
--
-- - Function: int ferror (FILE *STREAM)
-- The `ferror' function returns nonzero if and only if the error
-- indicator for the stream STREAM is set, indicating that an error
-- has occurred on a previous operation on the stream.
--
-- In addition to setting the error indicator associated with the
--stream, the functions that operate on streams also set `errno' in the
--same way as the corresponding low-level functions that operate on file
--descriptors. For example, all of the functions that perform output to a
--stream--such as `fputc', `printf', and `fflush'--are implemented in
--terms of `write', and all of the `errno' error conditions defined for
--`write' are meaningful for these functions. For more information about
--the descriptor-level I/O functions, see *Note Low-Level I/O::.
--
--
--File: libc.info, Node: Binary Streams, Next: File Positioning, Prev: EOF and Errors, Up: I/O on Streams
--
--Text and Binary Streams
--=======================
--
-- The GNU system and other POSIX-compatible operating systems organize
--all files as uniform sequences of characters. However, some other
--systems make a distinction between files containing text and files
--containing binary data, and the input and output facilities of ISO C
--provide for this distinction. This section tells you how to write
--programs portable to such systems.
--
-- When you open a stream, you can specify either a "text stream" or a
--"binary stream". You indicate that you want a binary stream by
--specifying the `b' modifier in the OPENTYPE argument to `fopen'; see
--*Note Opening Streams::. Without this option, `fopen' opens the file
--as a text stream.
--
-- Text and binary streams differ in several ways:
--
-- * The data read from a text stream is divided into "lines" which are
-- terminated by newline (`'\n'') characters, while a binary stream is
-- simply a long series of characters. A text stream might on some
-- systems fail to handle lines more than 254 characters long
-- (including the terminating newline character).
--
-- * On some systems, text files can contain only printing characters,
-- horizontal tab characters, and newlines, and so text streams may
-- not support other characters. However, binary streams can handle
-- any character value.
--
-- * Space characters that are written immediately preceding a newline
-- character in a text stream may disappear when the file is read in
-- again.
--
-- * More generally, there need not be a one-to-one mapping between
-- characters that are read from or written to a text stream, and the
-- characters in the actual file.
--
-- Since a binary stream is always more capable and more predictable
--than a text stream, you might wonder what purpose text streams serve.
--Why not simply always use binary streams? The answer is that on these
--operating systems, text and binary streams use different file formats,
--and the only way to read or write "an ordinary file of text" that can
--work with other text-oriented programs is through a text stream.
--
-- In the GNU library, and on all POSIX systems, there is no difference
--between text streams and binary streams. When you open a stream, you
--get the same kind of stream regardless of whether you ask for binary.
--This stream can handle any file content, and has none of the
--restrictions that text streams sometimes have.
--
--
--File: libc.info, Node: File Positioning, Next: Portable Positioning, Prev: Binary Streams, Up: I/O on Streams
--
--File Positioning
--================
--
-- The "file position" of a stream describes where in the file the
--stream is currently reading or writing. I/O on the stream advances the
--file position through the file. In the GNU system, the file position is
--represented as an integer, which counts the number of bytes from the
--beginning of the file. *Note File Position::.
--
-- During I/O to an ordinary disk file, you can change the file position
--whenever you wish, so as to read or write any portion of the file. Some
--other kinds of files may also permit this. Files which support changing
--the file position are sometimes referred to as "random-access" files.
--
-- You can use the functions in this section to examine or modify the
--file position indicator associated with a stream. The symbols listed
--below are declared in the header file `stdio.h'.
--
-- - Function: long int ftell (FILE *STREAM)
-- This function returns the current file position of the stream
-- STREAM.
--
-- This function can fail if the stream doesn't support file
-- positioning, or if the file position can't be represented in a
-- `long int', and possibly for other reasons as well. If a failure
-- occurs, a value of `-1' is returned.
--
-- - Function: off_t ftello (FILE *STREAM)
-- The `ftello' function is similar to `ftell' only it corrects a
-- problem which the POSIX type system. In this type system all file
-- positions are described using values of type `off_t' which is not
-- necessarily of the same size as `long int'. Therefore using
-- `ftell' can lead to problems if the implementation is written on
-- top of a POSIX compliant lowlevel I/O implementation.
--
-- Therefore it is a good idea to prefer `ftello' whenever it is
-- available since its functionality is (if different at all) closer
-- the underlying definition.
--
-- If this function fails it return `(off_t) -1'. This can happen due
-- to missing support for file positioning or internal errors.
-- Otherwise the return value is the current file position.
--
-- The function is an extension defined in the Unix Single
-- Specification version 2.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system this function is in fact `ftello64'. I.e., the LFS
-- interface transparently replaces the old interface.
--
-- - Function: off64_t ftello64 (FILE *STREAM)
-- This function is similar to `ftello' with the only difference that
-- the return value is of type `off64_t'. This also requires that the
-- stream STREAM was opened using either `fopen64', `freopen64', or
-- `tmpfile64' since otherwise the underlying file operations to
-- position the file pointer beyond the 2^31 bytes limit might fail.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' on a 32
-- bits machine this function is available under the name `ftello'
-- and so transparently replaces the old interface.
--
-- - Function: int fseek (FILE *STREAM, long int OFFSET, int WHENCE)
-- The `fseek' function is used to change the file position of the
-- stream STREAM. The value of WHENCE must be one of the constants
-- `SEEK_SET', `SEEK_CUR', or `SEEK_END', to indicate whether the
-- OFFSET is relative to the beginning of the file, the current file
-- position, or the end of the file, respectively.
--
-- This function returns a value of zero if the operation was
-- successful, and a nonzero value to indicate failure. A successful
-- call also clears the end-of-file indicator of STREAM and discards
-- any characters that were "pushed back" by the use of `ungetc'.
--
-- `fseek' either flushes any buffered output before setting the file
-- position or else remembers it so it will be written later in its
-- proper place in the file.
--
-- - Function: int fseeko (FILE *STREAM, off_t OFFSET, int WHENCE)
-- This function is similar to `fseek' but it corrects a problem with
-- `fseek' in a system with POSIX types. Using a value of type `long
-- int' for the offset is not compatible with POSIX. `fseeko' uses
-- the correct type `off_t' for the OFFSET parameter.
--
-- For this reason it is a good idea to prefer `ftello' whenever it is
-- available since its functionality is (if different at all) closer
-- the underlying definition.
--
-- The functionality and return value is the same as for `fseek'.
--
-- The function is an extension defined in the Unix Single
-- Specification version 2.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system this function is in fact `fseeko64'. I.e., the LFS
-- interface transparently replaces the old interface.
--
-- - Function: int fseeko64 (FILE *STREAM, off64_t OFFSET, int WHENCE)
-- This function is similar to `fseeko' with the only difference that
-- the OFFSET parameter is of type `off64_t'. This also requires
-- that the stream STREAM was opened using either `fopen64',
-- `freopen64', or `tmpfile64' since otherwise the underlying file
-- operations to position the file pointer beyond the 2^31 bytes
-- limit might fail.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' on a 32
-- bits machine this function is available under the name `fseeko'
-- and so transparently replaces the old interface.
--
-- *Portability Note:* In non-POSIX systems, `ftell', `ftello', `fseek'
--and `fseeko' might work reliably only on binary streams. *Note Binary
--Streams::.
--
-- The following symbolic constants are defined for use as the WHENCE
--argument to `fseek'. They are also used with the `lseek' function
--(*note I/O Primitives::.) and to specify offsets for file locks (*note
--Control Operations::.).
--
-- - Macro: int SEEK_SET
-- This is an integer constant which, when used as the WHENCE
-- argument to the `fseek' or `fseeko' function, specifies that the
-- offset provided is relative to the beginning of the file.
--
-- - Macro: int SEEK_CUR
-- This is an integer constant which, when used as the WHENCE
-- argument to the `fseek' or `fseeko' function, specifies that the
-- offset provided is relative to the current file position.
--
-- - Macro: int SEEK_END
-- This is an integer constant which, when used as the WHENCE
-- argument to the `fseek' or `fseeko' function, specifies that the
-- offset provided is relative to the end of the file.
--
-- - Function: void rewind (FILE *STREAM)
-- The `rewind' function positions the stream STREAM at the beginning
-- of the file. It is equivalent to calling `fseek' or `fseeko' on
-- the STREAM with an OFFSET argument of `0L' and a WHENCE argument
-- of `SEEK_SET', except that the return value is discarded and the
-- error indicator for the stream is reset.
--
-- These three aliases for the `SEEK_...' constants exist for the sake
--of compatibility with older BSD systems. They are defined in two
--different header files: `fcntl.h' and `sys/file.h'.
--
--`L_SET'
-- An alias for `SEEK_SET'.
--
--`L_INCR'
-- An alias for `SEEK_CUR'.
--
--`L_XTND'
-- An alias for `SEEK_END'.
--
--
--File: libc.info, Node: Portable Positioning, Next: Stream Buffering, Prev: File Positioning, Up: I/O on Streams
--
--Portable File-Position Functions
--================================
--
-- On the GNU system, the file position is truly a character count. You
--can specify any character count value as an argument to `fseek' or
--`fseeko' and get reliable results for any random access file. However,
--some ISO C systems do not represent file positions in this way.
--
-- On some systems where text streams truly differ from binary streams,
--it is impossible to represent the file position of a text stream as a
--count of characters from the beginning of the file. For example, the
--file position on some systems must encode both a record offset within
--the file, and a character offset within the record.
--
-- As a consequence, if you want your programs to be portable to these
--systems, you must observe certain rules:
--
-- * The value returned from `ftell' on a text stream has no predictable
-- relationship to the number of characters you have read so far.
-- The only thing you can rely on is that you can use it subsequently
-- as the OFFSET argument to `fseek' or `fseeko' to move back to the
-- same file position.
--
-- * In a call to `fseek' or `fseeko' on a text stream, either the
-- OFFSET must either be zero; or WHENCE must be `SEEK_SET' and the
-- OFFSET must be the result of an earlier call to `ftell' on the
-- same stream.
--
-- * The value of the file position indicator of a text stream is
-- undefined while there are characters that have been pushed back
-- with `ungetc' that haven't been read or discarded. *Note
-- Unreading::.
--
-- But even if you observe these rules, you may still have trouble for
--long files, because `ftell' and `fseek' use a `long int' value to
--represent the file position. This type may not have room to encode all
--the file positions in a large file. Using the `ftello' and `fseeko'
--functions might help here since the `off_t' type is expected to be able
--to hold all file position values but this still does not help to handle
--additional information which must be associated with a file position.
--
-- So if you do want to support systems with peculiar encodings for the
--file positions, it is better to use the functions `fgetpos' and
--`fsetpos' instead. These functions represent the file position using
--the data type `fpos_t', whose internal representation varies from
--system to system.
--
-- These symbols are declared in the header file `stdio.h'.
--
-- - Data Type: fpos_t
-- This is the type of an object that can encode information about the
-- file position of a stream, for use by the functions `fgetpos' and
-- `fsetpos'.
--
-- In the GNU system, `fpos_t' is equivalent to `off_t' or `long
-- int'. In other systems, it might have a different internal
-- representation.
--
-- When compiling with `_FILE_OFFSET_BITS == 64' on a 32 bits machine
-- this type is in fact equivalent to `off64_t' since the LFS
-- interface transparently replaced the old interface.
--
-- - Data Type: fpos64_t
-- This is the type of an object that can encode information about the
-- file position of a stream, for use by the functions `fgetpos64' and
-- `fsetpos64'.
--
-- In the GNU system, `fpos64_t' is equivalent to `off64_t' or `long
-- long int'. In other systems, it might have a different internal
-- representation.
--
-- - Function: int fgetpos (FILE *STREAM, fpos_t *POSITION)
-- This function stores the value of the file position indicator for
-- the stream STREAM in the `fpos_t' object pointed to by POSITION.
-- If successful, `fgetpos' returns zero; otherwise it returns a
-- nonzero value and stores an implementation-defined positive value
-- in `errno'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system the function is in fact `fgetpos64'. I.e., the LFS
-- interface transparently replaced the old interface.
--
-- - Function: int fgetpos64 (FILE *STREAM, fpos64_t *POSITION)
-- This function is similar to `fgetpos' but the file position is
-- returned in a variable of type `fpos64_t' to which POSITION points.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' on a 32
-- bits machine this function is available under the name `fgetpos'
-- and so transparently replaces the old interface.
--
-- - Function: int fsetpos (FILE *STREAM, const fpos_t *POSITION)
-- This function sets the file position indicator for the stream
-- STREAM to the position POSITION, which must have been set by a
-- previous call to `fgetpos' on the same stream. If successful,
-- `fsetpos' clears the end-of-file indicator on the stream, discards
-- any characters that were "pushed back" by the use of `ungetc', and
-- returns a value of zero. Otherwise, `fsetpos' returns a nonzero
-- value and stores an implementation-defined positive value in
-- `errno'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system the function is in fact `fsetpos64'. I.e., the LFS
-- interface transparently replaced the old interface.
--
-- - Function: int fsetpos64 (FILE *STREAM, const fpos64_t *POSITION)
-- This function is similar to `fsetpos' but the file position used
-- for positioning is provided in a variable of type `fpos64_t' to
-- which POSITION points.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' on a 32
-- bits machine this function is available under the name `fsetpos'
-- and so transparently replaces the old interface.
--
--
--File: libc.info, Node: Stream Buffering, Next: Other Kinds of Streams, Prev: Portable Positioning, Up: I/O on Streams
--
--Stream Buffering
--================
--
-- Characters that are written to a stream are normally accumulated and
--transmitted asynchronously to the file in a block, instead of appearing
--as soon as they are output by the application program. Similarly,
--streams often retrieve input from the host environment in blocks rather
--than on a character-by-character basis. This is called "buffering".
--
-- If you are writing programs that do interactive input and output
--using streams, you need to understand how buffering works when you
--design the user interface to your program. Otherwise, you might find
--that output (such as progress or prompt messages) doesn't appear when
--you intended it to, or other unexpected behavior.
--
-- This section deals only with controlling when characters are
--transmitted between the stream and the file or device, and *not* with
--how things like echoing, flow control, and the like are handled on
--specific classes of devices. For information on common control
--operations on terminal devices, see *Note Low-Level Terminal
--Interface::.
--
-- You can bypass the stream buffering facilities altogether by using
--the low-level input and output functions that operate on file
--descriptors instead. *Note Low-Level I/O::.
--
--* Menu:
--
--* Buffering Concepts:: Terminology is defined here.
--* Flushing Buffers:: How to ensure that output buffers are flushed.
--* Controlling Buffering:: How to specify what kind of buffering to use.
--
--
--File: libc.info, Node: Buffering Concepts, Next: Flushing Buffers, Up: Stream Buffering
--
--Buffering Concepts
--------------------
--
-- There are three different kinds of buffering strategies:
--
-- * Characters written to or read from an "unbuffered" stream are
-- transmitted individually to or from the file as soon as possible.
--
-- * Characters written to a "line buffered" stream are transmitted to
-- the file in blocks when a newline character is encountered.
--
-- * Characters written to or read from a "fully buffered" stream are
-- transmitted to or from the file in blocks of arbitrary size.
--
-- Newly opened streams are normally fully buffered, with one
--exception: a stream connected to an interactive device such as a
--terminal is initially line buffered. *Note Controlling Buffering::,
--for information on how to select a different kind of buffering.
--Usually the automatic selection gives you the most convenient kind of
--buffering for the file or device you open.
--
-- The use of line buffering for interactive devices implies that output
--messages ending in a newline will appear immediately--which is usually
--what you want. Output that doesn't end in a newline might or might not
--show up immediately, so if you want them to appear immediately, you
--should flush buffered output explicitly with `fflush', as described in
--*Note Flushing Buffers::.
--
--
--File: libc.info, Node: Flushing Buffers, Next: Controlling Buffering, Prev: Buffering Concepts, Up: Stream Buffering
--
--Flushing Buffers
------------------
--
-- "Flushing" output on a buffered stream means transmitting all
--accumulated characters to the file. There are many circumstances when
--buffered output on a stream is flushed automatically:
--
-- * When you try to do output and the output buffer is full.
--
-- * When the stream is closed. *Note Closing Streams::.
--
-- * When the program terminates by calling `exit'. *Note Normal
-- Termination::.
--
-- * When a newline is written, if the stream is line buffered.
--
-- * Whenever an input operation on *any* stream actually reads data
-- from its file.
--
-- If you want to flush the buffered output at another time, call
--`fflush', which is declared in the header file `stdio.h'.
--
-- - Function: int fflush (FILE *STREAM)
-- This function causes any buffered output on STREAM to be delivered
-- to the file. If STREAM is a null pointer, then `fflush' causes
-- buffered output on *all* open output streams to be flushed.
--
-- This function returns `EOF' if a write error occurs, or zero
-- otherwise.
--
-- *Compatibility Note:* Some brain-damaged operating systems have been
--known to be so thoroughly fixated on line-oriented input and output
--that flushing a line buffered stream causes a newline to be written!
--Fortunately, this "feature" seems to be becoming less common. You do
--not need to worry about this in the GNU system.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-17 glibc-2.1.3/manual/libc.info-17
---- ../glibc-2.1.3/manual/libc.info-17 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-17 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1134 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Controlling Buffering, Prev: Flushing Buffers, Up: Stream Buffering
--
--Controlling Which Kind of Buffering
-------------------------------------
--
-- After opening a stream (but before any other operations have been
--performed on it), you can explicitly specify what kind of buffering you
--want it to have using the `setvbuf' function.
--
-- The facilities listed in this section are declared in the header
--file `stdio.h'.
--
-- - Function: int setvbuf (FILE *STREAM, char *BUF, int MODE, size_t
-- SIZE)
-- This function is used to specify that the stream STREAM should
-- have the buffering mode MODE, which can be either `_IOFBF' (for
-- full buffering), `_IOLBF' (for line buffering), or `_IONBF' (for
-- unbuffered input/output).
--
-- If you specify a null pointer as the BUF argument, then `setvbuf'
-- allocates a buffer itself using `malloc'. This buffer will be
-- freed when you close the stream.
--
-- Otherwise, BUF should be a character array that can hold at least
-- SIZE characters. You should not free the space for this array as
-- long as the stream remains open and this array remains its buffer.
-- You should usually either allocate it statically, or `malloc'
-- (*note Unconstrained Allocation::.) the buffer. Using an
-- automatic array is not a good idea unless you close the file
-- before exiting the block that declares the array.
--
-- While the array remains a stream buffer, the stream I/O functions
-- will use the buffer for their internal purposes. You shouldn't
-- try to access the values in the array directly while the stream is
-- using it for buffering.
--
-- The `setvbuf' function returns zero on success, or a nonzero value
-- if the value of MODE is not valid or if the request could not be
-- honored.
--
-- - Macro: int _IOFBF
-- The value of this macro is an integer constant expression that can
-- be used as the MODE argument to the `setvbuf' function to specify
-- that the stream should be fully buffered.
--
-- - Macro: int _IOLBF
-- The value of this macro is an integer constant expression that can
-- be used as the MODE argument to the `setvbuf' function to specify
-- that the stream should be line buffered.
--
-- - Macro: int _IONBF
-- The value of this macro is an integer constant expression that can
-- be used as the MODE argument to the `setvbuf' function to specify
-- that the stream should be unbuffered.
--
-- - Macro: int BUFSIZ
-- The value of this macro is an integer constant expression that is
-- good to use for the SIZE argument to `setvbuf'. This value is
-- guaranteed to be at least `256'.
--
-- The value of `BUFSIZ' is chosen on each system so as to make stream
-- I/O efficient. So it is a good idea to use `BUFSIZ' as the size
-- for the buffer when you call `setvbuf'.
--
-- Actually, you can get an even better value to use for the buffer
-- size by means of the `fstat' system call: it is found in the
-- `st_blksize' field of the file attributes. *Note Attribute
-- Meanings::.
--
-- Sometimes people also use `BUFSIZ' as the allocation size of
-- buffers used for related purposes, such as strings used to receive
-- a line of input with `fgets' (*note Character Input::.). There is
-- no particular reason to use `BUFSIZ' for this instead of any other
-- integer, except that it might lead to doing I/O in chunks of an
-- efficient size.
--
-- - Function: void setbuf (FILE *STREAM, char *BUF)
-- If BUF is a null pointer, the effect of this function is
-- equivalent to calling `setvbuf' with a MODE argument of `_IONBF'.
-- Otherwise, it is equivalent to calling `setvbuf' with BUF, and a
-- MODE of `_IOFBF' and a SIZE argument of `BUFSIZ'.
--
-- The `setbuf' function is provided for compatibility with old code;
-- use `setvbuf' in all new programs.
--
-- - Function: void setbuffer (FILE *STREAM, char *BUF, size_t SIZE)
-- If BUF is a null pointer, this function makes STREAM unbuffered.
-- Otherwise, it makes STREAM fully buffered using BUF as the buffer.
-- The SIZE argument specifies the length of BUF.
--
-- This function is provided for compatibility with old BSD code. Use
-- `setvbuf' instead.
--
-- - Function: void setlinebuf (FILE *STREAM)
-- This function makes STREAM be line buffered, and allocates the
-- buffer for you.
--
-- This function is provided for compatibility with old BSD code. Use
-- `setvbuf' instead.
--
--
--File: libc.info, Node: Other Kinds of Streams, Next: Formatted Messages, Prev: Stream Buffering, Up: I/O on Streams
--
--Other Kinds of Streams
--======================
--
-- The GNU library provides ways for you to define additional kinds of
--streams that do not necessarily correspond to an open file.
--
-- One such type of stream takes input from or writes output to a
--string. These kinds of streams are used internally to implement the
--`sprintf' and `sscanf' functions. You can also create such a stream
--explicitly, using the functions described in *Note String Streams::.
--
-- More generally, you can define streams that do input/output to
--arbitrary objects using functions supplied by your program. This
--protocol is discussed in *Note Custom Streams::.
--
-- *Portability Note:* The facilities described in this section are
--specific to GNU. Other systems or C implementations might or might not
--provide equivalent functionality.
--
--* Menu:
--
--* String Streams:: Streams that get data from or put data in
-- a string or memory buffer.
--* Obstack Streams:: Streams that store data in an obstack.
--* Custom Streams:: Defining your own streams with an arbitrary
-- input data source and/or output data sink.
--
--
--File: libc.info, Node: String Streams, Next: Obstack Streams, Up: Other Kinds of Streams
--
--String Streams
----------------
--
-- The `fmemopen' and `open_memstream' functions allow you to do I/O to
--a string or memory buffer. These facilities are declared in `stdio.h'.
--
-- - Function: FILE * fmemopen (void *BUF, size_t SIZE, const char
-- *OPENTYPE)
-- This function opens a stream that allows the access specified by
-- the OPENTYPE argument, that reads from or writes to the buffer
-- specified by the argument BUF. This array must be at least SIZE
-- bytes long.
--
-- If you specify a null pointer as the BUF argument, `fmemopen'
-- dynamically allocates (as with `malloc'; *note Unconstrained
-- Allocation::.) an array SIZE bytes long. This is really only
-- useful if you are going to write things to the buffer and then
-- read them back in again, because you have no way of actually
-- getting a pointer to the buffer (for this, try `open_memstream',
-- below). The buffer is freed when the stream is open.
--
-- The argument OPENTYPE is the same as in `fopen' (*note Opening
-- Streams::.). If the OPENTYPE specifies append mode, then the
-- initial file position is set to the first null character in the
-- buffer. Otherwise the initial file position is at the beginning
-- of the buffer.
--
-- When a stream open for writing is flushed or closed, a null
-- character (zero byte) is written at the end of the buffer if it
-- fits. You should add an extra byte to the SIZE argument to
-- account for this. Attempts to write more than SIZE bytes to the
-- buffer result in an error.
--
-- For a stream open for reading, null characters (zero bytes) in the
-- buffer do not count as "end of file". Read operations indicate
-- end of file only when the file position advances past SIZE bytes.
-- So, if you want to read characters from a null-terminated string,
-- you should supply the length of the string as the SIZE argument.
--
-- Here is an example of using `fmemopen' to create a stream for
--reading from a string:
--
-- #include <stdio.h>
--
-- static char buffer[] = "foobar";
--
-- int
-- main (void)
-- {
-- int ch;
-- FILE *stream;
--
-- stream = fmemopen (buffer, strlen (buffer), "r");
-- while ((ch = fgetc (stream)) != EOF)
-- printf ("Got %c\n", ch);
-- fclose (stream);
--
-- return 0;
-- }
--
-- This program produces the following output:
--
-- Got f
-- Got o
-- Got o
-- Got b
-- Got a
-- Got r
--
-- - Function: FILE * open_memstream (char **PTR, size_t *SIZELOC)
-- This function opens a stream for writing to a buffer. The buffer
-- is allocated dynamically (as with `malloc'; *note Unconstrained
-- Allocation::.) and grown as necessary.
--
-- When the stream is closed with `fclose' or flushed with `fflush',
-- the locations PTR and SIZELOC are updated to contain the pointer
-- to the buffer and its size. The values thus stored remain valid
-- only as long as no further output on the stream takes place. If
-- you do more output, you must flush the stream again to store new
-- values before you use them again.
--
-- A null character is written at the end of the buffer. This null
-- character is *not* included in the size value stored at SIZELOC.
--
-- You can move the stream's file position with `fseek' or `fseeko'
-- (*note File Positioning::.). Moving the file position past the
-- end of the data already written fills the intervening space with
-- zeroes.
--
-- Here is an example of using `open_memstream':
--
-- #include <stdio.h>
--
-- int
-- main (void)
-- {
-- char *bp;
-- size_t size;
-- FILE *stream;
--
-- stream = open_memstream (&bp, &size);
-- fprintf (stream, "hello");
-- fflush (stream);
-- printf ("buf = `%s', size = %d\n", bp, size);
-- fprintf (stream, ", world");
-- fclose (stream);
-- printf ("buf = `%s', size = %d\n", bp, size);
--
-- return 0;
-- }
--
-- This program produces the following output:
--
-- buf = `hello', size = 5
-- buf = `hello, world', size = 12
--
--
--File: libc.info, Node: Obstack Streams, Next: Custom Streams, Prev: String Streams, Up: Other Kinds of Streams
--
--Obstack Streams
-----------------
--
-- You can open an output stream that puts it data in an obstack.
--*Note Obstacks::.
--
-- - Function: FILE * open_obstack_stream (struct obstack *OBSTACK)
-- This function opens a stream for writing data into the obstack
-- OBSTACK. This starts an object in the obstack and makes it grow
-- as data is written (*note Growing Objects::.).
--
-- Calling `fflush' on this stream updates the current size of the
-- object to match the amount of data that has been written. After a
-- call to `fflush', you can examine the object temporarily.
--
-- You can move the file position of an obstack stream with `fseek' or
-- `fseeko' (*note File Positioning::.). Moving the file position
-- past the end of the data written fills the intervening space with
-- zeros.
--
-- To make the object permanent, update the obstack with `fflush', and
-- then use `obstack_finish' to finalize the object and get its
-- address. The following write to the stream starts a new object in
-- the obstack, and later writes add to that object until you do
-- another `fflush' and `obstack_finish'.
--
-- But how do you find out how long the object is? You can get the
-- length in bytes by calling `obstack_object_size' (*note Status of
-- an Obstack::.), or you can null-terminate the object like this:
--
-- obstack_1grow (OBSTACK, 0);
--
-- Whichever one you do, you must do it *before* calling
-- `obstack_finish'. (You can do both if you wish.)
--
-- Here is a sample function that uses `open_obstack_stream':
--
-- char *
-- make_message_string (const char *a, int b)
-- {
-- FILE *stream = open_obstack_stream (&message_obstack);
-- output_task (stream);
-- fprintf (stream, ": ");
-- fprintf (stream, a, b);
-- fprintf (stream, "\n");
-- fclose (stream);
-- obstack_1grow (&message_obstack, 0);
-- return obstack_finish (&message_obstack);
-- }
--
--
--File: libc.info, Node: Custom Streams, Prev: Obstack Streams, Up: Other Kinds of Streams
--
--Programming Your Own Custom Streams
-------------------------------------
--
-- This section describes how you can make a stream that gets input
--from an arbitrary data source or writes output to an arbitrary data sink
--programmed by you. We call these "custom streams".
--
--* Menu:
--
--* Streams and Cookies:: The "cookie" records where to fetch or
-- store data that is read or written.
--* Hook Functions:: How you should define the four "hook
-- functions" that a custom stream needs.
--
--
--File: libc.info, Node: Streams and Cookies, Next: Hook Functions, Up: Custom Streams
--
--Custom Streams and Cookies
--..........................
--
-- Inside every custom stream is a special object called the "cookie".
--This is an object supplied by you which records where to fetch or store
--the data read or written. It is up to you to define a data type to use
--for the cookie. The stream functions in the library never refer
--directly to its contents, and they don't even know what the type is;
--they record its address with type `void *'.
--
-- To implement a custom stream, you must specify *how* to fetch or
--store the data in the specified place. You do this by defining "hook
--functions" to read, write, change "file position", and close the
--stream. All four of these functions will be passed the stream's cookie
--so they can tell where to fetch or store the data. The library
--functions don't know what's inside the cookie, but your functions will
--know.
--
-- When you create a custom stream, you must specify the cookie pointer,
--and also the four hook functions stored in a structure of type
--`cookie_io_functions_t'.
--
-- These facilities are declared in `stdio.h'.
--
-- - Data Type: cookie_io_functions_t
-- This is a structure type that holds the functions that define the
-- communications protocol between the stream and its cookie. It has
-- the following members:
--
-- `cookie_read_function_t *read'
-- This is the function that reads data from the cookie. If the
-- value is a null pointer instead of a function, then read
-- operations on this stream always return `EOF'.
--
-- `cookie_write_function_t *write'
-- This is the function that writes data to the cookie. If the
-- value is a null pointer instead of a function, then data
-- written to the stream is discarded.
--
-- `cookie_seek_function_t *seek'
-- This is the function that performs the equivalent of file
-- positioning on the cookie. If the value is a null pointer
-- instead of a function, calls to `fseek' or `fseeko' on this
-- stream can only seek to locations within the buffer; any
-- attempt to seek outside the buffer will return an `ESPIPE'
-- error.
--
-- `cookie_close_function_t *close'
-- This function performs any appropriate cleanup on the cookie
-- when closing the stream. If the value is a null pointer
-- instead of a function, nothing special is done to close the
-- cookie when the stream is closed.
--
-- - Function: FILE * fopencookie (void *COOKIE, const char *OPENTYPE,
-- cookie_io_functions_t IO-FUNCTIONS)
-- This function actually creates the stream for communicating with
-- the COOKIE using the functions in the IO-FUNCTIONS argument. The
-- OPENTYPE argument is interpreted as for `fopen'; see *Note Opening
-- Streams::. (But note that the "truncate on open" option is
-- ignored.) The new stream is fully buffered.
--
-- The `fopencookie' function returns the newly created stream, or a
-- null pointer in case of an error.
--
--
--File: libc.info, Node: Hook Functions, Prev: Streams and Cookies, Up: Custom Streams
--
--Custom Stream Hook Functions
--............................
--
-- Here are more details on how you should define the four hook
--functions that a custom stream needs.
--
-- You should define the function to read data from the cookie as:
--
-- ssize_t READER (void *COOKIE, void *BUFFER, size_t SIZE)
--
-- This is very similar to the `read' function; see *Note I/O
--Primitives::. Your function should transfer up to SIZE bytes into the
--BUFFER, and return the number of bytes read, or zero to indicate
--end-of-file. You can return a value of `-1' to indicate an error.
--
-- You should define the function to write data to the cookie as:
--
-- ssize_t WRITER (void *COOKIE, const void *BUFFER, size_t SIZE)
--
-- This is very similar to the `write' function; see *Note I/O
--Primitives::. Your function should transfer up to SIZE bytes from the
--buffer, and return the number of bytes written. You can return a value
--of `-1' to indicate an error.
--
-- You should define the function to perform seek operations on the
--cookie as:
--
-- int SEEKER (void *COOKIE, fpos_t *POSITION, int WHENCE)
--
-- For this function, the POSITION and WHENCE arguments are interpreted
--as for `fgetpos'; see *Note Portable Positioning::. In the GNU
--library, `fpos_t' is equivalent to `off_t' or `long int', and simply
--represents the number of bytes from the beginning of the file.
--
-- After doing the seek operation, your function should store the
--resulting file position relative to the beginning of the file in
--POSITION. Your function should return a value of `0' on success and
--`-1' to indicate an error.
--
-- You should define the function to do cleanup operations on the cookie
--appropriate for closing the stream as:
--
-- int CLEANER (void *COOKIE)
--
-- Your function should return `-1' to indicate an error, and `0'
--otherwise.
--
-- - Data Type: cookie_read_function
-- This is the data type that the read function for a custom stream
-- should have. If you declare the function as shown above, this is
-- the type it will have.
--
-- - Data Type: cookie_write_function
-- The data type of the write function for a custom stream.
--
-- - Data Type: cookie_seek_function
-- The data type of the seek function for a custom stream.
--
-- - Data Type: cookie_close_function
-- The data type of the close function for a custom stream.
--
--
--File: libc.info, Node: Formatted Messages, Prev: Other Kinds of Streams, Up: I/O on Streams
--
--Formatted Messages
--==================
--
-- On systems which are based on System V messages of programs
--(especially the system tools) are printed in a strict form using the
--`fmtmsg' function. The uniformity sometimes helps the user to
--interpret messages and the strictness tests of the `fmtmsg' function
--ensure that the programmer follows some minimal requirements.
--
--* Menu:
--
--* Printing Formatted Messages:: The `fmtmsg' function.
--* Adding Severity Classes:: Add more severity classes.
--* Example:: How to use `fmtmsg' and `addseverity'.
--
--
--File: libc.info, Node: Printing Formatted Messages, Next: Adding Severity Classes, Up: Formatted Messages
--
--Printing Formatted Messages
-----------------------------
--
-- Messages can be printed to standard error and/or to the console. To
--select the destination the programmer can use the following two values,
--bitwise OR combined if wanted, for the CLASSIFICATION parameter of
--`fmtmsg':
--
--`MM_PRINT'
-- Display the message in standard error.
--
--`MM_CONSOLE'
-- Display the message on the system console.
--
-- The erroneous piece of the system can be signalled by exactly one of
--the following values which also is bitwise ORed with the CLASSIFICATION
--parameter to `fmtmsg':
--
--`MM_HARD'
-- The source of the condition is some hardware.
--
--`MM_SOFT'
-- The source of the condition is some software.
--
--`MM_FIRM'
-- The source of the condition is some firmware.
--
-- A third component of the CLASSIFICATION parameter to `fmtmsg' can
--describe the part of the system which detects the problem. This is
--done by using exactly one of the following values:
--
--`MM_APPL'
-- The erroneous condition is detected by the application.
--
--`MM_UTIL'
-- The erroneous condition is detected by a utility.
--
--`MM_OPSYS'
-- The erroneous condition is detected by the operating system.
--
-- A last component of CLASSIFICATION can signal the results of this
--message. Exactly one of the following values can be used:
--
--`MM_RECOVER'
-- It is a recoverable error.
--
--`MM_NRECOV'
-- It is a non-recoverable error.
--
-- - Function: int fmtmsg (long int CLASSIFICATION, const char *LABEL,
-- int SEVERITY, const char *TEXT, const char *ACTION, const
-- char *TAG)
-- Display a message described by its parameters on the device(s)
-- specified in the CLASSIFICATION parameter. The LABEL parameter
-- identifies the source of the message. The string should consist
-- of two colon separated parts where the first part has not more
-- than 10 and the second part not more the 14 characters. The TEXT
-- parameter describes the condition of the error, the ACTION
-- parameter possible steps to recover from the error and the TAG
-- parameter is a reference to the online documentation where more
-- information can be found. It should contain the LABEL value and a
-- unique identification number.
--
-- Each of the parameters can be a special value which means this
-- value is to be omitted. The symbolic names for these values are:
--
-- `MM_NULLLBL'
-- Ignore LABEL parameter.
--
-- `MM_NULLSEV'
-- Ignore SEVERITY parameter.
--
-- `MM_NULLMC'
-- Ignore CLASSIFICATION parameter. This implies that nothing is
-- actually printed.
--
-- `MM_NULLTXT'
-- Ignore TEXT parameter.
--
-- `MM_NULLACT'
-- Ignore ACTION parameter.
--
-- `MM_NULLTAG'
-- Ignore TAG parameter.
--
-- There is another way certain fields can be omitted from the output
-- to standard error. This is described below in the description of
-- environment variables influencing the behaviour.
--
-- The SEVERITY parameter can have one of the values in the following
-- table:
--
-- `MM_NOSEV'
-- Nothing is printed, this value is the same as `MM_NULLSEV'.
--
-- `MM_HALT'
-- This value is printed as `HALT'.
--
-- `MM_ERROR'
-- This value is printed as `ERROR'.
--
-- `MM_WARNING'
-- This value is printed as `WARNING'.
--
-- `MM_INFO'
-- This value is printed as `INFO'.
--
-- The numeric value of these five macros are between `0' and `4'.
-- Using the environment variable `SEV_LEVEL' or using the
-- `addseverity' function one can add more severity levels with their
-- corresponding string to print. This is described below (*note
-- Adding Severity Classes::.).
--
-- If no parameter is ignored the output looks like this:
--
-- LABEL: SEVERITY-STRING: TEXT
-- TO FIX: ACTION TAG
--
-- The colons, new line characters and the `TO FIX' string are
-- inserted if necessary, i.e., if the corresponding parameter is not
-- ignored.
--
-- This function is specified in the X/Open Portability Guide. It is
-- also available on all system derived from System V.
--
-- The function returns the value `MM_OK' if no error occurred. If
-- only the printing to standard error failed, it returns `MM_NOMSG'.
-- If printing to the console fails, it returns `MM_NOCON'. If
-- nothing is printed `MM_NOTOK' is returned. Among situations where
-- all outputs fail this last value is also returned if a parameter
-- value is incorrect.
--
-- There are two environment variables which influence the behaviour of
--`fmtmsg'. The first is `MSGVERB'. It is used to control the output
--actually happening on standard error (*not* the console output). Each
--of the five fields can explicitely be enabled. To do this the user has
--to put the `MSGVERB' variable with a format like the following in the
--environment before calling the `fmtmsg' function the first time:
--
-- MSGVERB=KEYWORD[:KEYWORD[:...]]
--
-- Valid KEYWORDs are `label', `severity', `text', `action', and `tag'.
--If the environment variable is not given or is the empty string, a not
--supported keyword is given or the value is somehow else invalid, no
--part of the message is masked out.
--
-- The second environment variable which influences the behaviour of
--`fmtmsg' is `SEV_LEVEL'. This variable and the change in the behaviour
--of `fmtmsg' is not specified in the X/Open Portability Guide. It is
--available in System V systems, though. It can be used to introduce new
--severity levels. By default, only the five severity levels described
--above are available. Any other numeric value would make `fmtmsg' print
--nothing.
--
-- If the user puts `SEV_LEVEL' with a format like
--
-- SEV_LEVEL=[DESCRIPTION[:DESCRIPTION[:...]]]
--
--in the environment of the process before the first call to `fmtmsg',
--where DESCRIPTION has a value of the form
--
-- SEVERITY-KEYWORD,LEVEL,PRINTSTRING
--
-- The SEVERITY-KEYWORD part is not used by `fmtmsg' but it has to be
--present. The LEVEL part is a string representation of a number. The
--numeric value must be a number greater than 4. This value must be used
--in the SEVERITY parameter of `fmtmsg' to select this class. It is not
--possible to overwrite any of the predefined classes. The PRINTSTRING
--is the string printed when a message of this class is processed by
--`fmtmsg' (see above, `fmtsmg' does not print the numeric value but
--instead the string representation).
--
--
--File: libc.info, Node: Adding Severity Classes, Next: Example, Prev: Printing Formatted Messages, Up: Formatted Messages
--
--Adding Severity Classes
-------------------------
--
-- There is another possibility to introduce severity classes beside
--using the environment variable `SEV_LEVEL'. This simplifies the task of
--introducing new classes in a running program. One could use the
--`setenv' or `putenv' function to set the environment variable, but this
--is toilsome.
--
-- - Function: int addseverity (int SEVERITY, const char *STRING)
-- This function allows to introduce new severity classes which can be
-- addressed by the SEVERITY parameter of the `fmtmsg' function. The
-- SEVERITY parameter of `addseverity' must match the value for the
-- parameter with the same name of `fmtmsg' and STRING is the string
-- printed in the actual messages instead of the numeric value.
--
-- If STRING is `NULL' the severity class with the numeric value
-- according to SEVERITY is removed.
--
-- It is not possible to overwrite or remove one of the default
-- severity classes. All calls to `addseverity' with SEVERITY set to
-- one of the values for the default classes will fail.
--
-- The return value is `MM_OK' if the task was successfully performed.
-- If the return value is `MM_NOTOK' something went wrong. This could
-- mean that no more memory is available or a class is not available
-- when it has to be removed.
--
-- This function is not specified in the X/Open Portability Guide
-- although the `fmtsmg' function is. It is available on System V
-- systems.
--
--
--File: libc.info, Node: Example, Prev: Adding Severity Classes, Up: Formatted Messages
--
--How to use `fmtmsg' and `addseverity'
---------------------------------------
--
-- Here is a simple example program to illustrate the use of the both
--functions described in this section.
--
-- #include <fmtmsg.h>
--
-- int
-- main (void)
-- {
-- addseverity (5, "NOTE2");
-- fmtmsg (MM_PRINT, "only1field", MM_INFO, "text2", "action2", "tag2");
-- fmtmsg (MM_PRINT, "UX:cat", 5, "invalid syntax", "refer to manual",
-- "UX:cat:001");
-- fmtmsg (MM_PRINT, "label:foo", 6, "text", "action", "tag");
-- return 0;
-- }
--
-- The second call to `fmtmsg' illustrates a use of this function how
--it usually happens on System V systems which heavily use this function.
--It might be worth a thought to follow the scheme used in System V
--systems so we give a short explanation here. The value of the LABEL
--field (`UX:cat') says that the error occured in the Unix program `cat'.
--The explanation of the error follows and the value for the ACTION
--parameter is `"refer to manual"'. One could me more specific here, if
--needed. The TAG field contains, as proposed above, the value of the
--string given for the LABEL parameter, and additionally a unique ID
--(`001' in this case). For a GNU environment this string could contain
--a reference to the corresponding node in the Info page for the program.
--
--Running this program without specifying the `MSGVERB' and `SEV_LEVEL'
--function produces the following output:
--
-- UX:cat: NOTE2: invalid syntax
-- TO FIX: refer to manual UX:cat:001
--
-- We see the different fields of the message and how the extra glue
--(the colons and the `TO FIX' string) are printed. But only one of the
--three calls to `fmtmsg' produced output. The first call does not print
--anything because the LABEL parameter is not in the correct form. The
--string must contain two fields, separated by a colon (*note Printing
--Formatted Messages::.). The third `fmtmsg' call produced no output
--since the class with the numeric value `6' is not defined. Although a
--class with numeric value `5' is also not defined by default, the call
--the `addseverity' introduces it and the second call to `fmtmsg'
--produces the above output.
--
-- When we change the environment of the program to contain
--`SEV_LEVEL=XXX,6,NOTE' when running it we get a different result:
--
-- UX:cat: NOTE2: invalid syntax
-- TO FIX: refer to manual UX:cat:001
-- label:foo: NOTE: text
-- TO FIX: action tag
--
-- Now the third call the `fmtmsg' produced some output and we see how
--the string `NOTE' from the environment variable appears in the message.
--
-- Now we can reduce the output by specifying in which fields we are
--interested in. If we additionally set the environment variable
--`MSGVERB' to the value `severity:label:action' we get the following
--output:
--
-- UX:cat: NOTE2
-- TO FIX: refer to manual
-- label:foo: NOTE
-- TO FIX: action
--
--I.e., the output produced by the TEXT and the TAG parameters to
--`fmtmsg' vanished. Please also note that now there is no colon after
--the `NOTE' and `NOTE2' strings in the output. This is not necessary
--since there is no more output on this line since the text is missing.
--
--
--File: libc.info, Node: Low-Level I/O, Next: File System Interface, Prev: I/O on Streams, Up: Top
--
--Low-Level Input/Output
--**********************
--
-- This chapter describes functions for performing low-level
--input/output operations on file descriptors. These functions include
--the primitives for the higher-level I/O functions described in *Note
--I/O on Streams::, as well as functions for performing low-level control
--operations for which there are no equivalents on streams.
--
-- Stream-level I/O is more flexible and usually more convenient;
--therefore, programmers generally use the descriptor-level functions only
--when necessary. These are some of the usual reasons:
--
-- * For reading binary files in large chunks.
--
-- * For reading an entire file into core before parsing it.
--
-- * To perform operations other than data transfer, which can only be
-- done with a descriptor. (You can use `fileno' to get the
-- descriptor corresponding to a stream.)
--
-- * To pass descriptors to a child process. (The child can create its
-- own stream to use a descriptor that it inherits, but cannot
-- inherit a stream directly.)
--
--* Menu:
--
--* Opening and Closing Files:: How to open and close file
-- descriptors.
--* Truncating Files:: Change the size of a file.
--* I/O Primitives:: Reading and writing data.
--* File Position Primitive:: Setting a descriptor's file
-- position.
--* Descriptors and Streams:: Converting descriptor to stream
-- or vice-versa.
--* Stream/Descriptor Precautions:: Precautions needed if you use both
-- descriptors and streams.
--* Scatter-Gather:: Fast I/O to discontinous buffers.
--* Memory-mapped I/O:: Using files like memory.
--* Waiting for I/O:: How to check for input or output
-- on multiple file descriptors.
--* Synchronizing I/O:: Making sure all I/O actions completed.
--* Asynchronous I/O:: Perform I/O in parallel.
--* Control Operations:: Various other operations on file
-- descriptors.
--* Duplicating Descriptors:: Fcntl commands for duplicating
-- file descriptors.
--* Descriptor Flags:: Fcntl commands for manipulating
-- flags associated with file
-- descriptors.
--* File Status Flags:: Fcntl commands for manipulating
-- flags associated with open files.
--* File Locks:: Fcntl commands for implementing
-- file locking.
--* Interrupt Input:: Getting an asynchronous signal when
-- input arrives.
--* IOCTLs:: Generic I/O Control operations.
--
--
--File: libc.info, Node: Opening and Closing Files, Next: Truncating Files, Up: Low-Level I/O
--
--Opening and Closing Files
--=========================
--
-- This section describes the primitives for opening and closing files
--using file descriptors. The `open' and `creat' functions are declared
--in the header file `fcntl.h', while `close' is declared in `unistd.h'.
--
-- - Function: int open (const char *FILENAME, int FLAGS[, mode_t MODE])
-- The `open' function creates and returns a new file descriptor for
-- the file named by FILENAME. Initially, the file position
-- indicator for the file is at the beginning of the file. The
-- argument MODE is used only when a file is created, but it doesn't
-- hurt to supply the argument in any case.
--
-- The FLAGS argument controls how the file is to be opened. This is
-- a bit mask; you create the value by the bitwise OR of the
-- appropriate parameters (using the `|' operator in C). *Note File
-- Status Flags::, for the parameters available.
--
-- The normal return value from `open' is a non-negative integer file
-- descriptor. In the case of an error, a value of -1 is returned
-- instead. In addition to the usual file name errors (*note File
-- Name Errors::.), the following `errno' error conditions are defined
-- for this function:
--
-- `EACCES'
-- The file exists but is not readable/writable as requested by
-- the FLAGS argument, the file does not exist and the directory
-- is unwritable so it cannot be created.
--
-- `EEXIST'
-- Both `O_CREAT' and `O_EXCL' are set, and the named file
-- already exists.
--
-- `EINTR'
-- The `open' operation was interrupted by a signal. *Note
-- Interrupted Primitives::.
--
-- `EISDIR'
-- The FLAGS argument specified write access, and the file is a
-- directory.
--
-- `EMFILE'
-- The process has too many files open. The maximum number of
-- file descriptors is controlled by the `RLIMIT_NOFILE'
-- resource limit; *note Limits on Resources::..
--
-- `ENFILE'
-- The entire system, or perhaps the file system which contains
-- the directory, cannot support any additional open files at
-- the moment. (This problem cannot happen on the GNU system.)
--
-- `ENOENT'
-- The named file does not exist, and `O_CREAT' is not specified.
--
-- `ENOSPC'
-- The directory or file system that would contain the new file
-- cannot be extended, because there is no disk space left.
--
-- `ENXIO'
-- `O_NONBLOCK' and `O_WRONLY' are both set in the FLAGS
-- argument, the file named by FILENAME is a FIFO (*note Pipes
-- and FIFOs::.), and no process has the file open for reading.
--
-- `EROFS'
-- The file resides on a read-only file system and any of
-- `O_WRONLY', `O_RDWR', and `O_TRUNC' are set in the FLAGS
-- argument, or `O_CREAT' is set and the file does not already
-- exist.
--
-- If on a 32 bits machine the sources are translated with
-- `_FILE_OFFSET_BITS == 64' the function `open' returns a file
-- descriptor opened in the large file mode which enables the file
-- handling functions to use files up to 2^63 bytes in size and
-- offset from -2^63 to 2^63. This happens transparently for the user
-- since all of the lowlevel file handling functions are equally
-- replaced.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `open' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `open' should be protected using cancelation handlers.
--
-- The `open' function is the underlying primitive for the `fopen'
-- and `freopen' functions, that create streams.
--
-- - Function: int open64 (const char *FILENAME, int FLAGS[, mode_t MODE])
-- This function is similar to `open'. It returns a file descriptor
-- which can be used to access the file named by FILENAME. The only
-- the difference is that on 32 bits systems the file is opened in the
-- large file mode. I.e., file length and file offsets can exceed 31
-- bits.
--
-- When the sources are translated with `_FILE_OFFSET_BITS == 64' this
-- function is actually available under the name `open'. I.e., the
-- new, extended API using 64 bit file sizes and offsets transparently
-- replaces the old API.
--
-- - Obsolete function: int creat (const char *FILENAME, mode_t MODE)
-- This function is obsolete. The call:
--
-- creat (FILENAME, MODE)
--
-- is equivalent to:
--
-- open (FILENAME, O_WRONLY | O_CREAT | O_TRUNC, MODE)
--
-- If on a 32 bits machine the sources are translated with
-- `_FILE_OFFSET_BITS == 64' the function `creat' returns a file
-- descriptor opened in the large file mode which enables the file
-- handling functions to use files up to 2^63 in size and offset from
-- -2^63 to 2^63. This happens transparently for the user since all
-- of the lowlevel file handling functions are equally replaced.
--
-- - Obsolete function: int creat64 (const char *FILENAME, mode_t MODE)
-- This function is similar to `creat'. It returns a file descriptor
-- which can be used to access the file named by FILENAME. The only
-- the difference is that on 32 bits systems the file is opened in the
-- large file mode. I.e., file length and file offsets can exceed 31
-- bits.
--
-- To use this file descriptor one must not use the normal operations
-- but instead the counterparts named `*64', e.g., `read64'.
--
-- When the sources are translated with `_FILE_OFFSET_BITS == 64' this
-- function is actually available under the name `open'. I.e., the
-- new, extended API using 64 bit file sizes and offsets transparently
-- replaces the old API.
--
-- - Function: int close (int FILEDES)
-- The function `close' closes the file descriptor FILEDES. Closing
-- a file has the following consequences:
--
-- * The file descriptor is deallocated.
--
-- * Any record locks owned by the process on the file are
-- unlocked.
--
-- * When all file descriptors associated with a pipe or FIFO have
-- been closed, any unread data is discarded.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `close' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `close' should be protected using cancelation handlers.
--
-- The normal return value from `close' is 0; a value of -1 is
-- returned in case of failure. The following `errno' error
-- conditions are defined for this function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `EINTR'
-- The `close' call was interrupted by a signal. *Note
-- Interrupted Primitives::. Here is an example of how to
-- handle `EINTR' properly:
--
-- TEMP_FAILURE_RETRY (close (desc));
--
-- `ENOSPC'
-- `EIO'
-- `EDQUOT'
-- When the file is accessed by NFS, these errors from `write'
-- can sometimes not be detected until `close'. *Note I/O
-- Primitives::, for details on their meaning.
--
-- Please note that there is *no* separate `close64' function. This
-- is not necessary since this function does not determine nor depend
-- on the mode of the file. The kernel which performs the `close'
-- operation knows for which mode the descriptor is used and can
-- handle this situation.
--
-- To close a stream, call `fclose' (*note Closing Streams::.) instead
--of trying to close its underlying file descriptor with `close'. This
--flushes any buffered output and updates the stream object to indicate
--that it is closed.
--
--
--File: libc.info, Node: Truncating Files, Next: I/O Primitives, Prev: Opening and Closing Files, Up: Low-Level I/O
--
--Change the size of a file
--=========================
--
-- In some situations it is useful to explicitly determine the size of a
--file. Since the 4.2BSD days there is a function to truncate a file to
--at most a given number of bytes and POSIX defines one additional
--function. The prototypes for these functions are in `unistd.h'.
--
-- - Function: int truncate (const char *NAME, off_t LENGTH)
-- The `truncation' function truncates the file named by NAME to at
-- most LENGTH bytes. I.e., if the file was larger before the extra
-- bytes are stripped of. If the file was small or equal to LENGTH
-- in size before nothing is done. The file must be writable by the
-- user to perform this operation.
--
-- When the source file is compiled with `_FILE_OFFSET_BITS == 64' the
-- `truncate' function is in fact `truncate64' and the type `off_t'
-- has 64 bits which makes it possible to handle files up to 2^63
-- bytes in length.
--
-- The return value is zero is everything went ok. Otherwise the
-- return value is -1 and the global variable ERRNO is set to:
-- `EACCES'
-- The file is not accessible to the user.
--
-- `EINVAL'
-- The LENGTH value is illegal.
--
-- `EISDIR'
-- The object named by NAME is a directory.
--
-- `ENOENT'
-- The file named by NAME does not exist.
--
-- `ENOTDIR'
-- One part of the NAME is not a directory.
--
-- This function was introduced in 4.2BSD but also was available in
-- later System V systems. It is not added to POSIX since the
-- authors felt it is only of marginally additional utility. See
-- below.
--
-- - Function: int truncate64 (const char *NAME, off64_t LENGTH)
-- This function is similar to the `truncate' function. The
-- difference is that the LENGTH argument is 64 bits wide even on 32
-- bits machines which allows to handle file with a size up to 2^63
-- bytes.
--
-- When the source file is compiled with `_FILE_OFFSET_BITS == 64' on
-- a 32 bits machine this function is actually available under the
-- name `truncate' and so transparently replaces the 32 bits
-- interface.
--
-- - Function: int ftruncate (int FD, off_t LENGTH)
-- The `ftruncate' function is similar to the `truncate' function.
-- The main difference is that it takes a descriptor for an opened
-- file instead of a file name to identify the object. The file must
-- be opened for writing to successfully carry out the operation.
--
-- The POSIX standard leaves it implementation defined what happens
-- if the specified new LENGTH of the file is bigger than the
-- original size. The `ftruncate' function might simply leave the
-- file alone and do nothing or it can increase the size to the
-- desired size. In this later case the extended area should be
-- zero-filled. So using `ftruncate' is no reliable way to increase
-- the file size but if it is possible it is probably the fastest
-- way. The function also operates on POSIX shared memory segments
-- if these are implemented by the system.
--
-- When the source file is compiled with `_FILE_OFFSET_BITS == 64' the
-- `ftruncate' function is in fact `ftruncate64' and the type `off_t'
-- has 64 bits which makes it possible to handle files up to 2^63
-- bytes in length.
--
-- On success the function returns zero. Otherwise it returns -1 and
-- set ERRNO to one of these values:
-- `EBADF'
-- FD is no valid file descriptor or is not opened for writing.
--
-- `EINVAL'
-- The object referred to by FD does not permit this operation.
--
-- `EROFS'
-- The file is on a read-only file system.
--
-- - Function: int ftruncate64 (int ID, off64_t LENGTH)
-- This function is similar to the `ftruncate' function. The
-- difference is that the LENGTH argument is 64 bits wide even on 32
-- bits machines which allows to handle file with a size up to 2^63
-- bytes.
--
-- When the source file is compiled with `_FILE_OFFSET_BITS == 64' on
-- a 32 bits machine this function is actually available under the
-- name `ftruncate' and so transparently replaces the 32 bits
-- interface.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-18 glibc-2.1.3/manual/libc.info-18
---- ../glibc-2.1.3/manual/libc.info-18 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-18 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1157 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: I/O Primitives, Next: File Position Primitive, Prev: Truncating Files, Up: Low-Level I/O
--
--Input and Output Primitives
--===========================
--
-- This section describes the functions for performing primitive input
--and output operations on file descriptors: `read', `write', and
--`lseek'. These functions are declared in the header file `unistd.h'.
--
-- - Data Type: ssize_t
-- This data type is used to represent the sizes of blocks that can be
-- read or written in a single operation. It is similar to `size_t',
-- but must be a signed type.
--
-- - Function: ssize_t read (int FILEDES, void *BUFFER, size_t SIZE)
-- The `read' function reads up to SIZE bytes from the file with
-- descriptor FILEDES, storing the results in the BUFFER. (This is
-- not necessarily a character string and there is no terminating
-- null character added.)
--
-- The return value is the number of bytes actually read. This might
-- be less than SIZE; for example, if there aren't that many bytes
-- left in the file or if there aren't that many bytes immediately
-- available. The exact behavior depends on what kind of file it is.
-- Note that reading less than SIZE bytes is not an error.
--
-- A value of zero indicates end-of-file (except if the value of the
-- SIZE argument is also zero). This is not considered an error. If
-- you keep calling `read' while at end-of-file, it will keep
-- returning zero and doing nothing else.
--
-- If `read' returns at least one character, there is no way you can
-- tell whether end-of-file was reached. But if you did reach the
-- end, the next read will return zero.
--
-- In case of an error, `read' returns -1. The following `errno'
-- error conditions are defined for this function:
--
-- `EAGAIN'
-- Normally, when no input is immediately available, `read'
-- waits for some input. But if the `O_NONBLOCK' flag is set
-- for the file (*note File Status Flags::.), `read' returns
-- immediately without reading any data, and reports this error.
--
-- *Compatibility Note:* Most versions of BSD Unix use a
-- different error code for this: `EWOULDBLOCK'. In the GNU
-- library, `EWOULDBLOCK' is an alias for `EAGAIN', so it
-- doesn't matter which name you use.
--
-- On some systems, reading a large amount of data from a
-- character special file can also fail with `EAGAIN' if the
-- kernel cannot find enough physical memory to lock down the
-- user's pages. This is limited to devices that transfer with
-- direct memory access into the user's memory, which means it
-- does not include terminals, since they always use separate
-- buffers inside the kernel. This problem never happens in the
-- GNU system.
--
-- Any condition that could result in `EAGAIN' can instead
-- result in a successful `read' which returns fewer bytes than
-- requested. Calling `read' again immediately would result in
-- `EAGAIN'.
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor, or is
-- not open for reading.
--
-- `EINTR'
-- `read' was interrupted by a signal while it was waiting for
-- input. *Note Interrupted Primitives::. A signal will not
-- necessary cause `read' to return `EINTR'; it may instead
-- result in a successful `read' which returns fewer bytes than
-- requested.
--
-- `EIO'
-- For many devices, and for disk files, this error code
-- indicates a hardware error.
--
-- `EIO' also occurs when a background process tries to read
-- from the controlling terminal, and the normal action of
-- stopping the process by sending it a `SIGTTIN' signal isn't
-- working. This might happen if signal is being blocked or
-- ignored, or because the process group is orphaned. *Note Job
-- Control::, for more information about job control, and *Note
-- Signal Handling::, for information about signals.
--
-- Please note that there is no function named `read64'. This is not
-- necessary since this function does not directly modify or handle
-- the possibly wide file offset. Since the kernel handles this state
-- internally the `read' function can be used for all cases.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `read' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `read' should be protected using cancelation handlers.
--
-- The `read' function is the underlying primitive for all of the
-- functions that read from streams, such as `fgetc'.
--
-- - Function: ssize_t pread (int FILEDES, void *BUFFER, size_t SIZE,
-- off_t OFFSET)
-- The `pread' function is similar to the `read' function. The first
-- three arguments are identical and also the return values and error
-- codes correspond.
--
-- The difference is the fourth argument and its handling. The data
-- block is not read from the current position of the file descriptor
-- `filedes'. Instead the data is read from the file starting at
-- position OFFSET. The position of the file descriptor itself is
-- not effected by the operation. The value is the same as before
-- the call.
--
-- When the source file is compiled with `_FILE_OFFSET_BITS == 64' the
-- `pread' function is in fact `pread64' and the type `off_t' has 64
-- bits which makes it possible to handle files up to 2^63 bytes in
-- length.
--
-- The return value of `pread' describes the number of bytes read.
-- In the error case it returns -1 like `read' does and the error
-- codes are also the same. Only there are a few more error codes:
-- `EINVAL'
-- The value given for OFFSET is negative and therefore illegal.
--
-- `ESPIPE'
-- The file descriptor FILEDES is associate with a pipe or a
-- FIFO and this device does not allow positioning of the file
-- pointer.
--
-- The function is an extension defined in the Unix Single
-- Specification version 2.
--
-- - Function: ssize_t pread64 (int FILEDES, void *BUFFER, size_t SIZE,
-- off64_t OFFSET)
-- This function is similar to the `pread' function. The difference
-- is that the OFFSET parameter is of type `off64_t' instead of
-- `off_t' which makes it possible on 32 bits machines to address
-- files larger than 2^31 bytes and up to 2^63 bytes. The file
-- descriptor `filedes' must be opened using `open64' since otherwise
-- the large offsets possible with `off64_t' will lead to errors with
-- a descriptor in small file mode.
--
-- When the source file is compiled with `_FILE_OFFSET_BITS == 64' on
-- a 32 bits machine this function is actually available under the
-- name `pread' and so transparently replaces the 32 bits interface.
--
-- - Function: ssize_t write (int FILEDES, const void *BUFFER, size_t
-- SIZE)
-- The `write' function writes up to SIZE bytes from BUFFER to the
-- file with descriptor FILEDES. The data in BUFFER is not
-- necessarily a character string and a null character is output like
-- any other character.
--
-- The return value is the number of bytes actually written. This
-- may be SIZE, but can always be smaller. Your program should
-- always call `write' in a loop, iterating until all the data is
-- written.
--
-- Once `write' returns, the data is enqueued to be written and can be
-- read back right away, but it is not necessarily written out to
-- permanent storage immediately. You can use `fsync' when you need
-- to be sure your data has been permanently stored before
-- continuing. (It is more efficient for the system to batch up
-- consecutive writes and do them all at once when convenient.
-- Normally they will always be written to disk within a minute or
-- less.) Modern systems provide another function `fdatasync' which
-- guarantees integrity only for the file data and is therefore
-- faster. You can use the `O_FSYNC' open mode to make `write' always
-- store the data to disk before returning; *note Operating Modes::..
--
-- In the case of an error, `write' returns -1. The following
-- `errno' error conditions are defined for this function:
--
-- `EAGAIN'
-- Normally, `write' blocks until the write operation is
-- complete. But if the `O_NONBLOCK' flag is set for the file
-- (*note Control Operations::.), it returns immediately without
-- writing any data, and reports this error. An example of a
-- situation that might cause the process to block on output is
-- writing to a terminal device that supports flow control,
-- where output has been suspended by receipt of a STOP
-- character.
--
-- *Compatibility Note:* Most versions of BSD Unix use a
-- different error code for this: `EWOULDBLOCK'. In the GNU
-- library, `EWOULDBLOCK' is an alias for `EAGAIN', so it
-- doesn't matter which name you use.
--
-- On some systems, writing a large amount of data from a
-- character special file can also fail with `EAGAIN' if the
-- kernel cannot find enough physical memory to lock down the
-- user's pages. This is limited to devices that transfer with
-- direct memory access into the user's memory, which means it
-- does not include terminals, since they always use separate
-- buffers inside the kernel. This problem does not arise in the
-- GNU system.
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor, or is
-- not open for writing.
--
-- `EFBIG'
-- The size of the file would become larger than the
-- implementation can support.
--
-- `EINTR'
-- The `write' operation was interrupted by a signal while it was
-- blocked waiting for completion. A signal will not necessary
-- cause `write' to return `EINTR'; it may instead result in a
-- successful `write' which writes fewer bytes than requested.
-- *Note Interrupted Primitives::.
--
-- `EIO'
-- For many devices, and for disk files, this error code
-- indicates a hardware error.
--
-- `ENOSPC'
-- The device containing the file is full.
--
-- `EPIPE'
-- This error is returned when you try to write to a pipe or
-- FIFO that isn't open for reading by any process. When this
-- happens, a `SIGPIPE' signal is also sent to the process; see
-- *Note Signal Handling::.
--
-- Unless you have arranged to prevent `EINTR' failures, you should
-- check `errno' after each failing call to `write', and if the error
-- was `EINTR', you should simply repeat the call. *Note Interrupted
-- Primitives::. The easy way to do this is with the macro
-- `TEMP_FAILURE_RETRY', as follows:
--
-- nbytes = TEMP_FAILURE_RETRY (write (desc, buffer, count));
--
-- Please note that there is no function named `write64'. This is not
-- necessary since this function does not directly modify or handle
-- the possibly wide file offset. Since the kernel handles this state
-- internally the `write' function can be used for all cases.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `write' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `write' should be protected using cancelation handlers.
--
-- The `write' function is the underlying primitive for all of the
-- functions that write to streams, such as `fputc'.
--
-- - Function: ssize_t pwrite (int FILEDES, const void *BUFFER, size_t
-- SIZE, off_t OFFSET)
-- The `pwrite' function is similar to the `write' function. The
-- first three arguments are identical and also the return values and
-- error codes correspond.
--
-- The difference is the fourth argument and its handling. The data
-- block is not written to the current position of the file descriptor
-- `filedes'. Instead the data is written to the file starting at
-- position OFFSET. The position of the file descriptor itself is
-- not effected by the operation. The value is the same as before
-- the call.
--
-- When the source file is compiled with `_FILE_OFFSET_BITS == 64' the
-- `pwrite' function is in fact `pwrite64' and the type `off_t' has
-- 64 bits which makes it possible to handle files up to 2^63 bytes
-- in length.
--
-- The return value of `pwrite' describes the number of written bytes.
-- In the error case it returns -1 like `write' does and the error
-- codes are also the same. Only there are a few more error codes:
-- `EINVAL'
-- The value given for OFFSET is negative and therefore illegal.
--
-- `ESPIPE'
-- The file descriptor FILEDES is associate with a pipe or a
-- FIFO and this device does not allow positioning of the file
-- pointer.
--
-- The function is an extension defined in the Unix Single
-- Specification version 2.
--
-- - Function: ssize_t pwrite64 (int FILEDES, const void *BUFFER, size_t
-- SIZE, off64_t OFFSET)
-- This function is similar to the `pwrite' function. The difference
-- is that the OFFSET parameter is of type `off64_t' instead of
-- `off_t' which makes it possible on 32 bits machines to address
-- files larger than 2^31 bytes and up to 2^63 bytes. The file
-- descriptor `filedes' must be opened using `open64' since otherwise
-- the large offsets possible with `off64_t' will lead to errors with
-- a descriptor in small file mode.
--
-- When the source file is compiled using `_FILE_OFFSET_BITS == 64'
-- on a 32 bits machine this function is actually available under the
-- name `pwrite' and so transparently replaces the 32 bits interface.
--
--
--File: libc.info, Node: File Position Primitive, Next: Descriptors and Streams, Prev: I/O Primitives, Up: Low-Level I/O
--
--Setting the File Position of a Descriptor
--=========================================
--
-- Just as you can set the file position of a stream with `fseek', you
--can set the file position of a descriptor with `lseek'. This specifies
--the position in the file for the next `read' or `write' operation.
--*Note File Positioning::, for more information on the file position and
--what it means.
--
-- To read the current file position value from a descriptor, use
--`lseek (DESC, 0, SEEK_CUR)'.
--
-- - Function: off_t lseek (int FILEDES, off_t OFFSET, int WHENCE)
-- The `lseek' function is used to change the file position of the
-- file with descriptor FILEDES.
--
-- The WHENCE argument specifies how the OFFSET should be interpreted
-- in the same way as for the `fseek' function, and must be one of
-- the symbolic constants `SEEK_SET', `SEEK_CUR', or `SEEK_END'.
--
-- `SEEK_SET'
-- Specifies that WHENCE is a count of characters from the
-- beginning of the file.
--
-- `SEEK_CUR'
-- Specifies that WHENCE is a count of characters from the
-- current file position. This count may be positive or
-- negative.
--
-- `SEEK_END'
-- Specifies that WHENCE is a count of characters from the end of
-- the file. A negative count specifies a position within the
-- current extent of the file; a positive count specifies a
-- position past the current end. If you set the position past
-- the current end, and actually write data, you will extend the
-- file with zeros up to that position.
--
-- The return value from `lseek' is normally the resulting file
-- position, measured in bytes from the beginning of the file. You
-- can use this feature together with `SEEK_CUR' to read the current
-- file position.
--
-- If you want to append to the file, setting the file position to the
-- current end of file with `SEEK_END' is not sufficient. Another
-- process may write more data after you seek but before you write,
-- extending the file so the position you write onto clobbers their
-- data. Instead, use the `O_APPEND' operating mode; *note Operating
-- Modes::..
--
-- You can set the file position past the current end of the file.
-- This does not by itself make the file longer; `lseek' never
-- changes the file. But subsequent output at that position will
-- extend the file. Characters between the previous end of file and
-- the new position are filled with zeros. Extending the file in
-- this way can create a "hole": the blocks of zeros are not actually
-- allocated on disk, so the file takes up less space than it appears
-- so; it is then called a "sparse file".
--
-- If the file position cannot be changed, or the operation is in
-- some way invalid, `lseek' returns a value of -1. The following
-- `errno' error conditions are defined for this function:
--
-- `EBADF'
-- The FILEDES is not a valid file descriptor.
--
-- `EINVAL'
-- The WHENCE argument value is not valid, or the resulting file
-- offset is not valid. A file offset is invalid.
--
-- `ESPIPE'
-- The FILEDES corresponds to an object that cannot be
-- positioned, such as a pipe, FIFO or terminal device.
-- (POSIX.1 specifies this error only for pipes and FIFOs, but
-- in the GNU system, you always get `ESPIPE' if the object is
-- not seekable.)
--
-- When the source file is compiled with `_FILE_OFFSET_BITS == 64' the
-- `lseek' function is in fact `lseek64' and the type `off_t' has 64
-- bits which makes it possible to handle files up to 2^63 bytes in
-- length.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `lseek' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `lseek' should be protected using cancelation handlers.
--
-- The `lseek' function is the underlying primitive for the `fseek',
-- `fseeko', `ftell', `ftello' and `rewind' functions, which operate
-- on streams instead of file descriptors.
--
-- - Function: off64_t lseek64 (int FILEDES, off64_t OFFSET, int WHENCE)
-- This function is similar to the `lseek' function. The difference
-- is that the OFFSET parameter is of type `off64_t' instead of
-- `off_t' which makes it possible on 32 bits machines to address
-- files larger than 2^31 bytes and up to 2^63 bytes. The file
-- descriptor `filedes' must be opened using `open64' since otherwise
-- the large offsets possible with `off64_t' will lead to errors with
-- a descriptor in small file mode.
--
-- When the source file is compiled with `_FILE_OFFSET_BITS == 64' on
-- a 32 bits machine this function is actually available under the
-- name `lseek' and so transparently replaces the 32 bits interface.
--
-- You can have multiple descriptors for the same file if you open the
--file more than once, or if you duplicate a descriptor with `dup'.
--Descriptors that come from separate calls to `open' have independent
--file positions; using `lseek' on one descriptor has no effect on the
--other. For example,
--
-- {
-- int d1, d2;
-- char buf[4];
-- d1 = open ("foo", O_RDONLY);
-- d2 = open ("foo", O_RDONLY);
-- lseek (d1, 1024, SEEK_SET);
-- read (d2, buf, 4);
-- }
--
--will read the first four characters of the file `foo'. (The
--error-checking code necessary for a real program has been omitted here
--for brevity.)
--
-- By contrast, descriptors made by duplication share a common file
--position with the original descriptor that was duplicated. Anything
--which alters the file position of one of the duplicates, including
--reading or writing data, affects all of them alike. Thus, for example,
--
-- {
-- int d1, d2, d3;
-- char buf1[4], buf2[4];
-- d1 = open ("foo", O_RDONLY);
-- d2 = dup (d1);
-- d3 = dup (d2);
-- lseek (d3, 1024, SEEK_SET);
-- read (d1, buf1, 4);
-- read (d2, buf2, 4);
-- }
--
--will read four characters starting with the 1024'th character of `foo',
--and then four more characters starting with the 1028'th character.
--
-- - Data Type: off_t
-- This is an arithmetic data type used to represent file sizes. In
-- the GNU system, this is equivalent to `fpos_t' or `long int'.
--
-- If the source is compiled with `_FILE_OFFSET_BITS == 64' this type
-- is transparently replaced by `off64_t'.
--
-- - Data Type: off64_t
-- This type is used similar to `off_t'. The difference is that even
-- on 32 bits machines, where the `off_t' type would have 32 bits,
-- `off64_t' has 64 bits and so is able to address files up to 2^63
-- bytes in length.
--
-- When compiling with `_FILE_OFFSET_BITS == 64' this type is
-- available under the name `off_t'.
--
-- These aliases for the `SEEK_...' constants exist for the sake of
--compatibility with older BSD systems. They are defined in two
--different header files: `fcntl.h' and `sys/file.h'.
--
--`L_SET'
-- An alias for `SEEK_SET'.
--
--`L_INCR'
-- An alias for `SEEK_CUR'.
--
--`L_XTND'
-- An alias for `SEEK_END'.
--
--
--File: libc.info, Node: Descriptors and Streams, Next: Stream/Descriptor Precautions, Prev: File Position Primitive, Up: Low-Level I/O
--
--Descriptors and Streams
--=======================
--
-- Given an open file descriptor, you can create a stream for it with
--the `fdopen' function. You can get the underlying file descriptor for
--an existing stream with the `fileno' function. These functions are
--declared in the header file `stdio.h'.
--
-- - Function: FILE * fdopen (int FILEDES, const char *OPENTYPE)
-- The `fdopen' function returns a new stream for the file descriptor
-- FILEDES.
--
-- The OPENTYPE argument is interpreted in the same way as for the
-- `fopen' function (*note Opening Streams::.), except that the `b'
-- option is not permitted; this is because GNU makes no distinction
-- between text and binary files. Also, `"w"' and `"w+"' do not
-- cause truncation of the file; these have affect only when opening
-- a file, and in this case the file has already been opened. You
-- must make sure that the OPENTYPE argument matches the actual mode
-- of the open file descriptor.
--
-- The return value is the new stream. If the stream cannot be
-- created (for example, if the modes for the file indicated by the
-- file descriptor do not permit the access specified by the OPENTYPE
-- argument), a null pointer is returned instead.
--
-- In some other systems, `fdopen' may fail to detect that the modes
-- for file descriptor do not permit the access specified by
-- `opentype'. The GNU C library always checks for this.
--
-- For an example showing the use of the `fdopen' function, see *Note
--Creating a Pipe::.
--
-- - Function: int fileno (FILE *STREAM)
-- This function returns the file descriptor associated with the
-- stream STREAM. If an error is detected (for example, if the STREAM
-- is not valid) or if STREAM does not do I/O to a file, `fileno'
-- returns -1.
--
-- There are also symbolic constants defined in `unistd.h' for the file
--descriptors belonging to the standard streams `stdin', `stdout', and
--`stderr'; see *Note Standard Streams::.
--
--`STDIN_FILENO'
-- This macro has value `0', which is the file descriptor for
-- standard input.
--
--`STDOUT_FILENO'
-- This macro has value `1', which is the file descriptor for
-- standard output.
--
--`STDERR_FILENO'
-- This macro has value `2', which is the file descriptor for
-- standard error output.
--
--
--File: libc.info, Node: Stream/Descriptor Precautions, Next: Scatter-Gather, Prev: Descriptors and Streams, Up: Low-Level I/O
--
--Dangers of Mixing Streams and Descriptors
--=========================================
--
-- You can have multiple file descriptors and streams (let's call both
--streams and descriptors "channels" for short) connected to the same
--file, but you must take care to avoid confusion between channels. There
--are two cases to consider: "linked" channels that share a single file
--position value, and "independent" channels that have their own file
--positions.
--
-- It's best to use just one channel in your program for actual data
--transfer to any given file, except when all the access is for input.
--For example, if you open a pipe (something you can only do at the file
--descriptor level), either do all I/O with the descriptor, or construct a
--stream from the descriptor with `fdopen' and then do all I/O with the
--stream.
--
--* Menu:
--
--* Linked Channels:: Dealing with channels sharing a file position.
--* Independent Channels:: Dealing with separately opened, unlinked channels.
--* Cleaning Streams:: Cleaning a stream makes it safe to use
-- another channel.
--
--
--File: libc.info, Node: Linked Channels, Next: Independent Channels, Up: Stream/Descriptor Precautions
--
--Linked Channels
-----------------
--
-- Channels that come from a single opening share the same file
--position; we call them "linked" channels. Linked channels result when
--you make a stream from a descriptor using `fdopen', when you get a
--descriptor from a stream with `fileno', when you copy a descriptor with
--`dup' or `dup2', and when descriptors are inherited during `fork'. For
--files that don't support random access, such as terminals and pipes,
--*all* channels are effectively linked. On random-access files, all
--append-type output streams are effectively linked to each other.
--
-- If you have been using a stream for I/O, and you want to do I/O using
--another channel (either a stream or a descriptor) that is linked to it,
--you must first "clean up" the stream that you have been using. *Note
--Cleaning Streams::.
--
-- Terminating a process, or executing a new program in the process,
--destroys all the streams in the process. If descriptors linked to these
--streams persist in other processes, their file positions become
--undefined as a result. To prevent this, you must clean up the streams
--before destroying them.
--
--
--File: libc.info, Node: Independent Channels, Next: Cleaning Streams, Prev: Linked Channels, Up: Stream/Descriptor Precautions
--
--Independent Channels
----------------------
--
-- When you open channels (streams or descriptors) separately on a
--seekable file, each channel has its own file position. These are called
--"independent channels".
--
-- The system handles each channel independently. Most of the time,
--this is quite predictable and natural (especially for input): each
--channel can read or write sequentially at its own place in the file.
--However, if some of the channels are streams, you must take these
--precautions:
--
-- * You should clean an output stream after use, before doing anything
-- else that might read or write from the same part of the file.
--
-- * You should clean an input stream before reading data that may have
-- been modified using an independent channel. Otherwise, you might
-- read obsolete data that had been in the stream's buffer.
--
-- If you do output to one channel at the end of the file, this will
--certainly leave the other independent channels positioned somewhere
--before the new end. You cannot reliably set their file positions to the
--new end of file before writing, because the file can always be extended
--by another process between when you set the file position and when you
--write the data. Instead, use an append-type descriptor or stream; they
--always output at the current end of the file. In order to make the
--end-of-file position accurate, you must clean the output channel you
--were using, if it is a stream.
--
-- It's impossible for two channels to have separate file pointers for a
--file that doesn't support random access. Thus, channels for reading or
--writing such files are always linked, never independent. Append-type
--channels are also always linked. For these channels, follow the rules
--for linked channels; see *Note Linked Channels::.
--
--
--File: libc.info, Node: Cleaning Streams, Prev: Independent Channels, Up: Stream/Descriptor Precautions
--
--Cleaning Streams
------------------
--
-- On the GNU system, you can clean up any stream with `fclean':
--
-- - Function: int fclean (FILE *STREAM)
-- Clean up the stream STREAM so that its buffer is empty. If STREAM
-- is doing output, force it out. If STREAM is doing input, give the
-- data in the buffer back to the system, arranging to reread it.
--
-- On other systems, you can use `fflush' to clean a stream in most
--cases.
--
-- You can skip the `fclean' or `fflush' if you know the stream is
--already clean. A stream is clean whenever its buffer is empty. For
--example, an unbuffered stream is always clean. An input stream that is
--at end-of-file is clean. A line-buffered stream is clean when the last
--character output was a newline.
--
-- There is one case in which cleaning a stream is impossible on most
--systems. This is when the stream is doing input from a file that is not
--random-access. Such streams typically read ahead, and when the file is
--not random access, there is no way to give back the excess data already
--read. When an input stream reads from a random-access file, `fflush'
--does clean the stream, but leaves the file pointer at an unpredictable
--place; you must set the file pointer before doing any further I/O. On
--the GNU system, using `fclean' avoids both of these problems.
--
-- Closing an output-only stream also does `fflush', so this is a valid
--way of cleaning an output stream. On the GNU system, closing an input
--stream does `fclean'.
--
-- You need not clean a stream before using its descriptor for control
--operations such as setting terminal modes; these operations don't affect
--the file position and are not affected by it. You can use any
--descriptor for these operations, and all channels are affected
--simultaneously. However, text already "output" to a stream but still
--buffered by the stream will be subject to the new terminal modes when
--subsequently flushed. To make sure "past" output is covered by the
--terminal settings that were in effect at the time, flush the output
--streams for that terminal before setting the modes. *Note Terminal
--Modes::.
--
--
--File: libc.info, Node: Scatter-Gather, Next: Memory-mapped I/O, Prev: Stream/Descriptor Precautions, Up: Low-Level I/O
--
--Fast Scatter-Gather I/O
--=======================
--
-- Some applications may need to read or write data to multiple buffers,
--which are seperated in memory. Although this can be done easily enough
--with multiple calls to `read' and `write', it is inefficent because
--there is overhead associated with each kernel call.
--
-- Instead, many platforms provide special high-speed primitives to
--perform these "scatter-gather" operations in a single kernel call. The
--GNU C library will provide an emulation on any system that lacks these
--primitives, so they are not a portability threat. They are defined in
--`sys/uio.h'.
--
-- These functions are controlled with arrays of `iovec' structures,
--which describe the location and size of each buffer.
--
-- - Data Type: struct iovec
-- The `iovec' structure describes a buffer. It contains two fields:
--
-- `void *iov_base'
-- Contains the address of a buffer.
--
-- `size_t iov_len'
-- Contains the length of the buffer.
--
--
-- - Function: ssize_t readv (int FILEDES, const struct iovec *VECTOR,
-- int COUNT)
-- The `readv' function reads data from FILEDES and scatters it into
-- the buffers described in VECTOR, which is taken to be COUNT
-- structures long. As each buffer is filled, data is sent to the
-- next.
--
-- Note that `readv' is not guaranteed to fill all the buffers. It
-- may stop at any point, for the same reasons `read' would.
--
-- The return value is a count of bytes (*not* buffers) read, 0
-- indicating end-of-file, or -1 indicating an error. The possible
-- errors are the same as in `read'.
--
--
-- - Function: ssize_t writev (int FILEDES, const struct iovec *VECTOR,
-- int COUNT)
-- The `writev' function gathers data from the buffers described in
-- VECTOR, which is taken to be COUNT structures long, and writes
-- them to `filedes'. As each buffer is written, it moves on to the
-- next.
--
-- Like `readv', `writev' may stop midstream under the same
-- conditions `write' would.
--
-- The return value is a count of bytes written, or -1 indicating an
-- error. The possible errors are the same as in `write'.
--
--
-- Note that if the buffers are small (under about 1kB), high-level
--streams may be easier to use than these functions. However, `readv' and
--`writev' are more efficient when the individual buffers themselves (as
--opposed to the total output), are large. In that case, a high-level
--stream would not be able to cache the data effectively.
--
--
--File: libc.info, Node: Memory-mapped I/O, Next: Waiting for I/O, Prev: Scatter-Gather, Up: Low-Level I/O
--
--Memory-mapped I/O
--=================
--
-- On modern operating systems, it is possible to "mmap" (pronounced
--"em-map") a file to a region of memory. When this is done, the file can
--be accessed just like an array in the program.
--
-- This is more efficent than `read' or `write', as only regions of the
--file a program actually accesses are loaded. Accesses to
--not-yet-loaded parts of the mmapped region are handled in the same way
--as swapped out pages.
--
-- Since mmapped pages can be stored back to their file when physical
--memory is low, it is possible to mmap files orders of magnitude larger
--than both the physical memory *and* swap space. The only limit is
--address space. The theoretical limit is 4GB on a 32-bit machine -
--however, the actual limit will be smaller since some areas will be
--reserved for other purposes.
--
-- Memory mapping only works on entire pages of memory. Thus, addresses
--for mapping must be page-aligned, and length values will be rounded up.
--To determine the size of a page the machine uses one should use
--
-- size_t page_size = (size_t) sysconf (_SC_PAGESIZE);
--
-- These functions are declared in `sys/mman.h'.
--
-- - Function: void * mmap (void *ADDRESS, size_t LENGTH,int PROTECT, int
-- FLAGS, int FILEDES, off_t OFFSET)
-- The `mmap' function creates a new mapping, connected to bytes
-- (OFFSET) to (OFFSET + LENGTH) in the file open on FILEDES.
--
-- ADDRESS gives a preferred starting address for the mapping.
-- `NULL' expresses no preference. Any previous mapping at that
-- address is automatically removed. The address you give may still be
-- changed, unless you use the `MAP_FIXED' flag.
--
-- PROTECT contains flags that control what kind of access is
-- permitted. They include `PROT_READ', `PROT_WRITE', and
-- `PROT_EXEC', which permit reading, writing, and execution,
-- respectively. Inappropriate access will cause a segfault (*note
-- Program Error Signals::.).
--
-- Note that most hardware designs cannot support write permission
-- without read permission, and many do not distinguish read and
-- execute permission. Thus, you may recieve wider permissions than
-- you ask for, and mappings of write-only files may be denied even
-- if you do not use `PROT_READ'.
--
-- FLAGS contains flags that control the nature of the map. One of
-- `MAP_SHARED' or `MAP_PRIVATE' must be specified.
--
-- They include:
--
-- `MAP_PRIVATE'
-- This specifies that writes to the region should never be
-- written back to the attached file. Instead, a copy is made
-- for the process, and the region will be swapped normally if
-- memory runs low. No other process will see the changes.
--
-- Since private mappings effectively revert to ordinary memory
-- when written to, you must have enough virtual memory for a
-- copy of the entire mmapped region if you use this mode with
-- `PROT_WRITE'.
--
-- `MAP_SHARED'
-- This specifies that writes to the region will be written back
-- to the file. Changes made will be shared immediately with
-- other processes mmaping the same file.
--
-- Note that actual writing may take place at any time. You
-- need to use `msync', described below, if it is important that
-- other processes using conventional I/O get a consistent view
-- of the file.
--
-- `MAP_FIXED'
-- This forces the system to use the exact mapping address
-- specified in ADDRESS and fail if it can't.
--
-- `MAP_ANONYMOUS'
-- `MAP_ANON'
-- This flag tells the system to create an anonymous mapping,
-- not connected to a file. FILEDES and OFF are ignored, and
-- the region is initialized with zeros.
--
-- Anonymous maps are used as the basic primitive to extend the
-- heap on some systems. They are also useful to share data
-- between multiple tasks without creating a file.
--
-- On some systems using private anonymous mmaps is more
-- efficent than using `malloc' for large blocks. This is not
-- an issue with the GNU C library, as the included `malloc'
-- automatically uses `mmap' where appropriate.
--
-- `mmap' returns the address of the new mapping, or -1 for an error.
--
-- Possible errors include:
--
-- `EINVAL'
-- Either ADDRESS was unusable, or inconsistent FLAGS were given.
--
-- `EACCES'
-- FILEDES was not open for the type of access specified in
-- PROTECT.
--
-- `ENOMEM'
-- Either there is not enough memory for the operation, or the
-- process is out of address space.
--
-- `ENODEV'
-- This file is of a type that doesn't support mapping.
--
-- `ENOEXEC'
-- The file is on a filesystem that doesn't support mapping.
--
--
-- - Function: int munmap (void *ADDR, size_t LENGTH)
-- `munmap' removes any memory maps from (ADDR) to (ADDR + LENGTH).
-- LENGTH should be the length of the mapping.
--
-- It is safe to un-map multiple mappings in one command, or include
-- unmapped space in the range. It is also possible to unmap only
-- part of an existing mapping, however only entire pages can be
-- removed. If LENGTH is not an even number of pages, it will be
-- rounded up.
--
-- It returns 0 for success and -1 for an error.
--
-- One error is possible:
--
-- `EINVAL'
-- The memory range given was outside the user mmap range, or
-- wasn't page aligned.
--
--
-- - Function: int msync (void *ADDRESS, size_t LENGTH, int FLAGS)
-- When using shared mappings, the kernel can write the file at any
-- time before the mapping is removed. To be certain data has
-- actually been written to the file and will be accessable to
-- non-memory-mapped I/O, it is neccessary to use this function.
--
-- It operates on the region ADDRESS to (ADDRESS + LENGTH). It may
-- be used on part of a mapping or multiple mappings, however the
-- region given should not contain any unmapped space.
--
-- FLAGS can contain some options:
--
-- `MS_SYNC'
-- This flag makes sure the data is actually written *to disk*.
-- Normally `msync' only makes sure that accesses to a file with
-- conventional I/O reflect the recent changes.
--
-- `MS_ASYNC'
-- This tells `msync' to begin the synchronization, but not to
-- wait for it to complete.
--
-- `msync' returns 0 for success and -1 for error. Errors include:
--
-- `EINVAL'
-- An invalid region was given, or the FLAGS were invalid.
--
-- `EFAULT'
-- There is no existing mapping in at least part of the given
-- region.
--
--
-- - Function: void * mremap (void *ADDRESS, size_t LENGTH, size_t
-- NEW_LENGTH, int FLAG)
-- This function can be used to change the size of an existing memory
-- area. ADDRESS and LENGTH must cover a region entirely mapped in
-- the same `mmap' statement. A new mapping with the same
-- characteristics will be returned, but a with the length NEW_LENGTH
-- instead.
--
-- One option is possible, `MREMAP_MAYMOVE'. If it is given in FLAGS,
-- the system may remove the existing mapping and create a new one of
-- the desired length in another location.
--
-- The address of the resulting mapping is returned, or -1. Possible
-- error codes include:
--
-- This function is only available on a few systems. Except for
-- performing optional optimizations one should not rely on this
-- function.
-- `EFAULT'
-- There is no existing mapping in at least part of the original
-- region, or the region covers two or more distinct mappings.
--
-- `EINVAL'
-- The address given is misaligned or inappropriate.
--
-- `EAGAIN'
-- The region has pages locked, and if extended it would exceed
-- the process's resource limit for locked pages. *Note Limits
-- on Resources::.
--
-- `ENOMEM'
-- The region is private writable, and insufficent virtual
-- memory is available to extend it. Also, this error will
-- occur if `MREMAP_MAYMOVE' is not given and the extension
-- would collide with another mapped region.
--
--
-- Not all file descriptors may be mapped. Sockets, pipes, and most
--devices only allow sequential access and do not fit into the mapping
--abstraction. In addition, some regular files may not be mmapable, and
--older kernels may not support mapping at all. Thus, programs using
--`mmap' should have a fallback method to use should it fail. *Note Mmap:
--(standards)Mmap.
--
--
--File: libc.info, Node: Waiting for I/O, Next: Synchronizing I/O, Prev: Memory-mapped I/O, Up: Low-Level I/O
--
--Waiting for Input or Output
--===========================
--
-- Sometimes a program needs to accept input on multiple input channels
--whenever input arrives. For example, some workstations may have devices
--such as a digitizing tablet, function button box, or dial box that are
--connected via normal asynchronous serial interfaces; good user interface
--style requires responding immediately to input on any device. Another
--example is a program that acts as a server to several other processes
--via pipes or sockets.
--
-- You cannot normally use `read' for this purpose, because this blocks
--the program until input is available on one particular file descriptor;
--input on other channels won't wake it up. You could set nonblocking
--mode and poll each file descriptor in turn, but this is very
--inefficient.
--
-- A better solution is to use the `select' function. This blocks the
--program until input or output is ready on a specified set of file
--descriptors, or until a timer expires, whichever comes first. This
--facility is declared in the header file `sys/types.h'.
--
-- In the case of a server socket (*note Listening::.), we say that
--"input" is available when there are pending connections that could be
--accepted (*note Accepting Connections::.). `accept' for server sockets
--blocks and interacts with `select' just as `read' does for normal input.
--
-- The file descriptor sets for the `select' function are specified as
--`fd_set' objects. Here is the description of the data type and some
--macros for manipulating these objects.
--
-- - Data Type: fd_set
-- The `fd_set' data type represents file descriptor sets for the
-- `select' function. It is actually a bit array.
--
-- - Macro: int FD_SETSIZE
-- The value of this macro is the maximum number of file descriptors
-- that a `fd_set' object can hold information about. On systems
-- with a fixed maximum number, `FD_SETSIZE' is at least that number.
-- On some systems, including GNU, there is no absolute limit on the
-- number of descriptors open, but this macro still has a constant
-- value which controls the number of bits in an `fd_set'; if you get
-- a file descriptor with a value as high as `FD_SETSIZE', you cannot
-- put that descriptor into an `fd_set'.
--
-- - Macro: void FD_ZERO (fd_set *SET)
-- This macro initializes the file descriptor set SET to be the empty
-- set.
--
-- - Macro: void FD_SET (int FILEDES, fd_set *SET)
-- This macro adds FILEDES to the file descriptor set SET.
--
-- - Macro: void FD_CLR (int FILEDES, fd_set *SET)
-- This macro removes FILEDES from the file descriptor set SET.
--
-- - Macro: int FD_ISSET (int FILEDES, fd_set *SET)
-- This macro returns a nonzero value (true) if FILEDES is a member
-- of the file descriptor set SET, and zero (false) otherwise.
--
-- Next, here is the description of the `select' function itself.
--
-- - Function: int select (int NFDS, fd_set *READ-FDS, fd_set *WRITE-FDS,
-- fd_set *EXCEPT-FDS, struct timeval *TIMEOUT)
-- The `select' function blocks the calling process until there is
-- activity on any of the specified sets of file descriptors, or
-- until the timeout period has expired.
--
-- The file descriptors specified by the READ-FDS argument are
-- checked to see if they are ready for reading; the WRITE-FDS file
-- descriptors are checked to see if they are ready for writing; and
-- the EXCEPT-FDS file descriptors are checked for exceptional
-- conditions. You can pass a null pointer for any of these
-- arguments if you are not interested in checking for that kind of
-- condition.
--
-- A file descriptor is considered ready for reading if it is not at
-- end of file. A server socket is considered ready for reading if
-- there is a pending connection which can be accepted with `accept';
-- *note Accepting Connections::.. A client socket is ready for
-- writing when its connection is fully established; *note
-- Connecting::..
--
-- "Exceptional conditions" does not mean errors--errors are reported
-- immediately when an erroneous system call is executed, and do not
-- constitute a state of the descriptor. Rather, they include
-- conditions such as the presence of an urgent message on a socket.
-- (*Note Sockets::, for information on urgent messages.)
--
-- The `select' function checks only the first NFDS file descriptors.
-- The usual thing is to pass `FD_SETSIZE' as the value of this
-- argument.
--
-- The TIMEOUT specifies the maximum time to wait. If you pass a
-- null pointer for this argument, it means to block indefinitely
-- until one of the file descriptors is ready. Otherwise, you should
-- provide the time in `struct timeval' format; see *Note
-- High-Resolution Calendar::. Specify zero as the time (a `struct
-- timeval' containing all zeros) if you want to find out which
-- descriptors are ready without waiting if none are ready.
--
-- The normal return value from `select' is the total number of ready
-- file descriptors in all of the sets. Each of the argument sets is
-- overwritten with information about the descriptors that are ready
-- for the corresponding operation. Thus, to see if a particular
-- descriptor DESC has input, use `FD_ISSET (DESC, READ-FDS)' after
-- `select' returns.
--
-- If `select' returns because the timeout period expires, it returns
-- a value of zero.
--
-- Any signal will cause `select' to return immediately. So if your
-- program uses signals, you can't rely on `select' to keep waiting
-- for the full time specified. If you want to be sure of waiting
-- for a particular amount of time, you must check for `EINTR' and
-- repeat the `select' with a newly calculated timeout based on the
-- current time. See the example below. See also *Note Interrupted
-- Primitives::.
--
-- If an error occurs, `select' returns `-1' and does not modify the
-- argument file descriptor sets. The following `errno' error
-- conditions are defined for this function:
--
-- `EBADF'
-- One of the file descriptor sets specified an invalid file
-- descriptor.
--
-- `EINTR'
-- The operation was interrupted by a signal. *Note Interrupted
-- Primitives::.
--
-- `EINVAL'
-- The TIMEOUT argument is invalid; one of the components is
-- negative or too large.
--
-- *Portability Note:* The `select' function is a BSD Unix feature.
--
-- Here is an example showing how you can use `select' to establish a
--timeout period for reading from a file descriptor. The `input_timeout'
--function blocks the calling process until input is available on the
--file descriptor, or until the timeout period expires.
--
-- #include <stdio.h>
-- #include <unistd.h>
-- #include <sys/types.h>
-- #include <sys/time.h>
--
-- int
-- input_timeout (int filedes, unsigned int seconds)
-- {
-- fd_set set;
-- struct timeval timeout;
--
-- /* Initialize the file descriptor set. */
-- FD_ZERO (&set);
-- FD_SET (filedes, &set);
--
-- /* Initialize the timeout data structure. */
-- timeout.tv_sec = seconds;
-- timeout.tv_usec = 0;
-- /* `select' returns 0 if timeout, 1 if input available, -1 if error. */
-- return TEMP_FAILURE_RETRY (select (FD_SETSIZE,
-- &set, NULL, NULL,
-- &timeout));
-- }
--
-- int
-- main (void)
-- {
-- fprintf (stderr, "select returned %d.\n",
-- input_timeout (STDIN_FILENO, 5));
-- return 0;
-- }
--
-- There is another example showing the use of `select' to multiplex
--input from multiple sockets in *Note Server Example::.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-19 glibc-2.1.3/manual/libc.info-19
---- ../glibc-2.1.3/manual/libc.info-19 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-19 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1158 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Synchronizing I/O, Next: Asynchronous I/O, Prev: Waiting for I/O, Up: Low-Level I/O
--
--Synchronizing I/O operations
--============================
--
-- In most modern operation systems the normal I/O operations are not
--executed synchronously. I.e., even if a `write' system call returns
--this does not mean the data is actually written to the media, e.g., the
--disk.
--
-- In situations where synchronization points are necessary the user can
--use special functions which ensure that all operations finished before
--they return.
--
-- - Function: int sync (void)
-- A call to this function will not return as long as there is data
-- which that is not written to the device. All dirty buffers in the
-- kernel will be written and so an overall consistent system can be
-- achieved (if no other process in parallel writes data).
--
-- A prototype for `sync' can be found in `unistd.h'.
--
-- The return value is zero to indicate no error.
--
-- More often it is wanted that not all data in the system is committed.
--Programs want to ensure that data written to a given file are all
--committed and in this situation `sync' is overkill.
--
-- - Function: int fsync (int FILDES)
-- The `fsync' can be used to make sure all data associated with the
-- open file FILDES is written to the device associated with the
-- descriptor. The function call does not return unless all actions
-- have finished.
--
-- A prototype for `fsync' can be found in `unistd.h'.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `fsync' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `fsync' should be protected using cancelation handlers.
--
-- The return value of the function is zero if no error occured.
-- Otherwise it is -1 and the global variable ERRNO is set to the
-- following values:
-- `EBADF'
-- The descriptor FILDES is not valid.
--
-- `EINVAL'
-- No synchronization is possible since the system does not
-- implement this.
--
-- Sometimes it is not even necessary to write all data associated with
--a file descriptor. E.g., in database files which do not change in size
--it is enough to write all the file content data to the device.
--Meta-information like the modification time etc. are not that important
--and leaving such information uncommitted does not prevent a successful
--recovering of the file in case of a problem.
--
-- - Function: int fdatasync (int FILDES)
-- When a call to the `fdatasync' function returns it is made sure
-- that all of the file data is written to the device. For all
-- pending I/O operations the parts guaranteeing data integrity
-- finished.
--
-- Not all systems implement the `fdatasync' operation. On systems
-- missing this functionality `fdatasync' is emulated by a call to
-- `fsync' since the performed actions are a superset of those
-- required by `fdatasyn'.
--
-- The prototype for `fdatasync' is in `unistd.h'.
--
-- The return value of the function is zero if no error occured.
-- Otherwise it is -1 and the global variable ERRNO is set to the
-- following values:
-- `EBADF'
-- The descriptor FILDES is not valid.
--
-- `EINVAL'
-- No synchronization is possible since the system does not
-- implement this.
--
--
--File: libc.info, Node: Asynchronous I/O, Next: Control Operations, Prev: Synchronizing I/O, Up: Low-Level I/O
--
--Perform I/O Operations in Parallel
--==================================
--
-- The POSIX.1b standard defines a new set of I/O operations which can
--reduce the time an application spends waiting at I/O significantly. The
--new functions allow a program to initiate one or more I/O operations and
--then immediately resume the normal work while the I/O operations are
--executed in parallel. The functionality is available if the `unistd.h'
--file defines the symbol `_POSIX_ASYNCHRONOUS_IO'.
--
-- These functions are part of the library with realtime functions named
--`librt'. They are not actually part of the `libc' binary. The
--implementation of these functions can be done using support in the
--kernel (if available) or using an implementation based on threads at
--userlevel. In the latter case it might be necessary to link
--applications with the thread library `libpthread' in addition to
--`librt'.
--
-- All AIO operations operate on files which were opened previously.
--There might be arbitrary many operations for one file running. The
--asynchronous I/O operations are controlled using a data structure named
--`struct aiocb' ("AIO control block"). It is defined in `aio.h' as
--follows.
--
-- - Data Type: struct aiocb
-- The POSIX.1b standard mandates that the `struct aiocb' structure
-- contains at least the members described in the following table.
-- There might be more elements which are used by the implementation
-- but depending on these elements is not portable and is highly
-- deprecated.
--
-- `int aio_fildes'
-- This element specifies the file descriptor which is used for
-- the operation. It must be a legal descriptor since otherwise
-- the operation fails for obvious reasons.
--
-- The device on which the file is opened must allow the seek
-- operation. I.e., it is not possible to use any of the AIO
-- operations on devices like terminals where an `lseek' call
-- would lead to an error.
--
-- `off_t aio_offset'
-- This element specifies at which offset in the file the
-- operation (input or output) is performed. Since the
-- operations are carried out in arbitrary order and more than
-- one operation for one file descriptor can be started, one
-- cannot expect a current read/write position of the file
-- descriptor.
--
-- `volatile void *aio_buf'
-- This is a pointer to the buffer with the data to be written
-- or the place where the read data is stored.
--
-- `size_t aio_nbytes'
-- This element specifies the length of the buffer pointed to by
-- `aio_buf'.
--
-- `int aio_reqprio'
-- If the platform has defined `_POSIX_PRIORITIZED_IO' and
-- `_POSIX_PRIORITY_SCHEDULING' the AIO requests are processed
-- based on the current scheduling priority. The `aio_reqprio'
-- element can then be used to lower the priority of the AIO
-- operation.
--
-- `struct sigevent aio_sigevent'
-- This element specifies how the calling process is notified
-- once the operation terminates. If the `sigev_notify' element
-- is `SIGEV_NONE' no notification is send. If it is
-- `SIGEV_SIGNAL' the signal determined by `sigev_signo' is
-- send. Otherwise `sigev_notify' must be `SIGEV_THREAD'. In
-- this case a thread is created which starts executing the
-- function pointed to by `sigev_notify_function'.
--
-- `int aio_lio_opcode'
-- This element is only used by the `lio_listio' and
-- `lio_listio64' functions. Since these functions allow to
-- start an arbitrary number of operations at once and since
-- each operation can be input or output (or nothing) the
-- information must be stored in the control block. The
-- possible values are:
--
-- `LIO_READ'
-- Start a read operation. Read from the file at position
-- `aio_offset' and store the next `aio_nbytes' bytes in the
-- buffer pointed to by `aio_buf'.
--
-- `LIO_WRITE'
-- Start a write operation. Write `aio_nbytes' bytes
-- starting at `aio_buf' into the file starting at position
-- `aio_offset'.
--
-- `LIO_NOP'
-- Do nothing for this control block. This value is useful
-- sometimes when an array of `struct aiocb' values
-- contains holes, i.e., some of the values must not be
-- handled although the whole array is presented to the
-- `lio_listio' function.
--
-- When the sources are compiled using `_FILE_OFFSET_BITS == 64' on a
-- 32 bits machine this type is in fact `struct aiocb64' since the LFS
-- interface transparently replaces the `struct aiocb' definition.
--
-- For use with the AIO functions defined in the LFS there is a similar
--type defined which replaces the types of the appropriate members with
--larger types but otherwise is equivalent to `struct aiocb'. Especially
--all member names are the same.
--
-- - Data Type: struct aiocb64
-- `int aio_fildes'
-- This element specifies the file descriptor which is used for
-- the operation. It must be a legal descriptor since otherwise
-- the operation fails for obvious reasons.
--
-- The device on which the file is opened must allow the seek
-- operation. I.e., it is not possible to use any of the AIO
-- operations on devices like terminals where an `lseek' call
-- would lead to an error.
--
-- `off64_t aio_offset'
-- This element specified at which offset in the file the
-- operation (input or output) is performed. Since the
-- operation are carried in arbitrary order and more than one
-- operation for one file descriptor can be started, one cannot
-- expect a current read/write position of the file descriptor.
--
-- `volatile void *aio_buf'
-- This is a pointer to the buffer with the data to be written
-- or the place where the ead data is stored.
--
-- `size_t aio_nbytes'
-- This element specifies the length of the buffer pointed to by
-- `aio_buf'.
--
-- `int aio_reqprio'
-- If for the platform `_POSIX_PRIORITIZED_IO' and
-- `_POSIX_PRIORITY_SCHEDULING' is defined the AIO requests are
-- processed based on the current scheduling priority. The
-- `aio_reqprio' element can then be used to lower the priority
-- of the AIO operation.
--
-- `struct sigevent aio_sigevent'
-- This element specifies how the calling process is notified
-- once the operation terminates. If the `sigev_notify' element
-- is `SIGEV_NONE' no notification is send. If it is
-- `SIGEV_SIGNAL' the signal determined by `sigev_signo' is
-- send. Otherwise `sigev_notify' must be `SIGEV_THREAD' in
-- which case a thread which starts executing the function
-- pointeed to by `sigev_notify_function'.
--
-- `int aio_lio_opcode'
-- This element is only used by the `lio_listio' and
-- `[lio_listio64' functions. Since these functions allow to
-- start an arbitrary number of operations at once and since
-- each operation can be input or output (or nothing) the
-- information must be stored in the control block. See the
-- description of `struct aiocb' for a description of the
-- possible values.
--
-- When the sources are compiled using `_FILE_OFFSET_BITS == 64' on a
-- 32 bits machine this type is available under the name `struct
-- aiocb64' since the LFS replaces transparently the old interface.
--
--* Menu:
--
--* Asynchronous Reads/Writes:: Asynchronous Read and Write Operations.
--* Status of AIO Operations:: Getting the Status of AIO Operations.
--* Synchronizing AIO Operations:: Getting into a consistent state.
--* Cancel AIO Operations:: Cancelation of AIO Operations.
--* Configuration of AIO:: How to optimize the AIO implementation.
--
--
--File: libc.info, Node: Asynchronous Reads/Writes, Next: Status of AIO Operations, Up: Asynchronous I/O
--
--Asynchronous Read and Write Operations
----------------------------------------
--
-- - Function: int aio_read (struct aiocb *AIOCBP)
-- This function initiates an asynchronous read operation. The
-- function call immediately returns after the operation was enqueued
-- or when an error was encountered.
--
-- The first `aiocbp->aio_nbytes' bytes of the file for which
-- `aiocbp->aio_fildes' is a descriptor are written to the buffer
-- starting at `aiocbp->aio_buf'. Reading starts at the absolute
-- position `aiocbp->aio_offset' in the file.
--
-- If prioritized I/O is supported by the platform the
-- `aiocbp->aio_reqprio' value is used to adjust the priority before
-- the request is actually enqueued.
--
-- The calling process is notified about the termination of the read
-- request according to the `aiocbp->aio_sigevent' value.
--
-- When `aio_read' returns the return value is zero if no error
-- occurred that can be found before the process is enqueued. If
-- such an early error is found the function returns -1 and sets
-- `errno' to one of the following values.
--
-- `EAGAIN'
-- The request was not enqueued due to (temporarily) exceeded
-- resource limitations.
--
-- `ENOSYS'
-- The `aio_read' function is not implemented.
--
-- `EBADF'
-- The `aiocbp->aio_fildes' descriptor is not valid. This
-- condition needs not be recognized before enqueueing the
-- request and so this error might also be signaled
-- asynchronously.
--
-- `EINVAL'
-- The `aiocbp->aio_offset' or `aiocbp->aio_reqpiro' value is
-- invalid. This condition need not be recognized before
-- enqueueing the request and so this error might also be
-- signaled asynchrously.
--
-- In the case `aio_read' returns zero the current status of the
-- request can be queried using `aio_error' and `aio_return'
-- functions. As long as the value returned by `aio_error' is
-- `EINPROGRESS' the operation has not yet completed. If `aio_error'
-- returns zero the operation successfully terminated, otherwise the
-- value is to be interpreted as an error code. If the function
-- terminated the result of the operation can be get using a call to
-- `aio_return'. The returned value is the same as an equivalent
-- call to `read' would have returned. Possible error codes returned
-- by `aio_error' are:
--
-- `EBADF'
-- The `aiocbp->aio_fildes' descriptor is not valid.
--
-- `ECANCELED'
-- The operation was canceled before the operation was finished
-- (*note Cancel AIO Operations::.)
--
-- `EINVAL'
-- The `aiocbp->aio_offset' value is invalid.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `aio_read64' since the LFS interface
-- transparently replaces the normal implementation.
--
-- - Function: int aio_read64 (struct aiocb *AIOCBP)
-- This function is similar to the `aio_read' function. The only
-- difference is that on 32 bits machines the file descriptor should
-- be opened in the large file mode. Internally `aio_read64' uses
-- functionality equivalent to `lseek64' (*note File Position
-- Primitive::.) to position the file descriptor correctly for the
-- reading, as opposed to `lseek' functionality used in `aio_read'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `aio_read' and so
-- transparently replaces the interface for small files on 32 bits
-- machines.
--
-- To write data asynchronously to a file there exists an equivalent
--pair of functions with a very similar interface.
--
-- - Function: int aio_write (struct aiocb *AIOCBP)
-- This function initiates an asynchronous write operation. The
-- function call immediately returns after the operation was enqueued
-- or if before this happens an error was encountered.
--
-- The first `aiocbp->aio_nbytes' bytes from the buffer starting at
-- `aiocbp->aio_buf' are written to the file for which
-- `aiocbp->aio_fildes' is an descriptor, starting at the absolute
-- position `aiocbp->aio_offset' in the file.
--
-- If prioritized I/O is supported by the platform the
-- `aiocbp->aio_reqprio' value is used to adjust the priority before
-- the request is actually enqueued.
--
-- The calling process is notified about the termination of the read
-- request according to the `aiocbp->aio_sigevent' value.
--
-- When `aio_write' returns the return value is zero if no error
-- occurred that can be found before the process is enqueued. If
-- such an early error is found the function returns -1 and sets
-- `errno' to one of the following values.
--
-- `EAGAIN'
-- The request was not enqueued due to (temporarily) exceeded
-- resource limitations.
--
-- `ENOSYS'
-- The `aio_write' function is not implemented.
--
-- `EBADF'
-- The `aiocbp->aio_fildes' descriptor is not valid. This
-- condition needs not be recognized before enqueueing the
-- request and so this error might also be signaled
-- asynchronously.
--
-- `EINVAL'
-- The `aiocbp->aio_offset' or `aiocbp->aio_reqpiro' value is
-- invalid. This condition needs not be recognized before
-- enqueueing the request and so this error might also be
-- signaled asynchronously.
--
-- In the case `aio_write' returns zero the current status of the
-- request can be queried using `aio_error' and `aio_return'
-- functions. As long as the value returned by `aio_error' is
-- `EINPROGRESS' the operation has not yet completed. If `aio_error'
-- returns zero the operation successfully terminated, otherwise the
-- value is to be interpreted as an error code. If the function
-- terminated the result of the operation can be get using a call to
-- `aio_return'. The returned value is the same as an equivalent
-- call to `read' would have returned. Possible error code returned
-- by `aio_error' are:
--
-- `EBADF'
-- The `aiocbp->aio_fildes' descriptor is not valid.
--
-- `ECANCELED'
-- The operation was canceled before the operation was finished
-- (*note Cancel AIO Operations::.)
--
-- `EINVAL'
-- The `aiocbp->aio_offset' value is invalid.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `aio_write64' since the LFS interface
-- transparently replaces the normal implementation.
--
-- - Function: int aio_write64 (struct aiocb *AIOCBP)
-- This function is similar to the `aio_write' function. The only
-- difference is that on 32 bits machines the file descriptor should
-- be opened in the large file mode. Internally `aio_write64' uses
-- functionality equivalent to `lseek64' (*note File Position
-- Primitive::.) to position the file descriptor correctly for the
-- writing, as opposed to `lseek' functionality used in `aio_write'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `aio_write' and so
-- transparently replaces the interface for small files on 32 bits
-- machines.
--
-- Beside these functions with the more or less traditional interface
--POSIX.1b also defines a function with can initiate more than one
--operation at once and which can handled freely mixed read and write
--operation. It is therefore similar to a combination of `readv' and
--`writev'.
--
-- - Function: int lio_listio (int MODE, struct aiocb *const LIST[], int
-- NENT, struct sigevent *SIG)
-- The `lio_listio' function can be used to enqueue an arbitrary
-- number of read and write requests at one time. The requests can
-- all be meant for the same file, all for different files or every
-- solution in between.
--
-- `lio_listio' gets the NENT requests from the array pointed to by
-- LIST. What operation has to be performed is determined by the
-- `aio_lio_opcode' member in each element of LIST. If this field is
-- `LIO_READ' an read operation is queued, similar to a call of
-- `aio_read' for this element of the array (except that the way the
-- termination is signalled is different, as we will see below). If
-- the `aio_lio_opcode' member is `LIO_WRITE' an write operation is
-- enqueued. Otherwise the `aio_lio_opcode' must be `LIO_NOP' in
-- which case this element of LIST is simply ignored. This
-- "operation" is useful in situations where one has a fixed array of
-- `struct aiocb' elements from which only a few need to be handled at
-- a time. Another situation is where the `lio_listio' call was
-- cancelled before all requests are processed (*note Cancel AIO
-- Operations::.) and the remaining requests have to be reissued.
--
-- The other members of each element of the array pointed to by
-- `list' must have values suitable for the operation as described in
-- the documentation for `aio_read' and `aio_write' above.
--
-- The MODE argument determines how `lio_listio' behaves after having
-- enqueued all the requests. If MODE is `LIO_WAIT' it waits until
-- all requests terminated. Otherwise MODE must be `LIO_NOWAIT' and
-- in this case the function returns immediately after having
-- enqueued all the requests. In this case the caller gets a
-- notification of the termination of all requests according to the
-- SIG parameter. If SIG is `NULL' no notification is send.
-- Otherwise a signal is sent or a thread is started, just as
-- described in the description for `aio_read' or `aio_write'.
--
-- If MODE is `LIO_WAIT' the return value of `lio_listio' is 0 when
-- all requests completed successfully. Otherwise the function
-- return -1 and `errno' is set accordingly. To find out which
-- request or requests failed one has to use the `aio_error' function
-- on all the elements of the array LIST.
--
-- In case MODE is `LIO_NOWAIT' the function return 0 if all requests
-- were enqueued correctly. The current state of the requests can be
-- found using `aio_error' and `aio_return' as described above. In
-- case `lio_listio' returns -1 in this mode the global variable
-- `errno' is set accordingly. If a request did not yet terminate a
-- call to `aio_error' returns `EINPROGRESS'. If the value is
-- different the request is finished and the error value (or 0) is
-- returned and the result of the operation can be retrieved using
-- `aio_return'.
--
-- Possible values for `errno' are:
--
-- `EAGAIN'
-- The resources necessary to queue all the requests are not
-- available in the moment. The error status for each element
-- of LIST must be checked which request failed.
--
-- Another reason could be that the system wide limit of AIO
-- requests is exceeded. This cannot be the case for the
-- implementation on GNU systems since no arbitrary limits exist.
--
-- `EINVAL'
-- The MODE parameter is invalid or NENT is larger than
-- `AIO_LISTIO_MAX'.
--
-- `EIO'
-- One or more of the request's I/O operations failed. The
-- error status of each request should be checked for which one
-- failed.
--
-- `ENOSYS'
-- The `lio_listio' function is not supported.
--
-- If the MODE parameter is `LIO_NOWAIT' and the caller cancels an
-- request the error status for this request returned by `aio_error'
-- is `ECANCELED'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `lio_listio64' since the LFS interface
-- transparently replaces the normal implementation.
--
-- - Function: int lio_listio64 (int MODE, struct aiocb *const LIST, int
-- NENT, struct sigevent *SIG)
-- This function is similar to the `aio_listio' function. The only
-- difference is that only 32 bits machines the file descriptor should
-- be opened in the large file mode. Internally `lio_listio64' uses
-- functionality equivalent to `lseek64' (*note File Position
-- Primitive::.) to position the file descriptor correctly for the
-- reading or writing, as opposed to `lseek' functionality used in
-- `lio_listio'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `lio_listio' and so
-- transparently replaces the interface for small files on 32 bits
-- machines.
--
--
--File: libc.info, Node: Status of AIO Operations, Next: Synchronizing AIO Operations, Prev: Asynchronous Reads/Writes, Up: Asynchronous I/O
--
--Getting the Status of AIO Operations
--------------------------------------
--
-- As already described in the documentation of the functions in the
--last section it must be possible to get information about the status of
--a I/O request. When the operation is performed really asynchronous (as
--with `aio_read' and `aio_write' and with `aio_listio' when the mode is
--`LIO_NOWAIT') one sometimes needs to know whether a specific request
--already terminated and if yes, what the result was.. The following two
--function allow to get this kind of information.
--
-- - Function: int aio_error (const struct aiocb *AIOCBP)
-- This function determines the error state of the request described
-- by the `struct aiocb' variable pointed to by AIOCBP. If the
-- request has not yet terminated the value returned is always
-- `EINPROGRESS'. Once the request has terminated the value
-- `aio_error' returns is either 0 if the request completed
-- successfully or it returns the value which would be stored in the
-- `errno' variable if the request would have been done using `read',
-- `write', or `fsync'.
--
-- The function can return `ENOSYS' if it is not implemented. It
-- could also return `EINVAL' if the AIOCBP parameter does not refer
-- to an asynchronous operation whose return status is not yet known.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `aio_error64' since the LFS interface
-- transparently replaces the normal implementation.
--
-- - Function: int aio_error64 (const struct aiocb64 *AIOCBP)
-- This function is similar to `aio_error' with the only difference
-- that the argument is a reference to a variable of type `struct
-- aiocb64'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `aio_error' and so
-- transparently replaces the interface for small files on 32 bits
-- machines.
--
-- - Function: ssize_t aio_return (const struct aiocb *AIOCBP)
-- This function can be used to retrieve the return status of the
-- operation carried out by the request described in the variable
-- pointed to by AIOCBP. As long as the error status of this request
-- as returned by `aio_error' is `EINPROGRESS' the return of this
-- function is undefined.
--
-- Once the request is finished this function can be used exactly
-- once to retrieve the return value. Following calls might lead to
-- undefined behaviour. The return value itself is the value which
-- would have been returned by the `read', `write', or `fsync' call.
--
-- The function can return `ENOSYS' if it is not implemented. It
-- could also return `EINVAL' if the AIOCBP parameter does not refer
-- to an asynchronous operation whose return status is not yet known.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `aio_return64' since the LFS interface
-- transparently replaces the normal implementation.
--
-- - Function: int aio_return64 (const struct aiocb64 *AIOCBP)
-- This function is similar to `aio_return' with the only difference
-- that the argument is a reference to a variable of type `struct
-- aiocb64'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `aio_return' and so
-- transparently replaces the interface for small files on 32 bits
-- machines.
--
--
--File: libc.info, Node: Synchronizing AIO Operations, Next: Cancel AIO Operations, Prev: Status of AIO Operations, Up: Asynchronous I/O
--
--Getting into a Consistent State
---------------------------------
--
-- When dealing with asynchronous operations it is sometimes necessary
--to get into a consistent state. This would mean for AIO that one wants
--to know whether a certain request or a group of request were processed.
--This could be done by waiting for the notification sent by the system
--after the operation terminated but this sometimes would mean wasting
--resources (mainly computation time). Instead POSIX.1b defines two
--functions which will help with most kinds of consistency.
--
-- The `aio_fsync' and `aio_fsync64' functions are only available if in
--`unistd.h' the symbol `_POSIX_SYNCHRONIZED_IO' is defined.
--
-- - Function: int aio_fsync (int OP, struct aiocb *AIOCBP)
-- Calling this function forces all I/O operations operating queued
-- at the time of the function call operating on the file descriptor
-- `aiocbp->aio_fildes' into the synchronized I/O completion state
-- (*note Synchronizing I/O::.). The `aio_fsync' function return
-- immediately but the notification through the method described in
-- `aiocbp->aio_sigevent' will happen only after all requests for this
-- file descriptor terminated and the file is synchronized. This also
-- means that requests for this very same file descriptor which are
-- queued after the synchronization request are not effected.
--
-- If OP is `O_DSYNC' the synchronization happens as with a call to
-- `fdatasync'. Otherwise OP should be `O_SYNC' and the
-- synchronization happens as with `fsync'.
--
-- As long as the synchronization has not happened a call to
-- `aio_error' with the reference to the object pointed to by AIOCBP
-- returns `EINPROGRESS'. Once the synchronization is done
-- `aio_error' return 0 if the synchronization was not successful.
-- Otherwise the value returned is the value to which the `fsync' or
-- `fdatasync' function would have set the `errno' variable. In this
-- case nothing can be assumed about the consistency for the data
-- written to this file descriptor.
--
-- The return value of this function is 0 if the request was
-- successfully filed. Otherwise the return value is -1 and `errno'
-- is set to one of the following values:
--
-- `EAGAIN'
-- The request could not be enqueued due to temporary lack of
-- resources.
--
-- `EBADF'
-- The file descriptor `aiocbp->aio_fildes' is not valid or not
-- open for writing.
--
-- `EINVAL'
-- The implementation does not support I/O synchronization or
-- the OP parameter is other than `O_DSYNC' and `O_SYNC'.
--
-- `ENOSYS'
-- This function is not implemented.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `aio_return64' since the LFS interface
-- transparently replaces the normal implementation.
--
-- - Function: int aio_fsync64 (int OP, struct aiocb64 *AIOCBP)
-- This function is similar to `aio_fsync' with the only difference
-- that the argument is a reference to a variable of type `struct
-- aiocb64'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `aio_fsync' and so
-- transparently replaces the interface for small files on 32 bits
-- machines.
--
-- Another method of synchronization is to wait until one or more
--requests of a specific set terminated. This could be achieved by the
--`aio_*' functions to notify the initiating process about the
--termination but in some situations this is not the ideal solution. In
--a program which constantly updates clients somehow connected to the
--server it is not always the best solution to go round robin since some
--connections might be slow. On the other hand letting the `aio_*'
--function notify the caller might also be not the best solution since
--whenever the process works on preparing data for on client it makes no
--sense to be interrupted by a notification since the new client will not
--be handled before the current client is served. For situations like
--this `aio_suspend' should be used.
--
-- - Function: int aio_suspend (const struct aiocb *const LIST[], int
-- NENT, const struct timespec *TIMEOUT)
-- When calling this function the calling thread is suspended until at
-- least one of the requests pointed to by the NENT elements of the
-- array LIST has completed. If any of the requests already has
-- completed at the time `aio_suspend' is called the function returns
-- immediately. Whether a request has terminated or not is done by
-- comparing the error status of the request with `EINPROGRESS'. If
-- an element of LIST is `NULL' the entry is simply ignored.
--
-- If no request has finished the calling process is suspended. If
-- TIMEOUT is `NULL' the process is not waked until a request
-- finished. If TIMEOUT is not `NULL' the process remains suspended
-- at as long as specified in TIMEOUT. In this case `aio_suspend'
-- returns with an error.
--
-- The return value of the function is 0 if one or more requests from
-- the LIST have terminated. Otherwise the function returns -1 and
-- `errno' is set to one of the following values:
--
-- `EAGAIN'
-- None of the requests from the LIST completed in the time
-- specified by TIMEOUT.
--
-- `EINTR'
-- A signal interrupted the `aio_suspend' function. This signal
-- might also be sent by the AIO implementation while signalling
-- the termination of one of the requests.
--
-- `ENOSYS'
-- The `aio_suspend' function is not implemented.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `aio_suspend64' since the LFS interface
-- transparently replaces the normal implementation.
--
-- - Function: int aio_suspend64 (const struct aiocb64 *const LIST[], int
-- NENT, const struct timespec *TIMEOUT)
-- This function is similar to `aio_suspend' with the only difference
-- that the argument is a reference to a variable of type `struct
-- aiocb64'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `aio_suspend' and so
-- transparently replaces the interface for small files on 32 bits
-- machines.
--
--
--File: libc.info, Node: Cancel AIO Operations, Next: Configuration of AIO, Prev: Synchronizing AIO Operations, Up: Asynchronous I/O
--
--Cancelation of AIO Operations
-------------------------------
--
-- When one or more requests are asynchronously processed it might be
--useful in some situations to cancel a selected operation, e.g., if it
--becomes obvious that the written data is not anymore accurate and would
--have to be overwritten soon. As an example assume an application, which
--writes data in files in a situation where new incoming data would have
--to be written in a file which will be updated by an enqueued request.
--The POSIX AIO implementation provides such a function but this function
--is not capable to force the cancelation of the request. It is up to the
--implementation to decide whether it is possible to cancel the operation
--or not. Therefore using this function is merely a hint.
--
-- - Function: int aio_cancel (int FILDES, struct aiocb *AIOCBP)
-- The `aio_cancel' function can be used to cancel one or more
-- outstanding requests. If the AIOCBP parameter is `NULL' the
-- function tries to cancel all outstanding requests which would
-- process the file descriptor FILDES (i.e.,, whose `aio_fildes'
-- member is FILDES). If AIOCBP is not `NULL' the very specific
-- request pointed to by AIOCBP is tried to be canceled.
--
-- For requests which were successfully canceled the normal
-- notification about the termination of the request should take
-- place. I.e., depending on the `struct sigevent' object which
-- controls this, nothing happens, a signal is sent or a thread is
-- started. If the request cannot be canceled it terminates the
-- usual way after performing te operation.
--
-- After a request is successfully canceled a call to `aio_error' with
-- a reference to this request as the parameter will return
-- `ECANCELED' and a call to `aio_return' will return -1. If the
-- request wasn't canceled and is still running the error status is
-- still `EINPROGRESS'.
--
-- The return value of the function is `AIO_CANCELED' if there were
-- requests which haven't terminated and which successfully were
-- canceled. If there is one or more request left which couldn't be
-- canceled the return value is `AIO_NOTCANCELED'. In this case
-- `aio_error' must be used to find out which of the perhaps multiple
-- requests (in AIOCBP is `NULL') wasn't successfully canceled. If
-- all requests already terminated at the time `aio_cancel' is called
-- the return value is `AIO_ALLDONE'.
--
-- If an error occurred during the execution of `aio_cancel' the
-- function returns -1 and sets `errno' to one of the following
-- values.
--
-- `EBADF'
-- The file descriptor FILDES is not valid.
--
-- `ENOSYS'
-- `aio_cancel' is not implemented.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `aio_cancel64' since the LFS interface
-- transparently replaces the normal implementation.
--
-- - Function: int aio_cancel64 (int FILDES, struct aiocb *AIOCBP)
-- This function is similar to `aio_cancel' with the only difference
-- that the argument is a reference to a variable of type `struct
-- aiocb64'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `aio_cancel' and so
-- transparently replaces the interface for small files on 32 bits
-- machines.
--
--
--File: libc.info, Node: Configuration of AIO, Prev: Cancel AIO Operations, Up: Asynchronous I/O
--
--How to optimize the AIO implementation
----------------------------------------
--
-- The POSIX standard does not specify how the AIO functions are
--implemented. They could be system calls but it is also possible to
--emulate them at userlevel.
--
-- At least the available implementation at the point of this writing
--is a userlevel implementation which uses threads for handling the
--enqueued requests. This implementation requires to make some decisions
--about limitations but hard limitations are something which better
--should be avoided the GNU C library implementation provides a mean to
--tune the AIO implementation individually for each use.
--
-- - Data Type: struct aioinit
-- This data type is used to pass the configuration or tunable
-- parameters to the implementation. The program has to initialize
-- the members of this struct and pass it to the implementation using
-- the `aio_init' function.
--
-- `int aio_threads'
-- This member specifies the maximal number of threads which
-- must be used at any one time.
--
-- `int aio_num'
-- This number provides an estimate on the maximal number of
-- simultaneously enqueued requests.
--
-- `int aio_locks'
--
-- `int aio_usedba'
--
-- `int aio_debug'
--
-- `int aio_numusers'
--
-- `int aio_reserved[2]'
--
-- - Function: void aio_init (const struct aioinit *INIT)
-- This function must be called before any other AIO function.
-- Calling it is completely voluntarily since it only is meant to
-- help the AIO implementation to perform better.
--
-- Before calling the `aio_init' function the members of a variable of
-- type `struct aioinit' must be initialized. Then a reference to
-- this variable is passed as the parameter to `aio_init' which itself
-- may or may not pay attention to the hints.
--
-- The function has no return value and no error cases are defined.
-- It is a extension which follows a proposal from the SGI
-- implementation in Irix 6. It is not covered by POSIX.1b or Unix98.
--
--
--File: libc.info, Node: Control Operations, Next: Duplicating Descriptors, Prev: Asynchronous I/O, Up: Low-Level I/O
--
--Control Operations on Files
--===========================
--
-- This section describes how you can perform various other operations
--on file descriptors, such as inquiring about or setting flags describing
--the status of the file descriptor, manipulating record locks, and the
--like. All of these operations are performed by the function `fcntl'.
--
-- The second argument to the `fcntl' function is a command that
--specifies which operation to perform. The function and macros that name
--various flags that are used with it are declared in the header file
--`fcntl.h'. Many of these flags are also used by the `open' function;
--see *Note Opening and Closing Files::.
--
-- - Function: int fcntl (int FILEDES, int COMMAND, ...)
-- The `fcntl' function performs the operation specified by COMMAND
-- on the file descriptor FILEDES. Some commands require additional
-- arguments to be supplied. These additional arguments and the
-- return value and error conditions are given in the detailed
-- descriptions of the individual commands.
--
-- Briefly, here is a list of what the various commands are.
--
-- `F_DUPFD'
-- Duplicate the file descriptor (return another file descriptor
-- pointing to the same open file). *Note Duplicating
-- Descriptors::.
--
-- `F_GETFD'
-- Get flags associated with the file descriptor. *Note
-- Descriptor Flags::.
--
-- `F_SETFD'
-- Set flags associated with the file descriptor. *Note
-- Descriptor Flags::.
--
-- `F_GETFL'
-- Get flags associated with the open file. *Note File Status
-- Flags::.
--
-- `F_SETFL'
-- Set flags associated with the open file. *Note File Status
-- Flags::.
--
-- `F_GETLK'
-- Get a file lock. *Note File Locks::.
--
-- `F_SETLK'
-- Set or clear a file lock. *Note File Locks::.
--
-- `F_SETLKW'
-- Like `F_SETLK', but wait for completion. *Note File Locks::.
--
-- `F_GETOWN'
-- Get process or process group ID to receive `SIGIO' signals.
-- *Note Interrupt Input::.
--
-- `F_SETOWN'
-- Set process or process group ID to receive `SIGIO' signals.
-- *Note Interrupt Input::.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `fcntl' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `fcntl' should be protected using cancelation handlers.
--
--
--File: libc.info, Node: Duplicating Descriptors, Next: Descriptor Flags, Prev: Control Operations, Up: Low-Level I/O
--
--Duplicating Descriptors
--=======================
--
-- You can "duplicate" a file descriptor, or allocate another file
--descriptor that refers to the same open file as the original. Duplicate
--descriptors share one file position and one set of file status flags
--(*note File Status Flags::.), but each has its own set of file
--descriptor flags (*note Descriptor Flags::.).
--
-- The major use of duplicating a file descriptor is to implement
--"redirection" of input or output: that is, to change the file or pipe
--that a particular file descriptor corresponds to.
--
-- You can perform this operation using the `fcntl' function with the
--`F_DUPFD' command, but there are also convenient functions `dup' and
--`dup2' for duplicating descriptors.
--
-- The `fcntl' function and flags are declared in `fcntl.h', while
--prototypes for `dup' and `dup2' are in the header file `unistd.h'.
--
-- - Function: int dup (int OLD)
-- This function copies descriptor OLD to the first available
-- descriptor number (the first number not currently open). It is
-- equivalent to `fcntl (OLD, F_DUPFD, 0)'.
--
-- - Function: int dup2 (int OLD, int NEW)
-- This function copies the descriptor OLD to descriptor number NEW.
--
-- If OLD is an invalid descriptor, then `dup2' does nothing; it does
-- not close NEW. Otherwise, the new duplicate of OLD replaces any
-- previous meaning of descriptor NEW, as if NEW were closed first.
--
-- If OLD and NEW are different numbers, and OLD is a valid
-- descriptor number, then `dup2' is equivalent to:
--
-- close (NEW);
-- fcntl (OLD, F_DUPFD, NEW)
--
-- However, `dup2' does this atomically; there is no instant in the
-- middle of calling `dup2' at which NEW is closed and not yet a
-- duplicate of OLD.
--
-- - Macro: int F_DUPFD
-- This macro is used as the COMMAND argument to `fcntl', to copy the
-- file descriptor given as the first argument.
--
-- The form of the call in this case is:
--
-- fcntl (OLD, F_DUPFD, NEXT-FILEDES)
--
-- The NEXT-FILEDES argument is of type `int' and specifies that the
-- file descriptor returned should be the next available one greater
-- than or equal to this value.
--
-- The return value from `fcntl' with this command is normally the
-- value of the new file descriptor. A return value of -1 indicates
-- an error. The following `errno' error conditions are defined for
-- this command:
--
-- `EBADF'
-- The OLD argument is invalid.
--
-- `EINVAL'
-- The NEXT-FILEDES argument is invalid.
--
-- `EMFILE'
-- There are no more file descriptors available--your program is
-- already using the maximum. In BSD and GNU, the maximum is
-- controlled by a resource limit that can be changed; *note
-- Limits on Resources::., for more information about the
-- `RLIMIT_NOFILE' limit.
--
-- `ENFILE' is not a possible error code for `dup2' because `dup2'
-- does not create a new opening of a file; duplicate descriptors do
-- not count toward the limit which `ENFILE' indicates. `EMFILE' is
-- possible because it refers to the limit on distinct descriptor
-- numbers in use in one process.
--
-- Here is an example showing how to use `dup2' to do redirection.
--Typically, redirection of the standard streams (like `stdin') is done
--by a shell or shell-like program before calling one of the `exec'
--functions (*note Executing a File::.) to execute a new program in a
--child process. When the new program is executed, it creates and
--initializes the standard streams to point to the corresponding file
--descriptors, before its `main' function is invoked.
--
-- So, to redirect standard input to a file, the shell could do
--something like:
--
-- pid = fork ();
-- if (pid == 0)
-- {
-- char *filename;
-- char *program;
-- int file;
-- ...
-- file = TEMP_FAILURE_RETRY (open (filename, O_RDONLY));
-- dup2 (file, STDIN_FILENO);
-- TEMP_FAILURE_RETRY (close (file));
-- execv (program, NULL);
-- }
--
-- There is also a more detailed example showing how to implement
--redirection in the context of a pipeline of processes in *Note
--Launching Jobs::.
--
--
--File: libc.info, Node: Descriptor Flags, Next: File Status Flags, Prev: Duplicating Descriptors, Up: Low-Level I/O
--
--File Descriptor Flags
--=====================
--
-- "File descriptor flags" are miscellaneous attributes of a file
--descriptor. These flags are associated with particular file
--descriptors, so that if you have created duplicate file descriptors
--from a single opening of a file, each descriptor has its own set of
--flags.
--
-- Currently there is just one file descriptor flag: `FD_CLOEXEC',
--which causes the descriptor to be closed if you use any of the
--`exec...' functions (*note Executing a File::.).
--
-- The symbols in this section are defined in the header file `fcntl.h'.
--
-- - Macro: int F_GETFD
-- This macro is used as the COMMAND argument to `fcntl', to specify
-- that it should return the file descriptor flags associated with
-- the FILEDES argument.
--
-- The normal return value from `fcntl' with this command is a
-- nonnegative number which can be interpreted as the bitwise OR of
-- the individual flags (except that currently there is only one flag
-- to use).
--
-- In case of an error, `fcntl' returns -1. The following `errno'
-- error conditions are defined for this command:
--
-- `EBADF'
-- The FILEDES argument is invalid.
--
-- - Macro: int F_SETFD
-- This macro is used as the COMMAND argument to `fcntl', to specify
-- that it should set the file descriptor flags associated with the
-- FILEDES argument. This requires a third `int' argument to specify
-- the new flags, so the form of the call is:
--
-- fcntl (FILEDES, F_SETFD, NEW-FLAGS)
--
-- The normal return value from `fcntl' with this command is an
-- unspecified value other than -1, which indicates an error. The
-- flags and error conditions are the same as for the `F_GETFD'
-- command.
--
-- The following macro is defined for use as a file descriptor flag with
--the `fcntl' function. The value is an integer constant usable as a bit
--mask value.
--
-- - Macro: int FD_CLOEXEC
-- This flag specifies that the file descriptor should be closed when
-- an `exec' function is invoked; see *Note Executing a File::. When
-- a file descriptor is allocated (as with `open' or `dup'), this bit
-- is initially cleared on the new file descriptor, meaning that
-- descriptor will survive into the new program after `exec'.
--
-- If you want to modify the file descriptor flags, you should get the
--current flags with `F_GETFD' and modify the value. Don't assume that
--the flags listed here are the only ones that are implemented; your
--program may be run years from now and more flags may exist then. For
--example, here is a function to set or clear the flag `FD_CLOEXEC'
--without altering any other flags:
--
-- /* Set the `FD_CLOEXEC' flag of DESC if VALUE is nonzero,
-- or clear the flag if VALUE is 0.
-- Return 0 on success, or -1 on error with `errno' set. */
--
-- int
-- set_cloexec_flag (int desc, int value)
-- {
-- int oldflags = fcntl (desc, F_GETFD, 0);
-- /* If reading the flags failed, return error indication now.
-- if (oldflags < 0)
-- return oldflags;
-- /* Set just the flag we want to set. */
-- if (value != 0)
-- oldflags |= FD_CLOEXEC;
-- else
-- oldflags &= ~FD_CLOEXEC;
-- /* Store modified flag word in the descriptor. */
-- return fcntl (desc, F_SETFD, oldflags);
-- }
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-2 glibc-2.1.3/manual/libc.info-2
---- ../glibc-2.1.3/manual/libc.info-2 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-2 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1003 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Introduction, Next: Error Reporting, Prev: Top, Up: Top
--
--Introduction
--************
--
-- The C language provides no built-in facilities for performing such
--common operations as input/output, memory management, string
--manipulation, and the like. Instead, these facilities are defined in a
--standard "library", which you compile and link with your programs.
--
-- The GNU C library, described in this document, defines all of the
--library functions that are specified by the ISO C standard, as well as
--additional features specific to POSIX and other derivatives of the Unix
--operating system, and extensions specific to the GNU system.
--
-- The purpose of this manual is to tell you how to use the facilities
--of the GNU library. We have mentioned which features belong to which
--standards to help you identify things that are potentially non-portable
--to other systems. But the emphasis in this manual is not on strict
--portability.
--
--* Menu:
--
--* Getting Started:: What this manual is for and how to use it.
--* Standards and Portability:: Standards and sources upon which the GNU
-- C library is based.
--* Using the Library:: Some practical uses for the library.
--* Roadmap to the Manual:: Overview of the remaining chapters in
-- this manual.
--
--
--File: libc.info, Node: Getting Started, Next: Standards and Portability, Up: Introduction
--
--Getting Started
--===============
--
-- This manual is written with the assumption that you are at least
--somewhat familiar with the C programming language and basic programming
--concepts. Specifically, familiarity with ISO standard C (*note ISO
--C::.), rather than "traditional" pre-ISO C dialects, is assumed.
--
-- The GNU C library includes several "header files", each of which
--provides definitions and declarations for a group of related facilities;
--this information is used by the C compiler when processing your program.
--For example, the header file `stdio.h' declares facilities for
--performing input and output, and the header file `string.h' declares
--string processing utilities. The organization of this manual generally
--follows the same division as the header files.
--
-- If you are reading this manual for the first time, you should read
--all of the introductory material and skim the remaining chapters.
--There are a *lot* of functions in the GNU C library and it's not
--realistic to expect that you will be able to remember exactly *how* to
--use each and every one of them. It's more important to become
--generally familiar with the kinds of facilities that the library
--provides, so that when you are writing your programs you can recognize
--*when* to make use of library functions, and *where* in this manual you
--can find more specific information about them.
--
--
--File: libc.info, Node: Standards and Portability, Next: Using the Library, Prev: Getting Started, Up: Introduction
--
--Standards and Portability
--=========================
--
-- This section discusses the various standards and other sources that
--the GNU C library is based upon. These sources include the ISO C and
--POSIX standards, and the System V and Berkeley Unix implementations.
--
-- The primary focus of this manual is to tell you how to make effective
--use of the GNU library facilities. But if you are concerned about
--making your programs compatible with these standards, or portable to
--operating systems other than GNU, this can affect how you use the
--library. This section gives you an overview of these standards, so that
--you will know what they are when they are mentioned in other parts of
--the manual.
--
-- *Note Library Summary::, for an alphabetical list of the functions
--and other symbols provided by the library. This list also states which
--standards each function or symbol comes from.
--
--* Menu:
--
--* ISO C:: The international standard for the C
-- programming language.
--* POSIX:: The ISO/IEC 9945 (aka IEEE 1003) standards
-- for operating systems.
--* Berkeley Unix:: BSD and SunOS.
--* SVID:: The System V Interface Description.
--* XPG:: The X/Open Portability Guide.
--
--
--File: libc.info, Node: ISO C, Next: POSIX, Up: Standards and Portability
--
--ISO C
-------
--
-- The GNU C library is compatible with the C standard adopted by the
--American National Standards Institute (ANSI): `American National
--Standard X3.159-1989--"ANSI C"' and later by the International
--Standardization Organization (ISO): `ISO/IEC 9899:1990, "Programming
--languages--C"'. We here refer to the standard as ISO C since this is
--the more general standard in respect of ratification. The header files
--and library facilities that make up the GNU library are a superset of
--those specified by the ISO C standard.
--
-- If you are concerned about strict adherence to the ISO C standard,
--you should use the `-ansi' option when you compile your programs with
--the GNU C compiler. This tells the compiler to define *only* ISO
--standard features from the library header files, unless you explicitly
--ask for additional features. *Note Feature Test Macros::, for
--information on how to do this.
--
-- Being able to restrict the library to include only ISO C features is
--important because ISO C puts limitations on what names can be defined
--by the library implementation, and the GNU extensions don't fit these
--limitations. *Note Reserved Names::, for more information about these
--restrictions.
--
-- This manual does not attempt to give you complete details on the
--differences between ISO C and older dialects. It gives advice on how
--to write programs to work portably under multiple C dialects, but does
--not aim for completeness.
--
--
--File: libc.info, Node: POSIX, Next: Berkeley Unix, Prev: ISO C, Up: Standards and Portability
--
--POSIX (The Portable Operating System Interface)
-------------------------------------------------
--
-- The GNU library is also compatible with the ISO "POSIX" family of
--standards, known more formally as the "Portable Operating System
--Interface for Computer Environments" (ISO/IEC 9945). They were also
--published as ANSI/IEEE Std 1003. POSIX is derived mostly from various
--versions of the Unix operating system.
--
-- The library facilities specified by the POSIX standards are a
--superset of those required by ISO C; POSIX specifies additional
--features for ISO C functions, as well as specifying new additional
--functions. In general, the additional requirements and functionality
--defined by the POSIX standards are aimed at providing lower-level
--support for a particular kind of operating system environment, rather
--than general programming language support which can run in many diverse
--operating system environments.
--
-- The GNU C library implements all of the functions specified in
--`ISO/IEC 9945-1:1996, the POSIX System Application Program Interface',
--commonly referred to as POSIX.1. The primary extensions to the ISO C
--facilities specified by this standard include file system interface
--primitives (*note File System Interface::.), device-specific terminal
--control functions (*note Low-Level Terminal Interface::.), and process
--control functions (*note Processes::.).
--
-- Some facilities from `ISO/IEC 9945-2:1993, the POSIX Shell and
--Utilities standard' (POSIX.2) are also implemented in the GNU library.
--These include utilities for dealing with regular expressions and other
--pattern matching facilities (*note Pattern Matching::.).
--
--
--File: libc.info, Node: Berkeley Unix, Next: SVID, Prev: POSIX, Up: Standards and Portability
--
--Berkeley Unix
---------------
--
-- The GNU C library defines facilities from some versions of Unix which
--are not formally standardized, specifically from the 4.2 BSD, 4.3 BSD,
--and 4.4 BSD Unix systems (also known as "Berkeley Unix") and from
--"SunOS" (a popular 4.2 BSD derivative that includes some Unix System V
--functionality). These systems support most of the ISO C and POSIX
--facilities, and 4.4 BSD and newer releases of SunOS in fact support
--them all.
--
-- The BSD facilities include symbolic links (*note Symbolic Links::.),
--the `select' function (*note Waiting for I/O::.), the BSD signal
--functions (*note BSD Signal Handling::.), and sockets (*note
--Sockets::.).
--
--
--File: libc.info, Node: SVID, Next: XPG, Prev: Berkeley Unix, Up: Standards and Portability
--
--SVID (The System V Interface Description)
-------------------------------------------
--
-- The "System V Interface Description" (SVID) is a document describing
--the AT&T Unix System V operating system. It is to some extent a
--superset of the POSIX standard (*note POSIX::.).
--
-- The GNU C library defines most of the facilities required by the SVID
--that are not also required by the ISO C or POSIX standards, for
--compatibility with System V Unix and other Unix systems (such as
--SunOS) which include these facilities. However, many of the more
--obscure and less generally useful facilities required by the SVID are
--not included. (In fact, Unix System V itself does not provide them
--all.)
--
-- The supported facilities from System V include the methods for
--inter-process communication and shared memory, the `hsearch' and
--`drand48' families of functions, `fmtmsg' and several of the
--mathematical functions.
--
--
--File: libc.info, Node: XPG, Prev: SVID, Up: Standards and Portability
--
--XPG (The X/Open Portability Guide)
------------------------------------
--
-- The X/Open Portability Guide, published by the X/Open Company, Ltd.,
--is a more general standard than POSIX. X/Open owns the Unix copyright
--and the XPG specifies the requirements for systems which are intended
--to be a Unix system.
--
-- The GNU C library complies to the X/Open Portability Guide, Issue
--4.2, with all extensions common to XSI (X/Open System Interface)
--compliant systems and also all X/Open UNIX extensions.
--
-- The additions on top of POSIX are mainly derived from functionality
--available in System V and BSD systems. Some of the really bad mistakes
--in System V systems were corrected, though. Since fulfilling the XPG
--standard with the Unix extensions is a precondition for getting the
--Unix brand chances are good that the functionality is available on
--commercial systems.
--
--
--File: libc.info, Node: Using the Library, Next: Roadmap to the Manual, Prev: Standards and Portability, Up: Introduction
--
--Using the Library
--=================
--
-- This section describes some of the practical issues involved in using
--the GNU C library.
--
--* Menu:
--
--* Header Files:: How to include the header files in your
-- programs.
--* Macro Definitions:: Some functions in the library may really
-- be implemented as macros.
--* Reserved Names:: The C standard reserves some names for
-- the library, and some for users.
--* Feature Test Macros:: How to control what names are defined.
--
--
--File: libc.info, Node: Header Files, Next: Macro Definitions, Up: Using the Library
--
--Header Files
--------------
--
-- Libraries for use by C programs really consist of two parts: "header
--files" that define types and macros and declare variables and
--functions; and the actual library or "archive" that contains the
--definitions of the variables and functions.
--
-- (Recall that in C, a "declaration" merely provides information that
--a function or variable exists and gives its type. For a function
--declaration, information about the types of its arguments might be
--provided as well. The purpose of declarations is to allow the compiler
--to correctly process references to the declared variables and functions.
--A "definition", on the other hand, actually allocates storage for a
--variable or says what a function does.)
--
-- In order to use the facilities in the GNU C library, you should be
--sure that your program source files include the appropriate header
--files. This is so that the compiler has declarations of these
--facilities available and can correctly process references to them.
--Once your program has been compiled, the linker resolves these
--references to the actual definitions provided in the archive file.
--
-- Header files are included into a program source file by the
--`#include' preprocessor directive. The C language supports two forms
--of this directive; the first,
--
-- #include "HEADER"
--
--is typically used to include a header file HEADER that you write
--yourself; this would contain definitions and declarations describing the
--interfaces between the different parts of your particular application.
--By contrast,
--
-- #include <file.h>
--
--is typically used to include a header file `file.h' that contains
--definitions and declarations for a standard library. This file would
--normally be installed in a standard place by your system administrator.
--You should use this second form for the C library header files.
--
-- Typically, `#include' directives are placed at the top of the C
--source file, before any other code. If you begin your source files with
--some comments explaining what the code in the file does (a good idea),
--put the `#include' directives immediately afterwards, following the
--feature test macro definition (*note Feature Test Macros::.).
--
-- For more information about the use of header files and `#include'
--directives, *note Header Files: (cpp.info)Header Files..
--
-- The GNU C library provides several header files, each of which
--contains the type and macro definitions and variable and function
--declarations for a group of related facilities. This means that your
--programs may need to include several header files, depending on exactly
--which facilities you are using.
--
-- Some library header files include other library header files
--automatically. However, as a matter of programming style, you should
--not rely on this; it is better to explicitly include all the header
--files required for the library facilities you are using. The GNU C
--library header files have been written in such a way that it doesn't
--matter if a header file is accidentally included more than once;
--including a header file a second time has no effect. Likewise, if your
--program needs to include multiple header files, the order in which they
--are included doesn't matter.
--
-- *Compatibility Note:* Inclusion of standard header files in any
--order and any number of times works in any ISO C implementation.
--However, this has traditionally not been the case in many older C
--implementations.
--
-- Strictly speaking, you don't *have to* include a header file to use
--a function it declares; you could declare the function explicitly
--yourself, according to the specifications in this manual. But it is
--usually better to include the header file because it may define types
--and macros that are not otherwise available and because it may define
--more efficient macro replacements for some functions. It is also a sure
--way to have the correct declaration.
--
--
--File: libc.info, Node: Macro Definitions, Next: Reserved Names, Prev: Header Files, Up: Using the Library
--
--Macro Definitions of Functions
--------------------------------
--
-- If we describe something as a function in this manual, it may have a
--macro definition as well. This normally has no effect on how your
--program runs--the macro definition does the same thing as the function
--would. In particular, macro equivalents for library functions evaluate
--arguments exactly once, in the same way that a function call would. The
--main reason for these macro definitions is that sometimes they can
--produce an inline expansion that is considerably faster than an actual
--function call.
--
-- Taking the address of a library function works even if it is also
--defined as a macro. This is because, in this context, the name of the
--function isn't followed by the left parenthesis that is syntactically
--necessary to recognize a macro call.
--
-- You might occasionally want to avoid using the macro definition of a
--function--perhaps to make your program easier to debug. There are two
--ways you can do this:
--
-- * You can avoid a macro definition in a specific use by enclosing
-- the name of the function in parentheses. This works because the
-- name of the function doesn't appear in a syntactic context where
-- it is recognizable as a macro call.
--
-- * You can suppress any macro definition for a whole source file by
-- using the `#undef' preprocessor directive, unless otherwise stated
-- explicitly in the description of that facility.
--
-- For example, suppose the header file `stdlib.h' declares a function
--named `abs' with
--
-- extern int abs (int);
--
--and also provides a macro definition for `abs'. Then, in:
--
-- #include <stdlib.h>
-- int f (int *i) { return abs (++*i); }
--
--the reference to `abs' might refer to either a macro or a function. On
--the other hand, in each of the following examples the reference is to a
--function and not a macro.
--
-- #include <stdlib.h>
-- int g (int *i) { return (abs) (++*i); }
--
-- #undef abs
-- int h (int *i) { return abs (++*i); }
--
-- Since macro definitions that double for a function behave in exactly
--the same way as the actual function version, there is usually no need
--for any of these methods. In fact, removing macro definitions usually
--just makes your program slower.
--
--
--File: libc.info, Node: Reserved Names, Next: Feature Test Macros, Prev: Macro Definitions, Up: Using the Library
--
--Reserved Names
----------------
--
-- The names of all library types, macros, variables and functions that
--come from the ISO C standard are reserved unconditionally; your program
--*may not* redefine these names. All other library names are reserved
--if your program explicitly includes the header file that defines or
--declares them. There are several reasons for these restrictions:
--
-- * Other people reading your code could get very confused if you were
-- using a function named `exit' to do something completely different
-- from what the standard `exit' function does, for example.
-- Preventing this situation helps to make your programs easier to
-- understand and contributes to modularity and maintainability.
--
-- * It avoids the possibility of a user accidentally redefining a
-- library function that is called by other library functions. If
-- redefinition were allowed, those other functions would not work
-- properly.
--
-- * It allows the compiler to do whatever special optimizations it
-- pleases on calls to these functions, without the possibility that
-- they may have been redefined by the user. Some library
-- facilities, such as those for dealing with variadic arguments
-- (*note Variadic Functions::.) and non-local exits (*note
-- Non-Local Exits::.), actually require a considerable amount of
-- cooperation on the part of the C compiler, and implementationally
-- it might be easier for the compiler to treat these as built-in
-- parts of the language.
--
-- In addition to the names documented in this manual, reserved names
--include all external identifiers (global functions and variables) that
--begin with an underscore (`_') and all identifiers regardless of use
--that begin with either two underscores or an underscore followed by a
--capital letter are reserved names. This is so that the library and
--header files can define functions, variables, and macros for internal
--purposes without risk of conflict with names in user programs.
--
-- Some additional classes of identifier names are reserved for future
--extensions to the C language or the POSIX.1 environment. While using
--these names for your own purposes right now might not cause a problem,
--they do raise the possibility of conflict with future versions of the C
--or POSIX standards, so you should avoid these names.
--
-- * Names beginning with a capital `E' followed a digit or uppercase
-- letter may be used for additional error code names. *Note Error
-- Reporting::.
--
-- * Names that begin with either `is' or `to' followed by a lowercase
-- letter may be used for additional character testing and conversion
-- functions. *Note Character Handling::.
--
-- * Names that begin with `LC_' followed by an uppercase letter may be
-- used for additional macros specifying locale attributes. *Note
-- Locales::.
--
-- * Names of all existing mathematics functions (*note Mathematics::.)
-- suffixed with `f' or `l' are reserved for corresponding functions
-- that operate on `float' and `long double' arguments, respectively.
--
-- * Names that begin with `SIG' followed by an uppercase letter are
-- reserved for additional signal names. *Note Standard Signals::.
--
-- * Names that begin with `SIG_' followed by an uppercase letter are
-- reserved for additional signal actions. *Note Basic Signal
-- Handling::.
--
-- * Names beginning with `str', `mem', or `wcs' followed by a
-- lowercase letter are reserved for additional string and array
-- functions. *Note String and Array Utilities::.
--
-- * Names that end with `_t' are reserved for additional type names.
--
-- In addition, some individual header files reserve names beyond those
--that they actually define. You only need to worry about these
--restrictions if your program includes that particular header file.
--
-- * The header file `dirent.h' reserves names prefixed with `d_'.
--
-- * The header file `fcntl.h' reserves names prefixed with `l_', `F_',
-- `O_', and `S_'.
--
-- * The header file `grp.h' reserves names prefixed with `gr_'.
--
-- * The header file `limits.h' reserves names suffixed with `_MAX'.
--
-- * The header file `pwd.h' reserves names prefixed with `pw_'.
--
-- * The header file `signal.h' reserves names prefixed with `sa_' and
-- `SA_'.
--
-- * The header file `sys/stat.h' reserves names prefixed with `st_'
-- and `S_'.
--
-- * The header file `sys/times.h' reserves names prefixed with `tms_'.
--
-- * The header file `termios.h' reserves names prefixed with `c_',
-- `V', `I', `O', and `TC'; and names prefixed with `B' followed by a
-- digit.
--
--
--File: libc.info, Node: Feature Test Macros, Prev: Reserved Names, Up: Using the Library
--
--Feature Test Macros
---------------------
--
-- The exact set of features available when you compile a source file
--is controlled by which "feature test macros" you define.
--
-- If you compile your programs using `gcc -ansi', you get only the
--ISO C library features, unless you explicitly request additional
--features by defining one or more of the feature macros. *Note GNU CC
--Command Options: (gcc.info)Invoking GCC, for more information about GCC
--options.
--
-- You should define these macros by using `#define' preprocessor
--directives at the top of your source code files. These directives
--*must* come before any `#include' of a system header file. It is best
--to make them the very first thing in the file, preceded only by
--comments. You could also use the `-D' option to GCC, but it's better
--if you make the source files indicate their own meaning in a
--self-contained way.
--
-- This system exists to allow the library to conform to multiple
--standards. Although the different standards are often described as
--supersets of each other, they are usually incompatible because larger
--standards require functions with names that smaller ones reserve to the
--user program. This is not mere pedantry -- it has been a problem in
--practice. For instance, some non-GNU programs define functions named
--`getline' that have nothing to do with this library's `getline'. They
--would not be compilable if all features were enabled indescriminantly.
--
-- This should not be used to verify that a program conforms to a
--limited standard. It is insufficent for this purpose, as it will not
--protect you from including header files outside the standard, or
--relying on semantics undefined within the standard.
--
-- - Macro: _POSIX_SOURCE
-- If you define this macro, then the functionality from the POSIX.1
-- standard (IEEE Standard 1003.1) is available, as well as all of the
-- ISO C facilities.
--
-- The state of `_POSIX_SOURCE' is irrelevant if you define the macro
-- `_POSIX_C_SOURCE' to a positive integer.
--
-- - Macro: _POSIX_C_SOURCE
-- Define this macro to a positive integer to control which POSIX
-- functionality is made available. The greater the value of this
-- macro, the more functionality is made available.
--
-- If you define this macro to a value greater than or equal to `1',
-- then the functionality from the 1990 edition of the POSIX.1
-- standard (IEEE Standard 1003.1-1990) is made available.
--
-- If you define this macro to a value greater than or equal to `2',
-- then the functionality from the 1992 edition of the POSIX.2
-- standard (IEEE Standard 1003.2-1992) is made available.
--
-- If you define this macro to a value greater than or equal to
-- `199309L', then the functionality from the 1993 edition of the
-- POSIX.1b standard (IEEE Standard 1003.1b-1993) is made available.
--
-- Greater values for `_POSIX_C_SOURCE' will enable future extensions.
-- The POSIX standards process will define these values as necessary,
-- and the GNU C Library should support them some time after they
-- become standardized. The 1996 edition of POSIX.1 (ISO/IEC 9945-1:
-- 1996) states that if you define `_POSIX_C_SOURCE' to a value
-- greater than or equal to `199506L', then the functionality from
-- the 1996 edition is made available.
--
-- The Single Unix Specification specify that setting this macro to
-- the value `199506L' selects all the values specified by the POSIX
-- standards plus those of the Single Unix Specification, i.e., is the
-- same as if `_XOPEN_SOURCE' is set to `500' (see below).
--
-- - Macro: _BSD_SOURCE
-- If you define this macro, functionality derived from 4.3 BSD Unix
-- is included as well as the ISO C, POSIX.1, and POSIX.2 material.
--
-- Some of the features derived from 4.3 BSD Unix conflict with the
-- corresponding features specified by the POSIX.1 standard. If this
-- macro is defined, the 4.3 BSD definitions take precedence over the
-- POSIX definitions.
--
-- Due to the nature of some of the conflicts between 4.3 BSD and
-- POSIX.1, you need to use a special "BSD compatibility library"
-- when linking programs compiled for BSD compatibility. This is
-- because some functions must be defined in two different ways, one
-- of them in the normal C library, and one of them in the
-- compatibility library. If your program defines `_BSD_SOURCE', you
-- must give the option `-lbsd-compat' to the compiler or linker when
-- linking the program, to tell it to find functions in this special
-- compatibility library before looking for them in the normal C
-- library.
--
-- - Macro: _SVID_SOURCE
-- If you define this macro, functionality derived from SVID is
-- included as well as the ISO C, POSIX.1, POSIX.2, and X/Open
-- material.
--
-- - Macro: _XOPEN_SOURCE
-- - Macro: _XOPEN_SOURCE_EXTENDED
-- If you define this macro, functionality described in the X/Open
-- Portability Guide is included. This is a superset of the POSIX.1
-- and POSIX.2 functionality and in fact `_POSIX_SOURCE' and
-- `_POSIX_C_SOURCE' are automatically defined.
--
-- As the unification of all Unices, functionality only available in
-- BSD and SVID is also included.
--
-- If the macro `_XOPEN_SOURCE_EXTENDED' is also defined, even more
-- functionality is available. The extra functions will make all
-- functions available which are necessary for the X/Open Unix brand.
--
-- If the macro `_XOPEN_SOURCE' has the value 500 this includes all
-- functionality described so far plus some new definitions from the
-- Single Unix Specification, version 2.
--
-- - Macro: _LARGEFILE_SOURCE
-- If this macro is defined some extra functions are available which
-- rectify a few shortcomings in all previous standards. More
-- concrete the functions `fseeko' and `ftello' are available.
-- Without these functions the difference between the ISO C interface
-- (`fseek', `ftell') and the low-level POSIX interface (`lseek')
-- would lead to problems.
--
-- This macro was introduced as part of the Large File Support
-- extension (LFS).
--
-- - Macro: _LARGEFILE64_SOURCE
-- If you define this macro an additional set of function gets
-- available which enables to use on 32 bit systems to use files of
-- sizes beyond the usual limit of 2GB. This interface is not
-- available if the system does not support files that large. On
-- systems where the natural file size limit is greater than 2GB
-- (i.e., on 64 bit systems) the new functions are identical to the
-- replaced functions.
--
-- The new functionality is made available by a new set of types and
-- functions which replace existing. The names of these new objects
-- contain `64' to indicate the intention, e.g., `off_t' vs.
-- `off64_t' and `fseeko' vs. `fseeko64'.
--
-- This macro was introduced as part of the Large File Support
-- extension (LFS). It is a transition interface for the time 64 bit
-- offsets are not generally used (see `_FILE_OFFSET_BITS'.
--
-- - Macro: _FILE_OFFSET_BITS
-- This macro lets decide which file system interface shall be used,
-- one replacing the other. While `_LARGEFILE64_SOURCE' makes the
-- 64 bit interface available as an additional interface
-- `_FILE_OFFSET_BITS' allows to use the 64 bit interface to replace
-- the old interface.
--
-- If `_FILE_OFFSET_BITS' is undefined or if it is defined to the
-- value `32' nothing changes. The 32 bit interface is used and
-- types like `off_t' have a size of 32 bits on 32 bit systems.
--
-- If the macro is defined to the value `64' the large file interface
-- replaces the old interface. I.e., the functions are not made
-- available under different names as `_LARGEFILE64_SOURCE' does.
-- Instead the old function names now reference the new functions,
-- e.g., a call to `fseeko' now indeed calls `fseeko64'.
--
-- This macro should only be selected if the system provides
-- mechanisms for handling large files. On 64 bit systems this macro
-- has no effect since the `*64' functions are identical to the
-- normal functions.
--
-- This macro was introduced as part of the Large File Support
-- extension (LFS).
--
-- - Macro: _GNU_SOURCE
-- If you define this macro, everything is included: ISO C, POSIX.1,
-- POSIX.2, BSD, SVID, X/Open, LFS, and GNU extensions. In the cases
-- where POSIX.1 conflicts with BSD, the POSIX definitions take
-- precedence.
--
-- If you want to get the full effect of `_GNU_SOURCE' but make the
-- BSD definitions take precedence over the POSIX definitions, use
-- this sequence of definitions:
--
-- #define _GNU_SOURCE
-- #define _BSD_SOURCE
-- #define _SVID_SOURCE
--
-- Note that if you do this, you must link your program with the BSD
-- compatibility library by passing the `-lbsd-compat' option to the
-- compiler or linker. *Note:* If you forget to do this, you may get
-- very strange errors at run time.
--
-- - Macro: _REENTRANT
-- - Macro: _THREAD_SAFE
-- If you define one of these macros, reentrant versions of several
-- functions get declared. Some of the functions are specified in
-- POSIX.1c but many others are only available on a few other systems
-- or are unique to GNU libc. The problem is that the
-- standardization of the thread safe C library interface still is
-- behind.
--
-- Unlike on some other systems no special version of the C library
-- must be used for linking. There is only one version but while
-- compiling this it must have been specified to compile as thread
-- safe.
--
-- We recommend you use `_GNU_SOURCE' in new programs. If you don't
--specify the `-ansi' option to GCC and don't define any of these macros
--explicitly, the effect is the same as defining `_POSIX_C_SOURCE' to 2
--and `_POSIX_SOURCE', `_SVID_SOURCE', and `_BSD_SOURCE' to 1.
--
-- When you define a feature test macro to request a larger class of
--features, it is harmless to define in addition a feature test macro for
--a subset of those features. For example, if you define
--`_POSIX_C_SOURCE', then defining `_POSIX_SOURCE' as well has no effect.
--Likewise, if you define `_GNU_SOURCE', then defining either
--`_POSIX_SOURCE' or `_POSIX_C_SOURCE' or `_SVID_SOURCE' as well has no
--effect.
--
-- Note, however, that the features of `_BSD_SOURCE' are not a subset of
--any of the other feature test macros supported. This is because it
--defines BSD features that take precedence over the POSIX features that
--are requested by the other macros. For this reason, defining
--`_BSD_SOURCE' in addition to the other feature test macros does have an
--effect: it causes the BSD features to take priority over the conflicting
--POSIX features.
--
--
--File: libc.info, Node: Roadmap to the Manual, Prev: Using the Library, Up: Introduction
--
--Roadmap to the Manual
--=====================
--
-- Here is an overview of the contents of the remaining chapters of
--this manual.
--
-- * *Note Error Reporting::, describes how errors detected by the
-- library are reported.
--
-- * *Note Language Features::, contains information about library
-- support for standard parts of the C language, including things
-- like the `sizeof' operator and the symbolic constant `NULL', how
-- to write functions accepting variable numbers of arguments, and
-- constants describing the ranges and other properties of the
-- numerical types. There is also a simple debugging mechanism which
-- allows you to put assertions in your code, and have diagnostic
-- messages printed if the tests fail.
--
-- * *Note Memory Allocation::, describes the GNU library's facilities
-- for dynamic allocation of storage. If you do not know in advance
-- how much storage your program needs, you can allocate it
-- dynamically instead, and manipulate it via pointers.
--
-- * *Note Character Handling::, contains information about character
-- classification functions (such as `isspace') and functions for
-- performing case conversion.
--
-- * *Note String and Array Utilities::, has descriptions of functions
-- for manipulating strings (null-terminated character arrays) and
-- general byte arrays, including operations such as copying and
-- comparison.
--
-- * *Note I/O Overview::, gives an overall look at the input and output
-- facilities in the library, and contains information about basic
-- concepts such as file names.
--
-- * *Note I/O on Streams::, describes I/O operations involving streams
-- (or `FILE *' objects). These are the normal C library functions
-- from `stdio.h'.
--
-- * *Note Low-Level I/O::, contains information about I/O operations
-- on file descriptors. File descriptors are a lower-level mechanism
-- specific to the Unix family of operating systems.
--
-- * *Note File System Interface::, has descriptions of operations on
-- entire files, such as functions for deleting and renaming them and
-- for creating new directories. This chapter also contains
-- information about how you can access the attributes of a file,
-- such as its owner and file protection modes.
--
-- * *Note Pipes and FIFOs::, contains information about simple
-- interprocess communication mechanisms. Pipes allow communication
-- between two related processes (such as between a parent and
-- child), while FIFOs allow communication between processes sharing
-- a common file system on the same machine.
--
-- * *Note Sockets::, describes a more complicated interprocess
-- communication mechanism that allows processes running on different
-- machines to communicate over a network. This chapter also
-- contains information about Internet host addressing and how to use
-- the system network databases.
--
-- * *Note Low-Level Terminal Interface::, describes how you can change
-- the attributes of a terminal device. If you want to disable echo
-- of characters typed by the user, for example, read this chapter.
--
-- * *Note Mathematics::, contains information about the math library
-- functions. These include things like random-number generators and
-- remainder functions on integers as well as the usual trigonometric
-- and exponential functions on floating-point numbers.
--
-- * *Note Low-Level Arithmetic Functions: Arithmetic, describes
-- functions for simple arithmetic, analysis of floating-point
-- values, and reading numbers from strings.
--
-- * *Note Searching and Sorting::, contains information about functions
-- for searching and sorting arrays. You can use these functions on
-- any kind of array by providing an appropriate comparison function.
--
-- * *Note Pattern Matching::, presents functions for matching regular
-- expressions and shell file name patterns, and for expanding words
-- as the shell does.
--
-- * *Note Date and Time::, describes functions for measuring both
-- calendar time and CPU time, as well as functions for setting
-- alarms and timers.
--
-- * *Note Character Set Handling::, contains information about
-- manipulating characters and strings using character sets larger
-- than will fit in the usual `char' data type.
--
-- * *Note Locales::, describes how selecting a particular country or
-- language affects the behavior of the library. For example, the
-- locale affects collation sequences for strings and how monetary
-- values are formatted.
--
-- * *Note Non-Local Exits::, contains descriptions of the `setjmp' and
-- `longjmp' functions. These functions provide a facility for
-- `goto'-like jumps which can jump from one function to another.
--
-- * *Note Signal Handling::, tells you all about signals--what they
-- are, how to establish a handler that is called when a particular
-- kind of signal is delivered, and how to prevent signals from
-- arriving during critical sections of your program.
--
-- * *Note Process Startup::, tells how your programs can access their
-- command-line arguments and environment variables.
--
-- * *Note Processes::, contains information about how to start new
-- processes and run programs.
--
-- * *Note Job Control::, describes functions for manipulating process
-- groups and the controlling terminal. This material is probably
-- only of interest if you are writing a shell or other program which
-- handles job control specially.
--
-- * *Note Name Service Switch::, describes the services which are
-- available for looking up names in the system databases, how to
-- determine which service is used for which database, and how these
-- services are implemented so that contributors can design their own
-- services.
--
-- * *Note User Database::, and *Note Group Database::, tell you how to
-- access the system user and group databases.
--
-- * *Note System Information::, describes functions for getting
-- information about the hardware and software configuration your
-- program is executing under.
--
-- * *Note System Configuration::, tells you how you can get
-- information about various operating system limits. Most of these
-- parameters are provided for compatibility with POSIX.
--
-- * *Note Library Summary::, gives a summary of all the functions,
-- variables, and macros in the library, with complete data types and
-- function prototypes, and says what standard or system each is
-- derived from.
--
-- * *Note Maintenance::, explains how to build and install the GNU C
-- library on your system, how to report any bugs you might find, and
-- how to add new functions or port the library to a new system.
--
-- If you already know the name of the facility you are interested in,
--you can look it up in *Note Library Summary::. This gives you a
--summary of its syntax and a pointer to where you can find a more
--detailed description. This appendix is particularly useful if you just
--want to verify the order and type of arguments to a function, for
--example. It also tells you what standard or system each function,
--variable, or macro is derived from.
--
--
--File: libc.info, Node: Error Reporting, Next: Memory Allocation, Prev: Introduction, Up: Top
--
--Error Reporting
--***************
--
-- Many functions in the GNU C library detect and report error
--conditions, and sometimes your programs need to check for these error
--conditions. For example, when you open an input file, you should
--verify that the file was actually opened correctly, and print an error
--message or take other appropriate action if the call to the library
--function failed.
--
-- This chapter describes how the error reporting facility works. Your
--program should include the header file `errno.h' to use this facility.
--
--* Menu:
--
--* Checking for Errors:: How errors are reported by library functions.
--* Error Codes:: Error code macros; all of these expand
-- into integer constant values.
--* Error Messages:: Mapping error codes onto error messages.
--
--
--File: libc.info, Node: Checking for Errors, Next: Error Codes, Up: Error Reporting
--
--Checking for Errors
--===================
--
-- Most library functions return a special value to indicate that they
--have failed. The special value is typically `-1', a null pointer, or a
--constant such as `EOF' that is defined for that purpose. But this
--return value tells you only that an error has occurred. To find out
--what kind of error it was, you need to look at the error code stored in
--the variable `errno'. This variable is declared in the header file
--`errno.h'.
--
-- - Variable: volatile int errno
-- The variable `errno' contains the system error number. You can
-- change the value of `errno'.
--
-- Since `errno' is declared `volatile', it might be changed
-- asynchronously by a signal handler; see *Note Defining Handlers::.
-- However, a properly written signal handler saves and restores the
-- value of `errno', so you generally do not need to worry about this
-- possibility except when writing signal handlers.
--
-- The initial value of `errno' at program startup is zero. Many
-- library functions are guaranteed to set it to certain nonzero
-- values when they encounter certain kinds of errors. These error
-- conditions are listed for each function. These functions do not
-- change `errno' when they succeed; thus, the value of `errno' after
-- a successful call is not necessarily zero, and you should not use
-- `errno' to determine *whether* a call failed. The proper way to
-- do that is documented for each function. *If* the call the
-- failed, you can examine `errno'.
--
-- Many library functions can set `errno' to a nonzero value as a
-- result of calling other library functions which might fail. You
-- should assume that any library function might alter `errno' when
-- the function returns an error.
--
-- *Portability Note:* ISO C specifies `errno' as a "modifiable
-- lvalue" rather than as a variable, permitting it to be implemented
-- as a macro. For example, its expansion might involve a function
-- call, like `*_errno ()'. In fact, that is what it is on the GNU
-- system itself. The GNU library, on non-GNU systems, does whatever
-- is right for the particular system.
--
-- There are a few library functions, like `sqrt' and `atan', that
-- return a perfectly legitimate value in case of an error, but also
-- set `errno'. For these functions, if you want to check to see
-- whether an error occurred, the recommended method is to set `errno'
-- to zero before calling the function, and then check its value
-- afterward.
--
-- All the error codes have symbolic names; they are macros defined in
--`errno.h'. The names start with `E' and an upper-case letter or digit;
--you should consider names of this form to be reserved names. *Note
--Reserved Names::.
--
-- The error code values are all positive integers and are all distinct,
--with one exception: `EWOULDBLOCK' and `EAGAIN' are the same. Since the
--values are distinct, you can use them as labels in a `switch'
--statement; just don't use both `EWOULDBLOCK' and `EAGAIN'. Your
--program should not make any other assumptions about the specific values
--of these symbolic constants.
--
-- The value of `errno' doesn't necessarily have to correspond to any
--of these macros, since some library functions might return other error
--codes of their own for other situations. The only values that are
--guaranteed to be meaningful for a particular library function are the
--ones that this manual lists for that function.
--
-- On non-GNU systems, almost any system call can return `EFAULT' if it
--is given an invalid pointer as an argument. Since this could only
--happen as a result of a bug in your program, and since it will not
--happen on the GNU system, we have saved space by not mentioning
--`EFAULT' in the descriptions of individual functions.
--
-- In some Unix systems, many system calls can also return `EFAULT' if
--given as an argument a pointer into the stack, and the kernel for some
--obscure reason fails in its attempt to extend the stack. If this ever
--happens, you should probably try using statically or dynamically
--allocated memory instead of stack memory on that system.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-20 glibc-2.1.3/manual/libc.info-20
---- ../glibc-2.1.3/manual/libc.info-20 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-20 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1238 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: File Status Flags, Next: File Locks, Prev: Descriptor Flags, Up: Low-Level I/O
--
--File Status Flags
--=================
--
-- "File status flags" are used to specify attributes of the opening of
--a file. Unlike the file descriptor flags discussed in *Note Descriptor
--Flags::, the file status flags are shared by duplicated file descriptors
--resulting from a single opening of the file. The file status flags are
--specified with the FLAGS argument to `open'; *note Opening and Closing
--Files::..
--
-- File status flags fall into three categories, which are described in
--the following sections.
--
-- * *Note Access Modes::, specify what type of access is allowed to the
-- file: reading, writing, or both. They are set by `open' and are
-- returned by `fcntl', but cannot be changed.
--
-- * *Note Open-time Flags::, control details of what `open' will do.
-- These flags are not preserved after the `open' call.
--
-- * *Note Operating Modes::, affect how operations such as `read' and
-- `write' are done. They are set by `open', and can be fetched or
-- changed with `fcntl'.
--
-- The symbols in this section are defined in the header file `fcntl.h'.
--
--* Menu:
--
--* Access Modes:: Whether the descriptor can read or write.
--* Open-time Flags:: Details of `open'.
--* Operating Modes:: Special modes to control I/O operations.
--* Getting File Status Flags:: Fetching and changing these flags.
--
--
--File: libc.info, Node: Access Modes, Next: Open-time Flags, Up: File Status Flags
--
--File Access Modes
-------------------
--
-- The file access modes allow a file descriptor to be used for reading,
--writing, or both. (In the GNU system, they can also allow none of
--these, and allow execution of the file as a program.) The access modes
--are chosen when the file is opened, and never change.
--
-- - Macro: int O_RDONLY
-- Open the file for read access.
--
-- - Macro: int O_WRONLY
-- Open the file for write access.
--
-- - Macro: int O_RDWR
-- Open the file for both reading and writing.
--
-- In the GNU system (and not in other systems), `O_RDONLY' and
--`O_WRONLY' are independent bits that can be bitwise-ORed together, and
--it is valid for either bit to be set or clear. This means that
--`O_RDWR' is the same as `O_RDONLY|O_WRONLY'. A file access mode of
--zero is permissible; it allows no operations that do input or output to
--the file, but does allow other operations such as `fchmod'. On the GNU
--system, since "read-only" or "write-only" is a misnomer, `fcntl.h'
--defines additional names for the file access modes. These names are
--preferred when writing GNU-specific code. But most programs will want
--to be portable to other POSIX.1 systems and should use the POSIX.1
--names above instead.
--
-- - Macro: int O_READ
-- Open the file for reading. Same as `O_RDWR'; only defined on GNU.
--
-- - Macro: int O_WRITE
-- Open the file for reading. Same as `O_WRONLY'; only defined on
-- GNU.
--
-- - Macro: int O_EXEC
-- Open the file for executing. Only defined on GNU.
--
-- To determine the file access mode with `fcntl', you must extract the
--access mode bits from the retrieved file status flags. In the GNU
--system, you can just test the `O_READ' and `O_WRITE' bits in the flags
--word. But in other POSIX.1 systems, reading and writing access modes
--are not stored as distinct bit flags. The portable way to extract the
--file access mode bits is with `O_ACCMODE'.
--
-- - Macro: int O_ACCMODE
-- This macro stands for a mask that can be bitwise-ANDed with the
-- file status flag value to produce a value representing the file
-- access mode. The mode will be `O_RDONLY', `O_WRONLY', or `O_RDWR'.
-- (In the GNU system it could also be zero, and it never includes the
-- `O_EXEC' bit.)
--
--
--File: libc.info, Node: Open-time Flags, Next: Operating Modes, Prev: Access Modes, Up: File Status Flags
--
--Open-time Flags
-----------------
--
-- The open-time flags specify options affecting how `open' will behave.
--These options are not preserved once the file is open. The exception to
--this is `O_NONBLOCK', which is also an I/O operating mode and so it
--*is* saved. *Note Opening and Closing Files::, for how to call `open'.
--
-- There are two sorts of options specified by open-time flags.
--
-- * "File name translation flags" affect how `open' looks up the file
-- name to locate the file, and whether the file can be created.
--
-- * "Open-time action flags" specify extra operations that `open' will
-- perform on the file once it is open.
--
-- Here are the file name translation flags.
--
-- - Macro: int O_CREAT
-- If set, the file will be created if it doesn't already exist.
--
-- - Macro: int O_EXCL
-- If both `O_CREAT' and `O_EXCL' are set, then `open' fails if the
-- specified file already exists. This is guaranteed to never
-- clobber an existing file.
--
-- - Macro: int O_NONBLOCK
-- This prevents `open' from blocking for a "long time" to open the
-- file. This is only meaningful for some kinds of files, usually
-- devices such as serial ports; when it is not meaningful, it is
-- harmless and ignored. Often opening a port to a modem blocks
-- until the modem reports carrier detection; if `O_NONBLOCK' is
-- specified, `open' will return immediately without a carrier.
--
-- Note that the `O_NONBLOCK' flag is overloaded as both an I/O
-- operating mode and a file name translation flag. This means that
-- specifying `O_NONBLOCK' in `open' also sets nonblocking I/O mode;
-- *note Operating Modes::.. To open the file without blocking but
-- do normal I/O that blocks, you must call `open' with `O_NONBLOCK'
-- set and then call `fcntl' to turn the bit off.
--
-- - Macro: int O_NOCTTY
-- If the named file is a terminal device, don't make it the
-- controlling terminal for the process. *Note Job Control::, for
-- information about what it means to be the controlling terminal.
--
-- In the GNU system and 4.4 BSD, opening a file never makes it the
-- controlling terminal and `O_NOCTTY' is zero. However, other
-- systems may use a nonzero value for `O_NOCTTY' and set the
-- controlling terminal when you open a file that is a terminal
-- device; so to be portable, use `O_NOCTTY' when it is important to
-- avoid this.
--
-- The following three file name translation flags exist only in the
--GNU system.
--
-- - Macro: int O_IGNORE_CTTY
-- Do not recognize the named file as the controlling terminal, even
-- if it refers to the process's existing controlling terminal
-- device. Operations on the new file descriptor will never induce
-- job control signals. *Note Job Control::.
--
-- - Macro: int O_NOLINK
-- If the named file is a symbolic link, open the link itself instead
-- of the file it refers to. (`fstat' on the new file descriptor will
-- return the information returned by `lstat' on the link's name.)
--
-- - Macro: int O_NOTRANS
-- If the named file is specially translated, do not invoke the
-- translator. Open the bare file the translator itself sees.
--
-- The open-time action flags tell `open' to do additional operations
--which are not really related to opening the file. The reason to do them
--as part of `open' instead of in separate calls is that `open' can do
--them atomically.
--
-- - Macro: int O_TRUNC
-- Truncate the file to zero length. This option is only useful for
-- regular files, not special files such as directories or FIFOs.
-- POSIX.1 requires that you open the file for writing to use
-- `O_TRUNC'. In BSD and GNU you must have permission to write the
-- file to truncate it, but you need not open for write access.
--
-- This is the only open-time action flag specified by POSIX.1.
-- There is no good reason for truncation to be done by `open',
-- instead of by calling `ftruncate' afterwards. The `O_TRUNC' flag
-- existed in Unix before `ftruncate' was invented, and is retained
-- for backward compatibility.
--
-- The remaining operating modes are BSD extensions. They exist only
--on some systems. On other systems, these macros are not defined.
--
-- - Macro: int O_SHLOCK
-- Acquire a shared lock on the file, as with `flock'. *Note File
-- Locks::.
--
-- If `O_CREAT' is specified, the locking is done atomically when
-- creating the file. You are guaranteed that no other process will
-- get the lock on the new file first.
--
-- - Macro: int O_EXLOCK
-- Acquire an exclusive lock on the file, as with `flock'. *Note
-- File Locks::. This is atomic like `O_SHLOCK'.
--
--
--File: libc.info, Node: Operating Modes, Next: Getting File Status Flags, Prev: Open-time Flags, Up: File Status Flags
--
--I/O Operating Modes
---------------------
--
-- The operating modes affect how input and output operations using a
--file descriptor work. These flags are set by `open' and can be fetched
--and changed with `fcntl'.
--
-- - Macro: int O_APPEND
-- The bit that enables append mode for the file. If set, then all
-- `write' operations write the data at the end of the file, extending
-- it, regardless of the current file position. This is the only
-- reliable way to append to a file. In append mode, you are
-- guaranteed that the data you write will always go to the current
-- end of the file, regardless of other processes writing to the
-- file. Conversely, if you simply set the file position to the end
-- of file and write, then another process can extend the file after
-- you set the file position but before you write, resulting in your
-- data appearing someplace before the real end of file.
--
-- - Macro: int O_NONBLOCK
-- The bit that enables nonblocking mode for the file. If this bit
-- is set, `read' requests on the file can return immediately with a
-- failure status if there is no input immediately available, instead
-- of blocking. Likewise, `write' requests can also return
-- immediately with a failure status if the output can't be written
-- immediately.
--
-- Note that the `O_NONBLOCK' flag is overloaded as both an I/O
-- operating mode and a file name translation flag; *note Open-time
-- Flags::..
--
-- - Macro: int O_NDELAY
-- This is an obsolete name for `O_NONBLOCK', provided for
-- compatibility with BSD. It is not defined by the POSIX.1 standard.
--
-- The remaining operating modes are BSD and GNU extensions. They
--exist only on some systems. On other systems, these macros are not
--defined.
--
-- - Macro: int O_ASYNC
-- The bit that enables asynchronous input mode. If set, then `SIGIO'
-- signals will be generated when input is available. *Note
-- Interrupt Input::.
--
-- Asynchronous input mode is a BSD feature.
--
-- - Macro: int O_FSYNC
-- The bit that enables synchronous writing for the file. If set,
-- each `write' call will make sure the data is reliably stored on
-- disk before returning. Synchronous writing is a BSD feature.
--
-- - Macro: int O_SYNC
-- This is another name for `O_FSYNC'. They have the same value.
--
-- - Macro: int O_NOATIME
-- If this bit is set, `read' will not update the access time of the
-- file. *Note File Times::. This is used by programs that do
-- backups, so that backing a file up does not count as reading it.
-- Only the owner of the file or the superuser may use this bit.
--
-- This is a GNU extension.
--
--
--File: libc.info, Node: Getting File Status Flags, Prev: Operating Modes, Up: File Status Flags
--
--Getting and Setting File Status Flags
---------------------------------------
--
-- The `fcntl' function can fetch or change file status flags.
--
-- - Macro: int F_GETFL
-- This macro is used as the COMMAND argument to `fcntl', to read the
-- file status flags for the open file with descriptor FILEDES.
--
-- The normal return value from `fcntl' with this command is a
-- nonnegative number which can be interpreted as the bitwise OR of
-- the individual flags. Since the file access modes are not
-- single-bit values, you can mask off other bits in the returned
-- flags with `O_ACCMODE' to compare them.
--
-- In case of an error, `fcntl' returns -1. The following `errno'
-- error conditions are defined for this command:
--
-- `EBADF'
-- The FILEDES argument is invalid.
--
-- - Macro: int F_SETFL
-- This macro is used as the COMMAND argument to `fcntl', to set the
-- file status flags for the open file corresponding to the FILEDES
-- argument. This command requires a third `int' argument to specify
-- the new flags, so the call looks like this:
--
-- fcntl (FILEDES, F_SETFL, NEW-FLAGS)
--
-- You can't change the access mode for the file in this way; that is,
-- whether the file descriptor was opened for reading or writing.
--
-- The normal return value from `fcntl' with this command is an
-- unspecified value other than -1, which indicates an error. The
-- error conditions are the same as for the `F_GETFL' command.
--
-- If you want to modify the file status flags, you should get the
--current flags with `F_GETFL' and modify the value. Don't assume that
--the flags listed here are the only ones that are implemented; your
--program may be run years from now and more flags may exist then. For
--example, here is a function to set or clear the flag `O_NONBLOCK'
--without altering any other flags:
--
-- /* Set the `O_NONBLOCK' flag of DESC if VALUE is nonzero,
-- or clear the flag if VALUE is 0.
-- Return 0 on success, or -1 on error with `errno' set. */
--
-- int
-- set_nonblock_flag (int desc, int value)
-- {
-- int oldflags = fcntl (desc, F_GETFL, 0);
-- /* If reading the flags failed, return error indication now. */
-- if (oldflags == -1)
-- return -1;
-- /* Set just the flag we want to set. */
-- if (value != 0)
-- oldflags |= O_NONBLOCK;
-- else
-- oldflags &= ~O_NONBLOCK;
-- /* Store modified flag word in the descriptor. */
-- return fcntl (desc, F_SETFL, oldflags);
-- }
--
--
--File: libc.info, Node: File Locks, Next: Interrupt Input, Prev: File Status Flags, Up: Low-Level I/O
--
--File Locks
--==========
--
-- The remaining `fcntl' commands are used to support "record locking",
--which permits multiple cooperating programs to prevent each other from
--simultaneously accessing parts of a file in error-prone ways.
--
-- An "exclusive" or "write" lock gives a process exclusive access for
--writing to the specified part of the file. While a write lock is in
--place, no other process can lock that part of the file.
--
-- A "shared" or "read" lock prohibits any other process from
--requesting a write lock on the specified part of the file. However,
--other processes can request read locks.
--
-- The `read' and `write' functions do not actually check to see
--whether there are any locks in place. If you want to implement a
--locking protocol for a file shared by multiple processes, your
--application must do explicit `fcntl' calls to request and clear locks
--at the appropriate points.
--
-- Locks are associated with processes. A process can only have one
--kind of lock set for each byte of a given file. When any file
--descriptor for that file is closed by the process, all of the locks
--that process holds on that file are released, even if the locks were
--made using other descriptors that remain open. Likewise, locks are
--released when a process exits, and are not inherited by child processes
--created using `fork' (*note Creating a Process::.).
--
-- When making a lock, use a `struct flock' to specify what kind of
--lock and where. This data type and the associated macros for the
--`fcntl' function are declared in the header file `fcntl.h'.
--
-- - Data Type: struct flock
-- This structure is used with the `fcntl' function to describe a file
-- lock. It has these members:
--
-- `short int l_type'
-- Specifies the type of the lock; one of `F_RDLCK', `F_WRLCK',
-- or `F_UNLCK'.
--
-- `short int l_whence'
-- This corresponds to the WHENCE argument to `fseek' or
-- `lseek', and specifies what the offset is relative to. Its
-- value can be one of `SEEK_SET', `SEEK_CUR', or `SEEK_END'.
--
-- `off_t l_start'
-- This specifies the offset of the start of the region to which
-- the lock applies, and is given in bytes relative to the point
-- specified by `l_whence' member.
--
-- `off_t l_len'
-- This specifies the length of the region to be locked. A
-- value of `0' is treated specially; it means the region
-- extends to the end of the file.
--
-- `pid_t l_pid'
-- This field is the process ID (*note Process Creation
-- Concepts::.) of the process holding the lock. It is filled
-- in by calling `fcntl' with the `F_GETLK' command, but is
-- ignored when making a lock.
--
-- - Macro: int F_GETLK
-- This macro is used as the COMMAND argument to `fcntl', to specify
-- that it should get information about a lock. This command
-- requires a third argument of type `struct flock *' to be passed to
-- `fcntl', so that the form of the call is:
--
-- fcntl (FILEDES, F_GETLK, LOCKP)
--
-- If there is a lock already in place that would block the lock
-- described by the LOCKP argument, information about that lock
-- overwrites `*LOCKP'. Existing locks are not reported if they are
-- compatible with making a new lock as specified. Thus, you should
-- specify a lock type of `F_WRLCK' if you want to find out about both
-- read and write locks, or `F_RDLCK' if you want to find out about
-- write locks only.
--
-- There might be more than one lock affecting the region specified
-- by the LOCKP argument, but `fcntl' only returns information about
-- one of them. The `l_whence' member of the LOCKP structure is set
-- to `SEEK_SET' and the `l_start' and `l_len' fields set to identify
-- the locked region.
--
-- If no lock applies, the only change to the LOCKP structure is to
-- update the `l_type' to a value of `F_UNLCK'.
--
-- The normal return value from `fcntl' with this command is an
-- unspecified value other than -1, which is reserved to indicate an
-- error. The following `errno' error conditions are defined for
-- this command:
--
-- `EBADF'
-- The FILEDES argument is invalid.
--
-- `EINVAL'
-- Either the LOCKP argument doesn't specify valid lock
-- information, or the file associated with FILEDES doesn't
-- support locks.
--
-- - Macro: int F_SETLK
-- This macro is used as the COMMAND argument to `fcntl', to specify
-- that it should set or clear a lock. This command requires a third
-- argument of type `struct flock *' to be passed to `fcntl', so that
-- the form of the call is:
--
-- fcntl (FILEDES, F_SETLK, LOCKP)
--
-- If the process already has a lock on any part of the region, the
-- old lock on that part is replaced with the new lock. You can
-- remove a lock by specifying a lock type of `F_UNLCK'.
--
-- If the lock cannot be set, `fcntl' returns immediately with a value
-- of -1. This function does not block waiting for other processes
-- to release locks. If `fcntl' succeeds, it return a value other
-- than -1.
--
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EAGAIN'
-- `EACCES'
-- The lock cannot be set because it is blocked by an existing
-- lock on the file. Some systems use `EAGAIN' in this case,
-- and other systems use `EACCES'; your program should treat
-- them alike, after `F_SETLK'. (The GNU system always uses
-- `EAGAIN'.)
--
-- `EBADF'
-- Either: the FILEDES argument is invalid; you requested a read
-- lock but the FILEDES is not open for read access; or, you
-- requested a write lock but the FILEDES is not open for write
-- access.
--
-- `EINVAL'
-- Either the LOCKP argument doesn't specify valid lock
-- information, or the file associated with FILEDES doesn't
-- support locks.
--
-- `ENOLCK'
-- The system has run out of file lock resources; there are
-- already too many file locks in place.
--
-- Well-designed file systems never report this error, because
-- they have no limitation on the number of locks. However, you
-- must still take account of the possibility of this error, as
-- it could result from network access to a file system on
-- another machine.
--
-- - Macro: int F_SETLKW
-- This macro is used as the COMMAND argument to `fcntl', to specify
-- that it should set or clear a lock. It is just like the `F_SETLK'
-- command, but causes the process to block (or wait) until the
-- request can be specified.
--
-- This command requires a third argument of type `struct flock *', as
-- for the `F_SETLK' command.
--
-- The `fcntl' return values and errors are the same as for the
-- `F_SETLK' command, but these additional `errno' error conditions
-- are defined for this command:
--
-- `EINTR'
-- The function was interrupted by a signal while it was waiting.
-- *Note Interrupted Primitives::.
--
-- `EDEADLK'
-- The specified region is being locked by another process. But
-- that process is waiting to lock a region which the current
-- process has locked, so waiting for the lock would result in
-- deadlock. The system does not guarantee that it will detect
-- all such conditions, but it lets you know if it notices one.
--
-- The following macros are defined for use as values for the `l_type'
--member of the `flock' structure. The values are integer constants.
--
--`F_RDLCK'
-- This macro is used to specify a read (or shared) lock.
--
--`F_WRLCK'
-- This macro is used to specify a write (or exclusive) lock.
--
--`F_UNLCK'
-- This macro is used to specify that the region is unlocked.
--
-- As an example of a situation where file locking is useful, consider a
--program that can be run simultaneously by several different users, that
--logs status information to a common file. One example of such a program
--might be a game that uses a file to keep track of high scores. Another
--example might be a program that records usage or accounting information
--for billing purposes.
--
-- Having multiple copies of the program simultaneously writing to the
--file could cause the contents of the file to become mixed up. But you
--can prevent this kind of problem by setting a write lock on the file
--before actually writing to the file.
--
-- If the program also needs to read the file and wants to make sure
--that the contents of the file are in a consistent state, then it can
--also use a read lock. While the read lock is set, no other process can
--lock that part of the file for writing.
--
-- Remember that file locks are only a *voluntary* protocol for
--controlling access to a file. There is still potential for access to
--the file by programs that don't use the lock protocol.
--
--
--File: libc.info, Node: Interrupt Input, Next: IOCTLs, Prev: File Locks, Up: Low-Level I/O
--
--Interrupt-Driven Input
--======================
--
-- If you set the `O_ASYNC' status flag on a file descriptor (*note
--File Status Flags::.), a `SIGIO' signal is sent whenever input or
--output becomes possible on that file descriptor. The process or
--process group to receive the signal can be selected by using the
--`F_SETOWN' command to the `fcntl' function. If the file descriptor is
--a socket, this also selects the recipient of `SIGURG' signals that are
--delivered when out-of-band data arrives on that socket; see *Note
--Out-of-Band Data::. (`SIGURG' is sent in any situation where `select'
--would report the socket as having an "exceptional condition". *Note
--Waiting for I/O::.)
--
-- If the file descriptor corresponds to a terminal device, then `SIGIO'
--signals are sent to the foreground process group of the terminal.
--*Note Job Control::.
--
-- The symbols in this section are defined in the header file `fcntl.h'.
--
-- - Macro: int F_GETOWN
-- This macro is used as the COMMAND argument to `fcntl', to specify
-- that it should get information about the process or process group
-- to which `SIGIO' signals are sent. (For a terminal, this is
-- actually the foreground process group ID, which you can get using
-- `tcgetpgrp'; see *Note Terminal Access Functions::.)
--
-- The return value is interpreted as a process ID; if negative, its
-- absolute value is the process group ID.
--
-- The following `errno' error condition is defined for this command:
--
-- `EBADF'
-- The FILEDES argument is invalid.
--
-- - Macro: int F_SETOWN
-- This macro is used as the COMMAND argument to `fcntl', to specify
-- that it should set the process or process group to which `SIGIO'
-- signals are sent. This command requires a third argument of type
-- `pid_t' to be passed to `fcntl', so that the form of the call is:
--
-- fcntl (FILEDES, F_SETOWN, PID)
--
-- The PID argument should be a process ID. You can also pass a
-- negative number whose absolute value is a process group ID.
--
-- The return value from `fcntl' with this command is -1 in case of
-- error and some other value if successful. The following `errno'
-- error conditions are defined for this command:
--
-- `EBADF'
-- The FILEDES argument is invalid.
--
-- `ESRCH'
-- There is no process or process group corresponding to PID.
--
--
--File: libc.info, Node: IOCTLs, Prev: Interrupt Input, Up: Low-Level I/O
--
--Generic I/O Control operations
--==============================
--
-- The GNU system can handle most input/output operations on many
--different devices and objects in terms of a few file primitives -
--`read', `write' and `lseek'. However, most devices also have a few
--peculiar operations which do not fit into this model. Such as:
--
-- * Changing the character font used on a terminal.
--
-- * Telling a magnetic tape system to rewind or fast forward. (Since
-- they cannot move in byte increments, `lseek' is inapplicable).
--
-- * Ejecting a disk from a drive.
--
-- * Playing an audio track from a CD-ROM drive.
--
-- * Maintaining routing tables for a network.
--
-- Although some such objects such as sockets and terminals (1) have
--special functions of their own, it would not be practical to create
--functions for all these cases.
--
-- Instead these minor operations, known as "IOCTL"s, are assigned code
--numbers and multiplexed through the `ioctl' function, defined in
--`sys/ioctl.h'. The code numbers themselves are defined in many
--different headers.
--
-- - Function: int ioctl (int FILEDES, int COMMAND, ...)
-- The `ioctl' function performs the generic I/O operation COMMAND on
-- FILEDES.
--
-- A third argument is usually present, either a single number or a
-- pointer to a structure. The meaning of this argument, the
-- returned value, and any error codes depends upon the command used.
-- Often -1 is returned for a failure.
--
--
-- On some systems, IOCTLs used by different devices share the same
--numbers. Thus, although use of an inappropriate IOCTL *usually* only
--produces an error, you should not attempt to use device-specific IOCTLs
--on an unknown device.
--
-- Most IOCTLs are OS-specific and/or only used in special system
--utilities, and are thus beyond the scope of this document. For an
--example of the use of an IOCTL, see *Note Out-of-Band Data::.
--
-- ---------- Footnotes ----------
--
-- (1) Actually, the terminal-specific functions are implemented with
--IOCTLs on many platforms.
--
--
--File: libc.info, Node: File System Interface, Next: Pipes and FIFOs, Prev: Low-Level I/O, Up: Top
--
--File System Interface
--*********************
--
-- This chapter describes the GNU C library's functions for manipulating
--files. Unlike the input and output functions (*note I/O on Streams::.;
--*note Low-Level I/O::.), these functions are concerned with operating
--on the files themselves, rather than on their contents.
--
-- Among the facilities described in this chapter are functions for
--examining or modifying directories, functions for renaming and deleting
--files, and functions for examining and setting file attributes such as
--access permissions and modification times.
--
--* Menu:
--
--* Working Directory:: This is used to resolve relative
-- file names.
--* Accessing Directories:: Finding out what files a directory
-- contains.
--* Working on Directory Trees:: Apply actions to all files or a selectable
-- subset of a directory hierarchy.
--* Hard Links:: Adding alternate names to a file.
--* Symbolic Links:: A file that "points to" a file name.
--* Deleting Files:: How to delete a file, and what that means.
--* Renaming Files:: Changing a file's name.
--* Creating Directories:: A system call just for creating a directory.
--* File Attributes:: Attributes of individual files.
--* Making Special Files:: How to create special files.
--* Temporary Files:: Naming and creating temporary files.
--
--
--File: libc.info, Node: Working Directory, Next: Accessing Directories, Up: File System Interface
--
--Working Directory
--=================
--
-- Each process has associated with it a directory, called its "current
--working directory" or simply "working directory", that is used in the
--resolution of relative file names (*note File Name Resolution::.).
--
-- When you log in and begin a new session, your working directory is
--initially set to the home directory associated with your login account
--in the system user database. You can find any user's home directory
--using the `getpwuid' or `getpwnam' functions; see *Note User Database::.
--
-- Users can change the working directory using shell commands like
--`cd'. The functions described in this section are the primitives used
--by those commands and by other programs for examining and changing the
--working directory.
--
-- Prototypes for these functions are declared in the header file
--`unistd.h'.
--
-- - Function: char * getcwd (char *BUFFER, size_t SIZE)
-- The `getcwd' function returns an absolute file name representing
-- the current working directory, storing it in the character array
-- BUFFER that you provide. The SIZE argument is how you tell the
-- system the allocation size of BUFFER.
--
-- The GNU library version of this function also permits you to
-- specify a null pointer for the BUFFER argument. Then `getcwd'
-- allocates a buffer automatically, as with `malloc' (*note
-- Unconstrained Allocation::.). If the SIZE is greater than zero,
-- then the buffer is that large; otherwise, the buffer is as large
-- as necessary to hold the result.
--
-- The return value is BUFFER on success and a null pointer on
-- failure. The following `errno' error conditions are defined for
-- this function:
--
-- `EINVAL'
-- The SIZE argument is zero and BUFFER is not a null pointer.
--
-- `ERANGE'
-- The SIZE argument is less than the length of the working
-- directory name. You need to allocate a bigger array and try
-- again.
--
-- `EACCES'
-- Permission to read or search a component of the file name was
-- denied.
--
-- You could implement the behavior of GNU's `getcwd (NULL, 0)' using
--only the standard behavior of `getcwd':
--
-- char *
-- gnu_getcwd ()
-- {
-- int size = 100;
-- char *buffer = (char *) xmalloc (size);
--
-- while (1)
-- {
-- char *value = getcwd (buffer, size);
-- if (value != 0)
-- return buffer;
-- size *= 2;
-- free (buffer);
-- buffer = (char *) xmalloc (size);
-- }
-- }
--
--*Note Malloc Examples::, for information about `xmalloc', which is not
--a library function but is a customary name used in most GNU software.
--
-- - Function: char * getwd (char *BUFFER)
-- This is similar to `getcwd', but has no way to specify the size of
-- the buffer. The GNU library provides `getwd' only for backwards
-- compatibility with BSD.
--
-- The BUFFER argument should be a pointer to an array at least
-- `PATH_MAX' bytes long (*note Limits for Files::.). In the GNU
-- system there is no limit to the size of a file name, so this is not
-- necessarily enough space to contain the directory name. That is
-- why this function is deprecated.
--
-- - Function: int chdir (const char *FILENAME)
-- This function is used to set the process's working directory to
-- FILENAME.
--
-- The normal, successful return value from `chdir' is `0'. A value
-- of `-1' is returned to indicate an error. The `errno' error
-- conditions defined for this function are the usual file name
-- syntax errors (*note File Name Errors::.), plus `ENOTDIR' if the
-- file FILENAME is not a directory.
--
--
--File: libc.info, Node: Accessing Directories, Next: Working on Directory Trees, Prev: Working Directory, Up: File System Interface
--
--Accessing Directories
--=====================
--
-- The facilities described in this section let you read the contents
--of a directory file. This is useful if you want your program to list
--all the files in a directory, perhaps as part of a menu.
--
-- The `opendir' function opens a "directory stream" whose elements are
--directory entries. You use the `readdir' function on the directory
--stream to retrieve these entries, represented as `struct dirent'
--objects. The name of the file for each entry is stored in the `d_name'
--member of this structure. There are obvious parallels here to the
--stream facilities for ordinary files, described in *Note I/O on
--Streams::.
--
--* Menu:
--
--* Directory Entries:: Format of one directory entry.
--* Opening a Directory:: How to open a directory stream.
--* Reading/Closing Directory:: How to read directory entries from the stream.
--* Simple Directory Lister:: A very simple directory listing program.
--* Random Access Directory:: Rereading part of the directory
-- already read with the same stream.
--* Scanning Directory Content:: Get entries for user selected subset of
-- contents in given directory.
--* Simple Directory Lister Mark II:: Revised version of the program.
--
--
--File: libc.info, Node: Directory Entries, Next: Opening a Directory, Up: Accessing Directories
--
--Format of a Directory Entry
-----------------------------
--
-- This section describes what you find in a single directory entry, as
--you might obtain it from a directory stream. All the symbols are
--declared in the header file `dirent.h'.
--
-- - Data Type: struct dirent
-- This is a structure type used to return information about directory
-- entries. It contains the following fields:
--
-- `char d_name[]'
-- This is the null-terminated file name component. This is the
-- only field you can count on in all POSIX systems.
--
-- `ino_t d_fileno'
-- This is the file serial number. For BSD compatibility, you
-- can also refer to this member as `d_ino'. In the GNU system
-- and most POSIX systems, for most files this the same as the
-- `st_ino' member that `stat' will return for the file. *Note
-- File Attributes::.
--
-- `unsigned char d_namlen'
-- This is the length of the file name, not including the
-- terminating null character. Its type is `unsigned char'
-- because that is the integer type of the appropriate size
--
-- `unsigned char d_type'
-- This is the type of the file, possibly unknown. The
-- following constants are defined for its value:
--
-- `DT_UNKNOWN'
-- The type is unknown. On some systems this is the only
-- value returned.
--
-- `DT_REG'
-- A regular file.
--
-- `DT_DIR'
-- A directory.
--
-- `DT_FIFO'
-- A named pipe, or FIFO. *Note FIFO Special Files::.
--
-- `DT_SOCK'
-- A local-domain socket.
--
-- `DT_CHR'
-- A character device.
--
-- `DT_BLK'
-- A block device.
--
-- This member is a BSD extension. On systems where it is used,
-- it corresponds to the file type bits in the `st_mode' member
-- of `struct statbuf'. On other systems it will always be
-- DT_UNKNOWN. These two macros convert between `d_type' values
-- and `st_mode' values:
--
-- - Function: int IFTODT (mode_t MODE)
-- This returns the `d_type' value corresponding to MODE.
--
-- - Function: mode_t DTTOIF (int DTYPE)
-- This returns the `st_mode' value corresponding to DTYPE.
--
-- This structure may contain additional members in the future.
--
-- When a file has multiple names, each name has its own directory
-- entry. The only way you can tell that the directory entries
-- belong to a single file is that they have the same value for the
-- `d_fileno' field.
--
-- File attributes such as size, modification times, and the like are
-- part of the file itself, not any particular directory entry.
-- *Note File Attributes::.
--
--
--File: libc.info, Node: Opening a Directory, Next: Reading/Closing Directory, Prev: Directory Entries, Up: Accessing Directories
--
--Opening a Directory Stream
----------------------------
--
-- This section describes how to open a directory stream. All the
--symbols are declared in the header file `dirent.h'.
--
-- - Data Type: DIR
-- The `DIR' data type represents a directory stream.
--
-- You shouldn't ever allocate objects of the `struct dirent' or `DIR'
--data types, since the directory access functions do that for you.
--Instead, you refer to these objects using the pointers returned by the
--following functions.
--
-- - Function: DIR * opendir (const char *DIRNAME)
-- The `opendir' function opens and returns a directory stream for
-- reading the directory whose file name is DIRNAME. The stream has
-- type `DIR *'.
--
-- If unsuccessful, `opendir' returns a null pointer. In addition to
-- the usual file name errors (*note File Name Errors::.), the
-- following `errno' error conditions are defined for this function:
--
-- `EACCES'
-- Read permission is denied for the directory named by
-- `dirname'.
--
-- `EMFILE'
-- The process has too many files open.
--
-- `ENFILE'
-- The entire system, or perhaps the file system which contains
-- the directory, cannot support any additional open files at
-- the moment. (This problem cannot happen on the GNU system.)
--
-- The `DIR' type is typically implemented using a file descriptor,
-- and the `opendir' function in terms of the `open' function. *Note
-- Low-Level I/O::. Directory streams and the underlying file
-- descriptors are closed on `exec' (*note Executing a File::.).
--
--
--File: libc.info, Node: Reading/Closing Directory, Next: Simple Directory Lister, Prev: Opening a Directory, Up: Accessing Directories
--
--Reading and Closing a Directory Stream
----------------------------------------
--
-- This section describes how to read directory entries from a directory
--stream, and how to close the stream when you are done with it. All the
--symbols are declared in the header file `dirent.h'.
--
-- - Function: struct dirent * readdir (DIR *DIRSTREAM)
-- This function reads the next entry from the directory. It normally
-- returns a pointer to a structure containing information about the
-- file. This structure is statically allocated and can be rewritten
-- by a subsequent call.
--
-- *Portability Note:* On some systems, `readdir' may not return
-- entries for `.' and `..', even though these are always valid file
-- names in any directory. *Note File Name Resolution::.
--
-- If there are no more entries in the directory or an error is
-- detected, `readdir' returns a null pointer. The following `errno'
-- error conditions are defined for this function:
--
-- `EBADF'
-- The DIRSTREAM argument is not valid.
--
-- `readdir' is not thread safe. Multiple threads using `readdir' on
-- the same DIRSTREAM may overwrite the return value. Use
-- `readdir_r' when this is critical.
--
-- - Function: int readdir_r (DIR *DIRSTREAM, struct dirent *ENTRY,
-- struct dirent **RESULT)
-- This function is the reentrant version of `readdir'. Like
-- `readdir' it returns the next entry from the directory. But to
-- prevent conflicts for simultaneously running threads the result is
-- not stored in some internal memory. Instead the argument ENTRY
-- has to point to a place where the result is stored.
--
-- The return value is `0' in case the next entry was read
-- successfully. In this case a pointer to the result is returned in
-- *RESULT. It is not required that *RESULT is the same as ENTRY.
-- If something goes wrong while executing `readdir_r' the function
-- returns a value indicating the error (as described for `readdir').
--
-- If there are no more directory entries, `readdir_r''s return value
-- is `0', and *RESULT is set to `NULL'.
--
-- *Portability Note:* On some systems, `readdir_r' may not return a
-- terminated string as the file name even if no `d_reclen' element
-- is available in `struct dirent' and the file name as the maximal
-- allowed size. Modern systems all have the `d_reclen' field and on
-- old systems multi threading is not critical. In any case, there
-- is no such problem with the `readdir' function so that even on
-- systems without `d_reclen' field one could use multiple threads by
-- using external locking.
--
-- - Function: int closedir (DIR *DIRSTREAM)
-- This function closes the directory stream DIRSTREAM. It returns
-- `0' on success and `-1' on failure.
--
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EBADF'
-- The DIRSTREAM argument is not valid.
--
--
--File: libc.info, Node: Simple Directory Lister, Next: Random Access Directory, Prev: Reading/Closing Directory, Up: Accessing Directories
--
--Simple Program to List a Directory
------------------------------------
--
-- Here's a simple program that prints the names of the files in the
--current working directory:
--
-- #include <stddef.h>
-- #include <stdio.h>
-- #include <sys/types.h>
-- #include <dirent.h>
--
-- int
-- main (void)
-- {
-- DIR *dp;
-- struct dirent *ep;
--
-- dp = opendir ("./");
-- if (dp != NULL)
-- {
-- while (ep = readdir (dp))
-- puts (ep->d_name);
-- (void) closedir (dp);
-- }
-- else
-- puts ("Couldn't open the directory.");
--
-- return 0;
-- }
--
-- The order in which files appear in a directory tends to be fairly
--random. A more useful program would sort the entries (perhaps by
--alphabetizing them) before printing them; see *Note Scanning Directory
--Content::, and *Note Array Sort Function::.
--
--
--File: libc.info, Node: Random Access Directory, Next: Scanning Directory Content, Prev: Simple Directory Lister, Up: Accessing Directories
--
--Random Access in a Directory Stream
-------------------------------------
--
-- This section describes how to reread parts of a directory that you
--have already read from an open directory stream. All the symbols are
--declared in the header file `dirent.h'.
--
-- - Function: void rewinddir (DIR *DIRSTREAM)
-- The `rewinddir' function is used to reinitialize the directory
-- stream DIRSTREAM, so that if you call `readdir' it returns
-- information about the first entry in the directory again. This
-- function also notices if files have been added or removed to the
-- directory since it was opened with `opendir'. (Entries for these
-- files might or might not be returned by `readdir' if they were
-- added or removed since you last called `opendir' or `rewinddir'.)
--
-- - Function: off_t telldir (DIR *DIRSTREAM)
-- The `telldir' function returns the file position of the directory
-- stream DIRSTREAM. You can use this value with `seekdir' to
-- restore the directory stream to that position.
--
-- - Function: void seekdir (DIR *DIRSTREAM, off_t POS)
-- The `seekdir' function sets the file position of the directory
-- stream DIRSTREAM to POS. The value POS must be the result of a
-- previous call to `telldir' on this particular stream; closing and
-- reopening the directory can invalidate values returned by
-- `telldir'.
--
--
--File: libc.info, Node: Scanning Directory Content, Next: Simple Directory Lister Mark II, Prev: Random Access Directory, Up: Accessing Directories
--
--Scanning the Content of a Directory
-------------------------------------
--
-- A higher-level interface to the directory handling functions is the
--`scandir' function. With its help one can select a subset of the
--entries in a directory, possibly sort them and get as the result a list
--of names.
--
-- - Function: int scandir (const char *DIR, struct dirent ***NAMELIST,
-- int (*SELECTOR) (const struct dirent *), int (*CMP) (const
-- void *, const void *))
-- The `scandir' function scans the contents of the directory selected
-- by DIR. The result in NAMELIST is an array of pointers to
-- structure of type `struct dirent' which describe all selected
-- directory entries and which is allocated using `malloc'. Instead
-- of always getting all directory entries returned, the user supplied
-- function SELECTOR can be used to decide which entries are in the
-- result. Only the entries for which SELECTOR returns a nonzero
-- value are selected.
--
-- Finally the entries in the NAMELIST are sorted using the user
-- supplied function CMP. The arguments of the CMP function are of
-- type `struct dirent **'. I.e., one cannot directly use the
-- `strcmp' or `strcoll' function; see the functions `alphasort' and
-- `versionsort' below.
--
-- The return value of the function gives the number of entries
-- placed in NAMELIST. If it is `-1' an error occurred (either the
-- directory could not be opened for reading or the malloc call
-- failed) and the global variable `errno' contains more information
-- on the error.
--
-- As said above the fourth argument to the `scandir' function must be
--a pointer to a sorting function. For the convenience of the programmer
--the GNU C library contains implementations of functions which are very
--helpful for this purpose.
--
-- - Function: int alphasort (const void *A, const void *B)
-- The `alphasort' function behaves like the `strcoll' function
-- (*note String/Array Comparison::.). The difference is that the
-- arguments are not string pointers but instead they are of type
-- `struct dirent **'.
--
-- Return value of `alphasort' is less than, equal to, or greater than
-- zero depending on the order of the two entries A and B.
--
-- - Function: int versionsort (const void *A, const void *B)
-- The `versionsort' function is like `alphasort', excepted that it
-- uses the `strverscmp' function internally.
--
-- If the filesystem supports large files we cannot use the `scandir'
--anymore since the `dirent' structure might not able to contain all the
--information. The LFS provides the new type `struct dirent64'. To use
--this we need a new function.
--
-- - Function: int scandir64 (const char *DIR, struct dirent64
-- ***NAMELIST, int (*SELECTOR) (const struct dirent64 *), int
-- (*CMP) (const void *, const void *))
-- The `scandir64' function works like the `scandir' function only
-- that the directory entries it returns are described by elements of
-- type `struct dirent64'. The function pointed to by SELECTOR is
-- again used to select the wanted entries only that SELECTOR now
-- must point to a function which takes a `struct dirent64 *'
-- parameter.
--
-- The CMP now must be a function which expects its two arguments to
-- be of type `struct dirent64 **'.
--
-- As just said the function expected as the fourth is different from
--the function expected in `scandir'. Therefore we cannot use the
--`alphasort' and `versionsort' functions anymore. Instead we have two
--similar functions available.
--
-- - Function: int alphasort64 (const void *A, const void *B)
-- The `alphasort64' function behaves like the `strcoll' function
-- (*note String/Array Comparison::.). The difference is that the
-- arguments are not string pointers but instead they are of type
-- `struct dirent64 **'.
--
-- Return value of `alphasort64' is less than, equal to, or greater
-- than zero depending on the order of the two entries A and B.
--
-- - Function: int versionsort64 (const void *A, const void *B)
-- The `versionsort64' function is like `alphasort64', excepted that
-- it uses the `strverscmp' function internally.
--
-- It is important not to mix the use of `scandir' and the 64 bits
--comparison functions or vice versa. There are systems on which this
--works but on others it will fail miserably.
--
--
--File: libc.info, Node: Simple Directory Lister Mark II, Prev: Scanning Directory Content, Up: Accessing Directories
--
--Simple Program to List a Directory, Mark II
---------------------------------------------
--
-- Here is a revised version of the directory lister found above (*note
--Simple Directory Lister::.). Using the `scandir' function we can avoid
--using the functions which directly work with the directory contents.
--After the call the found entries are available for direct used.
--
-- #include <stdio.h>
-- #include <dirent.h>
--
-- static int
-- one (struct dirent *unused)
-- {
-- return 1;
-- }
--
-- int
-- main (void)
-- {
-- struct dirent **eps;
-- int n;
--
-- n = scandir ("./", &eps, one, alphasort);
-- if (n >= 0)
-- {
-- int cnt;
-- for (cnt = 0; cnt < n; ++cnt)
-- puts (eps[cnt]->d_name);
-- }
-- else
-- perror ("Couldn't open the directory");
--
-- return 0;
-- }
--
-- Please note the simple selector function for this example. Since we
--want to see all directory entries we always return `1'.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-21 glibc-2.1.3/manual/libc.info-21
---- ../glibc-2.1.3/manual/libc.info-21 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-21 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1198 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Working on Directory Trees, Next: Hard Links, Prev: Accessing Directories, Up: File System Interface
--
--Working on Directory Trees
--==========================
--
-- The functions to handle files in directories described so far
--allowed to retrieve all the information in small pieces or process all
--files in a directory (see `scandir'). Sometimes it is useful to
--process whole hierarchies of directories and the contained files. The
--X/Open specification define two functions to do this. The simpler form
--is derived from an early definition in System V systems and therefore
--this function is available on SVID derived systems. The prototypes and
--required definitions can be found in the `ftw.h' header.
--
-- Both functions of this `ftw' family take as one of the arguments a
--reference to a callback function. The functions must be of these types.
--
-- - Data Type: __ftw_func_t
-- int (*) (const char *, const struct stat *, int)
--
-- Type for callback functions given to the `ftw' function. The first
-- parameter will contain a pointer to the filename, the second
-- parameter will point to an object of type `struct stat' which will
-- be filled for the file named by the first parameter.
--
-- The last parameter is a flag given more information about the
-- current file. It can have the following values:
--
-- `FTW_F'
-- The current item is a normal file or files which do not fit
-- into one of the following categories. This means especially
-- special files, sockets etc.
--
-- `FTW_D'
-- The current item is a directory.
--
-- `FTW_NS'
-- The `stat' call to fill the object pointed to by the second
-- parameter failed and so the information is invalid.
--
-- `FTW_DNR'
-- The item is a directory which cannot be read.
--
-- `FTW_SL'
-- The item is a symbolic link. Since symbolic links are
-- normally followed seeing this value in a `ftw' callback
-- function means the referenced file does not exist. The
-- situation for `nftw' is different.
--
-- This value is only available if the program is compiled with
-- `_BSD_SOURCE' or `_XOPEN_EXTENDED' defined before including
-- the first header. The original SVID systems do not have
-- symbolic links.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- type is in fact `__ftw64_func_t' since this mode also changes
-- `struct stat' to be `struct stat64'.
--
-- For the LFS interface and the use in the function `ftw64' the header
--`ftw.h' defines another function type.
--
-- - Data Type: __ftw64_func_t
-- int (*) (const char *, const struct stat64 *, int)
--
-- This type is used just like `__ftw_func_t' for the callback
-- function, but this time called from `ftw64'. The second parameter
-- to the function is this time a pointer to a variable of type
-- `struct stat64' which is able to represent the larger values.
--
-- - Data Type: __nftw_func_t
-- int (*) (const char *, const struct stat *, int, struct FTW *)
--
-- The first three arguments have the same as for the `__ftw_func_t'
-- type. A difference is that for the third argument some additional
-- values are defined to allow finer differentiation:
-- `FTW_DP'
-- The current item is a directory and all subdirectories have
-- already been visited and reported. This flag is returned
-- instead of `FTW_D' if the `FTW_DEPTH' flag is given to `nftw'
-- (see below).
--
-- `FTW_SLN'
-- The current item is a stale symbolic link. The file it
-- points to does not exist.
--
-- The last parameter of the callback function is a pointer to a
-- structure with some extra information as described below.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- type is in fact `__nftw64_func_t' since this mode also changes
-- `struct stat' to be `struct stat64'.
--
-- For the LFS interface there is also a variant of this data type
--available which has to be used with the `nftw64' function.
--
-- - Data Type: __nftw64_func_t
-- int (*) (const char *, const struct stat64 *, int, struct FTW *)
--
-- This type is used just like `__nftw_func_t' for the callback
-- function, but this time called from `nftw64'. The second parameter
-- to the function is this time a pointer to a variable of type
-- `struct stat64' which is able to represent the larger values.
--
-- - Data Type: struct FTW
-- The contained information helps to interpret the name parameter and
-- gives some information about current state of the traversal of the
-- directory hierarchy.
--
-- `int base'
-- The value specifies which part of the filename argument given
-- in the first parameter to the callback function is the name
-- of the file. The rest of the string is the path to locate
-- the file. This information is especially important if the
-- `FTW_CHDIR' flag for `nftw' was set since then the current
-- directory is the one the current item is found in.
--
-- `int level'
-- While processing the directory the functions tracks how many
-- directories have been examine to find the current item. This
-- nesting level is 0 for the item given starting item (file or
-- directory) and is incremented by one for each entered
-- directory.
--
-- - Function: int ftw (const char *FILENAME, __ftw_func_t FUNC, int
-- DESCRIPTORS)
-- The `ftw' function calls the callback function given in the
-- parameter FUNC for every item which is found in the directory
-- specified by FILENAME and all directories below. The function
-- follows symbolic links if necessary but does not process an item
-- twice. If FILENAME names no directory this item is the only object
-- reported by calling the callback function.
--
-- The filename given to the callback function is constructed by
-- taking the FILENAME parameter and appending the names of all passed
-- directories and then the local file name. So the callback
-- function can use this parameter to access the file. Before the
-- callback function is called `ftw' calls `stat' for this file and
-- passes the information up to the callback function. If this
-- `stat' call was not successful the failure is indicated by setting
-- the falg argument of the callback function to `FTW_NS'. Otherwise
-- the flag is set according to the description given in the
-- description of `__ftw_func_t' above.
--
-- The callback function is expected to return 0 to indicate that no
-- error occurred and the processing should be continued. If an error
-- occurred in the callback function or the call to `ftw' shall return
-- immediately the callback function can return a value other than 0.
-- This is the only correct way to stop the function. The program
-- must not use `setjmp' or similar techniques to continue the
-- program in another place. This would leave the resources
-- allocated in the `ftw' function allocated.
--
-- The DESCRIPTORS parameter to the `ftw' function specifies how many
-- file descriptors the `ftw' function is allowed to consume. The
-- more descriptors can be used the faster the function can run. For
-- each level of directories at most one descriptor is used so that
-- for very deep directory hierarchies the limit on open file
-- descriptors for the process or the system can be exceeded. Beside
-- this the limit on file descriptors is counted together for all
-- threads in a multi-threaded program and therefore it is always
-- good too limit the maximal number of open descriptors to a
-- reasonable number.
--
-- The return value of the `ftw' function is 0 if all callback
-- function calls returned 0 and all actions performed by the `ftw'
-- succeeded. If some function call failed (other than calling
-- `stat' on an item) the function return -1. If a callback function
-- returns a value other than 0 this value is returned as the return
-- value of `ftw'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system this function is in fact `ftw64'. I.e., the LFS
-- interface transparently replaces the old interface.
--
-- - Function: int ftw64 (const char *FILENAME, __ftw64_func_t FUNC, int
-- DESCRIPTORS)
-- This function is similar to `ftw' but it can work on filesystems
-- with large files since the information about the files is reported
-- using a variable of type `struct stat64' which is passed by
-- reference to the callback function.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system this function is available under the name `ftw' and
-- transparently replaces the old implementation.
--
-- - Function: int nftw (const char *FILENAME, __nftw_func_t FUNC, int
-- DESCRIPTORS, int FLAG)
-- The `nftw' functions works like the `ftw' functions. It calls the
-- callback function FUNC for all items it finds in the directory
-- FILENAME and below. At most DESCRIPTORS file descriptors are
-- consumed during the `nftw' call.
--
-- The differences are that for one the callback function is of a
-- different type. It is of type `struct FTW *' and provides the
-- callback functions the information described above.
--
-- The second difference is that `nftw' takes an additional fourth
-- argument which is 0 or a combination of any of the following
-- values, combined using bitwise OR.
--
-- `FTW_PHYS'
-- While traversing the directory symbolic links are not
-- followed. I.e., if this flag is given symbolic links are
-- reported using the `FTW_SL' value for the type parameter to
-- the callback function. Please note that if this flag is used
-- the appearance of `FTW_SL' in a callback function does not
-- mean the referenced file does not exist. To indicate this
-- the extra value `FTW_SLN' exists.
--
-- `FTW_MOUNT'
-- The callback function is only called for items which are on
-- the same mounted filesystem as the directory given as the
-- FILENAME parameter to `nftw'.
--
-- `FTW_CHDIR'
-- If this flag is given the current working directory is
-- changed to the directory containing the reported object
-- before the callback function is called.
--
-- `FTW_DEPTH'
-- If this option is given the function visits first all files
-- and subdirectories before the callback function is called for
-- the directory itself (depth-first processing). This also
-- means the type flag given to the callback function is
-- `FTW_DP' and not `FTW_D'.
--
-- The return value is computed in the same way as for `ftw'. `nftw'
-- return 0 if no failure occurred in `nftw' and all callback
-- function call return values are also 0. For internal errors such
-- as memory problems -1 is returned and ERRNO is set accordingly.
-- If the return value of a callback invocation is nonzero this very
-- same value is returned.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system this function is in fact `nftw64'. I.e., the LFS
-- interface transparently replaces the old interface.
--
-- - Function: int nftw64 (const char *FILENAME, __nftw64_func_t FUNC,
-- int DESCRIPTORS, int FLAG)
-- This function is similar to `nftw' but it can work on filesystems
-- with large files since the information about the files is reported
-- using a variable of type `struct stat64' which is passed by
-- reference to the callback function.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system this function is available under the name `nftw' and
-- transparently replaces the old implementation.
--
--
--File: libc.info, Node: Hard Links, Next: Symbolic Links, Prev: Working on Directory Trees, Up: File System Interface
--
--Hard Links
--==========
--
-- In POSIX systems, one file can have many names at the same time.
--All of the names are equally real, and no one of them is preferred to
--the others.
--
-- To add a name to a file, use the `link' function. (The new name is
--also called a "hard link" to the file.) Creating a new link to a file
--does not copy the contents of the file; it simply makes a new name by
--which the file can be known, in addition to the file's existing name or
--names.
--
-- One file can have names in several directories, so the organization
--of the file system is not a strict hierarchy or tree.
--
-- In most implementations, it is not possible to have hard links to the
--same file in multiple file systems. `link' reports an error if you try
--to make a hard link to the file from another file system when this
--cannot be done.
--
-- The prototype for the `link' function is declared in the header file
--`unistd.h'.
--
-- - Function: int link (const char *OLDNAME, const char *NEWNAME)
-- The `link' function makes a new link to the existing file named by
-- OLDNAME, under the new name NEWNAME.
--
-- This function returns a value of `0' if it is successful and `-1'
-- on failure. In addition to the usual file name errors (*note File
-- Name Errors::.) for both OLDNAME and NEWNAME, the following
-- `errno' error conditions are defined for this function:
--
-- `EACCES'
-- You are not allowed to write the directory in which the new
-- link is to be written.
--
-- `EEXIST'
-- There is already a file named NEWNAME. If you want to replace
-- this link with a new link, you must remove the old link
-- explicitly first.
--
-- `EMLINK'
-- There are already too many links to the file named by OLDNAME.
-- (The maximum number of links to a file is `LINK_MAX'; see
-- *Note Limits for Files::.)
--
-- `ENOENT'
-- The file named by OLDNAME doesn't exist. You can't make a
-- link to a file that doesn't exist.
--
-- `ENOSPC'
-- The directory or file system that would contain the new link
-- is full and cannot be extended.
--
-- `EPERM'
-- In the GNU system and some others, you cannot make links to
-- directories. Many systems allow only privileged users to do
-- so. This error is used to report the problem.
--
-- `EROFS'
-- The directory containing the new link can't be modified
-- because it's on a read-only file system.
--
-- `EXDEV'
-- The directory specified in NEWNAME is on a different file
-- system than the existing file.
--
-- `EIO'
-- A hardware error occurred while trying to read or write the
-- to filesystem.
--
--
--File: libc.info, Node: Symbolic Links, Next: Deleting Files, Prev: Hard Links, Up: File System Interface
--
--Symbolic Links
--==============
--
-- The GNU system supports "soft links" or "symbolic links". This is a
--kind of "file" that is essentially a pointer to another file name.
--Unlike hard links, symbolic links can be made to directories or across
--file systems with no restrictions. You can also make a symbolic link
--to a name which is not the name of any file. (Opening this link will
--fail until a file by that name is created.) Likewise, if the symbolic
--link points to an existing file which is later deleted, the symbolic
--link continues to point to the same file name even though the name no
--longer names any file.
--
-- The reason symbolic links work the way they do is that special things
--happen when you try to open the link. The `open' function realizes you
--have specified the name of a link, reads the file name contained in the
--link, and opens that file name instead. The `stat' function likewise
--operates on the file that the symbolic link points to, instead of on
--the link itself.
--
-- By contrast, other operations such as deleting or renaming the file
--operate on the link itself. The functions `readlink' and `lstat' also
--refrain from following symbolic links, because their purpose is to
--obtain information about the link. So does `link', the function that
--makes a hard link--it makes a hard link to the symbolic link, which one
--rarely wants.
--
-- Prototypes for the functions listed in this section are in
--`unistd.h'.
--
-- - Function: int symlink (const char *OLDNAME, const char *NEWNAME)
-- The `symlink' function makes a symbolic link to OLDNAME named
-- NEWNAME.
--
-- The normal return value from `symlink' is `0'. A return value of
-- `-1' indicates an error. In addition to the usual file name
-- syntax errors (*note File Name Errors::.), the following `errno'
-- error conditions are defined for this function:
--
-- `EEXIST'
-- There is already an existing file named NEWNAME.
--
-- `EROFS'
-- The file NEWNAME would exist on a read-only file system.
--
-- `ENOSPC'
-- The directory or file system cannot be extended to make the
-- new link.
--
-- `EIO'
-- A hardware error occurred while reading or writing data on
-- the disk.
--
--
-- - Function: int readlink (const char *FILENAME, char *BUFFER, size_t
-- SIZE)
-- The `readlink' function gets the value of the symbolic link
-- FILENAME. The file name that the link points to is copied into
-- BUFFER. This file name string is *not* null-terminated;
-- `readlink' normally returns the number of characters copied. The
-- SIZE argument specifies the maximum number of characters to copy,
-- usually the allocation size of BUFFER.
--
-- If the return value equals SIZE, you cannot tell whether or not
-- there was room to return the entire name. So make a bigger buffer
-- and call `readlink' again. Here is an example:
--
-- char *
-- readlink_malloc (char *filename)
-- {
-- int size = 100;
--
-- while (1)
-- {
-- char *buffer = (char *) xmalloc (size);
-- int nchars = readlink (filename, buffer, size);
-- if (nchars < size)
-- return buffer;
-- free (buffer);
-- size *= 2;
-- }
-- }
--
-- A value of `-1' is returned in case of error. In addition to the
-- usual file name errors (*note File Name Errors::.), the following
-- `errno' error conditions are defined for this function:
--
-- `EINVAL'
-- The named file is not a symbolic link.
--
-- `EIO'
-- A hardware error occurred while reading or writing data on
-- the disk.
--
--
--File: libc.info, Node: Deleting Files, Next: Renaming Files, Prev: Symbolic Links, Up: File System Interface
--
--Deleting Files
--==============
--
-- You can delete a file with the functions `unlink' or `remove'.
--
-- Deletion actually deletes a file name. If this is the file's only
--name, then the file is deleted as well. If the file has other names as
--well (*note Hard Links::.), it remains accessible under its other names.
--
-- - Function: int unlink (const char *FILENAME)
-- The `unlink' function deletes the file name FILENAME. If this is
-- a file's sole name, the file itself is also deleted. (Actually,
-- if any process has the file open when this happens, deletion is
-- postponed until all processes have closed the file.)
--
-- The function `unlink' is declared in the header file `unistd.h'.
--
-- This function returns `0' on successful completion, and `-1' on
-- error. In addition to the usual file name errors (*note File Name
-- Errors::.), the following `errno' error conditions are defined for
-- this function:
--
-- `EACCES'
-- Write permission is denied for the directory from which the
-- file is to be removed, or the directory has the sticky bit
-- set and you do not own the file.
--
-- `EBUSY'
-- This error indicates that the file is being used by the
-- system in such a way that it can't be unlinked. For example,
-- you might see this error if the file name specifies the root
-- directory or a mount point for a file system.
--
-- `ENOENT'
-- The file name to be deleted doesn't exist.
--
-- `EPERM'
-- On some systems, `unlink' cannot be used to delete the name
-- of a directory, or can only be used this way by a privileged
-- user. To avoid such problems, use `rmdir' to delete
-- directories. (In the GNU system `unlink' can never delete
-- the name of a directory.)
--
-- `EROFS'
-- The directory in which the file name is to be deleted is on a
-- read-only file system, and can't be modified.
--
-- - Function: int rmdir (const char *FILENAME)
-- The `rmdir' function deletes a directory. The directory must be
-- empty before it can be removed; in other words, it can only contain
-- entries for `.' and `..'.
--
-- In most other respects, `rmdir' behaves like `unlink'. There are
-- two additional `errno' error conditions defined for `rmdir':
--
-- `ENOTEMPTY'
-- `EEXIST'
-- The directory to be deleted is not empty.
--
-- These two error codes are synonymous; some systems use one, and
-- some use the other. The GNU system always uses `ENOTEMPTY'.
--
-- The prototype for this function is declared in the header file
-- `unistd.h'.
--
-- - Function: int remove (const char *FILENAME)
-- This is the ISO C function to remove a file. It works like
-- `unlink' for files and like `rmdir' for directories. `remove' is
-- declared in `stdio.h'.
--
--
--File: libc.info, Node: Renaming Files, Next: Creating Directories, Prev: Deleting Files, Up: File System Interface
--
--Renaming Files
--==============
--
-- The `rename' function is used to change a file's name.
--
-- - Function: int rename (const char *OLDNAME, const char *NEWNAME)
-- The `rename' function renames the file name OLDNAME with NEWNAME.
-- The file formerly accessible under the name OLDNAME is afterward
-- accessible as NEWNAME instead. (If the file had any other names
-- aside from OLDNAME, it continues to have those names.)
--
-- The directory containing the name NEWNAME must be on the same file
-- system as the file (as indicated by the name OLDNAME).
--
-- One special case for `rename' is when OLDNAME and NEWNAME are two
-- names for the same file. The consistent way to handle this case
-- is to delete OLDNAME. However, POSIX requires that in this case
-- `rename' do nothing and report success--which is inconsistent. We
-- don't know what your operating system will do.
--
-- If the OLDNAME is not a directory, then any existing file named
-- NEWNAME is removed during the renaming operation. However, if
-- NEWNAME is the name of a directory, `rename' fails in this case.
--
-- If the OLDNAME is a directory, then either NEWNAME must not exist
-- or it must name a directory that is empty. In the latter case,
-- the existing directory named NEWNAME is deleted first. The name
-- NEWNAME must not specify a subdirectory of the directory `oldname'
-- which is being renamed.
--
-- One useful feature of `rename' is that the meaning of the name
-- NEWNAME changes "atomically" from any previously existing file by
-- that name to its new meaning (the file that was called OLDNAME).
-- There is no instant at which NEWNAME is nonexistent "in between"
-- the old meaning and the new meaning. If there is a system crash
-- during the operation, it is possible for both names to still
-- exist; but NEWNAME will always be intact if it exists at all.
--
-- If `rename' fails, it returns `-1'. In addition to the usual file
-- name errors (*note File Name Errors::.), the following `errno'
-- error conditions are defined for this function:
--
-- `EACCES'
-- One of the directories containing NEWNAME or OLDNAME refuses
-- write permission; or NEWNAME and OLDNAME are directories and
-- write permission is refused for one of them.
--
-- `EBUSY'
-- A directory named by OLDNAME or NEWNAME is being used by the
-- system in a way that prevents the renaming from working.
-- This includes directories that are mount points for
-- filesystems, and directories that are the current working
-- directories of processes.
--
-- `ENOTEMPTY'
-- `EEXIST'
-- The directory NEWNAME isn't empty. The GNU system always
-- returns `ENOTEMPTY' for this, but some other systems return
-- `EEXIST'.
--
-- `EINVAL'
-- The OLDNAME is a directory that contains NEWNAME.
--
-- `EISDIR'
-- The NEWNAME names a directory, but the OLDNAME doesn't.
--
-- `EMLINK'
-- The parent directory of NEWNAME would have too many links.
--
-- `ENOENT'
-- The file named by OLDNAME doesn't exist.
--
-- `ENOSPC'
-- The directory that would contain NEWNAME has no room for
-- another entry, and there is no space left in the file system
-- to expand it.
--
-- `EROFS'
-- The operation would involve writing to a directory on a
-- read-only file system.
--
-- `EXDEV'
-- The two file names NEWNAME and OLDNAMES are on different file
-- systems.
--
--
--File: libc.info, Node: Creating Directories, Next: File Attributes, Prev: Renaming Files, Up: File System Interface
--
--Creating Directories
--====================
--
-- Directories are created with the `mkdir' function. (There is also a
--shell command `mkdir' which does the same thing.)
--
-- - Function: int mkdir (const char *FILENAME, mode_t MODE)
-- The `mkdir' function creates a new, empty directory whose name is
-- FILENAME.
--
-- The argument MODE specifies the file permissions for the new
-- directory file. *Note Permission Bits::, for more information
-- about this.
--
-- A return value of `0' indicates successful completion, and `-1'
-- indicates failure. In addition to the usual file name syntax
-- errors (*note File Name Errors::.), the following `errno' error
-- conditions are defined for this function:
--
-- `EACCES'
-- Write permission is denied for the parent directory in which
-- the new directory is to be added.
--
-- `EEXIST'
-- A file named FILENAME already exists.
--
-- `EMLINK'
-- The parent directory has too many links.
--
-- Well-designed file systems never report this error, because
-- they permit more links than your disk could possibly hold.
-- However, you must still take account of the possibility of
-- this error, as it could result from network access to a file
-- system on another machine.
--
-- `ENOSPC'
-- The file system doesn't have enough room to create the new
-- directory.
--
-- `EROFS'
-- The parent directory of the directory being created is on a
-- read-only file system, and cannot be modified.
--
-- To use this function, your program should include the header file
-- `sys/stat.h'.
--
--
--File: libc.info, Node: File Attributes, Next: Making Special Files, Prev: Creating Directories, Up: File System Interface
--
--File Attributes
--===============
--
-- When you issue an `ls -l' shell command on a file, it gives you
--information about the size of the file, who owns it, when it was last
--modified, and the like. This kind of information is called the "file
--attributes"; it is associated with the file itself and not a particular
--one of its names.
--
-- This section contains information about how you can inquire about and
--modify these attributes of files.
--
--* Menu:
--
--* Attribute Meanings:: The names of the file attributes,
-- and what their values mean.
--* Reading Attributes:: How to read the attributes of a file.
--* Testing File Type:: Distinguishing ordinary files,
-- directories, links...
--* File Owner:: How ownership for new files is determined,
-- and how to change it.
--* Permission Bits:: How information about a file's access
-- mode is stored.
--* Access Permission:: How the system decides who can access a file.
--* Setting Permissions:: How permissions for new files are assigned,
-- and how to change them.
--* Testing File Access:: How to find out if your process can
-- access a file.
--* File Times:: About the time attributes of a file.
--* File Size:: Manually changing the size of a file.
--
--
--File: libc.info, Node: Attribute Meanings, Next: Reading Attributes, Up: File Attributes
--
--What the File Attribute Values Mean
-------------------------------------
--
-- When you read the attributes of a file, they come back in a structure
--called `struct stat'. This section describes the names of the
--attributes, their data types, and what they mean. For the functions to
--read the attributes of a file, see *Note Reading Attributes::.
--
-- The header file `sys/stat.h' declares all the symbols defined in
--this section.
--
-- - Data Type: struct stat
-- The `stat' structure type is used to return information about the
-- attributes of a file. It contains at least the following members:
--
-- `mode_t st_mode'
-- Specifies the mode of the file. This includes file type
-- information (*note Testing File Type::.) and the file
-- permission bits (*note Permission Bits::.).
--
-- `ino_t st_ino'
-- The file serial number, which distinguishes this file from
-- all other files on the same device.
--
-- `dev_t st_dev'
-- Identifies the device containing the file. The `st_ino' and
-- `st_dev', taken together, uniquely identify the file. The
-- `st_dev' value is not necessarily consistent across reboots or
-- system crashes, however.
--
-- `nlink_t st_nlink'
-- The number of hard links to the file. This count keeps track
-- of how many directories have entries for this file. If the
-- count is ever decremented to zero, then the file itself is
-- discarded as soon as no process still holds it open.
-- Symbolic links are not counted in the total.
--
-- `uid_t st_uid'
-- The user ID of the file's owner. *Note File Owner::.
--
-- `gid_t st_gid'
-- The group ID of the file. *Note File Owner::.
--
-- `off_t st_size'
-- This specifies the size of a regular file in bytes. For
-- files that are really devices and the like, this field isn't
-- usually meaningful. For symbolic links, this specifies the
-- length of the file name the link refers to.
--
-- `time_t st_atime'
-- This is the last access time for the file. *Note File
-- Times::.
--
-- `unsigned long int st_atime_usec'
-- This is the fractional part of the last access time for the
-- file. *Note File Times::.
--
-- `time_t st_mtime'
-- This is the time of the last modification to the contents of
-- the file. *Note File Times::.
--
-- `unsigned long int st_mtime_usec'
-- This is the fractional part of the time of last modification
-- to the contents of the file. *Note File Times::.
--
-- `time_t st_ctime'
-- This is the time of the last modification to the attributes
-- of the file. *Note File Times::.
--
-- `unsigned long int st_ctime_usec'
-- This is the fractional part of the time of last modification
-- to the attributes of the file. *Note File Times::.
--
-- `blkcnt_t st_blocks'
-- This is the amount of disk space that the file occupies,
-- measured in units of 512-byte blocks.
--
-- The number of disk blocks is not strictly proportional to the
-- size of the file, for two reasons: the file system may use
-- some blocks for internal record keeping; and the file may be
-- sparse--it may have "holes" which contain zeros but do not
-- actually take up space on the disk.
--
-- You can tell (approximately) whether a file is sparse by
-- comparing this value with `st_size', like this:
--
-- (st.st_blocks * 512 < st.st_size)
--
-- This test is not perfect because a file that is just slightly
-- sparse might not be detected as sparse at all. For practical
-- applications, this is not a problem.
--
-- `unsigned int st_blksize'
-- The optimal block size for reading of writing this file, in
-- bytes. You might use this size for allocating the buffer
-- space for reading of writing the file. (This is unrelated to
-- `st_blocks'.)
--
-- The extensions for the Large File Support (LFS) require even on 32
--bits machine types which can handle file sizes up to 2^63. Therefore a
--new definition of `struct stat' is necessary.
--
-- - Data Type: struct stat64
-- The members of this type are the same and have the same names as
-- those in `struct stat'. The only difference is that the members
-- `st_ino', `st_size', and `st_blocks' have a different type to
-- support larger values.
--
-- `mode_t st_mode'
-- Specifies the mode of the file. This includes file type
-- information (*note Testing File Type::.) and the file
-- permission bits (*note Permission Bits::.).
--
-- `ino64_t st_ino'
-- The file serial number, which distinguishes this file from
-- all other files on the same device.
--
-- `dev_t st_dev'
-- Identifies the device containing the file. The `st_ino' and
-- `st_dev', taken together, uniquely identify the file. The
-- `st_dev' value is not necessarily consistent across reboots or
-- system crashes, however.
--
-- `nlink_t st_nlink'
-- The number of hard links to the file. This count keeps track
-- of how many directories have entries for this file. If the
-- count is ever decremented to zero, then the file itself is
-- discarded as soon as no process still holds it open.
-- Symbolic links are not counted in the total.
--
-- `uid_t st_uid'
-- The user ID of the file's owner. *Note File Owner::.
--
-- `gid_t st_gid'
-- The group ID of the file. *Note File Owner::.
--
-- `off64_t st_size'
-- This specifies the size of a regular file in bytes. For
-- files that are really devices and the like, this field isn't
-- usually meaningful. For symbolic links, this specifies the
-- length of the file name the link refers to.
--
-- `time_t st_atime'
-- This is the last access time for the file. *Note File
-- Times::.
--
-- `unsigned long int st_atime_usec'
-- This is the fractional part of the last access time for the
-- file. *Note File Times::.
--
-- `time_t st_mtime'
-- This is the time of the last modification to the contents of
-- the file. *Note File Times::.
--
-- `unsigned long int st_mtime_usec'
-- This is the fractional part of the time of last modification
-- to the contents of the file. *Note File Times::.
--
-- `time_t st_ctime'
-- This is the time of the last modification to the attributes
-- of the file. *Note File Times::.
--
-- `unsigned long int st_ctime_usec'
-- This is the fractional part of the time of last modification
-- to the attributes of the file. *Note File Times::.
--
-- `blkcnt64_t st_blocks'
-- This is the amount of disk space that the file occupies,
-- measured in units of 512-byte blocks.
--
-- `unsigned int st_blksize'
-- The optimal block size for reading of writing this file, in
-- bytes. You might use this size for allocating the buffer
-- space for reading of writing the file. (This is unrelated to
-- `st_blocks'.)
--
-- Some of the file attributes have special data type names which exist
--specifically for those attributes. (They are all aliases for well-known
--integer types that you know and love.) These typedef names are defined
--in the header file `sys/types.h' as well as in `sys/stat.h'. Here is a
--list of them.
--
-- - Data Type: mode_t
-- This is an integer data type used to represent file modes. In the
-- GNU system, this is equivalent to `unsigned int'.
--
-- - Data Type: ino_t
-- This is an arithmetic data type used to represent file serial
-- numbers. (In Unix jargon, these are sometimes called "inode
-- numbers".) In the GNU system, this type is equivalent to
-- `unsigned long int'.
--
-- If the source is compiled with `_FILE_OFFSET_BITS == 64' this type
-- is transparently replaced by `ino64_t'.
--
-- - Data Type: ino64_t
-- This is an arithmetic data type used to represent file serial
-- numbers for the use in LFS. In the GNU system, this type is
-- equivalent to `unsigned long longint'.
--
-- When compiling with `_FILE_OFFSET_BITS == 64' this type is
-- available under the name `ino_t'.
--
-- - Data Type: dev_t
-- This is an arithmetic data type used to represent file device
-- numbers. In the GNU system, this is equivalent to `int'.
--
-- - Data Type: nlink_t
-- This is an arithmetic data type used to represent file link counts.
-- In the GNU system, this is equivalent to `unsigned short int'.
--
-- - Data Type: blkcnt_t
-- This is an arithmetic data type used to represent block counts.
-- In the GNU system, this is equivalent to `unsigned long int'.
--
-- If the source is compiled with `_FILE_OFFSET_BITS == 64' this type
-- is transparently replaced by `blkcnt64_t'.
--
-- - Data Type: blkcnt64_t
-- This is an arithmetic data type used to represent block counts for
-- the use in LFS. In the GNU system, this is equivalent to `unsigned
-- long long int'.
--
-- When compiling with `_FILE_OFFSET_BITS == 64' this type is
-- available under the name `blkcnt_t'.
--
--
--File: libc.info, Node: Reading Attributes, Next: Testing File Type, Prev: Attribute Meanings, Up: File Attributes
--
--Reading the Attributes of a File
----------------------------------
--
-- To examine the attributes of files, use the functions `stat',
--`fstat' and `lstat'. They return the attribute information in a
--`struct stat' object. All three functions are declared in the header
--file `sys/stat.h'.
--
-- - Function: int stat (const char *FILENAME, struct stat *BUF)
-- The `stat' function returns information about the attributes of the
-- file named by FILENAME in the structure pointed at by BUF.
--
-- If FILENAME is the name of a symbolic link, the attributes you get
-- describe the file that the link points to. If the link points to a
-- nonexistent file name, then `stat' fails, reporting a nonexistent
-- file.
--
-- The return value is `0' if the operation is successful, and `-1'
-- on failure. In addition to the usual file name errors (*note File
-- Name Errors::., the following `errno' error conditions are defined
-- for this function:
--
-- `ENOENT'
-- The file named by FILENAME doesn't exist.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `stat64' since the LFS interface transparently
-- replaces the normal implementation.
--
-- - Function: int stat64 (const char *FILENAME, struct stat64 *BUF)
-- This function is similar to `stat' but it is also able to work on
-- file larger then 2^31 bytes on 32 bits systems. To be able to do
-- this the result is stored in a variable of type `struct stat64' to
-- which BUF must point.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `stat' and so transparently
-- replaces the interface for small fiels on 32 bits machines.
--
-- - Function: int fstat (int FILEDES, struct stat *BUF)
-- The `fstat' function is like `stat', except that it takes an open
-- file descriptor as an argument instead of a file name. *Note
-- Low-Level I/O::.
--
-- Like `stat', `fstat' returns `0' on success and `-1' on failure.
-- The following `errno' error conditions are defined for `fstat':
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `fstat64' since the LFS interface transparently
-- replaces the normal implementation.
--
-- - Function: int fstat64 (int FILEDES, struct stat64 *BUF)
-- This function is similar to `fstat' but it is prepared to work on
-- large files on 32 bits platforms. For large files the file
-- descriptor FILEDES should be returned by `open64' or `creat64'.
-- The BUF pointer points to a variable of type `struct stat64' which
-- is able to represent the larger values.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `fstat' and so transparently
-- replaces the interface for small fiels on 32 bits machines.
--
-- - Function: int lstat (const char *FILENAME, struct stat *BUF)
-- The `lstat' function is like `stat', except that it does not
-- follow symbolic links. If FILENAME is the name of a symbolic
-- link, `lstat' returns information about the link itself; otherwise,
-- `lstat' works like `stat'. *Note Symbolic Links::.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is in fact `lstat64' since the LFS interface transparently
-- replaces the normal implementation.
--
-- - Function: int lstat64 (const char *FILENAME, struct stat64 *BUF)
-- This function is similar to `lstat' but it is also able to work on
-- file larger then 2^31 bytes on 32 bits systems. To be able to do
-- this the result is stored in a variable of type `struct stat64' to
-- which BUF must point.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' this
-- function is available under the name `lstat' and so transparently
-- replaces the interface for small fiels on 32 bits machines.
--
--
--File: libc.info, Node: Testing File Type, Next: File Owner, Prev: Reading Attributes, Up: File Attributes
--
--Testing the Type of a File
----------------------------
--
-- The "file mode", stored in the `st_mode' field of the file
--attributes, contains two kinds of information: the file type code, and
--the access permission bits. This section discusses only the type code,
--which you can use to tell whether the file is a directory, whether it is
--a socket, and so on. For information about the access permission,
--*Note Permission Bits::.
--
-- There are two predefined ways you can access the file type portion of
--the file mode. First of all, for each type of file, there is a
--"predicate macro" which examines a file mode value and returns true or
--false--is the file of that type, or not. Secondly, you can mask out
--the rest of the file mode to get just a file type code. You can
--compare this against various constants for the supported file types.
--
-- All of the symbols listed in this section are defined in the header
--file `sys/stat.h'.
--
-- The following predicate macros test the type of a file, given the
--value M which is the `st_mode' field returned by `stat' on that file:
--
-- - Macro: int S_ISDIR (mode_t M)
-- This macro returns nonzero if the file is a directory.
--
-- - Macro: int S_ISCHR (mode_t M)
-- This macro returns nonzero if the file is a character special file
-- (a device like a terminal).
--
-- - Macro: int S_ISBLK (mode_t M)
-- This macro returns nonzero if the file is a block special file (a
-- device like a disk).
--
-- - Macro: int S_ISREG (mode_t M)
-- This macro returns nonzero if the file is a regular file.
--
-- - Macro: int S_ISFIFO (mode_t M)
-- This macro returns nonzero if the file is a FIFO special file, or a
-- pipe. *Note Pipes and FIFOs::.
--
-- - Macro: int S_ISLNK (mode_t M)
-- This macro returns nonzero if the file is a symbolic link. *Note
-- Symbolic Links::.
--
-- - Macro: int S_ISSOCK (mode_t M)
-- This macro returns nonzero if the file is a socket. *Note
-- Sockets::.
--
-- An alternate non-POSIX method of testing the file type is supported
--for compatibility with BSD. The mode can be bitwise ANDed with
--`S_IFMT' to extract the file type code, and compared to the appropriate
--type code constant. For example,
--
-- S_ISCHR (MODE)
--
--is equivalent to:
--
-- ((MODE & S_IFMT) == S_IFCHR)
--
-- - Macro: int S_IFMT
-- This is a bit mask used to extract the file type code portion of a
-- mode value.
--
-- These are the symbolic names for the different file type codes:
--
--`S_IFDIR'
-- This macro represents the value of the file type code for a
-- directory file.
--
--`S_IFCHR'
-- This macro represents the value of the file type code for a
-- character-oriented device file.
--
--`S_IFBLK'
-- This macro represents the value of the file type code for a
-- block-oriented device file.
--
--`S_IFREG'
-- This macro represents the value of the file type code for a
-- regular file.
--
--`S_IFLNK'
-- This macro represents the value of the file type code for a
-- symbolic link.
--
--`S_IFSOCK'
-- This macro represents the value of the file type code for a socket.
--
--`S_IFIFO'
-- This macro represents the value of the file type code for a FIFO
-- or pipe.
--
--
--File: libc.info, Node: File Owner, Next: Permission Bits, Prev: Testing File Type, Up: File Attributes
--
--File Owner
------------
--
-- Every file has an "owner" which is one of the registered user names
--defined on the system. Each file also has a "group", which is one of
--the defined groups. The file owner can often be useful for showing you
--who edited the file (especially when you edit with GNU Emacs), but its
--main purpose is for access control.
--
-- The file owner and group play a role in determining access because
--the file has one set of access permission bits for the user that is the
--owner, another set that apply to users who belong to the file's group,
--and a third set of bits that apply to everyone else. *Note Access
--Permission::, for the details of how access is decided based on this
--data.
--
-- When a file is created, its owner is set from the effective user ID
--of the process that creates it (*note Process Persona::.). The file's
--group ID may be set from either effective group ID of the process, or
--the group ID of the directory that contains the file, depending on the
--system where the file is stored. When you access a remote file system,
--it behaves according to its own rule, not according to the system your
--program is running on. Thus, your program must be prepared to encounter
--either kind of behavior, no matter what kind of system you run it on.
--
-- You can change the owner and/or group owner of an existing file using
--the `chown' function. This is the primitive for the `chown' and
--`chgrp' shell commands.
--
-- The prototype for this function is declared in `unistd.h'.
--
-- - Function: int chown (const char *FILENAME, uid_t OWNER, gid_t GROUP)
-- The `chown' function changes the owner of the file FILENAME to
-- OWNER, and its group owner to GROUP.
--
-- Changing the owner of the file on certain systems clears the
-- set-user-ID and set-group-ID bits of the file's permissions.
-- (This is because those bits may not be appropriate for the new
-- owner.) The other file permission bits are not changed.
--
-- The return value is `0' on success and `-1' on failure. In
-- addition to the usual file name errors (*note File Name Errors::.),
-- the following `errno' error conditions are defined for this
-- function:
--
-- `EPERM'
-- This process lacks permission to make the requested change.
--
-- Only privileged users or the file's owner can change the
-- file's group. On most file systems, only privileged users
-- can change the file owner; some file systems allow you to
-- change the owner if you are currently the owner. When you
-- access a remote file system, the behavior you encounter is
-- determined by the system that actually holds the file, not by
-- the system your program is running on.
--
-- *Note Options for Files::, for information about the
-- `_POSIX_CHOWN_RESTRICTED' macro.
--
-- `EROFS'
-- The file is on a read-only file system.
--
-- - Function: int fchown (int FILEDES, int OWNER, int GROUP)
-- This is like `chown', except that it changes the owner of the file
-- with open file descriptor FILEDES.
--
-- The return value from `fchown' is `0' on success and `-1' on
-- failure. The following `errno' error codes are defined for this
-- function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `EINVAL'
-- The FILEDES argument corresponds to a pipe or socket, not an
-- ordinary file.
--
-- `EPERM'
-- This process lacks permission to make the requested change.
-- For details, see `chmod', above.
--
-- `EROFS'
-- The file resides on a read-only file system.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-22 glibc-2.1.3/manual/libc.info-22
---- ../glibc-2.1.3/manual/libc.info-22 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-22 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1259 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Permission Bits, Next: Access Permission, Prev: File Owner, Up: File Attributes
--
--The Mode Bits for Access Permission
-------------------------------------
--
-- The "file mode", stored in the `st_mode' field of the file
--attributes, contains two kinds of information: the file type code, and
--the access permission bits. This section discusses only the access
--permission bits, which control who can read or write the file. *Note
--Testing File Type::, for information about the file type code.
--
-- All of the symbols listed in this section are defined in the header
--file `sys/stat.h'.
--
-- These symbolic constants are defined for the file mode bits that
--control access permission for the file:
--
--`S_IRUSR'
--`S_IREAD'
-- Read permission bit for the owner of the file. On many systems,
-- this bit is 0400. `S_IREAD' is an obsolete synonym provided for
-- BSD compatibility.
--
--`S_IWUSR'
--`S_IWRITE'
-- Write permission bit for the owner of the file. Usually 0200.
-- `S_IWRITE' is an obsolete synonym provided for BSD compatibility.
--
--`S_IXUSR'
--`S_IEXEC'
-- Execute (for ordinary files) or search (for directories)
-- permission bit for the owner of the file. Usually 0100.
-- `S_IEXEC' is an obsolete synonym provided for BSD compatibility.
--
--`S_IRWXU'
-- This is equivalent to `(S_IRUSR | S_IWUSR | S_IXUSR)'.
--
--`S_IRGRP'
-- Read permission bit for the group owner of the file. Usually 040.
--
--`S_IWGRP'
-- Write permission bit for the group owner of the file. Usually 020.
--
--`S_IXGRP'
-- Execute or search permission bit for the group owner of the file.
-- Usually 010.
--
--`S_IRWXG'
-- This is equivalent to `(S_IRGRP | S_IWGRP | S_IXGRP)'.
--
--`S_IROTH'
-- Read permission bit for other users. Usually 04.
--
--`S_IWOTH'
-- Write permission bit for other users. Usually 02.
--
--`S_IXOTH'
-- Execute or search permission bit for other users. Usually 01.
--
--`S_IRWXO'
-- This is equivalent to `(S_IROTH | S_IWOTH | S_IXOTH)'.
--
--`S_ISUID'
-- This is the set-user-ID on execute bit, usually 04000. *Note How
-- Change Persona::.
--
--`S_ISGID'
-- This is the set-group-ID on execute bit, usually 02000. *Note How
-- Change Persona::.
--
--`S_ISVTX'
-- This is the "sticky" bit, usually 01000.
--
-- On a directory, it gives permission to delete a file in the
-- directory only if you own that file. Ordinarily, a user either
-- can delete all the files in the directory or cannot delete any of
-- them (based on whether the user has write permission for the
-- directory). The same restriction applies--you must both have
-- write permission for the directory and own the file you want to
-- delete. The one exception is that the owner of the directory can
-- delete any file in the directory, no matter who owns it (provided
-- the owner has given himself write permission for the directory).
-- This is commonly used for the `/tmp' directory, where anyone may
-- create files, but not delete files created by other users.
--
-- Originally the sticky bit on an executable file modified the
-- swapping policies of the system. Normally, when a program
-- terminated, its pages in core were immediately freed and reused.
-- If the sticky bit was set on the executable file, the system kept
-- the pages in core for a while as if the program were still
-- running. This was advantageous for a program likely to be run
-- many times in succession. This usage is obsolete in modern
-- systems. When a program terminates, its pages always remain in
-- core as long as there is no shortage of memory in the system.
-- When the program is next run, its pages will still be in core if
-- no shortage arose since the last run.
--
-- On some modern systems where the sticky bit has no useful meaning
-- for an executable file, you cannot set the bit at all for a
-- non-directory. If you try, `chmod' fails with `EFTYPE'; *note
-- Setting Permissions::..
--
-- Some systems (particularly SunOS) have yet another use for the
-- sticky bit. If the sticky bit is set on a file that is *not*
-- executable, it means the opposite: never cache the pages of this
-- file at all. The main use of this is for the files on an NFS
-- server machine which are used as the swap area of diskless client
-- machines. The idea is that the pages of the file will be cached
-- in the client's memory, so it is a waste of the server's memory to
-- cache them a second time. In this use the sticky bit also says
-- that the filesystem may fail to record the file's modification
-- time onto disk reliably (the idea being that no-one cares for a
-- swap file).
--
-- This bit is only available on BSD systems (and those derived from
-- them). Therefore one has to use the `_BSD_SOURCE' feature select
-- macro to get the definition (*note Feature Test Macros::.).
--
-- The actual bit values of the symbols are listed in the table above
--so you can decode file mode values when debugging your programs. These
--bit values are correct for most systems, but they are not guaranteed.
--
-- *Warning:* Writing explicit numbers for file permissions is bad
--practice. It is not only non-portable, it also requires everyone who
--reads your program to remember what the bits mean. To make your
--program clean, use the symbolic names.
--
--
--File: libc.info, Node: Access Permission, Next: Setting Permissions, Prev: Permission Bits, Up: File Attributes
--
--How Your Access to a File is Decided
--------------------------------------
--
-- Recall that the operating system normally decides access permission
--for a file based on the effective user and group IDs of the process,
--and its supplementary group IDs, together with the file's owner, group
--and permission bits. These concepts are discussed in detail in *Note
--Process Persona::.
--
-- If the effective user ID of the process matches the owner user ID of
--the file, then permissions for read, write, and execute/search are
--controlled by the corresponding "user" (or "owner") bits. Likewise, if
--any of the effective group ID or supplementary group IDs of the process
--matches the group owner ID of the file, then permissions are controlled
--by the "group" bits. Otherwise, permissions are controlled by the
--"other" bits.
--
-- Privileged users, like `root', can access any file, regardless of
--its file permission bits. As a special case, for a file to be
--executable even for a privileged user, at least one of its execute bits
--must be set.
--
--
--File: libc.info, Node: Setting Permissions, Next: Testing File Access, Prev: Access Permission, Up: File Attributes
--
--Assigning File Permissions
----------------------------
--
-- The primitive functions for creating files (for example, `open' or
--`mkdir') take a MODE argument, which specifies the file permissions for
--the newly created file. But the specified mode is modified by the
--process's "file creation mask", or "umask", before it is used.
--
-- The bits that are set in the file creation mask identify permissions
--that are always to be disabled for newly created files. For example, if
--you set all the "other" access bits in the mask, then newly created
--files are not accessible at all to processes in the "other" category,
--even if the MODE argument specified to the creation function would
--permit such access. In other words, the file creation mask is the
--complement of the ordinary access permissions you want to grant.
--
-- Programs that create files typically specify a MODE argument that
--includes all the permissions that make sense for the particular file.
--For an ordinary file, this is typically read and write permission for
--all classes of users. These permissions are then restricted as
--specified by the individual user's own file creation mask.
--
-- To change the permission of an existing file given its name, call
--`chmod'. This function ignores the file creation mask; it uses exactly
--the specified permission bits.
--
-- In normal use, the file creation mask is initialized in the user's
--login shell (using the `umask' shell command), and inherited by all
--subprocesses. Application programs normally don't need to worry about
--the file creation mask. It will do automatically what it is supposed to
--do.
--
-- When your program should create a file and bypass the umask for its
--access permissions, the easiest way to do this is to use `fchmod' after
--opening the file, rather than changing the umask.
--
-- In fact, changing the umask is usually done only by shells. They use
--the `umask' function.
--
-- The functions in this section are declared in `sys/stat.h'.
--
-- - Function: mode_t umask (mode_t MASK)
-- The `umask' function sets the file creation mask of the current
-- process to MASK, and returns the previous value of the file
-- creation mask.
--
-- Here is an example showing how to read the mask with `umask'
-- without changing it permanently:
--
-- mode_t
-- read_umask (void)
-- {
-- mode_t mask = umask (0);
-- umask (mask);
-- return mask;
-- }
--
-- However, it is better to use `getumask' if you just want to read
-- the mask value, because that is reentrant (at least if you use the
-- GNU operating system).
--
-- - Function: mode_t getumask (void)
-- Return the current value of the file creation mask for the current
-- process. This function is a GNU extension.
--
-- - Function: int chmod (const char *FILENAME, mode_t MODE)
-- The `chmod' function sets the access permission bits for the file
-- named by FILENAME to MODE.
--
-- If the FILENAME names a symbolic link, `chmod' changes the
-- permission of the file pointed to by the link, not those of the
-- link itself.
--
-- This function returns `0' if successful and `-1' if not. In
-- addition to the usual file name errors (*note File Name
-- Errors::.), the following `errno' error conditions are defined for
-- this function:
--
-- `ENOENT'
-- The named file doesn't exist.
--
-- `EPERM'
-- This process does not have permission to change the access
-- permission of this file. Only the file's owner (as judged by
-- the effective user ID of the process) or a privileged user
-- can change them.
--
-- `EROFS'
-- The file resides on a read-only file system.
--
-- `EFTYPE'
-- MODE has the `S_ISVTX' bit (the "sticky bit") set, and the
-- named file is not a directory. Some systems do not allow
-- setting the sticky bit on non-directory files, and some do
-- (and only some of those assign a useful meaning to the bit
-- for non-directory files).
--
-- You only get `EFTYPE' on systems where the sticky bit has no
-- useful meaning for non-directory files, so it is always safe
-- to just clear the bit in MODE and call `chmod' again. *Note
-- Permission Bits::, for full details on the sticky bit.
--
-- - Function: int fchmod (int FILEDES, int MODE)
-- This is like `chmod', except that it changes the permissions of
-- the file currently open via descriptor FILEDES.
--
-- The return value from `fchmod' is `0' on success and `-1' on
-- failure. The following `errno' error codes are defined for this
-- function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `EINVAL'
-- The FILEDES argument corresponds to a pipe or socket, or
-- something else that doesn't really have access permissions.
--
-- `EPERM'
-- This process does not have permission to change the access
-- permission of this file. Only the file's owner (as judged by
-- the effective user ID of the process) or a privileged user
-- can change them.
--
-- `EROFS'
-- The file resides on a read-only file system.
--
--
--File: libc.info, Node: Testing File Access, Next: File Times, Prev: Setting Permissions, Up: File Attributes
--
--Testing Permission to Access a File
-------------------------------------
--
-- When a program runs as a privileged user, this permits it to access
--files off-limits to ordinary users--for example, to modify
--`/etc/passwd'. Programs designed to be run by ordinary users but
--access such files use the setuid bit feature so that they always run
--with `root' as the effective user ID.
--
-- Such a program may also access files specified by the user, files
--which conceptually are being accessed explicitly by the user. Since the
--program runs as `root', it has permission to access whatever file the
--user specifies--but usually the desired behavior is to permit only
--those files which the user could ordinarily access.
--
-- The program therefore must explicitly check whether *the user* would
--have the necessary access to a file, before it reads or writes the file.
--
-- To do this, use the function `access', which checks for access
--permission based on the process's *real* user ID rather than the
--effective user ID. (The setuid feature does not alter the real user ID,
--so it reflects the user who actually ran the program.)
--
-- There is another way you could check this access, which is easy to
--describe, but very hard to use. This is to examine the file mode bits
--and mimic the system's own access computation. This method is
--undesirable because many systems have additional access control
--features; your program cannot portably mimic them, and you would not
--want to try to keep track of the diverse features that different systems
--have. Using `access' is simple and automatically does whatever is
--appropriate for the system you are using.
--
-- `access' is *only* only appropriate to use in setuid programs. A
--non-setuid program will always use the effective ID rather than the
--real ID.
--
-- The symbols in this section are declared in `unistd.h'.
--
-- - Function: int access (const char *FILENAME, int HOW)
-- The `access' function checks to see whether the file named by
-- FILENAME can be accessed in the way specified by the HOW argument.
-- The HOW argument either can be the bitwise OR of the flags
-- `R_OK', `W_OK', `X_OK', or the existence test `F_OK'.
--
-- This function uses the *real* user and group ID's of the calling
-- process, rather than the *effective* ID's, to check for access
-- permission. As a result, if you use the function from a `setuid'
-- or `setgid' program (*note How Change Persona::.), it gives
-- information relative to the user who actually ran the program.
--
-- The return value is `0' if the access is permitted, and `-1'
-- otherwise. (In other words, treated as a predicate function,
-- `access' returns true if the requested access is *denied*.)
--
-- In addition to the usual file name errors (*note File Name
-- Errors::.), the following `errno' error conditions are defined for
-- this function:
--
-- `EACCES'
-- The access specified by HOW is denied.
--
-- `ENOENT'
-- The file doesn't exist.
--
-- `EROFS'
-- Write permission was requested for a file on a read-only file
-- system.
--
-- These macros are defined in the header file `unistd.h' for use as
--the HOW argument to the `access' function. The values are integer
--constants.
--
-- - Macro: int R_OK
-- Argument that means, test for read permission.
--
-- - Macro: int W_OK
-- Argument that means, test for write permission.
--
-- - Macro: int X_OK
-- Argument that means, test for execute/search permission.
--
-- - Macro: int F_OK
-- Argument that means, test for existence of the file.
--
--
--File: libc.info, Node: File Times, Next: File Size, Prev: Testing File Access, Up: File Attributes
--
--File Times
------------
--
-- Each file has three time stamps associated with it: its access time,
--its modification time, and its attribute modification time. These
--correspond to the `st_atime', `st_mtime', and `st_ctime' members of the
--`stat' structure; see *Note File Attributes::.
--
-- All of these times are represented in calendar time format, as
--`time_t' objects. This data type is defined in `time.h'. For more
--information about representation and manipulation of time values, see
--*Note Calendar Time::.
--
-- Reading from a file updates its access time attribute, and writing
--updates its modification time. When a file is created, all three time
--stamps for that file are set to the current time. In addition, the
--attribute change time and modification time fields of the directory that
--contains the new entry are updated.
--
-- Adding a new name for a file with the `link' function updates the
--attribute change time field of the file being linked, and both the
--attribute change time and modification time fields of the directory
--containing the new name. These same fields are affected if a file name
--is deleted with `unlink', `remove', or `rmdir'. Renaming a file with
--`rename' affects only the attribute change time and modification time
--fields of the two parent directories involved, and not the times for
--the file being renamed.
--
-- Changing attributes of a file (for example, with `chmod') updates
--its attribute change time field.
--
-- You can also change some of the time stamps of a file explicitly
--using the `utime' function--all except the attribute change time. You
--need to include the header file `utime.h' to use this facility.
--
-- - Data Type: struct utimbuf
-- The `utimbuf' structure is used with the `utime' function to
-- specify new access and modification times for a file. It contains
-- the following members:
--
-- `time_t actime'
-- This is the access time for the file.
--
-- `time_t modtime'
-- This is the modification time for the file.
--
-- - Function: int utime (const char *FILENAME, const struct utimbuf
-- *TIMES)
-- This function is used to modify the file times associated with the
-- file named FILENAME.
--
-- If TIMES is a null pointer, then the access and modification times
-- of the file are set to the current time. Otherwise, they are set
-- to the values from the `actime' and `modtime' members
-- (respectively) of the `utimbuf' structure pointed at by TIMES.
--
-- The attribute modification time for the file is set to the current
-- time in either case (since changing the time stamps is itself a
-- modification of the file attributes).
--
-- The `utime' function returns `0' if successful and `-1' on
-- failure. In addition to the usual file name errors (*note File
-- Name Errors::.), the following `errno' error conditions are
-- defined for this function:
--
-- `EACCES'
-- There is a permission problem in the case where a null
-- pointer was passed as the TIMES argument. In order to update
-- the time stamp on the file, you must either be the owner of
-- the file, have write permission on the file, or be a
-- privileged user.
--
-- `ENOENT'
-- The file doesn't exist.
--
-- `EPERM'
-- If the TIMES argument is not a null pointer, you must either
-- be the owner of the file or be a privileged user. This error
-- is used to report the problem.
--
-- `EROFS'
-- The file lives on a read-only file system.
--
-- Each of the three time stamps has a corresponding microsecond part,
--which extends its resolution. These fields are called `st_atime_usec',
--`st_mtime_usec', and `st_ctime_usec'; each has a value between 0 and
--999,999, which indicates the time in microseconds. They correspond to
--the `tv_usec' field of a `timeval' structure; see *Note High-Resolution
--Calendar::.
--
-- The `utimes' function is like `utime', but also lets you specify the
--fractional part of the file times. The prototype for this function is
--in the header file `sys/time.h'.
--
-- - Function: int utimes (const char *FILENAME, struct timeval TVP[2])
-- This function sets the file access and modification times for the
-- file named by FILENAME. The new file access time is specified by
-- `TVP[0]', and the new modification time by `TVP[1]'. This
-- function comes from BSD.
--
-- The return values and error conditions are the same as for the
-- `utime' function.
--
--
--File: libc.info, Node: File Size, Prev: File Times, Up: File Attributes
--
--File Size
-----------
--
-- Normally file sizes are maintained automatically. A file begins
--with a size of 0 and is automatically extended when data is written
--past its end. It is also possible to empty a file completely in an
--`open' or `fopen' call.
--
-- However, sometimes it is neccessary to *reduce* the size of a file.
--This can be done with the `truncate' and `ftruncate' functions. They
--were introduced in BSD Unix. `ftruncate' was later added to POSIX.1.
--
-- Some systems allow you to extend a file (creating holes) with these
--functions. This is useful when using memory-mapped I/O (*note
--Memory-mapped I/O::.), where files are not automatically extended.
--However it is not portable but must be implemented if `mmap' allows
--mapping of files (i.e., `_POSIX_MAPPED_FILES' is defined).
--
-- Using these functions on anything other than a regular file gives
--*undefined* results. On many systems, such a call will appear to
--succeed, without actually accomplishing anything.
--
-- - Function: int truncate (const char *FILENAME, off_t LENGTH)
-- The `truncate' function changes the size of FILENAME to LENGTH.
-- If LENGTH is shorter than the previous length, data at the end
-- will be lost.
--
-- If LENGTH is longer, holes will be added to the end. However, some
-- systems do not support this feature and will leave the file
-- unchanged.
--
-- The return value is 0 for success, or -1 for an error. In
-- addition to the usual file name errors, the following errors may
-- occur:
--
-- `EACCES'
-- The file is a directory or not writable.
--
-- `EINVAL'
-- LENGTH is negative.
--
-- `EFBIG'
-- The operation would extend the file beyond the limits of the
-- operating system.
--
-- `EIO'
-- A hardware I/O error occured.
--
-- `EPERM'
-- The file is "append-only" or "immutable".
--
-- `EINTR'
-- The operation was interrupted by a signal.
--
--
-- - Function: int ftruncate (int FD, off_t LENGTH)
-- This is like `truncate', but it works on a file descriptor FD.
--
-- `ftruncate' is especially useful in combination with `mmap'.
-- Since the mapped region must have a fixed size one cannot enlarge
-- the file by writing something beyond the last mapped page.
-- Instead one has to enlarge the file itself and then remap the file
-- with the new size. The example below shows how this works.
--
-- The return value is 0 for success, or -1 for an error. The
-- following errors may occur:
--
-- `EBADF'
-- FD does not correspond to an open file.
--
-- `EACCES'
-- FD is a directory or not open for write.
--
-- `EINVAL'
-- LENGTH is negative.
--
-- `EFBIG'
-- The operation would extend the file beyond the limits of the
-- operating system.
--
-- `EIO'
-- A hardware I/O error occured.
--
-- `EPERM'
-- The file is "append-only" or "immutable".
--
-- `EINTR'
-- The operation was interrupted by a signal.
--
--
-- As announced here is a little example how to use `ftruncate' in
--combination with `mmap':
--
-- int fd;
-- void *start;
-- size_t len;
--
-- int
-- add (off_t at, void *block, size_t size)
-- {
-- if (at + size > len)
-- {
-- /* Resize the file and remap. */
-- size_t ps = sysconf (_SC_PAGESIZE);
-- size_t ns = (at + size + ps - 1) & ~(ps - 1);
-- void *np;
-- if (ftruncate (fd, ns) < 0)
-- return -1;
-- np = mmap (NULL, ns, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-- if (np == MAP_FAILED)
-- return -1;
-- start = np;
-- len = ns;
-- }
-- memcpy ((char *) start + at, block, size);
-- return 0;
-- }
--
-- The function `add' allows to add at arbitrary positions in the file
--given blocks of memory. If the current size of the file is too small it
--is extended. Please note the it is extended in multiples of a pagesize.
--This is a requirement of `mmap'. The program has to track the real
--size and once the program finished to work a final `ftruncate' call
--should set the real size of the file.
--
--
--File: libc.info, Node: Making Special Files, Next: Temporary Files, Prev: File Attributes, Up: File System Interface
--
--Making Special Files
--====================
--
-- The `mknod' function is the primitive for making special files, such
--as files that correspond to devices. The GNU library includes this
--function for compatibility with BSD.
--
-- The prototype for `mknod' is declared in `sys/stat.h'.
--
-- - Function: int mknod (const char *FILENAME, int MODE, int DEV)
-- The `mknod' function makes a special file with name FILENAME. The
-- MODE specifies the mode of the file, and may include the various
-- special file bits, such as `S_IFCHR' (for a character special file)
-- or `S_IFBLK' (for a block special file). *Note Testing File
-- Type::.
--
-- The DEV argument specifies which device the special file refers to.
-- Its exact interpretation depends on the kind of special file being
-- created.
--
-- The return value is `0' on success and `-1' on error. In addition
-- to the usual file name errors (*note File Name Errors::.), the
-- following `errno' error conditions are defined for this function:
--
-- `EPERM'
-- The calling process is not privileged. Only the superuser
-- can create special files.
--
-- `ENOSPC'
-- The directory or file system that would contain the new file
-- is full and cannot be extended.
--
-- `EROFS'
-- The directory containing the new file can't be modified
-- because it's on a read-only file system.
--
-- `EEXIST'
-- There is already a file named FILENAME. If you want to
-- replace this file, you must remove the old file explicitly
-- first.
--
--
--File: libc.info, Node: Temporary Files, Prev: Making Special Files, Up: File System Interface
--
--Temporary Files
--===============
--
-- If you need to use a temporary file in your program, you can use the
--`tmpfile' function to open it. Or you can use the `tmpnam' (better:
--`tmpnam_r') function to make a name for a temporary file and then you
--can open it in the usual way with `fopen'.
--
-- The `tempnam' function is like `tmpnam' but lets you choose what
--directory temporary files will go in, and something about what their
--file names will look like. Important for multi threaded programs is
--that `tempnam' is reentrant while `tmpnam' is not since it returns a
--pointer to a static buffer.
--
-- These facilities are declared in the header file `stdio.h'.
--
-- - Function: FILE * tmpfile (void)
-- This function creates a temporary binary file for update mode, as
-- if by calling `fopen' with mode `"wb+"'. The file is deleted
-- automatically when it is closed or when the program terminates.
-- (On some other ISO C systems the file may fail to be deleted if
-- the program terminates abnormally).
--
-- This function is reentrant.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system this function is in fact `tmpfile64'. I.e., the
-- LFS interface transparently replaces the old interface.
--
-- - Function: FILE * tmpfile64 (void)
-- This function is similar to `tmpfile' but the stream it returns a
-- pointer for is opened using `tmpfile64'. Therefore this stream
-- can be used even on files larger then 2^31 bytes on 32 bits
-- machines.
--
-- Please note that the return type is still `FILE *'. There is no
-- special `FILE' type for the LFS interface.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' on a 32
-- bits machine this function is available under the name `tmpfile'
-- and so transparently replaces the old interface.
--
-- - Function: char * tmpnam (char *RESULT)
-- This function constructs and returns a file name that is a valid
-- file name and that does not name any existing file. If the RESULT
-- argument is a null pointer, the return value is a pointer to an
-- internal static string, which might be modified by subsequent
-- calls and therefore makes this function non-reentrant. Otherwise,
-- the RESULT argument should be a pointer to an array of at least
-- `L_tmpnam' characters, and the result is written into that array.
--
-- It is possible for `tmpnam' to fail if you call it too many times
-- without removing previously created files. This is because the
-- fixed length of a temporary file name gives room for only a finite
-- number of different names. If `tmpnam' fails, it returns a null
-- pointer.
--
-- *Warning:* Since between the time the pathname is constructed and
-- the file is created another process might have created a file with
-- this name using `tmpnam' is a possible security hole. The
-- implementation generates names which hardly can be predicted but
-- opening the file in any case should use the `O_EXCL' flag. Using
-- `tmpfile' is a safe way to avoid this problem.
--
-- - Function: char * tmpnam_r (char *RESULT)
-- This function is nearly identical to the `tmpnam' function. But it
-- does not allow RESULT to be a null pointer. In the later case a
-- null pointer is returned.
--
-- This function is reentrant because the non-reentrant situation of
-- `tmpnam' cannot happen here.
--
-- - Macro: int L_tmpnam
-- The value of this macro is an integer constant expression that
-- represents the minimum allocation size of a string large enough to
-- hold the file name generated by the `tmpnam' function.
--
-- - Macro: int TMP_MAX
-- The macro `TMP_MAX' is a lower bound for how many temporary names
-- you can create with `tmpnam'. You can rely on being able to call
-- `tmpnam' at least this many times before it might fail saying you
-- have made too many temporary file names.
--
-- With the GNU library, you can create a very large number of
-- temporary file names--if you actually create the files, you will
-- probably run out of disk space before you run out of names. Some
-- other systems have a fixed, small limit on the number of temporary
-- files. The limit is never less than `25'.
--
-- - Function: char * tempnam (const char *DIR, const char *PREFIX)
-- This function generates a unique temporary filename. If PREFIX is
-- not a null pointer, up to five characters of this string are used
-- as a prefix for the file name. The return value is a string newly
-- allocated with `malloc'; you should release its storage with
-- `free' when it is no longer needed.
--
-- Because the string is dynamically allocated this function is
-- reentrant.
--
-- The directory prefix for the temporary file name is determined by
-- testing each of the following, in sequence. The directory must
-- exist and be writable.
--
-- * The environment variable `TMPDIR', if it is defined. For
-- security reasons this only happens if the program is not SUID
-- or SGID enabled.
--
-- * The DIR argument, if it is not a null pointer.
--
-- * The value of the `P_tmpdir' macro.
--
-- * The directory `/tmp'.
--
-- This function is defined for SVID compatibility.
--
-- - SVID Macro: char * P_tmpdir
-- This macro is the name of the default directory for temporary
-- files.
--
-- Older Unix systems did not have the functions just described.
--Instead they used `mktemp' and `mkstemp'. Both of these functions work
--by modifying a file name template string you pass. The last six
--characters of this string must be `XXXXXX'. These six `X's are
--replaced with six characters which make the whole string a unique file
--name. Usually the template string is something like
--`/tmp/PREFIXXXXXXX', and each program uses a unique PREFIX.
--
-- *Note:* Because `mktemp' and `mkstemp' modify the template string,
--you *must not* pass string constants to them. String constants are
--normally in read-only storage, so your program would crash when
--`mktemp' or `mkstemp' tried to modify the string.
--
-- - Function: char * mktemp (char *TEMPLATE)
-- The `mktemp' function generates a unique file name by modifying
-- TEMPLATE as described above. If successful, it returns TEMPLATE
-- as modified. If `mktemp' cannot find a unique file name, it makes
-- TEMPLATE an empty string and returns that. If TEMPLATE does not
-- end with `XXXXXX', `mktemp' returns a null pointer.
--
-- *Warning:* Since between the time the pathname is constructed and
-- the file is created another process might have created a file with
-- this name using `mktemp' is a possible security hole. The
-- implementation generates names which hardly can be predicted but
-- opening the file in any case should use the `O_EXCL' flag. Using
-- `mkstemp' is a safe way to avoid this problem.
--
-- - Function: int mkstemp (char *TEMPLATE)
-- The `mkstemp' function generates a unique file name just as
-- `mktemp' does, but it also opens the file for you with `open'
-- (*note Opening and Closing Files::.). If successful, it modifies
-- TEMPLATE in place and returns a file descriptor open on that file
-- for reading and writing. If `mkstemp' cannot create a
-- uniquely-named file, it returns `-1'. If TEMPLATE does not end
-- with `XXXXXX', `mkstemp' returns `-1' and does not modify TEMPLATE.
--
-- The file is opened using mode `0600'. If the file is meant to be
-- used by other users the mode must explicitly changed.
--
-- Unlike `mktemp', `mkstemp' is actually guaranteed to create a unique
--file that cannot possibly clash with any other program trying to create
--a temporary file. This is because it works by calling `open' with the
--`O_EXCL' flag bit, which says you want to always create a new file, and
--get an error if the file already exists.
--
--
--File: libc.info, Node: Pipes and FIFOs, Next: Sockets, Prev: File System Interface, Up: Top
--
--Pipes and FIFOs
--***************
--
-- A "pipe" is a mechanism for interprocess communication; data written
--to the pipe by one process can be read by another process. The data is
--handled in a first-in, first-out (FIFO) order. The pipe has no name; it
--is created for one use and both ends must be inherited from the single
--process which created the pipe.
--
-- A "FIFO special file" is similar to a pipe, but instead of being an
--anonymous, temporary connection, a FIFO has a name or names like any
--other file. Processes open the FIFO by name in order to communicate
--through it.
--
-- A pipe or FIFO has to be open at both ends simultaneously. If you
--read from a pipe or FIFO file that doesn't have any processes writing
--to it (perhaps because they have all closed the file, or exited), the
--read returns end-of-file. Writing to a pipe or FIFO that doesn't have a
--reading process is treated as an error condition; it generates a
--`SIGPIPE' signal, and fails with error code `EPIPE' if the signal is
--handled or blocked.
--
-- Neither pipes nor FIFO special files allow file positioning. Both
--reading and writing operations happen sequentially; reading from the
--beginning of the file and writing at the end.
--
--* Menu:
--
--* Creating a Pipe:: Making a pipe with the `pipe' function.
--* Pipe to a Subprocess:: Using a pipe to communicate with a
-- child process.
--* FIFO Special Files:: Making a FIFO special file.
--* Pipe Atomicity:: When pipe (or FIFO) I/O is atomic.
--
--
--File: libc.info, Node: Creating a Pipe, Next: Pipe to a Subprocess, Up: Pipes and FIFOs
--
--Creating a Pipe
--===============
--
-- The primitive for creating a pipe is the `pipe' function. This
--creates both the reading and writing ends of the pipe. It is not very
--useful for a single process to use a pipe to talk to itself. In typical
--use, a process creates a pipe just before it forks one or more child
--processes (*note Creating a Process::.). The pipe is then used for
--communication either between the parent or child processes, or between
--two sibling processes.
--
-- The `pipe' function is declared in the header file `unistd.h'.
--
-- - Function: int pipe (int FILEDES[2])
-- The `pipe' function creates a pipe and puts the file descriptors
-- for the reading and writing ends of the pipe (respectively) into
-- `FILEDES[0]' and `FILEDES[1]'.
--
-- An easy way to remember that the input end comes first is that file
-- descriptor `0' is standard input, and file descriptor `1' is
-- standard output.
--
-- If successful, `pipe' returns a value of `0'. On failure, `-1' is
-- returned. The following `errno' error conditions are defined for
-- this function:
--
-- `EMFILE'
-- The process has too many files open.
--
-- `ENFILE'
-- There are too many open files in the entire system. *Note
-- Error Codes::, for more information about `ENFILE'. This
-- error never occurs in the GNU system.
--
-- Here is an example of a simple program that creates a pipe. This
--program uses the `fork' function (*note Creating a Process::.) to create
--a child process. The parent process writes data to the pipe, which is
--read by the child process.
--
-- #include <sys/types.h>
-- #include <unistd.h>
-- #include <stdio.h>
-- #include <stdlib.h>
--
-- /* Read characters from the pipe and echo them to `stdout'. */
--
-- void
-- read_from_pipe (int file)
-- {
-- FILE *stream;
-- int c;
-- stream = fdopen (file, "r");
-- while ((c = fgetc (stream)) != EOF)
-- putchar (c);
-- fclose (stream);
-- }
--
-- /* Write some random text to the pipe. */
--
-- void
-- write_to_pipe (int file)
-- {
-- FILE *stream;
-- stream = fdopen (file, "w");
-- fprintf (stream, "hello, world!\n");
-- fprintf (stream, "goodbye, world!\n");
-- fclose (stream);
-- }
--
-- int
-- main (void)
-- {
-- pid_t pid;
-- int mypipe[2];
-- /* Create the pipe. */
-- if (pipe (mypipe))
-- {
-- fprintf (stderr, "Pipe failed.\n");
-- return EXIT_FAILURE;
-- }
--
-- /* Create the child process. */
-- pid = fork ();
-- if (pid == (pid_t) 0)
-- {
-- /* This is the child process. */
-- read_from_pipe (mypipe[0]);
-- return EXIT_SUCCESS;
-- }
-- else if (pid < (pid_t) 0)
-- {
-- /* The fork failed. */
-- fprintf (stderr, "Fork failed.\n");
-- return EXIT_FAILURE;
-- }
-- else
-- {
-- /* This is the parent process. */
-- write_to_pipe (mypipe[1]);
-- return EXIT_SUCCESS;
-- }
-- }
--
--
--File: libc.info, Node: Pipe to a Subprocess, Next: FIFO Special Files, Prev: Creating a Pipe, Up: Pipes and FIFOs
--
--Pipe to a Subprocess
--====================
--
-- A common use of pipes is to send data to or receive data from a
--program being run as subprocess. One way of doing this is by using a
--combination of `pipe' (to create the pipe), `fork' (to create the
--subprocess), `dup2' (to force the subprocess to use the pipe as its
--standard input or output channel), and `exec' (to execute the new
--program). Or, you can use `popen' and `pclose'.
--
-- The advantage of using `popen' and `pclose' is that the interface is
--much simpler and easier to use. But it doesn't offer as much
--flexibility as using the low-level functions directly.
--
-- - Function: FILE * popen (const char *COMMAND, const char *MODE)
-- The `popen' function is closely related to the `system' function;
-- see *Note Running a Command::. It executes the shell command
-- COMMAND as a subprocess. However, instead of waiting for the
-- command to complete, it creates a pipe to the subprocess and
-- returns a stream that corresponds to that pipe.
--
-- If you specify a MODE argument of `"r"', you can read from the
-- stream to retrieve data from the standard output channel of the
-- subprocess. The subprocess inherits its standard input channel
-- from the parent process.
--
-- Similarly, if you specify a MODE argument of `"w"', you can write
-- to the stream to send data to the standard input channel of the
-- subprocess. The subprocess inherits its standard output channel
-- from the parent process.
--
-- In the event of an error, `popen' returns a null pointer. This
-- might happen if the pipe or stream cannot be created, if the
-- subprocess cannot be forked, or if the program cannot be executed.
--
-- - Function: int pclose (FILE *STREAM)
-- The `pclose' function is used to close a stream created by `popen'.
-- It waits for the child process to terminate and returns its status
-- value, as for the `system' function.
--
-- Here is an example showing how to use `popen' and `pclose' to filter
--output through another program, in this case the paging program `more'.
--
-- #include <stdio.h>
-- #include <stdlib.h>
--
-- void
-- write_data (FILE * stream)
-- {
-- int i;
-- for (i = 0; i < 100; i++)
-- fprintf (stream, "%d\n", i);
-- if (ferror (stream))
-- {
-- fprintf (stderr, "Output to stream failed.\n");
-- exit (EXIT_FAILURE);
-- }
-- }
-- int
-- main (void)
-- {
-- FILE *output;
--
-- output = popen ("more", "w");
-- if (!output)
-- {
-- fprintf (stderr, "Could not run more.\n");
-- return EXIT_FAILURE;
-- }
-- write_data (output);
-- pclose (output);
-- return EXIT_SUCCESS;
-- }
--
--
--File: libc.info, Node: FIFO Special Files, Next: Pipe Atomicity, Prev: Pipe to a Subprocess, Up: Pipes and FIFOs
--
--FIFO Special Files
--==================
--
-- A FIFO special file is similar to a pipe, except that it is created
--in a different way. Instead of being an anonymous communications
--channel, a FIFO special file is entered into the file system by calling
--`mkfifo'.
--
-- Once you have created a FIFO special file in this way, any process
--can open it for reading or writing, in the same way as an ordinary file.
--However, it has to be open at both ends simultaneously before you can
--proceed to do any input or output operations on it. Opening a FIFO for
--reading normally blocks until some other process opens the same FIFO for
--writing, and vice versa.
--
-- The `mkfifo' function is declared in the header file `sys/stat.h'.
--
-- - Function: int mkfifo (const char *FILENAME, mode_t MODE)
-- The `mkfifo' function makes a FIFO special file with name
-- FILENAME. The MODE argument is used to set the file's
-- permissions; see *Note Setting Permissions::.
--
-- The normal, successful return value from `mkfifo' is `0'. In the
-- case of an error, `-1' is returned. In addition to the usual file
-- name errors (*note File Name Errors::.), the following `errno'
-- error conditions are defined for this function:
--
-- `EEXIST'
-- The named file already exists.
--
-- `ENOSPC'
-- The directory or file system cannot be extended.
--
-- `EROFS'
-- The directory that would contain the file resides on a
-- read-only file system.
--
--
--File: libc.info, Node: Pipe Atomicity, Prev: FIFO Special Files, Up: Pipes and FIFOs
--
--Atomicity of Pipe I/O
--=====================
--
-- Reading or writing pipe data is "atomic" if the size of data written
--is not greater than `PIPE_BUF'. This means that the data transfer
--seems to be an instantaneous unit, in that nothing else in the system
--can observe a state in which it is partially complete. Atomic I/O may
--not begin right away (it may need to wait for buffer space or for data),
--but once it does begin, it finishes immediately.
--
-- Reading or writing a larger amount of data may not be atomic; for
--example, output data from other processes sharing the descriptor may be
--interspersed. Also, once `PIPE_BUF' characters have been written,
--further writes will block until some characters are read.
--
-- *Note Limits for Files::, for information about the `PIPE_BUF'
--parameter.
--
--
--File: libc.info, Node: Sockets, Next: Low-Level Terminal Interface, Prev: Pipes and FIFOs, Up: Top
--
--Sockets
--*******
--
-- This chapter describes the GNU facilities for interprocess
--communication using sockets.
--
-- A "socket" is a generalized interprocess communication channel.
--Like a pipe, a socket is represented as a file descriptor. But, unlike
--pipes, sockets support communication between unrelated processes, and
--even between processes running on different machines that communicate
--over a network. Sockets are the primary means of communicating with
--other machines; `telnet', `rlogin', `ftp', `talk', and the other
--familiar network programs use sockets.
--
-- Not all operating systems support sockets. In the GNU library, the
--header file `sys/socket.h' exists regardless of the operating system,
--and the socket functions always exist, but if the system does not
--really support sockets, these functions always fail.
--
-- *Incomplete:* We do not currently document the facilities for
--broadcast messages or for configuring Internet interfaces. The
--reentrant functions and some newer functions that are related to IPv6
--aren't documented either so far.
--
--* Menu:
--
--* Socket Concepts:: Basic concepts you need to know about.
--* Communication Styles::Stream communication, datagrams, and other styles.
--* Socket Addresses:: How socket names ("addresses") work.
--* Interface Naming:: Identifying specific network interfaces.
--* Local Namespace:: Details about the local namespace.
--* Internet Namespace:: Details about the Internet namespace.
--* Misc Namespaces:: Other namespaces not documented fully here.
--* Open/Close Sockets:: Creating sockets and destroying them.
--* Connections:: Operations on sockets with connection state.
--* Datagrams:: Operations on datagram sockets.
--* Inetd:: Inetd is a daemon that starts servers on request.
-- The most convenient way to write a server
-- is to make it work with Inetd.
--* Socket Options:: Miscellaneous low-level socket options.
--* Networks Database:: Accessing the database of network names.
--
--
--File: libc.info, Node: Socket Concepts, Next: Communication Styles, Up: Sockets
--
--Socket Concepts
--===============
--
-- When you create a socket, you must specify the style of communication
--you want to use and the type of protocol that should implement it. The
--"communication style" of a socket defines the user-level semantics of
--sending and receiving data on the socket. Choosing a communication
--style specifies the answers to questions such as these:
--
-- * *What are the units of data transmission?* Some communication
-- styles regard the data as a sequence of bytes, with no larger
-- structure; others group the bytes into records (which are known in
-- this context as "packets").
--
-- * *Can data be lost during normal operation?* Some communication
-- styles guarantee that all the data sent arrives in the order it was
-- sent (barring system or network crashes); other styles occasionally
-- lose data as a normal part of operation, and may sometimes deliver
-- packets more than once or in the wrong order.
--
-- Designing a program to use unreliable communication styles usually
-- involves taking precautions to detect lost or misordered packets
-- and to retransmit data as needed.
--
-- * *Is communication entirely with one partner?* Some communication
-- styles are like a telephone call--you make a "connection" with one
-- remote socket, and then exchange data freely. Other styles are
-- like mailing letters--you specify a destination address for each
-- message you send.
--
-- You must also choose a "namespace" for naming the socket. A socket
--name ("address") is meaningful only in the context of a particular
--namespace. In fact, even the data type to use for a socket name may
--depend on the namespace. Namespaces are also called "domains", but we
--avoid that word as it can be confused with other usage of the same
--term. Each namespace has a symbolic name that starts with `PF_'. A
--corresponding symbolic name starting with `AF_' designates the address
--format for that namespace.
--
-- Finally you must choose the "protocol" to carry out the
--communication. The protocol determines what low-level mechanism is used
--to transmit and receive data. Each protocol is valid for a particular
--namespace and communication style; a namespace is sometimes called a
--"protocol family" because of this, which is why the namespace names
--start with `PF_'.
--
-- The rules of a protocol apply to the data passing between two
--programs, perhaps on different computers; most of these rules are
--handled by the operating system, and you need not know about them.
--What you do need to know about protocols is this:
--
-- * In order to have communication between two sockets, they must
-- specify the *same* protocol.
--
-- * Each protocol is meaningful with particular style/namespace
-- combinations and cannot be used with inappropriate combinations.
-- For example, the TCP protocol fits only the byte stream style of
-- communication and the Internet namespace.
--
-- * For each combination of style and namespace, there is a "default
-- protocol" which you can request by specifying 0 as the protocol
-- number. And that's what you should normally do--use the default.
--
-- Throughout the following description at various places
--variables/parameters to denote sizes are required. And here the trouble
--starts. In the first implementations the type of these variables was
--simply `int'. This type was on almost all machines of this time 32
--bits wide and so a de-factor standard required 32 bit variables. This
--is important since references to variables of this type are passed to
--the kernel.
--
-- But then the POSIX people came and unified the interface with the
--words "all size values are of type `size_t'". But on 64 bit machines
--`size_t' is 64 bits wide, and so variable references are not anymore
--possible.
--
-- The Unix98 specification provides a solution by introducing a type
--`socklen_t'. This type is used in all of the cases that POSIX changed
--to use `size_t'. The only requirement of this type is that it be an
--unsigned type of at least 32 bits. Therefore, implementations which
--require that references to 32 bit variables be passed can be as happy
--as implementations which use 64 bit values.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-23 glibc-2.1.3/manual/libc.info-23
---- ../glibc-2.1.3/manual/libc.info-23 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-23 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1160 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Communication Styles, Next: Socket Addresses, Prev: Socket Concepts, Up: Sockets
--
--Communication Styles
--====================
--
-- The GNU library includes support for several different kinds of
--sockets, each with different characteristics. This section describes
--the supported socket types. The symbolic constants listed here are
--defined in `sys/socket.h'.
--
-- - Macro: int SOCK_STREAM
-- The `SOCK_STREAM' style is like a pipe (*note Pipes and FIFOs::.);
-- it operates over a connection with a particular remote socket, and
-- transmits data reliably as a stream of bytes.
--
-- Use of this style is covered in detail in *Note Connections::.
--
-- - Macro: int SOCK_DGRAM
-- The `SOCK_DGRAM' style is used for sending individually-addressed
-- packets, unreliably. It is the diametrical opposite of
-- `SOCK_STREAM'.
--
-- Each time you write data to a socket of this kind, that data
-- becomes one packet. Since `SOCK_DGRAM' sockets do not have
-- connections, you must specify the recipient address with each
-- packet.
--
-- The only guarantee that the system makes about your requests to
-- transmit data is that it will try its best to deliver each packet
-- you send. It may succeed with the sixth packet after failing with
-- the fourth and fifth packets; the seventh packet may arrive before
-- the sixth, and may arrive a second time after the sixth.
--
-- The typical use for `SOCK_DGRAM' is in situations where it is
-- acceptable to simply resend a packet if no response is seen in a
-- reasonable amount of time.
--
-- *Note Datagrams::, for detailed information about how to use
-- datagram sockets.
--
-- - Macro: int SOCK_RAW
-- This style provides access to low-level network protocols and
-- interfaces. Ordinary user programs usually have no need to use
-- this style.
--
--
--File: libc.info, Node: Socket Addresses, Next: Interface Naming, Prev: Communication Styles, Up: Sockets
--
--Socket Addresses
--================
--
-- The name of a socket is normally called an "address". The functions
--and symbols for dealing with socket addresses were named
--inconsistently, sometimes using the term "name" and sometimes using
--"address". You can regard these terms as synonymous where sockets are
--concerned.
--
-- A socket newly created with the `socket' function has no address.
--Other processes can find it for communication only if you give it an
--address. We call this "binding" the address to the socket, and the way
--to do it is with the `bind' function.
--
-- You need be concerned with the address of a socket if other processes
--are to find it and start communicating with it. You can specify an
--address for other sockets, but this is usually pointless; the first time
--you send data from a socket, or use it to initiate a connection, the
--system assigns an address automatically if you have not specified one.
--
-- Occasionally a client needs to specify an address because the server
--discriminates based on addresses; for example, the rsh and rlogin
--protocols look at the client's socket address and only bypass password
--checking if it is less than `IPPORT_RESERVED' (*note Ports::.).
--
-- The details of socket addresses vary depending on what namespace you
--are using. *Note Local Namespace::, or *Note Internet Namespace::, for
--specific information.
--
-- Regardless of the namespace, you use the same functions `bind' and
--`getsockname' to set and examine a socket's address. These functions
--use a phony data type, `struct sockaddr *', to accept the address. In
--practice, the address lives in a structure of some other data type
--appropriate to the address format you are using, but you cast its
--address to `struct sockaddr *' when you pass it to `bind'.
--
--* Menu:
--
--* Address Formats:: About `struct sockaddr'.
--* Setting Address:: Binding an address to a socket.
--* Reading Address:: Reading the address of a socket.
--
--
--File: libc.info, Node: Address Formats, Next: Setting Address, Up: Socket Addresses
--
--Address Formats
-----------------
--
-- The functions `bind' and `getsockname' use the generic data type
--`struct sockaddr *' to represent a pointer to a socket address. You
--can't use this data type effectively to interpret an address or
--construct one; for that, you must use the proper data type for the
--socket's namespace.
--
-- Thus, the usual practice is to construct an address in the proper
--namespace-specific type, then cast a pointer to `struct sockaddr *'
--when you call `bind' or `getsockname'.
--
-- The one piece of information that you can get from the `struct
--sockaddr' data type is the "address format" designator which tells you
--which data type to use to understand the address fully.
--
-- The symbols in this section are defined in the header file
--`sys/socket.h'.
--
-- - Data Type: struct sockaddr
-- The `struct sockaddr' type itself has the following members:
--
-- `short int sa_family'
-- This is the code for the address format of this address. It
-- identifies the format of the data which follows.
--
-- `char sa_data[14]'
-- This is the actual socket address data, which is
-- format-dependent. Its length also depends on the format, and
-- may well be more than 14. The length 14 of `sa_data' is
-- essentially arbitrary.
--
-- Each address format has a symbolic name which starts with `AF_'.
--Each of them corresponds to a `PF_' symbol which designates the
--corresponding namespace. Here is a list of address format names:
--
--`AF_LOCAL'
-- This designates the address format that goes with the local
-- namespace. (`PF_LOCAL' is the name of that namespace.) *Note
-- Local Namespace Details::, for information about this address
-- format.
--
--`AF_UNIX'
-- This is a synonym for `AF_LOCAL', for compatibility. (`PF_UNIX'
-- is likewise a synonym for `PF_LOCAL'.)
--
--`AF_FILE'
-- This is another synonym for `AF_LOCAL', for compatibility.
-- (`PF_FILE' is likewise a synonym for `PF_LOCAL'.)
--
--`AF_INET'
-- This designates the address format that goes with the Internet
-- namespace. (`PF_INET' is the name of that namespace.) *Note
-- Internet Address Formats::.
--
--`AF_INET6'
-- This is similar to `AF_INET', but refers to the IPv6 protocol.
-- (`PF_INET6' is the name of the corresponding namespace.)
--
--`AF_UNSPEC'
-- This designates no particular address format. It is used only in
-- rare cases, such as to clear out the default destination address
-- of a "connected" datagram socket. *Note Sending Datagrams::.
--
-- The corresponding namespace designator symbol `PF_UNSPEC' exists
-- for completeness, but there is no reason to use it in a program.
--
-- `sys/socket.h' defines symbols starting with `AF_' for many
--different kinds of networks, all or most of which are not actually
--implemented. We will document those that really work, as we receive
--information about how to use them.
--
--
--File: libc.info, Node: Setting Address, Next: Reading Address, Prev: Address Formats, Up: Socket Addresses
--
--Setting the Address of a Socket
---------------------------------
--
-- Use the `bind' function to assign an address to a socket. The
--prototype for `bind' is in the header file `sys/socket.h'. For
--examples of use, see *Note Local Socket Example::, or see *Note Inet
--Example::.
--
-- - Function: int bind (int SOCKET, struct sockaddr *ADDR, socklen_t
-- LENGTH)
-- The `bind' function assigns an address to the socket SOCKET. The
-- ADDR and LENGTH arguments specify the address; the detailed format
-- of the address depends on the namespace. The first part of the
-- address is always the format designator, which specifies a
-- namespace, and says that the address is in the format for that
-- namespace.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error conditions are defined for this function:
--
-- `EBADF'
-- The SOCKET argument is not a valid file descriptor.
--
-- `ENOTSOCK'
-- The descriptor SOCKET is not a socket.
--
-- `EADDRNOTAVAIL'
-- The specified address is not available on this machine.
--
-- `EADDRINUSE'
-- Some other socket is already using the specified address.
--
-- `EINVAL'
-- The socket SOCKET already has an address.
--
-- `EACCES'
-- You do not have permission to access the requested address.
-- (In the Internet domain, only the super-user is allowed to
-- specify a port number in the range 0 through
-- `IPPORT_RESERVED' minus one; see *Note Ports::.)
--
-- Additional conditions may be possible depending on the particular
-- namespace of the socket.
--
--
--File: libc.info, Node: Reading Address, Prev: Setting Address, Up: Socket Addresses
--
--Reading the Address of a Socket
---------------------------------
--
-- Use the function `getsockname' to examine the address of an Internet
--socket. The prototype for this function is in the header file
--`sys/socket.h'.
--
-- - Function: int getsockname (int SOCKET, struct sockaddr *ADDR,
-- socklen_t *LENGTH-PTR)
-- The `getsockname' function returns information about the address
-- of the socket SOCKET in the locations specified by the ADDR and
-- LENGTH-PTR arguments. Note that the LENGTH-PTR is a pointer; you
-- should initialize it to be the allocation size of ADDR, and on
-- return it contains the actual size of the address data.
--
-- The format of the address data depends on the socket namespace.
-- The length of the information is usually fixed for a given
-- namespace, so normally you can know exactly how much space is
-- needed and can provide that much. The usual practice is to
-- allocate a place for the value using the proper data type for the
-- socket's namespace, then cast its address to `struct sockaddr *'
-- to pass it to `getsockname'.
--
-- The return value is `0' on success and `-1' on error. The
-- following `errno' error conditions are defined for this function:
--
-- `EBADF'
-- The SOCKET argument is not a valid file descriptor.
--
-- `ENOTSOCK'
-- The descriptor SOCKET is not a socket.
--
-- `ENOBUFS'
-- There are not enough internal buffers available for the
-- operation.
--
-- You can't read the address of a socket in the file namespace. This
--is consistent with the rest of the system; in general, there's no way to
--find a file's name from a descriptor for that file.
--
--
--File: libc.info, Node: Interface Naming, Next: Local Namespace, Prev: Socket Addresses, Up: Sockets
--
--Interface Naming
--================
--
-- Each network interface has a name. This usually consists of a few
--letters that relate to the type of interface, which may be followed by a
--number if there is more than one interface of that type. Examples
--might be `lo' (the loopback interface) and `eth0' (the first Ethernet
--interface).
--
-- Although such names are convenient for humans, it would be clumsy to
--have to use them whenever a program needs to refer to an interface. In
--such situations an interface is referred to by its "index", which is an
--arbitrarily-assigned small positive integer.
--
-- The following functions, constants and data types are declared in the
--header file `net/if.h'.
--
-- - Constant: size_t IFNAMSIZ
-- This constant defines the maximum buffer size needed to hold an
-- interface name, including its terminating zero byte.
--
-- - Function: unsigned int if_nametoindex (const char *ifname)
-- This function yields the interface index corresponding to a
-- particular name. If no interface exists with the name given, it
-- returns 0.
--
-- - Function: char * if_indextoname (unsigned int ifindex, char *ifname)
-- This function maps an interface index to its corresponding name.
-- The returned name is placed in the buffer pointed to by `ifname',
-- which must be at least `IFNAMSIZE' bytes in length. If the index
-- was invalid, the function's return value is a null pointer,
-- otherwise it is `ifname'.
--
-- - Data Type: struct if_nameindex
-- This data type is used to hold the information about a single
-- interface. It has the following members:
--
-- `unsigned int if_index;'
-- This is the interface index.
--
-- `char *if_name'
-- This is the null-terminated index name.
--
--
-- - Function: struct if_nameindex * if_nameindex (void)
-- This function returns an array of `if_nameindex' structures, one
-- for every interface that is present. The end of the list is
-- indicated by a structure with an interface of 0 and a null name
-- pointer. If an error occurs, this function returns a null pointer.
--
-- The returned structure must be freed with `if_freenameindex' after
-- use.
--
-- - Function: void if_freenameindex (struct if_nameindex *ptr)
-- This function frees the structure returned by an earlier call to
-- `if_nameindex'.
--
--
--File: libc.info, Node: Local Namespace, Next: Internet Namespace, Prev: Interface Naming, Up: Sockets
--
--The Local Namespace
--===================
--
-- This section describes the details of the local namespace, whose
--symbolic name (required when you create a socket) is `PF_LOCAL'. The
--local namespace is also known as "Unix domain sockets". Another name
--is file namespace since socket addresses are normally implemented as
--file names.
--
--* Menu:
--
--* Concepts: Local Namespace Concepts. What you need to understand.
--* Details: Local Namespace Details. Address format, symbolic names, etc.
--* Example: Local Socket Example. Example of creating a socket.
--
--
--File: libc.info, Node: Local Namespace Concepts, Next: Local Namespace Details, Up: Local Namespace
--
--Local Namespace Concepts
--------------------------
--
-- In the local namespace, socket addresses are file names. You can
--specify any file name you want as the address of the socket, but you
--must have write permission on the directory containing it. In order to
--connect to a socket, you must have read permission for it. It's common
--to put these files in the `/tmp' directory.
--
-- One peculiarity of the local namespace is that the name is only used
--when opening the connection; once that is over with, the address is not
--meaningful and may not exist.
--
-- Another peculiarity is that you cannot connect to such a socket from
--another machine-not even if the other machine shares the file system
--which contains the name of the socket. You can see the socket in a
--directory listing, but connecting to it never succeeds. Some programs
--take advantage of this, such as by asking the client to send its own
--process ID, and using the process IDs to distinguish between clients.
--However, we recommend you not to use this method in protocols you
--design, as we might someday permit connections from other machines that
--mount the same file systems. Instead, send each new client an
--identifying number if you want it to have one.
--
-- After you close a socket in the local namespace, you should delete
--the file name from the file system. Use `unlink' or `remove' to do
--this; see *Note Deleting Files::.
--
-- The local namespace supports just one protocol for any communication
--style; it is protocol number `0'.
--
--
--File: libc.info, Node: Local Namespace Details, Next: Local Socket Example, Prev: Local Namespace Concepts, Up: Local Namespace
--
--Details of Local Namespace
----------------------------
--
-- To create a socket in the local namespace, use the constant
--`PF_LOCAL' as the NAMESPACE argument to `socket' or `socketpair'. This
--constant is defined in `sys/socket.h'.
--
-- - Macro: int PF_LOCAL
-- This designates the local namespace, in which socket addresses are
-- local names, and its associated family of protocols. `PF_Local'
-- is the macro used by Posix.1g.
--
-- - Macro: int PF_UNIX
-- This is a synonym for `PF_LOCAL', for compatibility's sake.
--
-- - Macro: int PF_FILE
-- This is a synonym for `PF_LOCAL', for compatibility's sake.
--
-- The structure for specifying socket names in the local namespace is
--defined in the header file `sys/un.h':
--
-- - Data Type: struct sockaddr_un
-- This structure is used to specify local namespace socket
-- addresses. It has the following members:
--
-- `short int sun_family'
-- This identifies the address family or format of the socket
-- address. You should store the value `AF_LOCAL' to designate
-- the local namespace. *Note Socket Addresses::.
--
-- `char sun_path[108]'
-- This is the file name to use.
--
-- *Incomplete:* Why is 108 a magic number? RMS suggests making
-- this a zero-length array and tweaking the example following
-- to use `alloca' to allocate an appropriate amount of storage
-- based on the length of the filename.
--
-- You should compute the LENGTH parameter for a socket address in the
--local namespace as the sum of the size of the `sun_family' component
--and the string length (*not* the allocation size!) of the file name
--string. This can be done using the macro `SUN_LEN':
--
-- - Macro: int SUN_LEN (*struct sockaddr_un ** PTR)
-- The macro computes the length of socket address in the local
-- namespace.
--
--
--File: libc.info, Node: Local Socket Example, Prev: Local Namespace Details, Up: Local Namespace
--
--Example of Local-Namespace Sockets
------------------------------------
--
-- Here is an example showing how to create and name a socket in the
--local namespace.
--
-- #include <stddef.h>
-- #include <stdio.h>
-- #include <errno.h>
-- #include <stdlib.h>
-- #include <sys/socket.h>
-- #include <sys/un.h>
--
-- int
-- make_named_socket (const char *filename)
-- {
-- struct sockaddr_un name;
-- int sock;
-- size_t size;
--
-- /* Create the socket. */
-- sock = socket (PF_LOCAL, SOCK_DGRAM, 0);
-- if (sock < 0)
-- {
-- perror ("socket");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Bind a name to the socket. */
-- name.sun_family = AF_LOCAL;
-- strncpy (name.sun_path, filename, sizeof (name.sun_path));
--
-- /* The size of the address is
-- the offset of the start of the filename,
-- plus its length,
-- plus one for the terminating null byte.
-- Alternativly you can just do:
-- size = SUN_LEN (&name);
-- */
-- size = (offsetof (struct sockaddr_un, sun_path)
-- + strlen (name.sun_path) + 1);
--
-- if (bind (sock, (struct sockaddr *) &name, size) < 0)
-- {
-- perror ("bind");
-- exit (EXIT_FAILURE);
-- }
--
-- return sock;
-- }
--
--
--File: libc.info, Node: Internet Namespace, Next: Misc Namespaces, Prev: Local Namespace, Up: Sockets
--
--The Internet Namespace
--======================
--
-- This section describes the details of the protocols and socket naming
--conventions used in the Internet namespace.
--
-- Originaly the Internet namespace used only IP version 4 (IPv4). With
--the growing number of hosts on the Internet, a new protocol with a
--larger address space was neccessary: IP version 6 (IPv6). IPv6
--introduces besides 128bit addresses (IPv4 has 32bit addresses) also
--other features and will eventually replace IPv4.
--
-- To create a socket in the IPv4 Internet namespace, use the symbolic
--name `PF_INET' of this namespace as the NAMESPACE argument to `socket'
--or `socketpair'. For IPv6 addresses, you need the macro `PF_INET6'.
--These macros are defined in `sys/socket.h'.
--
-- - Macro: int PF_INET
-- This designates the IPv4 Internet namespace and associated family
-- of protocols.
--
-- - Macro: int AF_INET6
-- This designates the IPv6 Internet namespace and associated family
-- of protocols.
--
-- A socket address for the Internet namespace includes the following
--components:
--
-- * The address of the machine you want to connect to. Internet
-- addresses can be specified in several ways; these are discussed in
-- *Note Internet Address Formats::, *Note Host Addresses::, and
-- *Note Host Names::.
--
-- * A port number for that machine. *Note Ports::.
--
-- You must ensure that the address and port number are represented in a
--canonical format called "network byte order". *Note Byte Order::, for
--information about this.
--
--* Menu:
--
--* Internet Address Formats:: How socket addresses are specified in the
-- Internet namespace.
--* Host Addresses:: All about host addresses of internet host.
--* Protocols Database:: Referring to protocols by name.
--* Ports:: Internet port numbers.
--* Services Database:: Ports may have symbolic names.
--* Byte Order:: Different hosts may use different byte
-- ordering conventions; you need to
-- canonicalize host address and port number.
--* Inet Example:: Putting it all together.
--
--
--File: libc.info, Node: Internet Address Formats, Next: Host Addresses, Up: Internet Namespace
--
--Internet Socket Address Formats
---------------------------------
--
-- In the Internet namespace, for both IPv4 (`AF_INET') and IPv6
--(`AF_INET6'), a socket address consists of a host address and a port on
--that host. In addition, the protocol you choose serves effectively as
--a part of the address because local port numbers are meaningful only
--within a particular protocol.
--
-- The data types for representing socket addresses in the Internet
--namespace are defined in the header file `netinet/in.h'.
--
-- - Data Type: struct sockaddr_in
-- This is the data type used to represent socket addresses in the
-- Internet namespace. It has the following members:
--
-- `sa_family_t sin_family'
-- This identifies the address family or format of the socket
-- address. You should store the value of `AF_INET' in this
-- member. *Note Socket Addresses::.
--
-- `struct in_addr sin_addr'
-- This is the Internet address of the host machine. *Note Host
-- Addresses::, and *Note Host Names::, for how to get a value
-- to store here.
--
-- `unsigned short int sin_port'
-- This is the port number. *Note Ports::.
--
-- When you call `bind' or `getsockname', you should specify `sizeof
--(struct sockaddr_in)' as the LENGTH parameter if you are using an IPv4
--Internet namespace socket address.
--
-- - Data Type: struct sockaddr_in6
-- This is the data type used to represent socket addresses in the
-- IPv6 namespace. It has the following members:
--
-- `sa_family_t sin6_family'
-- This identifies the address family or format of the socket
-- address. You should store the value of `AF_INET6' in this
-- member. *Note Socket Addresses::.
--
-- `struct in6_addr sin6_addr'
-- This is the IPv6 address of the host machine. *Note Host
-- Addresses::, and *Note Host Names::, for how to get a value
-- to store here.
--
-- `uint32_t sin6_flowinfo'
-- This is a currently unimplemented field.
--
-- `uint16_t sin6_port'
-- This is the port number. *Note Ports::.
--
--
--
--File: libc.info, Node: Host Addresses, Next: Protocols Database, Prev: Internet Address Formats, Up: Internet Namespace
--
--Host Addresses
----------------
--
-- Each computer on the Internet has one or more "Internet addresses",
--numbers which identify that computer among all those on the Internet.
--Users typically write IPv4 numeric host addresses as sequences of four
--numbers, separated by periods, as in `128.52.46.32', and IPv6 numeric
--host addresses as sequences of up to eight numbers separated by colons,
--as in `5f03:1200:836f:c100::1'.
--
-- Each computer also has one or more "host names", which are strings
--of words separated by periods, as in `mescaline.gnu.org'.
--
-- Programs that let the user specify a host typically accept both
--numeric addresses and host names. But the program needs a numeric
--address to open a connection; to use a host name, you must convert it
--to the numeric address it stands for.
--
--* Menu:
--
--* Abstract Host Addresses:: What a host number consists of.
--* Data type: Host Address Data Type. Data type for a host number.
--* Functions: Host Address Functions. Functions to operate on them.
--* Names: Host Names. Translating host names to host numbers.
--
--
--File: libc.info, Node: Abstract Host Addresses, Next: Host Address Data Type, Up: Host Addresses
--
--Internet Host Addresses
--.......................
--
-- Each computer on the Internet has one or more Internet addresses,
--numbers which identify that computer among all those on the Internet.
--
-- An IPv4 Internet host address is a number containing four bytes of
--data. Historically these are divided into two parts, a "network
--number" and a "local network address number" within that network. In
--the mid-1990s classless address were introduced which changed the
--behaviour. Since some functions implicitly expect the old definitions,
--we first describe the class based network and will then describe
--classless addresses. IPv6 uses only classless adresses and therefore
--the following paragraphs don't apply.
--
-- The class based IPv4 network number consists of the first one, two or
--three bytes; the rest of the bytes are the local address.
--
-- IPv4 network numbers are registered with the Network Information
--Center (NIC), and are divided into three classes--A, B, and C. The
--local network address numbers of individual machines are registered
--with the administrator of the particular network.
--
-- Class A networks have single-byte numbers in the range 0 to 127.
--There are only a small number of Class A networks, but they can each
--support a very large number of hosts. Medium-sized Class B networks
--have two-byte network numbers, with the first byte in the range 128 to
--191. Class C networks are the smallest; they have three-byte network
--numbers, with the first byte in the range 192-255. Thus, the first 1,
--2, or 3 bytes of an Internet address specifies a network. The
--remaining bytes of the Internet address specify the address within that
--network.
--
-- The Class A network 0 is reserved for broadcast to all networks. In
--addition, the host number 0 within each network is reserved for
--broadcast to all hosts in that network. These uses are obsolete now
--but out of compatibility reasons you shouldn't use network 0 and host
--number 0.
--
-- The Class A network 127 is reserved for loopback; you can always use
--the Internet address `127.0.0.1' to refer to the host machine.
--
-- Since a single machine can be a member of multiple networks, it can
--have multiple Internet host addresses. However, there is never
--supposed to be more than one machine with the same host address.
--
-- There are four forms of the "standard numbers-and-dots notation" for
--Internet addresses:
--
--`A.B.C.D'
-- This specifies all four bytes of the address individually and is
-- the commonly used representation.
--
--`A.B.C'
-- The last part of the address, C, is interpreted as a 2-byte
-- quantity. This is useful for specifying host addresses in a Class
-- B network with network address number `A.B'.
--
--`A.B'
-- The last part of the address, B, is interpreted as a 3-byte
-- quantity. This is useful for specifying host addresses in a Class
-- A network with network address number A.
--
--`A'
-- If only one part is given, this corresponds directly to the host
-- address number.
--
-- Within each part of the address, the usual C conventions for
--specifying the radix apply. In other words, a leading `0x' or `0X'
--implies hexadecimal radix; a leading `0' implies octal; and otherwise
--decimal radix is assumed.
--
--Classless Addresses
--...................
--
-- IPv4 addresses (and IPv6 addresses also) are now considered as
--classless. The distinction between classes A, B, and C can be ignored.
--Instead a IPv4 host adddress consists of a 32-bit address and a 32-bit
--mask. The mask contains bits of 1 for the network part and bits of 0
--for the host part. The 1-bits are contigous from the leftmost bit, the
--0-bits are contigous from the rightmost bit so that the netmask can also
--be written as a prefix length of bits of 1. Classes A, B and C are just
--special cases of this general rule. For example, class A addresses have
--a netmask of `255.0.0.0' or a prefix length of 8.
--
-- Classless IPv4 network addresses are written in numbers-and-dots
--notation with the prefix length appended and a slash as separator. For
--example the class A network 10 is written as `10.0.0.0/8'.
--
--IPv6 Addresses
--..............
--
-- IPv6 addresses contain 128 bits (IPv4 has 32 bits) of data. A host
--address is usually written as eight 16-bit hexadecimal numbers that are
--separated by colons. Two colons are used to abbreviate strings of
--consecutive zeros. For example the IPv6 loopback address which is
--`0:0:0:0:0:0:0:1' can be just written as `::1'.
--
--
--File: libc.info, Node: Host Address Data Type, Next: Host Address Functions, Prev: Abstract Host Addresses, Up: Host Addresses
--
--Host Address Data Type
--......................
--
-- IPv4 Internet host addresses are represented in some contexts as
--integers (type `uint32_t'). In other contexts, the integer is packaged
--inside a structure of type `struct in_addr'. It would be better if the
--usage were made consistent, but it is not hard to extract the integer
--from the structure or put the integer into a structure.
--
-- You will find older code that uses `unsigned long int' for IPv4
--Internet host addresses instead of `uint32_t' or `struct in_addr'.
--Historically `unsigned long int' was a 32 bit number but with 64 bit
--machines this has changed. Using `unsigned long int' might break the
--code if it is used on machines where this type doesn't have 32 bits.
--`uint32_t' is specified by Unix98 and guaranteed to have 32 bits.
--
-- IPv6 Internet host addresses have 128 bits and are packaged inside a
--structure of type `struct in6_addr'.
--
-- The following basic definitions for Internet addresses are declared
--in the header file `netinet/in.h':
--
-- - Data Type: struct in_addr
-- This data type is used in certain contexts to contain an IPv4
-- Internet host address. It has just one field, named `s_addr',
-- which records the host address number as an `uint32_t'.
--
-- - Macro: uint32_t INADDR_LOOPBACK
-- You can use this constant to stand for "the address of this
-- machine," instead of finding its actual address. It is the IPv4
-- Internet address `127.0.0.1', which is usually called `localhost'.
-- This special constant saves you the trouble of looking up the
-- address of your own machine. Also, the system usually implements
-- `INADDR_LOOPBACK' specially, avoiding any network traffic for the
-- case of one machine talking to itself.
--
-- - Macro: uint32_t INADDR_ANY
-- You can use this constant to stand for "any incoming address," when
-- binding to an address. *Note Setting Address::. This is the usual
-- address to give in the `sin_addr' member of `struct sockaddr_in'
-- when you want to accept Internet connections.
--
-- - Macro: uint32_t INADDR_BROADCAST
-- This constant is the address you use to send a broadcast message.
--
-- - Macro: uint32_t INADDR_NONE
-- This constant is returned by some functions to indicate an error.
--
-- - Data Type: struct in6_addr
-- This data type is used to store an IPv6 address. It stores 128
-- bits of data, which can be accessed (via a union) in a variety of
-- ways.
--
-- - Constant: struct in6_addr in6addr_loopback
-- This constant is the IPv6 address `::1', the loopback address. See
-- above for a description of what this means. The macro
-- `IN6ADDR_LOOPBACK_INIT' is provided to allow you to initialise your
-- own variables to this value.
--
-- - Constant: struct in6_addr in6addr_any
-- This constant is the IPv6 address `::', the unspecified address.
-- See above for a description of what this means. The macro
-- `IN6ADDR_ANY_INIT' is provided to allow you to initialise your own
-- variables to this value.
--
--
--File: libc.info, Node: Host Address Functions, Next: Host Names, Prev: Host Address Data Type, Up: Host Addresses
--
--Host Address Functions
--......................
--
--These additional functions for manipulating Internet addresses are
--declared in the header file `arpa/inet.h'. They represent Internet
--addresses in network byte order; they represent network numbers and
--local-address-within-network numbers in host byte order. *Note Byte
--Order::, for an explanation of network and host byte order.
--
-- - Function: int inet_aton (const char *NAME, struct in_addr *ADDR)
-- This function converts the IPv4 Internet host address NAME from
-- the standard numbers-and-dots notation into binary data and stores
-- it in the `struct in_addr' that ADDR points to. `inet_aton'
-- returns nonzero if the address is valid, zero if not.
--
-- - Function: uint32_t inet_addr (const char *NAME)
-- This function converts the IPv4 Internet host address NAME from the
-- standard numbers-and-dots notation into binary data. If the input
-- is not valid, `inet_addr' returns `INADDR_NONE'. This is an
-- obsolete interface to `inet_aton', described immediately above; it
-- is obsolete because `INADDR_NONE' is a valid address
-- (255.255.255.255), and `inet_aton' provides a cleaner way to
-- indicate error return.
--
-- - Function: uint32_t inet_network (const char *NAME)
-- This function extracts the network number from the address NAME,
-- given in the standard numbers-and-dots notation. The returned
-- address is in host order. If the input is not valid,
-- `inet_network' returns `-1'.
--
-- The function works only with traditional IPv4 class A, B and C
-- network types. It doesn't work with classless addresses and
-- shouldn't be used anymore.
--
-- - Function: char * inet_ntoa (struct in_addr ADDR)
-- This function converts the IPv4 Internet host address ADDR to a
-- string in the standard numbers-and-dots notation. The return
-- value is a pointer into a statically-allocated buffer. Subsequent
-- calls will overwrite the same buffer, so you should copy the
-- string if you need to save it.
--
-- In multi-threaded programs each thread has an own
-- statically-allocated buffer. But still subsequent calls of
-- `inet_ntoa' in the same thread will overwrite the result of the
-- last call.
--
-- Instead of `inet_ntoa' the newer function `inet_ntop' which is
-- described below should be used since it handles both IPv4 and IPv6
-- addresses.
--
-- - Function: struct in_addr inet_makeaddr (uint32_t NET, uint32_t LOCAL)
-- This function makes an IPv4 Internet host address by combining the
-- network number NET with the local-address-within-network number
-- LOCAL.
--
-- - Function: uint32_t inet_lnaof (struct in_addr ADDR)
-- This function returns the local-address-within-network part of the
-- Internet host address ADDR.
--
-- The function works only with traditional IPv4 class A, B and C
-- network types. It doesn't work with classless addresses and
-- shouldn't be used anymore.
--
-- - Function: uint32_t inet_netof (struct in_addr ADDR)
-- This function returns the network number part of the Internet host
-- address ADDR.
--
-- The function works only with traditional IPv4 class A, B and C
-- network types. It doesn't work with classless addresses and
-- shouldn't be used anymore.
--
-- - Function: int inet_pton (int AF, const char *CP, void *BUF)
-- This function converts an Internet address (either IPv4 or IPv6)
-- from presentation (textual) to network (binary) format. AF should
-- be either `AF_INET' or `AF_INET6', as appropriate for the type of
-- address being converted. CP is a pointer to the input string, and
-- BUF is a pointer to a buffer for the result. It is the caller's
-- responsibility to make sure the buffer is large enough.
--
-- - Function: const char * inet_ntop (int AF, const void *CP, char *BUF,
-- size_t LEN)
-- This function converts an Internet address (either IPv4 or IPv6)
-- from network (binary) to presentation (textual) form. AF should be
-- either `AF_INET' or `AF_INET6', as appropriate. CP is a pointer
-- to the address to be converted. BUF should be a pointer to a
-- buffer to hold the result, and LEN is the length of this buffer.
-- The return value from the function will be this buffer address.
--
--
--File: libc.info, Node: Host Names, Prev: Host Address Functions, Up: Host Addresses
--
--Host Names
--..........
--
-- Besides the standard numbers-and-dots notation for Internet
--addresses, you can also refer to a host by a symbolic name. The
--advantage of a symbolic name is that it is usually easier to remember.
--For example, the machine with Internet address `158.121.106.19' is also
--known as `alpha.gnu.org'; and other machines in the `gnu.org' domain
--can refer to it simply as `alpha'.
--
-- Internally, the system uses a database to keep track of the mapping
--between host names and host numbers. This database is usually either
--the file `/etc/hosts' or an equivalent provided by a name server. The
--functions and other symbols for accessing this database are declared in
--`netdb.h'. They are BSD features, defined unconditionally if you
--include `netdb.h'.
--
-- - Data Type: struct hostent
-- This data type is used to represent an entry in the hosts
-- database. It has the following members:
--
-- `char *h_name'
-- This is the "official" name of the host.
--
-- `char **h_aliases'
-- These are alternative names for the host, represented as a
-- null-terminated vector of strings.
--
-- `int h_addrtype'
-- This is the host address type; in practice, its value is
-- always either `AF_INET' or `AF_INET6', with the latter being
-- used for IPv6 hosts. In principle other kinds of addresses
-- could be represented in the data base as well as Internet
-- addresses; if this were done, you might find a value in this
-- field other than `AF_INET' or `AF_INET6'. *Note Socket
-- Addresses::.
--
-- `int h_length'
-- This is the length, in bytes, of each address.
--
-- `char **h_addr_list'
-- This is the vector of addresses for the host. (Recall that
-- the host might be connected to multiple networks and have
-- different addresses on each one.) The vector is terminated
-- by a null pointer.
--
-- `char *h_addr'
-- This is a synonym for `h_addr_list[0]'; in other words, it is
-- the first host address.
--
-- As far as the host database is concerned, each address is just a
--block of memory `h_length' bytes long. But in other contexts there is
--an implicit assumption that you can convert IPv4 addresses to a `struct
--in_addr' or an `uint32_t'. Host addresses in a `struct hostent'
--structure are always given in network byte order; see *Note Byte
--Order::.
--
-- You can use `gethostbyname', `gethostbyname2' or `gethostbyaddr' to
--search the hosts database for information about a particular host. The
--information is returned in a statically-allocated structure; you must
--copy the information if you need to save it across calls. You can also
--use `getaddrinfo' and `getnameinfo' to obtain this information.
--
-- - Function: struct hostent * gethostbyname (const char *NAME)
-- The `gethostbyname' function returns information about the host
-- named NAME. If the lookup fails, it returns a null pointer.
--
-- - Function: struct hostent * gethostbyname2 (const char *NAME, int AF)
-- The `gethostbyname2' function is like `gethostbyname', but allows
-- the caller to specify the desired address family (e.g. `AF_INET'
-- or `AF_INET6') for the result.
--
-- - Function: struct hostent * gethostbyaddr (const char *ADDR, int
-- LENGTH, int FORMAT)
-- The `gethostbyaddr' function returns information about the host
-- with Internet address ADDR. The parameter ADDR is not really a
-- pointer to char - it can be a pointer to an IPv4 or an IPv6
-- address. The LENGTH argument is the size (in bytes) of the address
-- at ADDR. FORMAT specifies the address format; for an IPv4
-- Internet address, specify a value of `AF_INET'; for an IPv6
-- Internet address, use `AF_INET6'.
--
-- If the lookup fails, `gethostbyaddr' returns a null pointer.
--
-- If the name lookup by `gethostbyname' or `gethostbyaddr' fails, you
--can find out the reason by looking at the value of the variable
--`h_errno'. (It would be cleaner design for these functions to set
--`errno', but use of `h_errno' is compatible with other systems.)
--
-- Here are the error codes that you may find in `h_errno':
--
--`HOST_NOT_FOUND'
-- No such host is known in the data base.
--
--`TRY_AGAIN'
-- This condition happens when the name server could not be
-- contacted. If you try again later, you may succeed then.
--
--`NO_RECOVERY'
-- A non-recoverable error occurred.
--
--`NO_ADDRESS'
-- The host database contains an entry for the name, but it doesn't
-- have an associated Internet address.
--
-- The lookup functions above all have one in common: they are not
--reentrant and therefore unusable in multi-threaded applications.
--Therefore provides the GNU C library a new set of functions which can be
--used in this context.
--
-- - Function: int gethostbyname_r (const char *restrict NAME, struct
-- hostent *restrict RESULT_BUF, char *restrict BUF, size_t
-- BUFLEN, struct hostent **restrict RESULT, int *restrict
-- H_ERRNOP)
-- The `gethostbyname_r' function returns information about the host
-- named NAME. The caller must pass a pointer to an object of type
-- `struct hostent' in the RESULT_BUF parameter. In addition the
-- function may need extra buffer space and the caller must pass an
-- pointer and the size of the buffer in the BUF and BUFLEN
-- parameters.
--
-- A pointer to the buffer, in which the result is stored, is
-- available in `*RESULT' after the function call successfully
-- returned. If an error occurs or if no entry is found, the pointer
-- `*RESULT' is a null pointer. Success is signalled by a zero
-- return value. If the function failed the return value is an error
-- number. In addition to the errors defined for `gethostbyname' it
-- can also be `ERANGE'. In this case the call should be repeated
-- with a larger buffer. Additional error information is not stored
-- in the global variable `h_errno' but instead in the object pointed
-- to by H_ERRNOP.
--
-- Here's a small example:
-- struct hostent *
-- gethostname (char *host)
-- {
-- struct hostent hostbuf, *hp;
-- size_t hstbuflen;
-- char *tmphstbuf;
-- int res;
-- int herr;
--
-- hstbuflen = 1024;
-- tmphstbuf = malloc (hstbuflen);
--
-- while ((res = gethostbyname_r (host, &hostbuf, tmphstbuf, hstbuflen,
-- &hp, &herr)) == ERANGE)
-- {
-- /* Enlarge the buffer. */
-- hstbuflen *= 2;
-- tmphstbuf = realloc (tmphstbuf, hstbuflen);
-- }
-- /* Check for errors. */
-- if (res || hp == NULL)
-- return NULL;
-- return hp->h_name;
-- }
--
-- - Function: int gethostbyname2_r (const char *NAME, int AF, struct
-- hostent *restrict RESULT_BUF, char *restrict BUF, size_t
-- BUFLEN, struct hostent **restrict RESULT, int *restrict
-- H_ERRNOP)
-- The `gethostbyname2_r' function is like `gethostbyname_r', but
-- allows the caller to specify the desired address family (e.g.
-- `AF_INET' or `AF_INET6') for the result.
--
-- - Function: int gethostbyaddr_r (const char *ADDR, int LENGTH, int
-- FORMAT, struct hostent *restrict RESULT_BUF, char *restrict
-- BUF, size_t BUFLEN, struct hostent **restrict RESULT, int
-- *restrict H_ERRNOP)
-- The `gethostbyaddr_r' function returns information about the host
-- with Internet address ADDR. The parameter ADDR is not really a
-- pointer to char - it can be a pointer to an IPv4 or an IPv6
-- address. The LENGTH argument is the size (in bytes) of the address
-- at ADDR. FORMAT specifies the address format; for an IPv4
-- Internet address, specify a value of `AF_INET'; for an IPv6
-- Internet address, use `AF_INET6'.
--
-- Similar to the `gethostbyname_r' function, the caller must provide
-- buffers for the result and memory used internally. In case of
-- success the function returns zero. Otherwise the value is an
-- error number where `ERANGE' has the special meaning that the
-- caller-provided buffer is too small.
--
-- You can also scan the entire hosts database one entry at a time using
--`sethostent', `gethostent', and `endhostent'. Be careful in using
--these functions, because they are not reentrant.
--
-- - Function: void sethostent (int STAYOPEN)
-- This function opens the hosts database to begin scanning it. You
-- can then call `gethostent' to read the entries.
--
-- If the STAYOPEN argument is nonzero, this sets a flag so that
-- subsequent calls to `gethostbyname' or `gethostbyaddr' will not
-- close the database (as they usually would). This makes for more
-- efficiency if you call those functions several times, by avoiding
-- reopening the database for each call.
--
-- - Function: struct hostent * gethostent (void)
-- This function returns the next entry in the hosts database. It
-- returns a null pointer if there are no more entries.
--
-- - Function: void endhostent (void)
-- This function closes the hosts database.
--
--
--File: libc.info, Node: Ports, Next: Services Database, Prev: Protocols Database, Up: Internet Namespace
--
--Internet Ports
----------------
--
-- A socket address in the Internet namespace consists of a machine's
--Internet address plus a "port number" which distinguishes the sockets
--on a given machine (for a given protocol). Port numbers range from 0
--to 65,535.
--
-- Port numbers less than `IPPORT_RESERVED' are reserved for standard
--servers, such as `finger' and `telnet'. There is a database that keeps
--track of these, and you can use the `getservbyname' function to map a
--service name onto a port number; see *Note Services Database::.
--
-- If you write a server that is not one of the standard ones defined in
--the database, you must choose a port number for it. Use a number
--greater than `IPPORT_USERRESERVED'; such numbers are reserved for
--servers and won't ever be generated automatically by the system.
--Avoiding conflicts with servers being run by other users is up to you.
--
-- When you use a socket without specifying its address, the system
--generates a port number for it. This number is between
--`IPPORT_RESERVED' and `IPPORT_USERRESERVED'.
--
-- On the Internet, it is actually legitimate to have two different
--sockets with the same port number, as long as they never both try to
--communicate with the same socket address (host address plus port
--number). You shouldn't duplicate a port number except in special
--circumstances where a higher-level protocol requires it. Normally, the
--system won't let you do it; `bind' normally insists on distinct port
--numbers. To reuse a port number, you must set the socket option
--`SO_REUSEADDR'. *Note Socket-Level Options::.
--
-- These macros are defined in the header file `netinet/in.h'.
--
-- - Macro: int IPPORT_RESERVED
-- Port numbers less than `IPPORT_RESERVED' are reserved for
-- superuser use.
--
-- - Macro: int IPPORT_USERRESERVED
-- Port numbers greater than or equal to `IPPORT_USERRESERVED' are
-- reserved for explicit use; they will never be allocated
-- automatically.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-24 glibc-2.1.3/manual/libc.info-24
---- ../glibc-2.1.3/manual/libc.info-24 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-24 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1331 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Services Database, Next: Byte Order, Prev: Ports, Up: Internet Namespace
--
--The Services Database
-----------------------
--
-- The database that keeps track of "well-known" services is usually
--either the file `/etc/services' or an equivalent from a name server.
--You can use these utilities, declared in `netdb.h', to access the
--services database.
--
-- - Data Type: struct servent
-- This data type holds information about entries from the services
-- database. It has the following members:
--
-- `char *s_name'
-- This is the "official" name of the service.
--
-- `char **s_aliases'
-- These are alternate names for the service, represented as an
-- array of strings. A null pointer terminates the array.
--
-- `int s_port'
-- This is the port number for the service. Port numbers are
-- given in network byte order; see *Note Byte Order::.
--
-- `char *s_proto'
-- This is the name of the protocol to use with this service.
-- *Note Protocols Database::.
--
-- To get information about a particular service, use the
--`getservbyname' or `getservbyport' functions. The information is
--returned in a statically-allocated structure; you must copy the
--information if you need to save it across calls.
--
-- - Function: struct servent * getservbyname (const char *NAME, const
-- char *PROTO)
-- The `getservbyname' function returns information about the service
-- named NAME using protocol PROTO. If it can't find such a service,
-- it returns a null pointer.
--
-- This function is useful for servers as well as for clients; servers
-- use it to determine which port they should listen on (*note
-- Listening::.).
--
-- - Function: struct servent * getservbyport (int PORT, const char
-- *PROTO)
-- The `getservbyport' function returns information about the service
-- at port PORT using protocol PROTO. If it can't find such a
-- service, it returns a null pointer.
--
--You can also scan the services database using `setservent',
--`getservent', and `endservent'. Be careful in using these functions,
--because they are not reentrant.
--
-- - Function: void setservent (int STAYOPEN)
-- This function opens the services database to begin scanning it.
--
-- If the STAYOPEN argument is nonzero, this sets a flag so that
-- subsequent calls to `getservbyname' or `getservbyport' will not
-- close the database (as they usually would). This makes for more
-- efficiency if you call those functions several times, by avoiding
-- reopening the database for each call.
--
-- - Function: struct servent * getservent (void)
-- This function returns the next entry in the services database. If
-- there are no more entries, it returns a null pointer.
--
-- - Function: void endservent (void)
-- This function closes the services database.
--
--
--File: libc.info, Node: Byte Order, Next: Inet Example, Prev: Services Database, Up: Internet Namespace
--
--Byte Order Conversion
-----------------------
--
-- Different kinds of computers use different conventions for the
--ordering of bytes within a word. Some computers put the most
--significant byte within a word first (this is called "big-endian"
--order), and others put it last ("little-endian" order).
--
-- So that machines with different byte order conventions can
--communicate, the Internet protocols specify a canonical byte order
--convention for data transmitted over the network. This is known as the
--"network byte order".
--
-- When establishing an Internet socket connection, you must make sure
--that the data in the `sin_port' and `sin_addr' members of the
--`sockaddr_in' structure are represented in the network byte order. If
--you are encoding integer data in the messages sent through the socket,
--you should convert this to network byte order too. If you don't do
--this, your program may fail when running on or talking to other kinds
--of machines.
--
-- If you use `getservbyname' and `gethostbyname' or `inet_addr' to get
--the port number and host address, the values are already in the network
--byte order, and you can copy them directly into the `sockaddr_in'
--structure.
--
-- Otherwise, you have to convert the values explicitly. Use `htons'
--and `ntohs' to convert values for the `sin_port' member. Use `htonl'
--and `ntohl' to convert IPv4 addresses for the `sin_addr' member.
--(Remember, `struct in_addr' is equivalent to `uint32_t'.) These
--functions are declared in `netinet/in.h'.
--
-- - Function: uint16_t htons (uint16_t HOSTSHORT)
-- This function converts the `uint16_t' integer HOSTSHORT from host
-- byte order to network byte order.
--
-- - Function: uint16_t ntohs (uint16_t NETSHORT)
-- This function converts the `uint16_t' integer NETSHORT from
-- network byte order to host byte order.
--
-- - Function: uint32_t htonl (uint32_t HOSTLONG)
-- This function converts the `uint32_t' integer HOSTLONG from host
-- byte order to network byte order.
--
-- This is used for IPv4 internet addresses.
--
-- - Function: uint32_t ntohl (uint32_t NETLONG)
-- This function converts the `uint32_t' integer NETLONG from network
-- byte order to host byte order.
--
-- This is used for IPv4 internet addresses.
--
--
--File: libc.info, Node: Protocols Database, Next: Ports, Prev: Host Addresses, Up: Internet Namespace
--
--Protocols Database
--------------------
--
-- The communications protocol used with a socket controls low-level
--details of how data is exchanged. For example, the protocol implements
--things like checksums to detect errors in transmissions, and routing
--instructions for messages. Normal user programs have little reason to
--mess with these details directly.
--
-- The default communications protocol for the Internet namespace
--depends on the communication style. For stream communication, the
--default is TCP ("transmission control protocol"). For datagram
--communication, the default is UDP ("user datagram protocol"). For
--reliable datagram communication, the default is RDP ("reliable datagram
--protocol"). You should nearly always use the default.
--
-- Internet protocols are generally specified by a name instead of a
--number. The network protocols that a host knows about are stored in a
--database. This is usually either derived from the file
--`/etc/protocols', or it may be an equivalent provided by a name server.
--You look up the protocol number associated with a named protocol in
--the database using the `getprotobyname' function.
--
-- Here are detailed descriptions of the utilities for accessing the
--protocols database. These are declared in `netdb.h'.
--
-- - Data Type: struct protoent
-- This data type is used to represent entries in the network
-- protocols database. It has the following members:
--
-- `char *p_name'
-- This is the official name of the protocol.
--
-- `char **p_aliases'
-- These are alternate names for the protocol, specified as an
-- array of strings. The last element of the array is a null
-- pointer.
--
-- `int p_proto'
-- This is the protocol number (in host byte order); use this
-- member as the PROTOCOL argument to `socket'.
--
-- You can use `getprotobyname' and `getprotobynumber' to search the
--protocols database for a specific protocol. The information is
--returned in a statically-allocated structure; you must copy the
--information if you need to save it across calls.
--
-- - Function: struct protoent * getprotobyname (const char *NAME)
-- The `getprotobyname' function returns information about the
-- network protocol named NAME. If there is no such protocol, it
-- returns a null pointer.
--
-- - Function: struct protoent * getprotobynumber (int PROTOCOL)
-- The `getprotobynumber' function returns information about the
-- network protocol with number PROTOCOL. If there is no such
-- protocol, it returns a null pointer.
--
-- You can also scan the whole protocols database one protocol at a
--time by using `setprotoent', `getprotoent', and `endprotoent'. Be
--careful in using these functions, because they are not reentrant.
--
-- - Function: void setprotoent (int STAYOPEN)
-- This function opens the protocols database to begin scanning it.
--
-- If the STAYOPEN argument is nonzero, this sets a flag so that
-- subsequent calls to `getprotobyname' or `getprotobynumber' will
-- not close the database (as they usually would). This makes for
-- more efficiency if you call those functions several times, by
-- avoiding reopening the database for each call.
--
-- - Function: struct protoent * getprotoent (void)
-- This function returns the next entry in the protocols database. It
-- returns a null pointer if there are no more entries.
--
-- - Function: void endprotoent (void)
-- This function closes the protocols database.
--
--
--File: libc.info, Node: Inet Example, Prev: Byte Order, Up: Internet Namespace
--
--Internet Socket Example
-------------------------
--
-- Here is an example showing how to create and name a socket in the
--Internet namespace. The newly created socket exists on the machine that
--the program is running on. Rather than finding and using the machine's
--Internet address, this example specifies `INADDR_ANY' as the host
--address; the system replaces that with the machine's actual address.
--
-- #include <stdio.h>
-- #include <stdlib.h>
-- #include <sys/socket.h>
-- #include <netinet/in.h>
--
-- int
-- make_socket (uint16_t port)
-- {
-- int sock;
-- struct sockaddr_in name;
--
-- /* Create the socket. */
-- sock = socket (PF_INET, SOCK_STREAM, 0);
-- if (sock < 0)
-- {
-- perror ("socket");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Give the socket a name. */
-- name.sin_family = AF_INET;
-- name.sin_port = htons (port);
-- name.sin_addr.s_addr = htonl (INADDR_ANY);
-- if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
-- {
-- perror ("bind");
-- exit (EXIT_FAILURE);
-- }
--
-- return sock;
-- }
--
-- Here is another example, showing how you can fill in a `sockaddr_in'
--structure, given a host name string and a port number:
--
-- #include <stdio.h>
-- #include <stdlib.h>
-- #include <sys/socket.h>
-- #include <netinet/in.h>
-- #include <netdb.h>
--
-- void
-- init_sockaddr (struct sockaddr_in *name,
-- const char *hostname,
-- uint16_t port)
-- {
-- struct hostent *hostinfo;
--
-- name->sin_family = AF_INET;
-- name->sin_port = htons (port);
-- hostinfo = gethostbyname (hostname);
-- if (hostinfo == NULL)
-- {
-- fprintf (stderr, "Unknown host %s.\n", hostname);
-- exit (EXIT_FAILURE);
-- }
-- name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
-- }
--
--
--File: libc.info, Node: Misc Namespaces, Next: Open/Close Sockets, Prev: Internet Namespace, Up: Sockets
--
--Other Namespaces
--================
--
-- Certain other namespaces and associated protocol families are
--supported but not documented yet because they are not often used.
--`PF_NS' refers to the Xerox Network Software protocols. `PF_ISO' stands
--for Open Systems Interconnect. `PF_CCITT' refers to protocols from
--CCITT. `socket.h' defines these symbols and others naming protocols
--not actually implemented.
--
-- `PF_IMPLINK' is used for communicating between hosts and Internet
--Message Processors. For information on this, and on `PF_ROUTE', an
--occasionally-used local area routing protocol, see the GNU Hurd Manual
--(to appear in the future).
--
--
--File: libc.info, Node: Open/Close Sockets, Next: Connections, Prev: Misc Namespaces, Up: Sockets
--
--Opening and Closing Sockets
--===========================
--
-- This section describes the actual library functions for opening and
--closing sockets. The same functions work for all namespaces and
--connection styles.
--
--* Menu:
--
--* Creating a Socket:: How to open a socket.
--* Closing a Socket:: How to close a socket.
--* Socket Pairs:: These are created like pipes.
--
--
--File: libc.info, Node: Creating a Socket, Next: Closing a Socket, Up: Open/Close Sockets
--
--Creating a Socket
-------------------
--
-- The primitive for creating a socket is the `socket' function,
--declared in `sys/socket.h'.
--
-- - Function: int socket (int NAMESPACE, int STYLE, int PROTOCOL)
-- This function creates a socket and specifies communication style
-- STYLE, which should be one of the socket styles listed in *Note
-- Communication Styles::. The NAMESPACE argument specifies the
-- namespace; it must be `PF_LOCAL' (*note Local Namespace::.) or
-- `PF_INET' (*note Internet Namespace::.). PROTOCOL designates the
-- specific protocol (*note Socket Concepts::.); zero is usually
-- right for PROTOCOL.
--
-- The return value from `socket' is the file descriptor for the new
-- socket, or `-1' in case of error. The following `errno' error
-- conditions are defined for this function:
--
-- `EPROTONOSUPPORT'
-- The PROTOCOL or STYLE is not supported by the NAMESPACE
-- specified.
--
-- `EMFILE'
-- The process already has too many file descriptors open.
--
-- `ENFILE'
-- The system already has too many file descriptors open.
--
-- `EACCESS'
-- The process does not have privilege to create a socket of the
-- specified STYLE or PROTOCOL.
--
-- `ENOBUFS'
-- The system ran out of internal buffer space.
--
-- The file descriptor returned by the `socket' function supports both
-- read and write operations. But, like pipes, sockets do not
-- support file positioning operations.
--
-- For examples of how to call the `socket' function, see *Note Local
--Socket Example::, or *Note Inet Example::.
--
--
--File: libc.info, Node: Closing a Socket, Next: Socket Pairs, Prev: Creating a Socket, Up: Open/Close Sockets
--
--Closing a Socket
------------------
--
-- When you are finished using a socket, you can simply close its file
--descriptor with `close'; see *Note Opening and Closing Files::. If
--there is still data waiting to be transmitted over the connection,
--normally `close' tries to complete this transmission. You can control
--this behavior using the `SO_LINGER' socket option to specify a timeout
--period; see *Note Socket Options::.
--
-- You can also shut down only reception or only transmission on a
--connection by calling `shutdown', which is declared in `sys/socket.h'.
--
-- - Function: int shutdown (int SOCKET, int HOW)
-- The `shutdown' function shuts down the connection of socket
-- SOCKET. The argument HOW specifies what action to perform:
--
-- `0'
-- Stop receiving data for this socket. If further data arrives,
-- reject it.
--
-- `1'
-- Stop trying to transmit data from this socket. Discard any
-- data waiting to be sent. Stop looking for acknowledgement of
-- data already sent; don't retransmit it if it is lost.
--
-- `2'
-- Stop both reception and transmission.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error conditions are defined for this function:
--
-- `EBADF'
-- SOCKET is not a valid file descriptor.
--
-- `ENOTSOCK'
-- SOCKET is not a socket.
--
-- `ENOTCONN'
-- SOCKET is not connected.
--
--
--File: libc.info, Node: Socket Pairs, Prev: Closing a Socket, Up: Open/Close Sockets
--
--Socket Pairs
--------------
--
-- A "socket pair" consists of a pair of connected (but unnamed)
--sockets. It is very similar to a pipe and is used in much the same
--way. Socket pairs are created with the `socketpair' function, declared
--in `sys/socket.h'. A socket pair is much like a pipe; the main
--difference is that the socket pair is bidirectional, whereas the pipe
--has one input-only end and one output-only end (*note Pipes and
--FIFOs::.).
--
-- - Function: int socketpair (int NAMESPACE, int STYLE, int PROTOCOL,
-- int FILEDES[2])
-- This function creates a socket pair, returning the file
-- descriptors in `FILEDES[0]' and `FILEDES[1]'. The socket pair is
-- a full-duplex communications channel, so that both reading and
-- writing may be performed at either end.
--
-- The NAMESPACE, STYLE, and PROTOCOL arguments are interpreted as
-- for the `socket' function. STYLE should be one of the
-- communication styles listed in *Note Communication Styles::. The
-- NAMESPACE argument specifies the namespace, which must be
-- `AF_LOCAL' (*note Local Namespace::.); PROTOCOL specifies the
-- communications protocol, but zero is the only meaningful value.
--
-- If STYLE specifies a connectionless communication style, then the
-- two sockets you get are not *connected*, strictly speaking, but
-- each of them knows the other as the default destination address,
-- so they can send packets to each other.
--
-- The `socketpair' function returns `0' on success and `-1' on
-- failure. The following `errno' error conditions are defined for
-- this function:
--
-- `EMFILE'
-- The process has too many file descriptors open.
--
-- `EAFNOSUPPORT'
-- The specified namespace is not supported.
--
-- `EPROTONOSUPPORT'
-- The specified protocol is not supported.
--
-- `EOPNOTSUPP'
-- The specified protocol does not support the creation of
-- socket pairs.
--
--
--File: libc.info, Node: Connections, Next: Datagrams, Prev: Open/Close Sockets, Up: Sockets
--
--Using Sockets with Connections
--==============================
--
-- The most common communication styles involve making a connection to a
--particular other socket, and then exchanging data with that socket over
--and over. Making a connection is asymmetric; one side (the "client")
--acts to request a connection, while the other side (the "server") makes
--a socket and waits for the connection request.
--
--* Menu:
--
--* Connecting:: What the client program must do.
--* Listening:: How a server program waits for requests.
--* Accepting Connections:: What the server does when it gets a request.
--* Who is Connected:: Getting the address of the
-- other side of a connection.
--* Transferring Data:: How to send and receive data.
--* Byte Stream Example:: An example program: a client for communicating
-- over a byte stream socket in the Internet namespace.
--* Server Example:: A corresponding server program.
--* Out-of-Band Data:: This is an advanced feature.
--
--
--File: libc.info, Node: Connecting, Next: Listening, Up: Connections
--
--Making a Connection
---------------------
--
-- In making a connection, the client makes a connection while the
--server waits for and accepts the connection. Here we discuss what the
--client program must do, using the `connect' function, which is declared
--in `sys/socket.h'.
--
-- - Function: int connect (int SOCKET, struct sockaddr *ADDR, socklen_t
-- LENGTH)
-- The `connect' function initiates a connection from the socket with
-- file descriptor SOCKET to the socket whose address is specified by
-- the ADDR and LENGTH arguments. (This socket is typically on
-- another machine, and it must be already set up as a server.)
-- *Note Socket Addresses::, for information about how these
-- arguments are interpreted.
--
-- Normally, `connect' waits until the server responds to the request
-- before it returns. You can set nonblocking mode on the socket
-- SOCKET to make `connect' return immediately without waiting for
-- the response. *Note File Status Flags::, for information about
-- nonblocking mode.
--
-- The normal return value from `connect' is `0'. If an error
-- occurs, `connect' returns `-1'. The following `errno' error
-- conditions are defined for this function:
--
-- `EBADF'
-- The socket SOCKET is not a valid file descriptor.
--
-- `ENOTSOCK'
-- File descriptor SOCKET is not a socket.
--
-- `EADDRNOTAVAIL'
-- The specified address is not available on the remote machine.
--
-- `EAFNOSUPPORT'
-- The namespace of the ADDR is not supported by this socket.
--
-- `EISCONN'
-- The socket SOCKET is already connected.
--
-- `ETIMEDOUT'
-- The attempt to establish the connection timed out.
--
-- `ECONNREFUSED'
-- The server has actively refused to establish the connection.
--
-- `ENETUNREACH'
-- The network of the given ADDR isn't reachable from this host.
--
-- `EADDRINUSE'
-- The socket address of the given ADDR is already in use.
--
-- `EINPROGRESS'
-- The socket SOCKET is non-blocking and the connection could
-- not be established immediately. You can determine when the
-- connection is completely established with `select'; *note
-- Waiting for I/O::.. Another `connect' call on the same
-- socket, before the connection is completely established, will
-- fail with `EALREADY'.
--
-- `EALREADY'
-- The socket SOCKET is non-blocking and already has a pending
-- connection in progress (see `EINPROGRESS' above).
--
-- This function is defined as a cancelation point in multi-threaded
-- programs. So one has to be prepared for this and make sure that
-- possibly allocated resources (like memory, files descriptors,
-- semaphores or whatever) are freed even if the thread is canceled.
--
--
--File: libc.info, Node: Listening, Next: Accepting Connections, Prev: Connecting, Up: Connections
--
--Listening for Connections
---------------------------
--
-- Now let us consider what the server process must do to accept
--connections on a socket. First it must use the `listen' function to
--enable connection requests on the socket, and then accept each incoming
--connection with a call to `accept' (*note Accepting Connections::.).
--Once connection requests are enabled on a server socket, the `select'
--function reports when the socket has a connection ready to be accepted
--(*note Waiting for I/O::.).
--
-- The `listen' function is not allowed for sockets using
--connectionless communication styles.
--
-- You can write a network server that does not even start running
--until a connection to it is requested. *Note Inetd Servers::.
--
-- In the Internet namespace, there are no special protection mechanisms
--for controlling access to connect to a port; any process on any machine
--can make a connection to your server. If you want to restrict access to
--your server, make it examine the addresses associated with connection
--requests or implement some other handshaking or identification protocol.
--
-- In the local namespace, the ordinary file protection bits control
--who has access to connect to the socket.
--
-- - Function: int listen (int SOCKET, unsigned int N)
-- The `listen' function enables the socket SOCKET to accept
-- connections, thus making it a server socket.
--
-- The argument N specifies the length of the queue for pending
-- connections. When the queue fills, new clients attempting to
-- connect fail with `ECONNREFUSED' until the server calls `accept' to
-- accept a connection from the queue.
--
-- The `listen' function returns `0' on success and `-1' on failure.
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EBADF'
-- The argument SOCKET is not a valid file descriptor.
--
-- `ENOTSOCK'
-- The argument SOCKET is not a socket.
--
-- `EOPNOTSUPP'
-- The socket SOCKET does not support this operation.
--
--
--File: libc.info, Node: Accepting Connections, Next: Who is Connected, Prev: Listening, Up: Connections
--
--Accepting Connections
-----------------------
--
-- When a server receives a connection request, it can complete the
--connection by accepting the request. Use the function `accept' to do
--this.
--
-- A socket that has been established as a server can accept connection
--requests from multiple clients. The server's original socket *does not
--become part* of the connection; instead, `accept' makes a new socket
--which participates in the connection. `accept' returns the descriptor
--for this socket. The server's original socket remains available for
--listening for further connection requests.
--
-- The number of pending connection requests on a server socket is
--finite. If connection requests arrive from clients faster than the
--server can act upon them, the queue can fill up and additional requests
--are refused with a `ECONNREFUSED' error. You can specify the maximum
--length of this queue as an argument to the `listen' function, although
--the system may also impose its own internal limit on the length of this
--queue.
--
-- - Function: int accept (int SOCKET, struct sockaddr *ADDR, socklen_t
-- *LENGTH_PTR)
-- This function is used to accept a connection request on the server
-- socket SOCKET.
--
-- The `accept' function waits if there are no connections pending,
-- unless the socket SOCKET has nonblocking mode set. (You can use
-- `select' to wait for a pending connection, with a nonblocking
-- socket.) *Note File Status Flags::, for information about
-- nonblocking mode.
--
-- The ADDR and LENGTH-PTR arguments are used to return information
-- about the name of the client socket that initiated the connection.
-- *Note Socket Addresses::, for information about the format of the
-- information.
--
-- Accepting a connection does not make SOCKET part of the
-- connection. Instead, it creates a new socket which becomes
-- connected. The normal return value of `accept' is the file
-- descriptor for the new socket.
--
-- After `accept', the original socket SOCKET remains open and
-- unconnected, and continues listening until you close it. You can
-- accept further connections with SOCKET by calling `accept' again.
--
-- If an error occurs, `accept' returns `-1'. The following `errno'
-- error conditions are defined for this function:
--
-- `EBADF'
-- The SOCKET argument is not a valid file descriptor.
--
-- `ENOTSOCK'
-- The descriptor SOCKET argument is not a socket.
--
-- `EOPNOTSUPP'
-- The descriptor SOCKET does not support this operation.
--
-- `EWOULDBLOCK'
-- SOCKET has nonblocking mode set, and there are no pending
-- connections immediately available.
--
-- This function is defined as a cancelation point in multi-threaded
-- programs. So one has to be prepared for this and make sure that
-- possibly allocated resources (like memory, files descriptors,
-- semaphores or whatever) are freed even if the thread is canceled.
--
-- The `accept' function is not allowed for sockets using
--connectionless communication styles.
--
--
--File: libc.info, Node: Who is Connected, Next: Transferring Data, Prev: Accepting Connections, Up: Connections
--
--Who is Connected to Me?
-------------------------
--
-- - Function: int getpeername (int SOCKET, struct sockaddr *ADDR,
-- socklen_t *LENGTH-PTR)
-- The `getpeername' function returns the address of the socket that
-- SOCKET is connected to; it stores the address in the memory space
-- specified by ADDR and LENGTH-PTR. It stores the length of the
-- address in `*LENGTH-PTR'.
--
-- *Note Socket Addresses::, for information about the format of the
-- address. In some operating systems, `getpeername' works only for
-- sockets in the Internet domain.
--
-- The return value is `0' on success and `-1' on error. The
-- following `errno' error conditions are defined for this function:
--
-- `EBADF'
-- The argument SOCKET is not a valid file descriptor.
--
-- `ENOTSOCK'
-- The descriptor SOCKET is not a socket.
--
-- `ENOTCONN'
-- The socket SOCKET is not connected.
--
-- `ENOBUFS'
-- There are not enough internal buffers available.
--
--
--File: libc.info, Node: Transferring Data, Next: Byte Stream Example, Prev: Who is Connected, Up: Connections
--
--Transferring Data
-------------------
--
-- Once a socket has been connected to a peer, you can use the ordinary
--`read' and `write' operations (*note I/O Primitives::.) to transfer
--data. A socket is a two-way communications channel, so read and write
--operations can be performed at either end.
--
-- There are also some I/O modes that are specific to socket operations.
--In order to specify these modes, you must use the `recv' and `send'
--functions instead of the more generic `read' and `write' functions.
--The `recv' and `send' functions take an additional argument which you
--can use to specify various flags to control the special I/O modes. For
--example, you can specify the `MSG_OOB' flag to read or write
--out-of-band data, the `MSG_PEEK' flag to peek at input, or the
--`MSG_DONTROUTE' flag to control inclusion of routing information on
--output.
--
--* Menu:
--
--* Sending Data:: Sending data with `send'.
--* Receiving Data:: Reading data with `recv'.
--* Socket Data Options:: Using `send' and `recv'.
--
--
--File: libc.info, Node: Sending Data, Next: Receiving Data, Up: Transferring Data
--
--Sending Data
--............
--
-- The `send' function is declared in the header file `sys/socket.h'.
--If your FLAGS argument is zero, you can just as well use `write'
--instead of `send'; see *Note I/O Primitives::. If the socket was
--connected but the connection has broken, you get a `SIGPIPE' signal for
--any use of `send' or `write' (*note Miscellaneous Signals::.).
--
-- - Function: int send (int SOCKET, void *BUFFER, size_t SIZE, int FLAGS)
-- The `send' function is like `write', but with the additional flags
-- FLAGS. The possible values of FLAGS are described in *Note Socket
-- Data Options::.
--
-- This function returns the number of bytes transmitted, or `-1' on
-- failure. If the socket is nonblocking, then `send' (like `write')
-- can return after sending just part of the data. *Note File Status
-- Flags::, for information about nonblocking mode.
--
-- Note, however, that a successful return value merely indicates that
-- the message has been sent without error, not necessarily that it
-- has been received without error.
--
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EBADF'
-- The SOCKET argument is not a valid file descriptor.
--
-- `EINTR'
-- The operation was interrupted by a signal before any data was
-- sent. *Note Interrupted Primitives::.
--
-- `ENOTSOCK'
-- The descriptor SOCKET is not a socket.
--
-- `EMSGSIZE'
-- The socket type requires that the message be sent atomically,
-- but the message is too large for this to be possible.
--
-- `EWOULDBLOCK'
-- Nonblocking mode has been set on the socket, and the write
-- operation would block. (Normally `send' blocks until the
-- operation can be completed.)
--
-- `ENOBUFS'
-- There is not enough internal buffer space available.
--
-- `ENOTCONN'
-- You never connected this socket.
--
-- `EPIPE'
-- This socket was connected but the connection is now broken.
-- In this case, `send' generates a `SIGPIPE' signal first; if
-- that signal is ignored or blocked, or if its handler returns,
-- then `send' fails with `EPIPE'.
--
-- This function is defined as a cancelation point in multi-threaded
-- programs. So one has to be prepared for this and make sure that
-- possibly allocated resources (like memory, files descriptors,
-- semaphores or whatever) are freed even if the thread is canceled.
--
--
--File: libc.info, Node: Receiving Data, Next: Socket Data Options, Prev: Sending Data, Up: Transferring Data
--
--Receiving Data
--..............
--
-- The `recv' function is declared in the header file `sys/socket.h'.
--If your FLAGS argument is zero, you can just as well use `read' instead
--of `recv'; see *Note I/O Primitives::.
--
-- - Function: int recv (int SOCKET, void *BUFFER, size_t SIZE, int FLAGS)
-- The `recv' function is like `read', but with the additional flags
-- FLAGS. The possible values of FLAGS are described in *Note Socket
-- Data Options::.
--
-- If nonblocking mode is set for SOCKET, and no data is available to
-- be read, `recv' fails immediately rather than waiting. *Note File
-- Status Flags::, for information about nonblocking mode.
--
-- This function returns the number of bytes received, or `-1' on
-- failure. The following `errno' error conditions are defined for
-- this function:
--
-- `EBADF'
-- The SOCKET argument is not a valid file descriptor.
--
-- `ENOTSOCK'
-- The descriptor SOCKET is not a socket.
--
-- `EWOULDBLOCK'
-- Nonblocking mode has been set on the socket, and the read
-- operation would block. (Normally, `recv' blocks until there
-- is input available to be read.)
--
-- `EINTR'
-- The operation was interrupted by a signal before any data was
-- read. *Note Interrupted Primitives::.
--
-- `ENOTCONN'
-- You never connected this socket.
--
-- This function is defined as a cancelation point in multi-threaded
-- programs. So one has to be prepared for this and make sure that
-- possibly allocated resources (like memory, files descriptors,
-- semaphores or whatever) are freed even if the thread is canceled.
--
--
--File: libc.info, Node: Socket Data Options, Prev: Receiving Data, Up: Transferring Data
--
--Socket Data Options
--...................
--
-- The FLAGS argument to `send' and `recv' is a bit mask. You can
--bitwise-OR the values of the following macros together to obtain a
--value for this argument. All are defined in the header file
--`sys/socket.h'.
--
-- - Macro: int MSG_OOB
-- Send or receive out-of-band data. *Note Out-of-Band Data::.
--
-- - Macro: int MSG_PEEK
-- Look at the data but don't remove it from the input queue. This is
-- only meaningful with input functions such as `recv', not with
-- `send'.
--
-- - Macro: int MSG_DONTROUTE
-- Don't include routing information in the message. This is only
-- meaningful with output operations, and is usually only of interest
-- for diagnostic or routing programs. We don't try to explain it
-- here.
--
--
--File: libc.info, Node: Byte Stream Example, Next: Server Example, Prev: Transferring Data, Up: Connections
--
--Byte Stream Socket Example
----------------------------
--
-- Here is an example client program that makes a connection for a byte
--stream socket in the Internet namespace. It doesn't do anything
--particularly interesting once it has connected to the server; it just
--sends a text string to the server and exits.
--
-- This program uses `init_sockaddr' to set up the socket address; see
--*Note Inet Example::.
--
-- #include <stdio.h>
-- #include <errno.h>
-- #include <stdlib.h>
-- #include <unistd.h>
-- #include <sys/types.h>
-- #include <sys/socket.h>
-- #include <netinet/in.h>
-- #include <netdb.h>
--
-- #define PORT 5555
-- #define MESSAGE "Yow!!! Are we having fun yet?!?"
-- #define SERVERHOST "mescaline.gnu.org"
--
-- void
-- write_to_server (int filedes)
-- {
-- int nbytes;
--
-- nbytes = write (filedes, MESSAGE, strlen (MESSAGE) + 1);
-- if (nbytes < 0)
-- {
-- perror ("write");
-- exit (EXIT_FAILURE);
-- }
-- }
--
--
-- int
-- main (void)
-- {
-- extern void init_sockaddr (struct sockaddr_in *name,
-- const char *hostname,
-- uint16_t port);
-- int sock;
-- struct sockaddr_in servername;
--
-- /* Create the socket. */
-- sock = socket (PF_INET, SOCK_STREAM, 0);
-- if (sock < 0)
-- {
-- perror ("socket (client)");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Connect to the server. */
-- init_sockaddr (&servername, SERVERHOST, PORT);
-- if (0 > connect (sock,
-- (struct sockaddr *) &servername,
-- sizeof (servername)))
-- {
-- perror ("connect (client)");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Send data to the server. */
-- write_to_server (sock);
-- close (sock);
-- exit (EXIT_SUCCESS);
-- }
--
--
--File: libc.info, Node: Server Example, Next: Out-of-Band Data, Prev: Byte Stream Example, Up: Connections
--
--Byte Stream Connection Server Example
---------------------------------------
--
-- The server end is much more complicated. Since we want to allow
--multiple clients to be connected to the server at the same time, it
--would be incorrect to wait for input from a single client by simply
--calling `read' or `recv'. Instead, the right thing to do is to use
--`select' (*note Waiting for I/O::.) to wait for input on all of the
--open sockets. This also allows the server to deal with additional
--connection requests.
--
-- This particular server doesn't do anything interesting once it has
--gotten a message from a client. It does close the socket for that
--client when it detects an end-of-file condition (resulting from the
--client shutting down its end of the connection).
--
-- This program uses `make_socket' to set up the socket address; see
--*Note Inet Example::.
--
-- #include <stdio.h>
-- #include <errno.h>
-- #include <stdlib.h>
-- #include <unistd.h>
-- #include <sys/types.h>
-- #include <sys/socket.h>
-- #include <netinet/in.h>
-- #include <netdb.h>
--
-- #define PORT 5555
-- #define MAXMSG 512
--
-- int
-- read_from_client (int filedes)
-- {
-- char buffer[MAXMSG];
-- int nbytes;
--
-- nbytes = read (filedes, buffer, MAXMSG);
-- if (nbytes < 0)
-- {
-- /* Read error. */
-- perror ("read");
-- exit (EXIT_FAILURE);
-- }
-- else if (nbytes == 0)
-- /* End-of-file. */
-- return -1;
-- else
-- {
-- /* Data read. */
-- fprintf (stderr, "Server: got message: `%s'\n", buffer);
-- return 0;
-- }
-- }
--
-- int
-- main (void)
-- {
-- extern int make_socket (uint16_t port);
-- int sock;
-- fd_set active_fd_set, read_fd_set;
-- int i;
-- struct sockaddr_in clientname;
-- size_t size;
--
-- /* Create the socket and set it up to accept connections. */
-- sock = make_socket (PORT);
-- if (listen (sock, 1) < 0)
-- {
-- perror ("listen");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Initialize the set of active sockets. */
-- FD_ZERO (&active_fd_set);
-- FD_SET (sock, &active_fd_set);
--
-- while (1)
-- {
-- /* Block until input arrives on one or more active sockets. */
-- read_fd_set = active_fd_set;
-- if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
-- {
-- perror ("select");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Service all the sockets with input pending. */
-- for (i = 0; i < FD_SETSIZE; ++i)
-- if (FD_ISSET (i, &read_fd_set))
-- {
-- if (i == sock)
-- {
-- /* Connection request on original socket. */
-- int new;
-- size = sizeof (clientname);
-- new = accept (sock,
-- (struct sockaddr *) &clientname,
-- &size);
-- if (new < 0)
-- {
-- perror ("accept");
-- exit (EXIT_FAILURE);
-- }
-- fprintf (stderr,
-- "Server: connect from host %s, port %hd.\n",
-- inet_ntoa (clientname.sin_addr),
-- ntohs (clientname.sin_port));
-- FD_SET (new, &active_fd_set);
-- }
-- else
-- {
-- /* Data arriving on an already-connected socket. */
-- if (read_from_client (i) < 0)
-- {
-- close (i);
-- FD_CLR (i, &active_fd_set);
-- }
-- }
-- }
-- }
-- }
--
--
--File: libc.info, Node: Out-of-Band Data, Prev: Server Example, Up: Connections
--
--Out-of-Band Data
------------------
--
-- Streams with connections permit "out-of-band" data that is delivered
--with higher priority than ordinary data. Typically the reason for
--sending out-of-band data is to send notice of an exceptional condition.
--The way to send out-of-band data is using `send', specifying the flag
--`MSG_OOB' (*note Sending Data::.).
--
-- Out-of-band data is received with higher priority because the
--receiving process need not read it in sequence; to read the next
--available out-of-band data, use `recv' with the `MSG_OOB' flag (*note
--Receiving Data::.). Ordinary read operations do not read out-of-band
--data; they read only the ordinary data.
--
-- When a socket finds that out-of-band data is on its way, it sends a
--`SIGURG' signal to the owner process or process group of the socket.
--You can specify the owner using the `F_SETOWN' command to the `fcntl'
--function; see *Note Interrupt Input::. You must also establish a
--handler for this signal, as described in *Note Signal Handling::, in
--order to take appropriate action such as reading the out-of-band data.
--
-- Alternatively, you can test for pending out-of-band data, or wait
--until there is out-of-band data, using the `select' function; it can
--wait for an exceptional condition on the socket. *Note Waiting for
--I/O::, for more information about `select'.
--
-- Notification of out-of-band data (whether with `SIGURG' or with
--`select') indicates that out-of-band data is on the way; the data may
--not actually arrive until later. If you try to read the out-of-band
--data before it arrives, `recv' fails with an `EWOULDBLOCK' error.
--
-- Sending out-of-band data automatically places a "mark" in the stream
--of ordinary data, showing where in the sequence the out-of-band data
--"would have been". This is useful when the meaning of out-of-band data
--is "cancel everything sent so far". Here is how you can test, in the
--receiving process, whether any ordinary data was sent before the mark:
--
-- success = ioctl (socket, SIOCATMARK, &atmark);
--
-- The `integer' variable ATMARK is set to a nonzero value if the
--socket's read pointer has reached the "mark".
--
-- Here's a function to discard any ordinary data preceding the
--out-of-band mark:
--
-- int
-- discard_until_mark (int socket)
-- {
-- while (1)
-- {
-- /* This is not an arbitrary limit; any size will do. */
-- char buffer[1024];
-- int atmark, success;
--
-- /* If we have reached the mark, return. */
-- success = ioctl (socket, SIOCATMARK, &atmark);
-- if (success < 0)
-- perror ("ioctl");
-- if (result)
-- return;
--
-- /* Otherwise, read a bunch of ordinary data and discard it.
-- This is guaranteed not to read past the mark
-- if it starts before the mark. */
-- success = read (socket, buffer, sizeof buffer);
-- if (success < 0)
-- perror ("read");
-- }
-- }
--
-- If you don't want to discard the ordinary data preceding the mark,
--you may need to read some of it anyway, to make room in internal system
--buffers for the out-of-band data. If you try to read out-of-band data
--and get an `EWOULDBLOCK' error, try reading some ordinary data (saving
--it so that you can use it when you want it) and see if that makes room.
--Here is an example:
--
-- struct buffer
-- {
-- char *buffer;
-- int size;
-- struct buffer *next;
-- };
--
-- /* Read the out-of-band data from SOCKET and return it
-- as a `struct buffer', which records the address of the data
-- and its size.
--
-- It may be necessary to read some ordinary data
-- in order to make room for the out-of-band data.
-- If so, the ordinary data is saved as a chain of buffers
-- found in the `next' field of the value. */
--
-- struct buffer *
-- read_oob (int socket)
-- {
-- struct buffer *tail = 0;
-- struct buffer *list = 0;
--
-- while (1)
-- {
-- /* This is an arbitrary limit.
-- Does anyone know how to do this without a limit? */
-- char *buffer = (char *) xmalloc (1024);
-- int success;
-- int atmark;
--
-- /* Try again to read the out-of-band data. */
-- success = recv (socket, buffer, sizeof buffer, MSG_OOB);
-- if (success >= 0)
-- {
-- /* We got it, so return it. */
-- struct buffer *link
-- = (struct buffer *) xmalloc (sizeof (struct buffer));
-- link->buffer = buffer;
-- link->size = success;
-- link->next = list;
-- return link;
-- }
--
-- /* If we fail, see if we are at the mark. */
-- success = ioctl (socket, SIOCATMARK, &atmark);
-- if (success < 0)
-- perror ("ioctl");
-- if (atmark)
-- {
-- /* At the mark; skipping past more ordinary data cannot help.
-- So just wait a while. */
-- sleep (1);
-- continue;
-- }
--
-- /* Otherwise, read a bunch of ordinary data and save it.
-- This is guaranteed not to read past the mark
-- if it starts before the mark. */
-- success = read (socket, buffer, sizeof buffer);
-- if (success < 0)
-- perror ("read");
--
-- /* Save this data in the buffer list. */
-- {
-- struct buffer *link
-- = (struct buffer *) xmalloc (sizeof (struct buffer));
-- link->buffer = buffer;
-- link->size = success;
--
-- /* Add the new link to the end of the list. */
-- if (tail)
-- tail->next = link;
-- else
-- list = link;
-- tail = link;
-- }
-- }
-- }
--
--
--File: libc.info, Node: Datagrams, Next: Inetd, Prev: Connections, Up: Sockets
--
--Datagram Socket Operations
--==========================
--
-- This section describes how to use communication styles that don't use
--connections (styles `SOCK_DGRAM' and `SOCK_RDM'). Using these styles,
--you group data into packets and each packet is an independent
--communication. You specify the destination for each packet
--individually.
--
-- Datagram packets are like letters: you send each one independently,
--with its own destination address, and they may arrive in the wrong
--order or not at all.
--
-- The `listen' and `accept' functions are not allowed for sockets
--using connectionless communication styles.
--
--* Menu:
--
--* Sending Datagrams:: Sending packets on a datagram socket.
--* Receiving Datagrams:: Receiving packets on a datagram socket.
--* Datagram Example:: An example program: packets sent over a
-- datagram socket in the local namespace.
--* Example Receiver:: Another program, that receives those packets.
--
--
--File: libc.info, Node: Sending Datagrams, Next: Receiving Datagrams, Up: Datagrams
--
--Sending Datagrams
-------------------
--
-- The normal way of sending data on a datagram socket is by using the
--`sendto' function, declared in `sys/socket.h'.
--
-- You can call `connect' on a datagram socket, but this only specifies
--a default destination for further data transmission on the socket.
--When a socket has a default destination, then you can use `send' (*note
--Sending Data::.) or even `write' (*note I/O Primitives::.) to send a
--packet there. You can cancel the default destination by calling
--`connect' using an address format of `AF_UNSPEC' in the ADDR argument.
--*Note Connecting::, for more information about the `connect' function.
--
-- - Function: int sendto (int SOCKET, void *BUFFER. size_t SIZE, int
-- FLAGS, struct sockaddr *ADDR, socklen_t LENGTH)
-- The `sendto' function transmits the data in the BUFFER through the
-- socket SOCKET to the destination address specified by the ADDR and
-- LENGTH arguments. The SIZE argument specifies the number of bytes
-- to be transmitted.
--
-- The FLAGS are interpreted the same way as for `send'; see *Note
-- Socket Data Options::.
--
-- The return value and error conditions are also the same as for
-- `send', but you cannot rely on the system to detect errors and
-- report them; the most common error is that the packet is lost or
-- there is no one at the specified address to receive it, and the
-- operating system on your machine usually does not know this.
--
-- It is also possible for one call to `sendto' to report an error
-- due to a problem related to a previous call.
--
-- This function is defined as a cancelation point in multi-threaded
-- programs. So one has to be prepared for this and make sure that
-- possibly allocated resources (like memory, files descriptors,
-- semaphores or whatever) are freed even if the thread is canceled.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-25 glibc-2.1.3/manual/libc.info-25
---- ../glibc-2.1.3/manual/libc.info-25 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-25 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1208 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Receiving Datagrams, Next: Datagram Example, Prev: Sending Datagrams, Up: Datagrams
--
--Receiving Datagrams
---------------------
--
-- The `recvfrom' function reads a packet from a datagram socket and
--also tells you where it was sent from. This function is declared in
--`sys/socket.h'.
--
-- - Function: int recvfrom (int SOCKET, void *BUFFER, size_t SIZE, int
-- FLAGS, struct sockaddr *ADDR, socklen_t *LENGTH-PTR)
-- The `recvfrom' function reads one packet from the socket SOCKET
-- into the buffer BUFFER. The SIZE argument specifies the maximum
-- number of bytes to be read.
--
-- If the packet is longer than SIZE bytes, then you get the first
-- SIZE bytes of the packet, and the rest of the packet is lost.
-- There's no way to read the rest of the packet. Thus, when you use
-- a packet protocol, you must always know how long a packet to
-- expect.
--
-- The ADDR and LENGTH-PTR arguments are used to return the address
-- where the packet came from. *Note Socket Addresses::. For a
-- socket in the local domain, the address information won't be
-- meaningful, since you can't read the address of such a socket
-- (*note Local Namespace::.). You can specify a null pointer as the
-- ADDR argument if you are not interested in this information.
--
-- The FLAGS are interpreted the same way as for `recv' (*note Socket
-- Data Options::.). The return value and error conditions are also
-- the same as for `recv'.
--
-- This function is defined as a cancelation point in multi-threaded
-- programs. So one has to be prepared for this and make sure that
-- possibly allocated resources (like memory, files descriptors,
-- semaphores or whatever) are freed even if the thread is canceled.
--
-- You can use plain `recv' (*note Receiving Data::.) instead of
--`recvfrom' if you know don't need to find out who sent the packet
--(either because you know where it should come from or because you treat
--all possible senders alike). Even `read' can be used if you don't want
--to specify FLAGS (*note I/O Primitives::.).
--
--
--File: libc.info, Node: Datagram Example, Next: Example Receiver, Prev: Receiving Datagrams, Up: Datagrams
--
--Datagram Socket Example
-------------------------
--
-- Here is a set of example programs that send messages over a datagram
--stream in the local namespace. Both the client and server programs use
--the `make_named_socket' function that was presented in *Note Local
--Socket Example::, to create and name their sockets.
--
-- First, here is the server program. It sits in a loop waiting for
--messages to arrive, bouncing each message back to the sender.
--Obviously, this isn't a particularly useful program, but it does show
--the general ideas involved.
--
-- #include <stdio.h>
-- #include <errno.h>
-- #include <stdlib.h>
-- #include <sys/socket.h>
-- #include <sys/un.h>
--
-- #define SERVER "/tmp/serversocket"
-- #define MAXMSG 512
--
-- int
-- main (void)
-- {
-- int sock;
-- char message[MAXMSG];
-- struct sockaddr_un name;
-- size_t size;
-- int nbytes;
--
-- /* Remove the filename first, it's ok if the call fails */
-- unlink (SERVER);
--
-- /* Make the socket, then loop endlessly. */
-- sock = make_named_socket (SERVER);
-- while (1)
-- {
-- /* Wait for a datagram. */
-- size = sizeof (name);
-- nbytes = recvfrom (sock, message, MAXMSG, 0,
-- (struct sockaddr *) & name, &size);
-- if (nbytes < 0)
-- {
-- perror ("recfrom (server)");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Give a diagnostic message. */
-- fprintf (stderr, "Server: got message: %s\n", message);
--
-- /* Bounce the message back to the sender. */
-- nbytes = sendto (sock, message, nbytes, 0,
-- (struct sockaddr *) & name, size);
-- if (nbytes < 0)
-- {
-- perror ("sendto (server)");
-- exit (EXIT_FAILURE);
-- }
-- }
-- }
--
--
--File: libc.info, Node: Example Receiver, Prev: Datagram Example, Up: Datagrams
--
--Example of Reading Datagrams
------------------------------
--
-- Here is the client program corresponding to the server above.
--
-- It sends a datagram to the server and then waits for a reply. Notice
--that the socket for the client (as well as for the server) in this
--example has to be given a name. This is so that the server can direct
--a message back to the client. Since the socket has no associated
--connection state, the only way the server can do this is by referencing
--the name of the client.
--
-- #include <stdio.h>
-- #include <errno.h>
-- #include <unistd.h>
-- #include <stdlib.h>
-- #include <sys/socket.h>
-- #include <sys/un.h>
--
-- #define SERVER "/tmp/serversocket"
-- #define CLIENT "/tmp/mysocket"
-- #define MAXMSG 512
-- #define MESSAGE "Yow!!! Are we having fun yet?!?"
--
-- int
-- main (void)
-- {
-- extern int make_named_socket (const char *name);
-- int sock;
-- char message[MAXMSG];
-- struct sockaddr_un name;
-- size_t size;
-- int nbytes;
--
-- /* Make the socket. */
-- sock = make_named_socket (CLIENT);
--
-- /* Initialize the server socket address. */
-- name.sun_family = AF_LOCAL;
-- strcpy (name.sun_path, SERVER);
-- size = strlen (name.sun_path) + sizeof (name.sun_family);
--
-- /* Send the datagram. */
-- nbytes = sendto (sock, MESSAGE, strlen (MESSAGE) + 1, 0,
-- (struct sockaddr *) & name, size);
-- if (nbytes < 0)
-- {
-- perror ("sendto (client)");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Wait for a reply. */
-- nbytes = recvfrom (sock, message, MAXMSG, 0, NULL, 0);
-- if (nbytes < 0)
-- {
-- perror ("recfrom (client)");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Print a diagnostic message. */
-- fprintf (stderr, "Client: got message: %s\n", message);
--
-- /* Clean up. */
-- remove (CLIENT);
-- close (sock);
-- }
--
-- Keep in mind that datagram socket communications are unreliable. In
--this example, the client program waits indefinitely if the message
--never reaches the server or if the server's response never comes back.
--It's up to the user running the program to kill it and restart it, if
--desired. A more automatic solution could be to use `select' (*note
--Waiting for I/O::.) to establish a timeout period for the reply, and in
--case of timeout either resend the message or shut down the socket and
--exit.
--
--
--File: libc.info, Node: Inetd, Next: Socket Options, Prev: Datagrams, Up: Sockets
--
--The `inetd' Daemon
--==================
--
-- We've explained above how to write a server program that does its own
--listening. Such a server must already be running in order for anyone
--to connect to it.
--
-- Another way to provide service for an Internet port is to let the
--daemon program `inetd' do the listening. `inetd' is a program that
--runs all the time and waits (using `select') for messages on a
--specified set of ports. When it receives a message, it accepts the
--connection (if the socket style calls for connections) and then forks a
--child process to run the corresponding server program. You specify the
--ports and their programs in the file `/etc/inetd.conf'.
--
--* Menu:
--
--* Inetd Servers::
--* Configuring Inetd::
--
--
--File: libc.info, Node: Inetd Servers, Next: Configuring Inetd, Up: Inetd
--
--`inetd' Servers
-----------------
--
-- Writing a server program to be run by `inetd' is very simple. Each
--time someone requests a connection to the appropriate port, a new server
--process starts. The connection already exists at this time; the socket
--is available as the standard input descriptor and as the standard
--output descriptor (descriptors 0 and 1) in the server process. So the
--server program can begin reading and writing data right away. Often
--the program needs only the ordinary I/O facilities; in fact, a
--general-purpose filter program that knows nothing about sockets can
--work as a byte stream server run by `inetd'.
--
-- You can also use `inetd' for servers that use connectionless
--communication styles. For these servers, `inetd' does not try to accept
--a connection, since no connection is possible. It just starts the
--server program, which can read the incoming datagram packet from
--descriptor 0. The server program can handle one request and then exit,
--or you can choose to write it to keep reading more requests until no
--more arrive, and then exit. You must specify which of these two
--techniques the server uses, when you configure `inetd'.
--
--
--File: libc.info, Node: Configuring Inetd, Prev: Inetd Servers, Up: Inetd
--
--Configuring `inetd'
---------------------
--
-- The file `/etc/inetd.conf' tells `inetd' which ports to listen to
--and what server programs to run for them. Normally each entry in the
--file is one line, but you can split it onto multiple lines provided all
--but the first line of the entry start with whitespace. Lines that
--start with `#' are comments.
--
-- Here are two standard entries in `/etc/inetd.conf':
--
-- ftp stream tcp nowait root /libexec/ftpd ftpd
-- talk dgram udp wait root /libexec/talkd talkd
--
-- An entry has this format:
--
-- SERVICE STYLE PROTOCOL WAIT USERNAME PROGRAM ARGUMENTS
--
-- The SERVICE field says which service this program provides. It
--should be the name of a service defined in `/etc/services'. `inetd'
--uses SERVICE to decide which port to listen on for this entry.
--
-- The fields STYLE and PROTOCOL specify the communication style and
--the protocol to use for the listening socket. The style should be the
--name of a communication style, converted to lower case and with `SOCK_'
--deleted--for example, `stream' or `dgram'. PROTOCOL should be one of
--the protocols listed in `/etc/protocols'. The typical protocol names
--are `tcp' for byte stream connections and `udp' for unreliable
--datagrams.
--
-- The WAIT field should be either `wait' or `nowait'. Use `wait' if
--STYLE is a connectionless style and the server, once started, handles
--multiple requests, as many as come in. Use `nowait' if `inetd' should
--start a new process for each message or request that comes in. If
--STYLE uses connections, then WAIT *must* be `nowait'.
--
-- USER is the user name that the server should run as. `inetd' runs
--as root, so it can set the user ID of its children arbitrarily. It's
--best to avoid using `root' for USER if you can; but some servers, such
--as Telnet and FTP, read a username and password themselves. These
--servers need to be root initially so they can log in as commanded by
--the data coming over the network.
--
-- PROGRAM together with ARGUMENTS specifies the command to run to
--start the server. PROGRAM should be an absolute file name specifying
--the executable file to run. ARGUMENTS consists of any number of
--whitespace-separated words, which become the command-line arguments of
--PROGRAM. The first word in ARGUMENTS is argument zero, which should by
--convention be the program name itself (sans directories).
--
-- If you edit `/etc/inetd.conf', you can tell `inetd' to reread the
--file and obey its new contents by sending the `inetd' process the
--`SIGHUP' signal. You'll have to use `ps' to determine the process ID
--of the `inetd' process, as it is not fixed.
--
--
--File: libc.info, Node: Socket Options, Next: Networks Database, Prev: Inetd, Up: Sockets
--
--Socket Options
--==============
--
-- This section describes how to read or set various options that modify
--the behavior of sockets and their underlying communications protocols.
--
-- When you are manipulating a socket option, you must specify which
--"level" the option pertains to. This describes whether the option
--applies to the socket interface, or to a lower-level communications
--protocol interface.
--
--* Menu:
--
--* Socket Option Functions:: The basic functions for setting and getting
-- socket options.
--* Socket-Level Options:: Details of the options at the socket level.
--
--
--File: libc.info, Node: Socket Option Functions, Next: Socket-Level Options, Up: Socket Options
--
--Socket Option Functions
-------------------------
--
-- Here are the functions for examining and modifying socket options.
--They are declared in `sys/socket.h'.
--
-- - Function: int getsockopt (int SOCKET, int LEVEL, int OPTNAME, void
-- *OPTVAL, socklen_t *OPTLEN-PTR)
-- The `getsockopt' function gets information about the value of
-- option OPTNAME at level LEVEL for socket SOCKET.
--
-- The option value is stored in a buffer that OPTVAL points to.
-- Before the call, you should supply in `*OPTLEN-PTR' the size of
-- this buffer; on return, it contains the number of bytes of
-- information actually stored in the buffer.
--
-- Most options interpret the OPTVAL buffer as a single `int' value.
--
-- The actual return value of `getsockopt' is `0' on success and `-1'
-- on failure. The following `errno' error conditions are defined:
--
-- `EBADF'
-- The SOCKET argument is not a valid file descriptor.
--
-- `ENOTSOCK'
-- The descriptor SOCKET is not a socket.
--
-- `ENOPROTOOPT'
-- The OPTNAME doesn't make sense for the given LEVEL.
--
-- - Function: int setsockopt (int SOCKET, int LEVEL, int OPTNAME, void
-- *OPTVAL, socklen_t OPTLEN)
-- This function is used to set the socket option OPTNAME at level
-- LEVEL for socket SOCKET. The value of the option is passed in the
-- buffer OPTVAL, which has size OPTLEN.
--
-- The return value and error codes for `setsockopt' are the same as
-- for `getsockopt'.
--
--
--
--File: libc.info, Node: Socket-Level Options, Prev: Socket Option Functions, Up: Socket Options
--
--Socket-Level Options
----------------------
--
-- - Constant: int SOL_SOCKET
-- Use this constant as the LEVEL argument to `getsockopt' or
-- `setsockopt' to manipulate the socket-level options described in
-- this section.
--
--Here is a table of socket-level option names; all are defined in the
--header file `sys/socket.h'.
--
--`SO_DEBUG'
-- This option toggles recording of debugging information in the
-- underlying protocol modules. The value has type `int'; a nonzero
-- value means "yes".
--
--`SO_REUSEADDR'
-- This option controls whether `bind' (*note Setting Address::.)
-- should permit reuse of local addresses for this socket. If you
-- enable this option, you can actually have two sockets with the
-- same Internet port number; but the system won't allow you to use
-- the two identically-named sockets in a way that would confuse the
-- Internet. The reason for this option is that some higher-level
-- Internet protocols, including FTP, require you to keep reusing the
-- same port number.
--
-- The value has type `int'; a nonzero value means "yes".
--
--`SO_KEEPALIVE'
-- This option controls whether the underlying protocol should
-- periodically transmit messages on a connected socket. If the peer
-- fails to respond to these messages, the connection is considered
-- broken. The value has type `int'; a nonzero value means "yes".
--
--`SO_DONTROUTE'
-- This option controls whether outgoing messages bypass the normal
-- message routing facilities. If set, messages are sent directly to
-- the network interface instead. The value has type `int'; a nonzero
-- value means "yes".
--
--`SO_LINGER'
-- This option specifies what should happen when the socket of a type
-- that promises reliable delivery still has untransmitted messages
-- when it is closed; see *Note Closing a Socket::. The value has
-- type `struct linger'.
--
-- - Data Type: struct linger
-- This structure type has the following members:
--
-- `int l_onoff'
-- This field is interpreted as a boolean. If nonzero,
-- `close' blocks until the data is transmitted or the
-- timeout period has expired.
--
-- `int l_linger'
-- This specifies the timeout period, in seconds.
--
--`SO_BROADCAST'
-- This option controls whether datagrams may be broadcast from the
-- socket. The value has type `int'; a nonzero value means "yes".
--
--`SO_OOBINLINE'
-- If this option is set, out-of-band data received on the socket is
-- placed in the normal input queue. This permits it to be read using
-- `read' or `recv' without specifying the `MSG_OOB' flag. *Note
-- Out-of-Band Data::. The value has type `int'; a nonzero value
-- means "yes".
--
--`SO_SNDBUF'
-- This option gets or sets the size of the output buffer. The value
-- is a `size_t', which is the size in bytes.
--
--`SO_RCVBUF'
-- This option gets or sets the size of the input buffer. The value
-- is a `size_t', which is the size in bytes.
--
--`SO_STYLE'
--`SO_TYPE'
-- This option can be used with `getsockopt' only. It is used to get
-- the socket's communication style. `SO_TYPE' is the historical
-- name, and `SO_STYLE' is the preferred name in GNU. The value has
-- type `int' and its value designates a communication style; see
-- *Note Communication Styles::.
--
--`SO_ERROR'
-- This option can be used with `getsockopt' only. It is used to
-- reset the error status of the socket. The value is an `int',
-- which represents the previous error status.
--
--
--File: libc.info, Node: Networks Database, Prev: Socket Options, Up: Sockets
--
--Networks Database
--=================
--
-- Many systems come with a database that records a list of networks
--known to the system developer. This is usually kept either in the file
--`/etc/networks' or in an equivalent from a name server. This data base
--is useful for routing programs such as `route', but it is not useful
--for programs that simply communicate over the network. We provide
--functions to access this data base, which are declared in `netdb.h'.
--
-- - Data Type: struct netent
-- This data type is used to represent information about entries in
-- the networks database. It has the following members:
--
-- `char *n_name'
-- This is the "official" name of the network.
--
-- `char **n_aliases'
-- These are alternative names for the network, represented as a
-- vector of strings. A null pointer terminates the array.
--
-- `int n_addrtype'
-- This is the type of the network number; this is always equal
-- to `AF_INET' for Internet networks.
--
-- `unsigned long int n_net'
-- This is the network number. Network numbers are returned in
-- host byte order; see *Note Byte Order::.
--
-- Use the `getnetbyname' or `getnetbyaddr' functions to search the
--networks database for information about a specific network. The
--information is returned in a statically-allocated structure; you must
--copy the information if you need to save it.
--
-- - Function: struct netent * getnetbyname (const char *NAME)
-- The `getnetbyname' function returns information about the network
-- named NAME. It returns a null pointer if there is no such network.
--
-- - Function: struct netent * getnetbyaddr (unsigned long int NET, int
-- TYPE)
-- The `getnetbyaddr' function returns information about the network
-- of type TYPE with number NET. You should specify a value of
-- `AF_INET' for the TYPE argument for Internet networks.
--
-- `getnetbyaddr' returns a null pointer if there is no such network.
--
-- You can also scan the networks database using `setnetent',
--`getnetent', and `endnetent'. Be careful in using these functions,
--because they are not reentrant.
--
-- - Function: void setnetent (int STAYOPEN)
-- This function opens and rewinds the networks database.
--
-- If the STAYOPEN argument is nonzero, this sets a flag so that
-- subsequent calls to `getnetbyname' or `getnetbyaddr' will not
-- close the database (as they usually would). This makes for more
-- efficiency if you call those functions several times, by avoiding
-- reopening the database for each call.
--
-- - Function: struct netent * getnetent (void)
-- This function returns the next entry in the networks database. It
-- returns a null pointer if there are no more entries.
--
-- - Function: void endnetent (void)
-- This function closes the networks database.
--
--
--File: libc.info, Node: Low-Level Terminal Interface, Next: Mathematics, Prev: Sockets, Up: Top
--
--Low-Level Terminal Interface
--****************************
--
-- This chapter describes functions that are specific to terminal
--devices. You can use these functions to do things like turn off input
--echoing; set serial line characteristics such as line speed and flow
--control; and change which characters are used for end-of-file,
--command-line editing, sending signals, and similar control functions.
--
-- Most of the functions in this chapter operate on file descriptors.
--*Note Low-Level I/O::, for more information about what a file
--descriptor is and how to open a file descriptor for a terminal device.
--
--* Menu:
--
--* Is It a Terminal:: How to determine if a file is a terminal
-- device, and what its name is.
--* I/O Queues:: About flow control and typeahead.
--* Canonical or Not:: Two basic styles of input processing.
--* Terminal Modes:: How to examine and modify flags controlling
-- details of terminal I/O: echoing,
-- signals, editing.
--* Line Control:: Sending break sequences, clearing
-- terminal buffers ...
--* Noncanon Example:: How to read single characters without echo.
--* Pseudo-Terminals:: How to open a pseudo-terminal.
--
--
--File: libc.info, Node: Is It a Terminal, Next: I/O Queues, Up: Low-Level Terminal Interface
--
--Identifying Terminals
--=====================
--
-- The functions described in this chapter only work on files that
--correspond to terminal devices. You can find out whether a file
--descriptor is associated with a terminal by using the `isatty' function.
--
-- Prototypes for the functions in this section are declared in the
--header file `unistd.h'.
--
-- - Function: int isatty (int FILEDES)
-- This function returns `1' if FILEDES is a file descriptor
-- associated with an open terminal device, and 0 otherwise.
--
-- If a file descriptor is associated with a terminal, you can get its
--associated file name using the `ttyname' function. See also the
--`ctermid' function, described in *Note Identifying the Terminal::.
--
-- - Function: char * ttyname (int FILEDES)
-- If the file descriptor FILEDES is associated with a terminal
-- device, the `ttyname' function returns a pointer to a
-- statically-allocated, null-terminated string containing the file
-- name of the terminal file. The value is a null pointer if the
-- file descriptor isn't associated with a terminal, or the file name
-- cannot be determined.
--
-- - Function: int ttyname_r (int FILEDES, char *BUF, size_t LEN)
-- The `ttyname_r' function is similar to the `ttyname' function
-- except that it places its result into the user-specified buffer
-- starting at BUF with length LEN.
--
-- The normal return value from `ttyname_r' is 0. Otherwise an error
-- number is returned to indicate the error. The following `errno'
-- error conditions are defined for this function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `ENOTTY'
-- The FILEDES is not associated with a terminal.
--
-- `ERANGE'
-- The buffer length LEN is too small to store the string to be
-- returned.
--
--
--File: libc.info, Node: I/O Queues, Next: Canonical or Not, Prev: Is It a Terminal, Up: Low-Level Terminal Interface
--
--I/O Queues
--==========
--
-- Many of the remaining functions in this section refer to the input
--and output queues of a terminal device. These queues implement a form
--of buffering *within the kernel* independent of the buffering
--implemented by I/O streams (*note I/O on Streams::.).
--
-- The "terminal input queue" is also sometimes referred to as its
--"typeahead buffer". It holds the characters that have been received
--from the terminal but not yet read by any process.
--
-- The size of the input queue is described by the `MAX_INPUT' and
--`_POSIX_MAX_INPUT' parameters; see *Note Limits for Files::. You are
--guaranteed a queue size of at least `MAX_INPUT', but the queue might be
--larger, and might even dynamically change size. If input flow control
--is enabled by setting the `IXOFF' input mode bit (*note Input
--Modes::.), the terminal driver transmits STOP and START characters to
--the terminal when necessary to prevent the queue from overflowing.
--Otherwise, input may be lost if it comes in too fast from the terminal.
--In canonical mode, all input stays in the queue until a newline
--character is received, so the terminal input queue can fill up when you
--type a very long line. *Note Canonical or Not::.
--
-- The "terminal output queue" is like the input queue, but for output;
--it contains characters that have been written by processes, but not yet
--transmitted to the terminal. If output flow control is enabled by
--setting the `IXON' input mode bit (*note Input Modes::.), the terminal
--driver obeys START and STOP characters sent by the terminal to stop and
--restart transmission of output.
--
-- "Clearing" the terminal input queue means discarding any characters
--that have been received but not yet read. Similarly, clearing the
--terminal output queue means discarding any characters that have been
--written but not yet transmitted.
--
--
--File: libc.info, Node: Canonical or Not, Next: Terminal Modes, Prev: I/O Queues, Up: Low-Level Terminal Interface
--
--Two Styles of Input: Canonical or Not
--=====================================
--
-- POSIX systems support two basic modes of input: canonical and
--noncanonical.
--
-- In "canonical input processing" mode, terminal input is processed in
--lines terminated by newline (`'\n''), EOF, or EOL characters. No input
--can be read until an entire line has been typed by the user, and the
--`read' function (*note I/O Primitives::.) returns at most a single line
--of input, no matter how many bytes are requested.
--
-- In canonical input mode, the operating system provides input editing
--facilities: some characters are interpreted specially to perform editing
--operations within the current line of text, such as ERASE and KILL.
--*Note Editing Characters::.
--
-- The constants `_POSIX_MAX_CANON' and `MAX_CANON' parameterize the
--maximum number of bytes which may appear in a single line of canonical
--input. *Note Limits for Files::. You are guaranteed a maximum line
--length of at least `MAX_CANON' bytes, but the maximum might be larger,
--and might even dynamically change size.
--
-- In "noncanonical input processing" mode, characters are not grouped
--into lines, and ERASE and KILL processing is not performed. The
--granularity with which bytes are read in noncanonical input mode is
--controlled by the MIN and TIME settings. *Note Noncanonical Input::.
--
-- Most programs use canonical input mode, because this gives the user a
--way to edit input line by line. The usual reason to use noncanonical
--mode is when the program accepts single-character commands or provides
--its own editing facilities.
--
-- The choice of canonical or noncanonical input is controlled by the
--`ICANON' flag in the `c_lflag' member of `struct termios'. *Note Local
--Modes::.
--
--
--File: libc.info, Node: Terminal Modes, Next: Line Control, Prev: Canonical or Not, Up: Low-Level Terminal Interface
--
--Terminal Modes
--==============
--
-- This section describes the various terminal attributes that control
--how input and output are done. The functions, data structures, and
--symbolic constants are all declared in the header file `termios.h'.
--
--* Menu:
--
--* Mode Data Types:: The data type `struct termios' and
-- related types.
--* Mode Functions:: Functions to read and set the terminal
-- attributes.
--* Setting Modes:: The right way to set terminal attributes
-- reliably.
--* Input Modes:: Flags controlling low-level input handling.
--* Output Modes:: Flags controlling low-level output handling.
--* Control Modes:: Flags controlling serial port behavior.
--* Local Modes:: Flags controlling high-level input handling.
--* Line Speed:: How to read and set the terminal line speed.
--* Special Characters:: Characters that have special effects,
-- and how to change them.
--* Noncanonical Input:: Controlling how long to wait for input.
--
--
--File: libc.info, Node: Mode Data Types, Next: Mode Functions, Up: Terminal Modes
--
--Terminal Mode Data Types
--------------------------
--
-- The entire collection of attributes of a terminal is stored in a
--structure of type `struct termios'. This structure is used with the
--functions `tcgetattr' and `tcsetattr' to read and set the attributes.
--
-- - Data Type: struct termios
-- Structure that records all the I/O attributes of a terminal. The
-- structure includes at least the following members:
--
-- `tcflag_t c_iflag'
-- A bit mask specifying flags for input modes; see *Note Input
-- Modes::.
--
-- `tcflag_t c_oflag'
-- A bit mask specifying flags for output modes; see *Note
-- Output Modes::.
--
-- `tcflag_t c_cflag'
-- A bit mask specifying flags for control modes; see *Note
-- Control Modes::.
--
-- `tcflag_t c_lflag'
-- A bit mask specifying flags for local modes; see *Note Local
-- Modes::.
--
-- `cc_t c_cc[NCCS]'
-- An array specifying which characters are associated with
-- various control functions; see *Note Special Characters::.
--
-- The `struct termios' structure also contains members which encode
-- input and output transmission speeds, but the representation is
-- not specified. *Note Line Speed::, for how to examine and store
-- the speed values.
--
-- The following sections describe the details of the members of the
--`struct termios' structure.
--
-- - Data Type: tcflag_t
-- This is an unsigned integer type used to represent the various bit
-- masks for terminal flags.
--
-- - Data Type: cc_t
-- This is an unsigned integer type used to represent characters
-- associated with various terminal control functions.
--
-- - Macro: int NCCS
-- The value of this macro is the number of elements in the `c_cc'
-- array.
--
--
--File: libc.info, Node: Mode Functions, Next: Setting Modes, Prev: Mode Data Types, Up: Terminal Modes
--
--Terminal Mode Functions
-------------------------
--
-- - Function: int tcgetattr (int FILEDES, struct termios *TERMIOS-P)
-- This function is used to examine the attributes of the terminal
-- device with file descriptor FILEDES. The attributes are returned
-- in the structure that TERMIOS-P points to.
--
-- If successful, `tcgetattr' returns 0. A return value of -1
-- indicates an error. The following `errno' error conditions are
-- defined for this function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `ENOTTY'
-- The FILEDES is not associated with a terminal.
--
-- - Function: int tcsetattr (int FILEDES, int WHEN, const struct termios
-- *TERMIOS-P)
-- This function sets the attributes of the terminal device with file
-- descriptor FILEDES. The new attributes are taken from the
-- structure that TERMIOS-P points to.
--
-- The WHEN argument specifies how to deal with input and output
-- already queued. It can be one of the following values:
--
-- `TCSANOW'
-- Make the change immediately.
--
-- `TCSADRAIN'
-- Make the change after waiting until all queued output has
-- been written. You should usually use this option when
-- changing parameters that affect output.
--
-- `TCSAFLUSH'
-- This is like `TCSADRAIN', but also discards any queued input.
--
-- `TCSASOFT'
-- This is a flag bit that you can add to any of the above
-- alternatives. Its meaning is to inhibit alteration of the
-- state of the terminal hardware. It is a BSD extension; it is
-- only supported on BSD systems and the GNU system.
--
-- Using `TCSASOFT' is exactly the same as setting the `CIGNORE'
-- bit in the `c_cflag' member of the structure TERMIOS-P points
-- to. *Note Control Modes::, for a description of `CIGNORE'.
--
-- If this function is called from a background process on its
-- controlling terminal, normally all processes in the process group
-- are sent a `SIGTTOU' signal, in the same way as if the process
-- were trying to write to the terminal. The exception is if the
-- calling process itself is ignoring or blocking `SIGTTOU' signals,
-- in which case the operation is performed and no signal is sent.
-- *Note Job Control::.
--
-- If successful, `tcsetattr' returns 0. A return value of -1
-- indicates an error. The following `errno' error conditions are
-- defined for this function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `ENOTTY'
-- The FILEDES is not associated with a terminal.
--
-- `EINVAL'
-- Either the value of the `when' argument is not valid, or
-- there is something wrong with the data in the TERMIOS-P
-- argument.
--
-- Although `tcgetattr' and `tcsetattr' specify the terminal device
--with a file descriptor, the attributes are those of the terminal device
--itself and not of the file descriptor. This means that the effects of
--changing terminal attributes are persistent; if another process opens
--the terminal file later on, it will see the changed attributes even
--though it doesn't have anything to do with the open file descriptor you
--originally specified in changing the attributes.
--
-- Similarly, if a single process has multiple or duplicated file
--descriptors for the same terminal device, changing the terminal
--attributes affects input and output to all of these file descriptors.
--This means, for example, that you can't open one file descriptor or
--stream to read from a terminal in the normal line-buffered, echoed
--mode; and simultaneously have another file descriptor for the same
--terminal that you use to read from it in single-character, non-echoed
--mode. Instead, you have to explicitly switch the terminal back and
--forth between the two modes.
--
--
--File: libc.info, Node: Setting Modes, Next: Input Modes, Prev: Mode Functions, Up: Terminal Modes
--
--Setting Terminal Modes Properly
---------------------------------
--
-- When you set terminal modes, you should call `tcgetattr' first to
--get the current modes of the particular terminal device, modify only
--those modes that you are really interested in, and store the result with
--`tcsetattr'.
--
-- It's a bad idea to simply initialize a `struct termios' structure to
--a chosen set of attributes and pass it directly to `tcsetattr'. Your
--program may be run years from now, on systems that support members not
--documented in this manual. The way to avoid setting these members to
--unreasonable values is to avoid changing them.
--
-- What's more, different terminal devices may require different mode
--settings in order to function properly. So you should avoid blindly
--copying attributes from one terminal device to another.
--
-- When a member contains a collection of independent flags, as the
--`c_iflag', `c_oflag' and `c_cflag' members do, even setting the entire
--member is a bad idea, because particular operating systems have their
--own flags. Instead, you should start with the current value of the
--member and alter only the flags whose values matter in your program,
--leaving any other flags unchanged.
--
-- Here is an example of how to set one flag (`ISTRIP') in the `struct
--termios' structure while properly preserving all the other data in the
--structure:
--
-- int
-- set_istrip (int desc, int value)
-- {
-- struct termios settings;
-- int result;
--
-- result = tcgetattr (desc, &settings);
-- if (result < 0)
-- {
-- perror ("error in tcgetattr");
-- return 0;
-- }
--
-- settings.c_iflag &= ~ISTRIP;
-- if (value)
-- settings.c_iflag |= ISTRIP;
--
-- result = tcsetattr (desc, TCSANOW, &settings);
-- if (result < 0)
-- {
-- perror ("error in tcgetattr");
-- return;
-- }
-- return 1;
-- }
--
--
--File: libc.info, Node: Input Modes, Next: Output Modes, Prev: Setting Modes, Up: Terminal Modes
--
--Input Modes
-------------
--
-- This section describes the terminal attribute flags that control
--fairly low-level aspects of input processing: handling of parity errors,
--break signals, flow control, and <RET> and <LFD> characters.
--
-- All of these flags are bits in the `c_iflag' member of the `struct
--termios' structure. The member is an integer, and you change flags
--using the operators `&', `|' and `^'. Don't try to specify the entire
--value for `c_iflag'--instead, change only specific flags and leave the
--rest untouched (*note Setting Modes::.).
--
-- - Macro: tcflag_t INPCK
-- If this bit is set, input parity checking is enabled. If it is
-- not set, no checking at all is done for parity errors on input; the
-- characters are simply passed through to the application.
--
-- Parity checking on input processing is independent of whether
-- parity detection and generation on the underlying terminal
-- hardware is enabled; see *Note Control Modes::. For example, you
-- could clear the `INPCK' input mode flag and set the `PARENB'
-- control mode flag to ignore parity errors on input, but still
-- generate parity on output.
--
-- If this bit is set, what happens when a parity error is detected
-- depends on whether the `IGNPAR' or `PARMRK' bits are set. If
-- neither of these bits are set, a byte with a parity error is
-- passed to the application as a `'\0'' character.
--
-- - Macro: tcflag_t IGNPAR
-- If this bit is set, any byte with a framing or parity error is
-- ignored. This is only useful if `INPCK' is also set.
--
-- - Macro: tcflag_t PARMRK
-- If this bit is set, input bytes with parity or framing errors are
-- marked when passed to the program. This bit is meaningful only
-- when `INPCK' is set and `IGNPAR' is not set.
--
-- The way erroneous bytes are marked is with two preceding bytes,
-- `377' and `0'. Thus, the program actually reads three bytes for
-- one erroneous byte received from the terminal.
--
-- If a valid byte has the value `0377', and `ISTRIP' (see below) is
-- not set, the program might confuse it with the prefix that marks a
-- parity error. So a valid byte `0377' is passed to the program as
-- two bytes, `0377' `0377', in this case.
--
-- - Macro: tcflag_t ISTRIP
-- If this bit is set, valid input bytes are stripped to seven bits;
-- otherwise, all eight bits are available for programs to read.
--
-- - Macro: tcflag_t IGNBRK
-- If this bit is set, break conditions are ignored.
--
-- A "break condition" is defined in the context of asynchronous
-- serial data transmission as a series of zero-value bits longer
-- than a single byte.
--
-- - Macro: tcflag_t BRKINT
-- If this bit is set and `IGNBRK' is not set, a break condition
-- clears the terminal input and output queues and raises a `SIGINT'
-- signal for the foreground process group associated with the
-- terminal.
--
-- If neither `BRKINT' nor `IGNBRK' are set, a break condition is
-- passed to the application as a single `'\0'' character if `PARMRK'
-- is not set, or otherwise as a three-character sequence `'\377'',
-- `'\0'', `'\0''.
--
-- - Macro: tcflag_t IGNCR
-- If this bit is set, carriage return characters (`'\r'') are
-- discarded on input. Discarding carriage return may be useful on
-- terminals that send both carriage return and linefeed when you
-- type the <RET> key.
--
-- - Macro: tcflag_t ICRNL
-- If this bit is set and `IGNCR' is not set, carriage return
-- characters (`'\r'') received as input are passed to the
-- application as newline characters (`'\n'').
--
-- - Macro: tcflag_t INLCR
-- If this bit is set, newline characters (`'\n'') received as input
-- are passed to the application as carriage return characters
-- (`'\r'').
--
-- - Macro: tcflag_t IXOFF
-- If this bit is set, start/stop control on input is enabled. In
-- other words, the computer sends STOP and START characters as
-- necessary to prevent input from coming in faster than programs are
-- reading it. The idea is that the actual terminal hardware that is
-- generating the input data responds to a STOP character by
-- suspending transmission, and to a START character by resuming
-- transmission. *Note Start/Stop Characters::.
--
-- - Macro: tcflag_t IXON
-- If this bit is set, start/stop control on output is enabled. In
-- other words, if the computer receives a STOP character, it
-- suspends output until a START character is received. In this
-- case, the STOP and START characters are never passed to the
-- application program. If this bit is not set, then START and STOP
-- can be read as ordinary characters. *Note Start/Stop Characters::.
--
-- - Macro: tcflag_t IXANY
-- If this bit is set, any input character restarts output when
-- output has been suspended with the STOP character. Otherwise,
-- only the START character restarts output.
--
-- This is a BSD extension; it exists only on BSD systems and the GNU
-- system.
--
-- - Macro: tcflag_t IMAXBEL
-- If this bit is set, then filling up the terminal input buffer
-- sends a BEL character (code `007') to the terminal to ring the
-- bell.
--
-- This is a BSD extension.
--
--
--File: libc.info, Node: Output Modes, Next: Control Modes, Prev: Input Modes, Up: Terminal Modes
--
--Output Modes
--------------
--
-- This section describes the terminal flags and fields that control how
--output characters are translated and padded for display. All of these
--are contained in the `c_oflag' member of the `struct termios' structure.
--
-- The `c_oflag' member itself is an integer, and you change the flags
--and fields using the operators `&', `|', and `^'. Don't try to specify
--the entire value for `c_oflag'--instead, change only specific flags and
--leave the rest untouched (*note Setting Modes::.).
--
-- - Macro: tcflag_t OPOST
-- If this bit is set, output data is processed in some unspecified
-- way so that it is displayed appropriately on the terminal device.
-- This typically includes mapping newline characters (`'\n'') onto
-- carriage return and linefeed pairs.
--
-- If this bit isn't set, the characters are transmitted as-is.
--
-- The following three bits are BSD features, and they exist only BSD
--systems and the GNU system. They are effective only if `OPOST' is set.
--
-- - Macro: tcflag_t ONLCR
-- If this bit is set, convert the newline character on output into a
-- pair of characters, carriage return followed by linefeed.
--
-- - Macro: tcflag_t OXTABS
-- If this bit is set, convert tab characters on output into the
-- appropriate number of spaces to emulate a tab stop every eight
-- columns.
--
-- - Macro: tcflag_t ONOEOT
-- If this bit is set, discard `C-d' characters (code `004') on
-- output. These characters cause many dial-up terminals to
-- disconnect.
--
--
--File: libc.info, Node: Control Modes, Next: Local Modes, Prev: Output Modes, Up: Terminal Modes
--
--Control Modes
---------------
--
-- This section describes the terminal flags and fields that control
--parameters usually associated with asynchronous serial data
--transmission. These flags may not make sense for other kinds of
--terminal ports (such as a network connection pseudo-terminal). All of
--these are contained in the `c_cflag' member of the `struct termios'
--structure.
--
-- The `c_cflag' member itself is an integer, and you change the flags
--and fields using the operators `&', `|', and `^'. Don't try to specify
--the entire value for `c_cflag'--instead, change only specific flags and
--leave the rest untouched (*note Setting Modes::.).
--
-- - Macro: tcflag_t CLOCAL
-- If this bit is set, it indicates that the terminal is connected
-- "locally" and that the modem status lines (such as carrier detect)
-- should be ignored.
--
-- On many systems if this bit is not set and you call `open' without
-- the `O_NONBLOCK' flag set, `open' blocks until a modem connection
-- is established.
--
-- If this bit is not set and a modem disconnect is detected, a
-- `SIGHUP' signal is sent to the controlling process group for the
-- terminal (if it has one). Normally, this causes the process to
-- exit; see *Note Signal Handling::. Reading from the terminal
-- after a disconnect causes an end-of-file condition, and writing
-- causes an `EIO' error to be returned. The terminal device must be
-- closed and reopened to clear the condition.
--
-- - Macro: tcflag_t HUPCL
-- If this bit is set, a modem disconnect is generated when all
-- processes that have the terminal device open have either closed
-- the file or exited.
--
-- - Macro: tcflag_t CREAD
-- If this bit is set, input can be read from the terminal.
-- Otherwise, input is discarded when it arrives.
--
-- - Macro: tcflag_t CSTOPB
-- If this bit is set, two stop bits are used. Otherwise, only one
-- stop bit is used.
--
-- - Macro: tcflag_t PARENB
-- If this bit is set, generation and detection of a parity bit are
-- enabled. *Note Input Modes::, for information on how input parity
-- errors are handled.
--
-- If this bit is not set, no parity bit is added to output
-- characters, and input characters are not checked for correct
-- parity.
--
-- - Macro: tcflag_t PARODD
-- This bit is only useful if `PARENB' is set. If `PARODD' is set,
-- odd parity is used, otherwise even parity is used.
--
-- The control mode flags also includes a field for the number of bits
--per character. You can use the `CSIZE' macro as a mask to extract the
--value, like this: `settings.c_cflag & CSIZE'.
--
-- - Macro: tcflag_t CSIZE
-- This is a mask for the number of bits per character.
--
-- - Macro: tcflag_t CS5
-- This specifies five bits per byte.
--
-- - Macro: tcflag_t CS6
-- This specifies six bits per byte.
--
-- - Macro: tcflag_t CS7
-- This specifies seven bits per byte.
--
-- - Macro: tcflag_t CS8
-- This specifies eight bits per byte.
--
-- The following four bits are BSD extensions; this exist only on BSD
--systems and the GNU system.
--
-- - Macro: tcflag_t CCTS_OFLOW
-- If this bit is set, enable flow control of output based on the CTS
-- wire (RS232 protocol).
--
-- - Macro: tcflag_t CRTS_IFLOW
-- If this bit is set, enable flow control of input based on the RTS
-- wire (RS232 protocol).
--
-- - Macro: tcflag_t MDMBUF
-- If this bit is set, enable carrier-based flow control of output.
--
-- - Macro: tcflag_t CIGNORE
-- If this bit is set, it says to ignore the control modes and line
-- speed values entirely. This is only meaningful in a call to
-- `tcsetattr'.
--
-- The `c_cflag' member and the line speed values returned by
-- `cfgetispeed' and `cfgetospeed' will be unaffected by the call.
-- `CIGNORE' is useful if you want to set all the software modes in
-- the other members, but leave the hardware details in `c_cflag'
-- unchanged. (This is how the `TCSASOFT' flag to `tcsettattr'
-- works.)
--
-- This bit is never set in the structure filled in by `tcgetattr'.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-26 glibc-2.1.3/manual/libc.info-26
---- ../glibc-2.1.3/manual/libc.info-26 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-26 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1201 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Local Modes, Next: Line Speed, Prev: Control Modes, Up: Terminal Modes
--
--Local Modes
-------------
--
-- This section describes the flags for the `c_lflag' member of the
--`struct termios' structure. These flags generally control higher-level
--aspects of input processing than the input modes flags described in
--*Note Input Modes::, such as echoing, signals, and the choice of
--canonical or noncanonical input.
--
-- The `c_lflag' member itself is an integer, and you change the flags
--and fields using the operators `&', `|', and `^'. Don't try to specify
--the entire value for `c_lflag'--instead, change only specific flags and
--leave the rest untouched (*note Setting Modes::.).
--
-- - Macro: tcflag_t ICANON
-- This bit, if set, enables canonical input processing mode.
-- Otherwise, input is processed in noncanonical mode. *Note
-- Canonical or Not::.
--
-- - Macro: tcflag_t ECHO
-- If this bit is set, echoing of input characters back to the
-- terminal is enabled.
--
-- - Macro: tcflag_t ECHOE
-- If this bit is set, echoing indicates erasure of input with the
-- ERASE character by erasing the last character in the current line
-- from the screen. Otherwise, the character erased is re-echoed to
-- show what has happened (suitable for a printing terminal).
--
-- This bit only controls the display behavior; the `ICANON' bit by
-- itself controls actual recognition of the ERASE character and
-- erasure of input, without which `ECHOE' is simply irrelevant.
--
-- - Macro: tcflag_t ECHOPRT
-- This bit is like `ECHOE', enables display of the ERASE character in
-- a way that is geared to a hardcopy terminal. When you type the
-- ERASE character, a `\' character is printed followed by the first
-- character erased. Typing the ERASE character again just prints
-- the next character erased. Then, the next time you type a normal
-- character, a `/' character is printed before the character echoes.
--
-- This is a BSD extension, and exists only in BSD systems and the
-- GNU system.
--
-- - Macro: tcflag_t ECHOK
-- This bit enables special display of the KILL character by moving
-- to a new line after echoing the KILL character normally. The
-- behavior of `ECHOKE' (below) is nicer to look at.
--
-- If this bit is not set, the KILL character echoes just as it would
-- if it were not the KILL character. Then it is up to the user to
-- remember that the KILL character has erased the preceding input;
-- there is no indication of this on the screen.
--
-- This bit only controls the display behavior; the `ICANON' bit by
-- itself controls actual recognition of the KILL character and
-- erasure of input, without which `ECHOK' is simply irrelevant.
--
-- - Macro: tcflag_t ECHOKE
-- This bit is similar to `ECHOK'. It enables special display of the
-- KILL character by erasing on the screen the entire line that has
-- been killed. This is a BSD extension, and exists only in BSD
-- systems and the GNU system.
--
-- - Macro: tcflag_t ECHONL
-- If this bit is set and the `ICANON' bit is also set, then the
-- newline (`'\n'') character is echoed even if the `ECHO' bit is not
-- set.
--
-- - Macro: tcflag_t ECHOCTL
-- If this bit is set and the `ECHO' bit is also set, echo control
-- characters with `^' followed by the corresponding text character.
-- Thus, control-A echoes as `^A'. This is usually the preferred mode
-- for interactive input, because echoing a control character back to
-- the terminal could have some undesired effect on the terminal.
--
-- This is a BSD extension, and exists only in BSD systems and the
-- GNU system.
--
-- - Macro: tcflag_t ISIG
-- This bit controls whether the INTR, QUIT, and SUSP characters are
-- recognized. The functions associated with these characters are
-- performed if and only if this bit is set. Being in canonical or
-- noncanonical input mode has no affect on the interpretation of
-- these characters.
--
-- You should use caution when disabling recognition of these
-- characters. Programs that cannot be interrupted interactively are
-- very user-unfriendly. If you clear this bit, your program should
-- provide some alternate interface that allows the user to
-- interactively send the signals associated with these characters,
-- or to escape from the program.
--
-- *Note Signal Characters::.
--
-- - Macro: tcflag_t IEXTEN
-- POSIX.1 gives `IEXTEN' implementation-defined meaning, so you
-- cannot rely on this interpretation on all systems.
--
-- On BSD systems and the GNU system, it enables the LNEXT and
-- DISCARD characters. *Note Other Special::.
--
-- - Macro: tcflag_t NOFLSH
-- Normally, the INTR, QUIT, and SUSP characters cause input and
-- output queues for the terminal to be cleared. If this bit is set,
-- the queues are not cleared.
--
-- - Macro: tcflag_t TOSTOP
-- If this bit is set and the system supports job control, then
-- `SIGTTOU' signals are generated by background processes that
-- attempt to write to the terminal. *Note Access to the Terminal::.
--
-- The following bits are BSD extensions; they exist only in BSD systems
--and the GNU system.
--
-- - Macro: tcflag_t ALTWERASE
-- This bit determines how far the WERASE character should erase. The
-- WERASE character erases back to the beginning of a word; the
-- question is, where do words begin?
--
-- If this bit is clear, then the beginning of a word is a
-- nonwhitespace character following a whitespace character. If the
-- bit is set, then the beginning of a word is an alphanumeric
-- character or underscore following a character which is none of
-- those.
--
-- *Note Editing Characters::, for more information about the WERASE
-- character.
--
-- - Macro: tcflag_t FLUSHO
-- This is the bit that toggles when the user types the DISCARD
-- character. While this bit is set, all output is discarded. *Note
-- Other Special::.
--
-- - Macro: tcflag_t NOKERNINFO
-- Setting this bit disables handling of the STATUS character. *Note
-- Other Special::.
--
-- - Macro: tcflag_t PENDIN
-- If this bit is set, it indicates that there is a line of input that
-- needs to be reprinted. Typing the REPRINT character sets this
-- bit; the bit remains set until reprinting is finished. *Note
-- Editing Characters::.
--
--
--File: libc.info, Node: Line Speed, Next: Special Characters, Prev: Local Modes, Up: Terminal Modes
--
--Line Speed
------------
--
-- The terminal line speed tells the computer how fast to read and write
--data on the terminal.
--
-- If the terminal is connected to a real serial line, the terminal
--speed you specify actually controls the line--if it doesn't match the
--terminal's own idea of the speed, communication does not work. Real
--serial ports accept only certain standard speeds. Also, particular
--hardware may not support even all the standard speeds. Specifying a
--speed of zero hangs up a dialup connection and turns off modem control
--signals.
--
-- If the terminal is not a real serial line (for example, if it is a
--network connection), then the line speed won't really affect data
--transmission speed, but some programs will use it to determine the
--amount of padding needed. It's best to specify a line speed value that
--matches the actual speed of the actual terminal, but you can safely
--experiment with different values to vary the amount of padding.
--
-- There are actually two line speeds for each terminal, one for input
--and one for output. You can set them independently, but most often
--terminals use the same speed for both directions.
--
-- The speed values are stored in the `struct termios' structure, but
--don't try to access them in the `struct termios' structure directly.
--Instead, you should use the following functions to read and store them:
--
-- - Function: speed_t cfgetospeed (const struct termios *TERMIOS-P)
-- This function returns the output line speed stored in the structure
-- `*TERMIOS-P'.
--
-- - Function: speed_t cfgetispeed (const struct termios *TERMIOS-P)
-- This function returns the input line speed stored in the structure
-- `*TERMIOS-P'.
--
-- - Function: int cfsetospeed (struct termios *TERMIOS-P, speed_t SPEED)
-- This function stores SPEED in `*TERMIOS-P' as the output speed.
-- The normal return value is 0; a value of -1 indicates an error.
-- If SPEED is not a speed, `cfsetospeed' returns -1.
--
-- - Function: int cfsetispeed (struct termios *TERMIOS-P, speed_t SPEED)
-- This function stores SPEED in `*TERMIOS-P' as the input speed.
-- The normal return value is 0; a value of -1 indicates an error.
-- If SPEED is not a speed, `cfsetospeed' returns -1.
--
-- - Function: int cfsetspeed (struct termios *TERMIOS-P, speed_t SPEED)
-- This function stores SPEED in `*TERMIOS-P' as both the input and
-- output speeds. The normal return value is 0; a value of -1
-- indicates an error. If SPEED is not a speed, `cfsetspeed' returns
-- -1. This function is an extension in 4.4 BSD.
--
-- - Data Type: speed_t
-- The `speed_t' type is an unsigned integer data type used to
-- represent line speeds.
--
-- The functions `cfsetospeed' and `cfsetispeed' report errors only for
--speed values that the system simply cannot handle. If you specify a
--speed value that is basically acceptable, then those functions will
--succeed. But they do not check that a particular hardware device can
--actually support the specified speeds--in fact, they don't know which
--device you plan to set the speed for. If you use `tcsetattr' to set
--the speed of a particular device to a value that it cannot handle,
--`tcsetattr' returns -1.
--
-- *Portability note:* In the GNU library, the functions above accept
--speeds measured in bits per second as input, and return speed values
--measured in bits per second. Other libraries require speeds to be
--indicated by special codes. For POSIX.1 portability, you must use one
--of the following symbols to represent the speed; their precise numeric
--values are system-dependent, but each name has a fixed meaning: `B110'
--stands for 110 bps, `B300' for 300 bps, and so on. There is no
--portable way to represent any speed but these, but these are the only
--speeds that typical serial lines can support.
--
-- B0 B50 B75 B110 B134 B150 B200
-- B300 B600 B1200 B1800 B2400 B4800
-- B9600 B19200 B38400 B57600 B115200
-- B230400 B460800
--
-- BSD defines two additional speed symbols as aliases: `EXTA' is an
--alias for `B19200' and `EXTB' is an alias for `B38400'. These aliases
--are obsolete.
--
--
--File: libc.info, Node: Special Characters, Next: Noncanonical Input, Prev: Line Speed, Up: Terminal Modes
--
--Special Characters
--------------------
--
-- In canonical input, the terminal driver recognizes a number of
--special characters which perform various control functions. These
--include the ERASE character (usually <DEL>) for editing input, and
--other editing characters. The INTR character (normally `C-c') for
--sending a `SIGINT' signal, and other signal-raising characters, may be
--available in either canonical or noncanonical input mode. All these
--characters are described in this section.
--
-- The particular characters used are specified in the `c_cc' member of
--the `struct termios' structure. This member is an array; each element
--specifies the character for a particular role. Each element has a
--symbolic constant that stands for the index of that element--for
--example, `VINTR' is the index of the element that specifies the INTR
--character, so storing `'='' in `TERMIOS.c_cc[VINTR]' specifies `=' as
--the INTR character.
--
-- On some systems, you can disable a particular special character
--function by specifying the value `_POSIX_VDISABLE' for that role. This
--value is unequal to any possible character code. *Note Options for
--Files::, for more information about how to tell whether the operating
--system you are using supports `_POSIX_VDISABLE'.
--
--* Menu:
--
--* Editing Characters:: Special characters that terminate lines and
-- delete text, and other editing functions.
--* Signal Characters:: Special characters that send or raise signals
-- to or for certain classes of processes.
--* Start/Stop Characters:: Special characters that suspend or resume
-- suspended output.
--* Other Special:: Other special characters for BSD systems:
-- they can discard output, and print status.
--
--
--File: libc.info, Node: Editing Characters, Next: Signal Characters, Up: Special Characters
--
--Characters for Input Editing
--............................
--
-- These special characters are active only in canonical input mode.
--*Note Canonical or Not::.
--
-- - Macro: int VEOF
-- This is the subscript for the EOF character in the special control
-- character array. `TERMIOS.c_cc[VEOF]' holds the character itself.
--
-- The EOF character is recognized only in canonical input mode. It
-- acts as a line terminator in the same way as a newline character,
-- but if the EOF character is typed at the beginning of a line it
-- causes `read' to return a byte count of zero, indicating
-- end-of-file. The EOF character itself is discarded.
--
-- Usually, the EOF character is `C-d'.
--
-- - Macro: int VEOL
-- This is the subscript for the EOL character in the special control
-- character array. `TERMIOS.c_cc[VEOL]' holds the character itself.
--
-- The EOL character is recognized only in canonical input mode. It
-- acts as a line terminator, just like a newline character. The EOL
-- character is not discarded; it is read as the last character in
-- the input line.
--
-- You don't need to use the EOL character to make <RET> end a line.
-- Just set the ICRNL flag. In fact, this is the default state of
-- affairs.
--
-- - Macro: int VEOL2
-- This is the subscript for the EOL2 character in the special control
-- character array. `TERMIOS.c_cc[VEOL2]' holds the character itself.
--
-- The EOL2 character works just like the EOL character (see above),
-- but it can be a different character. Thus, you can specify two
-- characters to terminate an input line, by setting EOL to one of
-- them and EOL2 to the other.
--
-- The EOL2 character is a BSD extension; it exists only on BSD
-- systems and the GNU system.
--
-- - Macro: int VERASE
-- This is the subscript for the ERASE character in the special
-- control character array. `TERMIOS.c_cc[VERASE]' holds the
-- character itself.
--
-- The ERASE character is recognized only in canonical input mode.
-- When the user types the erase character, the previous character
-- typed is discarded. (If the terminal generates multibyte
-- character sequences, this may cause more than one byte of input to
-- be discarded.) This cannot be used to erase past the beginning of
-- the current line of text. The ERASE character itself is discarded.
--
-- Usually, the ERASE character is <DEL>.
--
-- - Macro: int VWERASE
-- This is the subscript for the WERASE character in the special
-- control character array. `TERMIOS.c_cc[VWERASE]' holds the
-- character itself.
--
-- The WERASE character is recognized only in canonical mode. It
-- erases an entire word of prior input, and any whitespace after it;
-- whitespace characters before the word are not erased.
--
-- The definition of a "word" depends on the setting of the
-- `ALTWERASE' mode; *note Local Modes::..
--
-- If the `ALTWERASE' mode is not set, a word is defined as a sequence
-- of any characters except space or tab.
--
-- If the `ALTWERASE' mode is set, a word is defined as a sequence of
-- characters containing only letters, numbers, and underscores,
-- optionally followed by one character that is not a letter, number,
-- or underscore.
--
-- The WERASE character is usually `C-w'.
--
-- This is a BSD extension.
--
-- - Macro: int VKILL
-- This is the subscript for the KILL character in the special control
-- character array. `TERMIOS.c_cc[VKILL]' holds the character itself.
--
-- The KILL character is recognized only in canonical input mode.
-- When the user types the kill character, the entire contents of the
-- current line of input are discarded. The kill character itself is
-- discarded too.
--
-- The KILL character is usually `C-u'.
--
-- - Macro: int VREPRINT
-- This is the subscript for the REPRINT character in the special
-- control character array. `TERMIOS.c_cc[VREPRINT]' holds the
-- character itself.
--
-- The REPRINT character is recognized only in canonical mode. It
-- reprints the current input line. If some asynchronous output has
-- come while you are typing, this lets you see the line you are
-- typing clearly again.
--
-- The REPRINT character is usually `C-r'.
--
-- This is a BSD extension.
--
--
--File: libc.info, Node: Signal Characters, Next: Start/Stop Characters, Prev: Editing Characters, Up: Special Characters
--
--Characters that Cause Signals
--.............................
--
-- These special characters may be active in either canonical or
--noncanonical input mode, but only when the `ISIG' flag is set (*note
--Local Modes::.).
--
-- - Macro: int VINTR
-- This is the subscript for the INTR character in the special control
-- character array. `TERMIOS.c_cc[VINTR]' holds the character itself.
--
-- The INTR (interrupt) character raises a `SIGINT' signal for all
-- processes in the foreground job associated with the terminal. The
-- INTR character itself is then discarded. *Note Signal Handling::,
-- for more information about signals.
--
-- Typically, the INTR character is `C-c'.
--
-- - Macro: int VQUIT
-- This is the subscript for the QUIT character in the special control
-- character array. `TERMIOS.c_cc[VQUIT]' holds the character itself.
--
-- The QUIT character raises a `SIGQUIT' signal for all processes in
-- the foreground job associated with the terminal. The QUIT
-- character itself is then discarded. *Note Signal Handling::, for
-- more information about signals.
--
-- Typically, the QUIT character is `C-\'.
--
-- - Macro: int VSUSP
-- This is the subscript for the SUSP character in the special control
-- character array. `TERMIOS.c_cc[VSUSP]' holds the character itself.
--
-- The SUSP (suspend) character is recognized only if the
-- implementation supports job control (*note Job Control::.). It
-- causes a `SIGTSTP' signal to be sent to all processes in the
-- foreground job associated with the terminal. The SUSP character
-- itself is then discarded. *Note Signal Handling::, for more
-- information about signals.
--
-- Typically, the SUSP character is `C-z'.
--
-- Few applications disable the normal interpretation of the SUSP
--character. If your program does this, it should provide some other
--mechanism for the user to stop the job. When the user invokes this
--mechanism, the program should send a `SIGTSTP' signal to the process
--group of the process, not just to the process itself. *Note Signaling
--Another Process::.
--
-- - Macro: int VDSUSP
-- This is the subscript for the DSUSP character in the special
-- control character array. `TERMIOS.c_cc[VDSUSP]' holds the
-- character itself.
--
-- The DSUSP (suspend) character is recognized only if the
-- implementation supports job control (*note Job Control::.). It
-- sends a `SIGTSTP' signal, like the SUSP character, but not right
-- away--only when the program tries to read it as input. Not all
-- systems with job control support DSUSP; only BSD-compatible
-- systems (including the GNU system).
--
-- *Note Signal Handling::, for more information about signals.
--
-- Typically, the DSUSP character is `C-y'.
--
--
--File: libc.info, Node: Start/Stop Characters, Next: Other Special, Prev: Signal Characters, Up: Special Characters
--
--Special Characters for Flow Control
--...................................
--
-- These special characters may be active in either canonical or
--noncanonical input mode, but their use is controlled by the flags
--`IXON' and `IXOFF' (*note Input Modes::.).
--
-- - Macro: int VSTART
-- This is the subscript for the START character in the special
-- control character array. `TERMIOS.c_cc[VSTART]' holds the
-- character itself.
--
-- The START character is used to support the `IXON' and `IXOFF'
-- input modes. If `IXON' is set, receiving a START character resumes
-- suspended output; the START character itself is discarded. If
-- `IXANY' is set, receiving any character at all resumes suspended
-- output; the resuming character is not discarded unless it is the
-- START character. `IXOFF' is set, the system may also transmit
-- START characters to the terminal.
--
-- The usual value for the START character is `C-q'. You may not be
-- able to change this value--the hardware may insist on using `C-q'
-- regardless of what you specify.
--
-- - Macro: int VSTOP
-- This is the subscript for the STOP character in the special control
-- character array. `TERMIOS.c_cc[VSTOP]' holds the character itself.
--
-- The STOP character is used to support the `IXON' and `IXOFF' input
-- modes. If `IXON' is set, receiving a STOP character causes output
-- to be suspended; the STOP character itself is discarded. If
-- `IXOFF' is set, the system may also transmit STOP characters to the
-- terminal, to prevent the input queue from overflowing.
--
-- The usual value for the STOP character is `C-s'. You may not be
-- able to change this value--the hardware may insist on using `C-s'
-- regardless of what you specify.
--
--
--File: libc.info, Node: Other Special, Prev: Start/Stop Characters, Up: Special Characters
--
--Other Special Characters
--........................
--
-- These special characters exist only in BSD systems and the GNU
--system.
--
-- - Macro: int VLNEXT
-- This is the subscript for the LNEXT character in the special
-- control character array. `TERMIOS.c_cc[VLNEXT]' holds the
-- character itself.
--
-- The LNEXT character is recognized only when `IEXTEN' is set, but in
-- both canonical and noncanonical mode. It disables any special
-- significance of the next character the user types. Even if the
-- character would normally perform some editing function or generate
-- a signal, it is read as a plain character. This is the analogue
-- of the `C-q' command in Emacs. "LNEXT" stands for "literal next."
--
-- The LNEXT character is usually `C-v'.
--
-- - Macro: int VDISCARD
-- This is the subscript for the DISCARD character in the special
-- control character array. `TERMIOS.c_cc[VDISCARD]' holds the
-- character itself.
--
-- The DISCARD character is recognized only when `IEXTEN' is set, but
-- in both canonical and noncanonical mode. Its effect is to toggle
-- the discard-output flag. When this flag is set, all program
-- output is discarded. Setting the flag also discards all output
-- currently in the output buffer. Typing any other character resets
-- the flag.
--
-- - Macro: int VSTATUS
-- This is the subscript for the STATUS character in the special
-- control character array. `TERMIOS.c_cc[VSTATUS]' holds the
-- character itself.
--
-- The STATUS character's effect is to print out a status message
-- about how the current process is running.
--
-- The STATUS character is recognized only in canonical mode, and
-- only if `NOKERNINFO' is not set.
--
--
--File: libc.info, Node: Noncanonical Input, Prev: Special Characters, Up: Terminal Modes
--
--Noncanonical Input
--------------------
--
-- In noncanonical input mode, the special editing characters such as
--ERASE and KILL are ignored. The system facilities for the user to edit
--input are disabled in noncanonical mode, so that all input characters
--(unless they are special for signal or flow-control purposes) are passed
--to the application program exactly as typed. It is up to the
--application program to give the user ways to edit the input, if
--appropriate.
--
-- Noncanonical mode offers special parameters called MIN and TIME for
--controlling whether and how long to wait for input to be available. You
--can even use them to avoid ever waiting--to return immediately with
--whatever input is available, or with no input.
--
-- The MIN and TIME are stored in elements of the `c_cc' array, which
--is a member of the `struct termios' structure. Each element of this
--array has a particular role, and each element has a symbolic constant
--that stands for the index of that element. `VMIN' and `VMAX' are the
--names for the indices in the array of the MIN and TIME slots.
--
-- - Macro: int VMIN
-- This is the subscript for the MIN slot in the `c_cc' array. Thus,
-- `TERMIOS.c_cc[VMIN]' is the value itself.
--
-- The MIN slot is only meaningful in noncanonical input mode; it
-- specifies the minimum number of bytes that must be available in the
-- input queue in order for `read' to return.
--
-- - Macro: int VTIME
-- This is the subscript for the TIME slot in the `c_cc' array. Thus,
-- `TERMIOS.c_cc[VTIME]' is the value itself.
--
-- The TIME slot is only meaningful in noncanonical input mode; it
-- specifies how long to wait for input before returning, in units of
-- 0.1 seconds.
--
-- The MIN and TIME values interact to determine the criterion for when
--`read' should return; their precise meanings depend on which of them
--are nonzero. There are four possible cases:
--
-- * Both TIME and MIN are nonzero.
--
-- In this case, TIME specifies how long to wait after each input
-- character to see if more input arrives. After the first character
-- received, `read' keeps waiting until either MIN bytes have arrived
-- in all, or TIME elapses with no further input.
--
-- `read' always blocks until the first character arrives, even if
-- TIME elapses first. `read' can return more than MIN characters if
-- more than MIN happen to be in the queue.
--
-- * Both MIN and TIME are zero.
--
-- In this case, `read' always returns immediately with as many
-- characters as are available in the queue, up to the number
-- requested. If no input is immediately available, `read' returns a
-- value of zero.
--
-- * MIN is zero but TIME has a nonzero value.
--
-- In this case, `read' waits for time TIME for input to become
-- available; the availability of a single byte is enough to satisfy
-- the read request and cause `read' to return. When it returns, it
-- returns as many characters as are available, up to the number
-- requested. If no input is available before the timer expires,
-- `read' returns a value of zero.
--
-- * TIME is zero but MIN has a nonzero value.
--
-- In this case, `read' waits until at least MIN bytes are available
-- in the queue. At that time, `read' returns as many characters as
-- are available, up to the number requested. `read' can return more
-- than MIN characters if more than MIN happen to be in the queue.
--
-- What happens if MIN is 50 and you ask to read just 10 bytes?
--Normally, `read' waits until there are 50 bytes in the buffer (or, more
--generally, the wait condition described above is satisfied), and then
--reads 10 of them, leaving the other 40 buffered in the operating system
--for a subsequent call to `read'.
--
-- *Portability note:* On some systems, the MIN and TIME slots are
--actually the same as the EOF and EOL slots. This causes no serious
--problem because the MIN and TIME slots are used only in noncanonical
--input and the EOF and EOL slots are used only in canonical input, but it
--isn't very clean. The GNU library allocates separate slots for these
--uses.
--
-- - Function: int cfmakeraw (struct termios *TERMIOS-P)
-- This function provides an easy way to set up `*TERMIOS-P' for what
-- has traditionally been called "raw mode" in BSD. This uses
-- noncanonical input, and turns off most processing to give an
-- unmodified channel to the terminal.
--
-- It does exactly this:
-- TERMIOS-P->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
-- |INLCR|IGNCR|ICRNL|IXON);
-- TERMIOS-P->c_oflag &= ~OPOST;
-- TERMIOS-P->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
-- TERMIOS-P->c_cflag &= ~(CSIZE|PARENB);
-- TERMIOS-P->c_cflag |= CS8;
--
--
--File: libc.info, Node: Line Control, Next: Noncanon Example, Prev: Terminal Modes, Up: Low-Level Terminal Interface
--
--Line Control Functions
--======================
--
-- These functions perform miscellaneous control actions on terminal
--devices. As regards terminal access, they are treated like doing
--output: if any of these functions is used by a background process on its
--controlling terminal, normally all processes in the process group are
--sent a `SIGTTOU' signal. The exception is if the calling process
--itself is ignoring or blocking `SIGTTOU' signals, in which case the
--operation is performed and no signal is sent. *Note Job Control::.
--
-- - Function: int tcsendbreak (int FILEDES, int DURATION)
-- This function generates a break condition by transmitting a stream
-- of zero bits on the terminal associated with the file descriptor
-- FILEDES. The duration of the break is controlled by the DURATION
-- argument. If zero, the duration is between 0.25 and 0.5 seconds.
-- The meaning of a nonzero value depends on the operating system.
--
-- This function does nothing if the terminal is not an asynchronous
-- serial data port.
--
-- The return value is normally zero. In the event of an error, a
-- value of -1 is returned. The following `errno' error conditions
-- are defined for this function:
--
-- `EBADF'
-- The FILEDES is not a valid file descriptor.
--
-- `ENOTTY'
-- The FILEDES is not associated with a terminal device.
--
-- - Function: int tcdrain (int FILEDES)
-- The `tcdrain' function waits until all queued output to the
-- terminal FILEDES has been transmitted.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `tcdrain' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `tcdrain' should be protected using cancelation handlers.
--
-- The return value is normally zero. In the event of an error, a
-- value of -1 is returned. The following `errno' error conditions
-- are defined for this function:
--
-- `EBADF'
-- The FILEDES is not a valid file descriptor.
--
-- `ENOTTY'
-- The FILEDES is not associated with a terminal device.
--
-- `EINTR'
-- The operation was interrupted by delivery of a signal. *Note
-- Interrupted Primitives::.
--
-- - Function: int tcflush (int FILEDES, int QUEUE)
-- The `tcflush' function is used to clear the input and/or output
-- queues associated with the terminal file FILEDES. The QUEUE
-- argument specifies which queue(s) to clear, and can be one of the
-- following values:
--
-- `TCIFLUSH'
-- Clear any input data received, but not yet read.
--
-- `TCOFLUSH'
-- Clear any output data written, but not yet transmitted.
--
-- `TCIOFLUSH'
-- Clear both queued input and output.
--
-- The return value is normally zero. In the event of an error, a
-- value of -1 is returned. The following `errno' error conditions
-- are defined for this function:
--
-- `EBADF'
-- The FILEDES is not a valid file descriptor.
--
-- `ENOTTY'
-- The FILEDES is not associated with a terminal device.
--
-- `EINVAL'
-- A bad value was supplied as the QUEUE argument.
--
-- It is unfortunate that this function is named `tcflush', because
-- the term "flush" is normally used for quite another
-- operation--waiting until all output is transmitted--and using it
-- for discarding input or output would be confusing. Unfortunately,
-- the name `tcflush' comes from POSIX and we cannot change it.
--
-- - Function: int tcflow (int FILEDES, int ACTION)
-- The `tcflow' function is used to perform operations relating to
-- XON/XOFF flow control on the terminal file specified by FILEDES.
--
-- The ACTION argument specifies what operation to perform, and can
-- be one of the following values:
--
-- `TCOOFF'
-- Suspend transmission of output.
--
-- `TCOON'
-- Restart transmission of output.
--
-- `TCIOFF'
-- Transmit a STOP character.
--
-- `TCION'
-- Transmit a START character.
--
-- For more information about the STOP and START characters, see
-- *Note Special Characters::.
--
-- The return value is normally zero. In the event of an error, a
-- value of -1 is returned. The following `errno' error conditions
-- are defined for this function:
--
-- `EBADF'
-- The FILEDES is not a valid file descriptor.
--
-- `ENOTTY'
-- The FILEDES is not associated with a terminal device.
--
-- `EINVAL'
-- A bad value was supplied as the ACTION argument.
--
--
--File: libc.info, Node: Noncanon Example, Next: Pseudo-Terminals, Prev: Line Control, Up: Low-Level Terminal Interface
--
--Noncanonical Mode Example
--=========================
--
-- Here is an example program that shows how you can set up a terminal
--device to read single characters in noncanonical input mode, without
--echo.
--
-- #include <unistd.h>
-- #include <stdio.h>
-- #include <stdlib.h>
-- #include <termios.h>
--
-- /* Use this variable to remember original terminal attributes. */
--
-- struct termios saved_attributes;
--
-- void
-- reset_input_mode (void)
-- {
-- tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
-- }
--
-- void
-- set_input_mode (void)
-- {
-- struct termios tattr;
-- char *name;
--
-- /* Make sure stdin is a terminal. */
-- if (!isatty (STDIN_FILENO))
-- {
-- fprintf (stderr, "Not a terminal.\n");
-- exit (EXIT_FAILURE);
-- }
--
-- /* Save the terminal attributes so we can restore them later. */
-- tcgetattr (STDIN_FILENO, &saved_attributes);
-- atexit (reset_input_mode);
-- /* Set the funny terminal modes. */
-- tcgetattr (STDIN_FILENO, &tattr);
-- tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
-- tattr.c_cc[VMIN] = 1;
-- tattr.c_cc[VTIME] = 0;
-- tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
-- }
--
-- int
-- main (void)
-- {
-- char c;
--
-- set_input_mode ();
--
-- while (1)
-- {
-- read (STDIN_FILENO, &c, 1);
-- if (c == '\004') /* `C-d' */
-- break;
-- else
-- putchar (c);
-- }
--
-- return EXIT_SUCCESS;
-- }
--
-- This program is careful to restore the original terminal modes before
--exiting or terminating with a signal. It uses the `atexit' function
--(*note Cleanups on Exit::.) to make sure this is done by `exit'.
--
-- The shell is supposed to take care of resetting the terminal modes
--when a process is stopped or continued; see *Note Job Control::. But
--some existing shells do not actually do this, so you may wish to
--establish handlers for job control signals that reset terminal modes.
--The above example does so.
--
--
--File: libc.info, Node: Pseudo-Terminals, Prev: Noncanon Example, Up: Low-Level Terminal Interface
--
--Pseudo-Terminals
--================
--
-- A "pseudo-terminal" is a special interprocess communication channel
--that acts like a terminal. One end of the channel is called the
--"master" side or "master pseudo-terminal device", the other side is
--called the "slave" side. Data written to the master side is received
--by the slave side as if it was the result of a user typing at an
--ordinary terminal, and data written to the slave side is sent to the
--master side as if it was written on an ordinary terminal.
--
-- Pseudo terminals are the way programs like `xterm' and `emacs'
--implement their terminal emulation functionality.
--
--* Menu:
--
--* Allocation:: Allocating a pseudo terminal.
--* Pseudo-Terminal Pairs:: How to open both sides of a
-- pseudo-terminal in a single operation.
--
--
--File: libc.info, Node: Allocation, Next: Pseudo-Terminal Pairs, Up: Pseudo-Terminals
--
--Allocating Pseudo-Terminals
-----------------------------
--
-- This subsection describes functions for allocating a pseudo-terminal,
--and for making this pseudo-terminal available for actual use. These
--functions are declared in the header file `stdlib.h'.
--
-- - Function: int getpt (void)
-- The `getpt' function returns a new file descriptor for the next
-- available master pseudo-terminal. The normal return value from
-- `getpt' is a non-negative integer file descriptor. In the case of
-- an error, a value of -1 is returned instead. The following
-- `errno' conditions are defined for this function:
--
-- `ENOENT'
-- There are no free master pseudo-terminals available.
--
-- This function is a GNU extension.
--
-- - Function: int grantpt (int FILEDES)
-- The `grantpt' function changes the ownership and access permission
-- of the slave pseudo-terminal device corresponding to the master
-- pseudo-terminal device associated with the file descriptor
-- FILEDES. The owner is set from the real user ID of the calling
-- process (*note Process Persona::.), and the group is set to a
-- special group (typically "tty") or from the real group ID of the
-- calling process. The access permission is set such that the file
-- is both readable and writable by the owner and only writable by
-- the group.
--
-- On some systems this function is implemented by invoking a special
-- `setuid' root program (*note How Change Persona::.). As a
-- consequence, installing a signal handler for the `SIGCHLD' signal
-- (*note Job Control Signals::.) may interfere with a call to
-- `grantpt'.
--
-- The normal return value from `grantpt' is 0; a value of -1 is
-- returned in case of failure. The following `errno' error
-- conditions are defined for this function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `ENINVAL'
-- The FILEDES argument is not associated with a master
-- pseudo-terminal device.
--
-- `EACCESS'
-- The slave pseudo-terminal device corresponding to the master
-- associated with FILEDES could not be accessed.
--
--
-- - Function: int unlockpt (int FILEDES)
-- The `unlockpt' function unlocks the slave pseudo-terminal device
-- corresponding to the master pseudo-terminal device associated with
-- the file descriptor FILEDES. On many systems, the slave can only
-- be opened after unlocking, so portable applications should always
-- call `unlockpt' before trying to open the slave.
--
-- The normal return value from `unlockpt' is 0; a value of -1 is
-- returned in case of failure. The following `errno' error
-- conditions are defined for this function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `EINVAL'
-- The FILEDES argument is not associated with a master
-- pseudo-terminal device.
--
-- - Function: char * ptsname (int FILEDES)
-- If the file descriptor FILEDES is associated with a master
-- pseudo-terminal device, the `ptsname' function returns a pointer
-- to a statically-allocated, null-terminated string containing the
-- file name of the associated slave pseudo-terminal file. This
-- string might be overwritten by subsequent calls to `ptsname'.
--
-- - Function: int ptsname_r (int FILEDES, char *BUF, size_t LEN)
-- The `ptsname_r' function is similar to the `ptsname' function
-- except that it places its result into the user-specified buffer
-- starting at BUF with length LEN.
--
-- This function is a GNU extension.
--
-- *Portability Note:* On System V derived systems, the file returned
--by the `ptsname' and `ptsname_r' functions may be STREAMS-based, and
--therefore require additional processing after opening before it
--actually behaves as a pseudo terminal.
--
-- Typical usage of these functions is illustrated by the following
--example:
-- int
-- open_pty_pair (int *amaster, int *aslave)
-- {
-- int master, slave;
-- char *name
--
-- master = getpt ();
-- if (master < 0)
-- return 0;
--
-- if (grantpt (master) < 0 || unlockpt (master) < 0)
-- goto close_master;
-- name = ptsname (master);
-- if (name == NULL)
-- goto close_master;
--
-- slave = open (name, O_RDWR);
-- if (slave == -1)
-- goto close_master;
--
-- if (isastream (slave))
-- {
-- if (ioctl (slave, I_PUSH, "ptem") < 0
-- || ioctl (slave, I_PUSH, "ldterm") < 0)
-- goto close_slave;
-- }
--
-- *amaster = master;
-- *aslave = slave;
-- return 1;
--
-- close_slave:
-- close (slave);
--
-- close_master:
-- close (master);
-- return 0;
-- }
--
--
--File: libc.info, Node: Pseudo-Terminal Pairs, Prev: Allocation, Up: Pseudo-Terminals
--
--Opening a Pseudo-Terminal Pair
--------------------------------
--
-- These functions, derived from BSD, are available in the separate
--`libutil' library, and declared in `pty.h'.
--
-- - Function: int openpty (int *AMASTER, int *ASLAVE, char *NAME, struct
-- termios *TERMP, struct winsize *WINP)
-- This function allocates and opens a pseudo-terminal pair,
-- returning the file descriptor for the master in *AMASTER, and the
-- file descriptor for the slave in *ASLAVE. If the argument NAME is
-- not a null pointer, the file name of the slave pseudo-terminal
-- device is stored in `*name'. If TERMP is not a null pointer, the
-- terminal attributes of the slave are set to the ones specified in
-- the structure that TERMP points to (*note Terminal Modes::.).
-- Likewise, if the WINP is not a null pointer, the screen size of
-- the slave is set to the values specified in the structure that
-- WINP points to.
--
-- The normal return value from `openpty' is 0; a value of -1 is
-- returned in case of failure. The following `errno' conditions are
-- defined for this function:
--
-- `ENOENT'
-- There are no free pseudo-terminal pairs available.
--
-- *Warning:* Using the `openpty' function with NAME not set to
-- `NULL' is *very dangerous* because it provides no protection
-- against overflowing the string NAME. You should use the `ttyname'
-- function on the file descriptor returned in *SLAVE to find out the
-- file name of the slave pseudo-terminal device instead.
--
-- - Function: int forkpty (int *AMASTER, char *NAME, struct termios
-- *TERMP, struct winsize *WINP)
-- This function is similar to the `openpty' function, but in
-- addition, forks a new process (*note Creating a Process::.) and
-- makes the newly opened slave pseudo-terminal device the
-- controlling terminal (*note Controlling Terminal::.) for the child
-- process.
--
-- If the operation is successful, there are then both parent and
-- child processes and both see `forkpty' return, but with different
-- values: it returns a value of 0 in the child process and returns
-- the child's process ID in the parent process.
--
-- If the allocation of a pseudo-terminal pair or the process creation
-- failed, `forkpty' returns a value of -1 in the parent process.
--
-- *Warning:* The `forkpty' function has the same problems with
-- respect to the NAME argument as `openpty'.
--
--
--File: libc.info, Node: Mathematics, Next: Arithmetic, Prev: Low-Level Terminal Interface, Up: Top
--
--Mathematics
--***********
--
-- This chapter contains information about functions for performing
--mathematical computations, such as trigonometric functions. Most of
--these functions have prototypes declared in the header file `math.h'.
--The complex-valued functions are defined in `complex.h'.
--
-- All mathematical functions which take a floating-point argument have
--three variants, one each for `double', `float', and `long double'
--arguments. The `double' versions are mostly defined in ISO C 89. The
--`float' and `long double' versions are from the numeric extensions to C
--included in ISO C 9X.
--
-- Which of the three versions of a function should be used depends on
--the situation. For most calculations, the `float' functions are the
--fastest. On the other hand, the `long double' functions have the
--highest precision. `double' is somewhere in between. It is usually
--wise to pick the narrowest type that can accomodate your data. Not all
--machines have a distinct `long double' type; it may be the same as
--`double'.
--
--* Menu:
--
--* Mathematical Constants:: Precise numeric values for often-used
-- constants.
--* Trig Functions:: Sine, cosine, tangent, and friends.
--* Inverse Trig Functions:: Arcsine, arccosine, etc.
--* Exponents and Logarithms:: Also pow and sqrt.
--* Hyperbolic Functions:: sinh, cosh, tanh, etc.
--* Special Functions:: Bessel, gamma, erf.
--* Pseudo-Random Numbers:: Functions for generating pseudo-random
-- numbers.
--* FP Function Optimizations:: Fast code or small code.
--
--
--File: libc.info, Node: Mathematical Constants, Next: Trig Functions, Up: Mathematics
--
--Predefined Mathematical Constants
--=================================
--
-- The header `math.h' defines several useful mathematical constants.
--All values are defined as preprocessor macros starting with `M_'. The
--values provided are:
--
--`M_E'
-- The base of natural logarithms.
--
--`M_LOG2E'
-- The logarithm to base `2' of `M_E'.
--
--`M_LOG10E'
-- The logarithm to base `10' of `M_E'.
--
--`M_LN2'
-- The natural logarithm of `2'.
--
--`M_LN10'
-- The natural logarithm of `10'.
--
--`M_PI'
-- Pi, the ratio of a circle's circumrefence to its diameter.
--
--`M_PI_2'
-- Pi divided by two.
--
--`M_PI_4'
-- Pi divided by four.
--
--`M_1_PI'
-- The reciprocal of pi (1/pi)
--
--`M_2_PI'
-- Two times the reciprocal of pi.
--
--`M_2_SQRTPI'
-- Two times the reciprocal of the square root of pi.
--
--`M_SQRT2'
-- The square root of two.
--
--`M_SQRT1_2'
-- The reciprocal of the square root of two (also the square root of
-- 1/2).
--
-- These constants come from the Unix98 standard and were also
--available in 4.4BSD; therefore, they are only defined if `_BSD_SOURCE'
--or `_XOPEN_SOURCE=500', or a more general feature select macro, is
--defined. The default set of features includes these constants. *Note
--Feature Test Macros::.
--
-- All values are of type `double'. As an extension, the GNU C library
--also defines these constants with type `long double'. The `long
--double' macros have a lowercase `l' appended to their names: `M_El',
--`M_PIl', and so forth. These are only available if `_GNU_SOURCE' is
--defined.
--
-- *Note:* Some programs use a constant named `PI' which has the same
--value as `M_PI'. This constant is not standard; it may have appeared
--in some old AT&T headers, and is mentioned in Stroustrup's book on C++.
--It infringes on the user's name space, so the GNU C library does not
--define it. Fixing programs written to expect it is simple: replace
--`PI' with `M_PI' throughout, or put `-DPI=M_PI' on the compiler command
--line.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-27 glibc-2.1.3/manual/libc.info-27
---- ../glibc-2.1.3/manual/libc.info-27 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-27 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1146 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Trig Functions, Next: Inverse Trig Functions, Prev: Mathematical Constants, Up: Mathematics
--
--Trigonometric Functions
--=======================
--
-- These are the familiar `sin', `cos', and `tan' functions. The
--arguments to all of these functions are in units of radians; recall
--that pi radians equals 180 degrees.
--
-- The math library normally defines `M_PI' to a `double' approximation
--of pi. If strict ISO and/or POSIX compliance are requested this
--constant is not defined, but you can easily define it yourself:
--
-- #define M_PI 3.14159265358979323846264338327
--
--You can also compute the value of pi with the expression `acos (-1.0)'.
--
-- - Function: double sin (double X)
-- - Function: float sinf (float X)
-- - Function: long double sinl (long double X)
-- These functions return the sine of X, where X is given in radians.
-- The return value is in the range `-1' to `1'.
--
-- - Function: double cos (double X)
-- - Function: float cosf (float X)
-- - Function: long double cosl (long double X)
-- These functions return the cosine of X, where X is given in
-- radians. The return value is in the range `-1' to `1'.
--
-- - Function: double tan (double X)
-- - Function: float tanf (float X)
-- - Function: long double tanl (long double X)
-- These functions return the tangent of X, where X is given in
-- radians.
--
-- Mathematically, the tangent function has singularities at odd
-- multiples of pi/2. If the argument X is too close to one of these
-- singularities, `tan' will signal overflow.
--
-- In many applications where `sin' and `cos' are used, the sine and
--cosine of the same angle are needed at the same time. It is more
--efficient to compute them simultaneously, so the library provides a
--function to do that.
--
-- - Function: void sincos (double X, double *SINX, double *COSX)
-- - Function: void sincosf (float X, float *SINX, float *COSX)
-- - Function: void sincosl (long double X, long double *SINX, long
-- double *COSX)
-- These functions return the sine of X in `*SINX' and the cosine of
-- X in `*COS', where X is given in radians. Both values, `*SINX'
-- and `*COSX', are in the range of `-1' to `1'.
--
-- This function is a GNU extension. Portable programs should be
-- prepared to cope with its absence.
--
-- ISO C 9x defines variants of the trig functions which work on
--complex numbers. The GNU C library provides these functions, but they
--are only useful if your compiler supports the new complex types defined
--by the standard. (As of this writing GCC supports complex numbers, but
--there are bugs in the implementation.)
--
-- - Function: complex double csin (complex double Z)
-- - Function: complex float csinf (complex float Z)
-- - Function: complex long double csinl (complex long double Z)
-- These functions return the complex sine of Z. The mathematical
-- definition of the complex sine is
--
-- sin (z) = 1/(2*i) * (exp (z*i) - exp (-z*i)).
--
-- - Function: complex double ccos (complex double Z)
-- - Function: complex float ccosf (complex float Z)
-- - Function: complex long double ccosl (complex long double Z)
-- These functions return the complex cosine of Z. The mathematical
-- definition of the complex cosine is
--
-- cos (z) = 1/2 * (exp (z*i) + exp (-z*i))
--
-- - Function: complex double ctan (complex double Z)
-- - Function: complex float ctanf (complex float Z)
-- - Function: complex long double ctanl (complex long double Z)
-- These functions return the complex tangent of Z. The mathematical
-- definition of the complex tangent is
--
-- tan (z) = -i * (exp (z*i) - exp (-z*i)) / (exp (z*i) + exp (-z*i))
--
-- The complex tangent has poles at pi/2 + 2n, where n is an integer.
-- `ctan' may signal overflow if Z is too close to a pole.
--
--
--File: libc.info, Node: Inverse Trig Functions, Next: Exponents and Logarithms, Prev: Trig Functions, Up: Mathematics
--
--Inverse Trigonometric Functions
--===============================
--
-- These are the usual arc sine, arc cosine and arc tangent functions,
--which are the inverses of the sine, cosine and tangent functions,
--respectively.
--
-- - Function: double asin (double X)
-- - Function: float asinf (float X)
-- - Function: long double asinl (long double X)
-- These functions compute the arc sine of X--that is, the value whose
-- sine is X. The value is in units of radians. Mathematically,
-- there are infinitely many such values; the one actually returned
-- is the one between `-pi/2' and `pi/2' (inclusive).
--
-- The arc sine function is defined mathematically only over the
-- domain `-1' to `1'. If X is outside the domain, `asin' signals a
-- domain error.
--
-- - Function: double acos (double X)
-- - Function: float acosf (float X)
-- - Function: long double acosl (long double X)
-- These functions compute the arc cosine of X--that is, the value
-- whose cosine is X. The value is in units of radians.
-- Mathematically, there are infinitely many such values; the one
-- actually returned is the one between `0' and `pi' (inclusive).
--
-- The arc cosine function is defined mathematically only over the
-- domain `-1' to `1'. If X is outside the domain, `acos' signals a
-- domain error.
--
-- - Function: double atan (double X)
-- - Function: float atanf (float X)
-- - Function: long double atanl (long double X)
-- These functions compute the arc tangent of X--that is, the value
-- whose tangent is X. The value is in units of radians.
-- Mathematically, there are infinitely many such values; the one
-- actually returned is the one between `-pi/2' and `pi/2'
-- (inclusive).
--
-- - Function: double atan2 (double Y, double X)
-- - Function: float atan2f (float Y, float X)
-- - Function: long double atan2l (long double Y, long double X)
-- This function computes the arc tangent of Y/X, but the signs of
-- both arguments are used to determine the quadrant of the result,
-- and X is permitted to be zero. The return value is given in
-- radians and is in the range `-pi' to `pi', inclusive.
--
-- If X and Y are coordinates of a point in the plane, `atan2'
-- returns the signed angle between the line from the origin to that
-- point and the x-axis. Thus, `atan2' is useful for converting
-- Cartesian coordinates to polar coordinates. (To compute the
-- radial coordinate, use `hypot'; see *Note Exponents and
-- Logarithms::.)
--
-- If both X and Y are zero, `atan2' returns zero.
--
-- ISO C 9x defines complex versions of the inverse trig functions.
--
-- - Function: complex double casin (complex double Z)
-- - Function: complex float casinf (complex float Z)
-- - Function: complex long double casinl (complex long double Z)
-- These functions compute the complex arc sine of Z--that is, the
-- value whose sine is Z. The value returned is in radians.
--
-- Unlike the real-valued functions, `casin' is defined for all
-- values of Z.
--
-- - Function: complex double cacos (complex double Z)
-- - Function: complex float cacosf (complex float Z)
-- - Function: complex long double cacosl (complex long double Z)
-- These functions compute the complex arc cosine of Z--that is, the
-- value whose cosine is Z. The value returned is in radians.
--
-- Unlike the real-valued functions, `cacos' is defined for all
-- values of Z.
--
-- - Function: complex double catan (complex double Z)
-- - Function: complex float catanf (complex float Z)
-- - Function: complex long double catanl (complex long double Z)
-- These functions compute the complex arc tangent of Z--that is, the
-- value whose tangent is Z. The value is in units of radians.
--
--
--File: libc.info, Node: Exponents and Logarithms, Next: Hyperbolic Functions, Prev: Inverse Trig Functions, Up: Mathematics
--
--Exponentiation and Logarithms
--=============================
--
-- - Function: double exp (double X)
-- - Function: float expf (float X)
-- - Function: long double expl (long double X)
-- These functions compute `e' (the base of natural logarithms) raised
-- to the power X.
--
-- If the magnitude of the result is too large to be representable,
-- `exp' signals overflow.
--
-- - Function: double exp2 (double X)
-- - Function: float exp2f (float X)
-- - Function: long double exp2l (long double X)
-- These functions compute `2' raised to the power X.
-- Mathematically, `exp2 (x)' is the same as `exp (x * log (2))'.
--
-- - Function: double exp10 (double X)
-- - Function: float exp10f (float X)
-- - Function: long double exp10l (long double X)
-- - Function: double pow10 (double X)
-- - Function: float pow10f (float X)
-- - Function: long double pow10l (long double X)
-- These functions compute `10' raised to the power X.
-- Mathematically, `exp10 (x)' is the same as `exp (x * log (10))'.
--
-- These functions are GNU extensions. The name `exp10' is
-- preferred, since it is analogous to `exp' and `exp2'.
--
-- - Function: double log (double X)
-- - Function: float logf (float X)
-- - Function: long double logl (long double X)
-- These functions compute the natural logarithm of X. `exp (log
-- (X))' equals X, exactly in mathematics and approximately in C.
--
-- If X is negative, `log' signals a domain error. If X is zero, it
-- returns negative infinity; if X is too close to zero, it may
-- signal overflow.
--
-- - Function: double log10 (double X)
-- - Function: float log10f (float X)
-- - Function: long double log10l (long double X)
-- These functions return the base-10 logarithm of X. `log10 (X)'
-- equals `log (X) / log (10)'.
--
--
-- - Function: double log2 (double X)
-- - Function: float log2f (float X)
-- - Function: long double log2l (long double X)
-- These functions return the base-2 logarithm of X. `log2 (X)'
-- equals `log (X) / log (2)'.
--
-- - Function: double logb (double X)
-- - Function: float logbf (float X)
-- - Function: long double logbl (long double X)
-- These functions extract the exponent of X and return it as a
-- floating-point value. If `FLT_RADIX' is two, `logb' is equal to
-- `floor (log2 (x))', except it's probably faster.
--
-- If X is denormalized, `logb' returns the exponent X would have if
-- it were normalized. If X is infinity (positive or negative),
-- `logb' returns oo. If X is zero, `logb' returns oo. It does not
-- signal.
--
-- - Function: int ilogb (double X)
-- - Function: int ilogbf (float X)
-- - Function: int ilogbl (long double X)
-- These functions are equivalent to the corresponding `logb'
-- functions except that they return signed integer values.
--
--Since integers cannot represent infinity and NaN, `ilogb' instead
--returns an integer that can't be the exponent of a normal floating-point
--number. `math.h' defines constants so you can check for this.
--
-- - Macro: int FP_ILOGB0
-- `ilogb' returns this value if its argument is `0'. The numeric
-- value is either `INT_MIN' or `-INT_MAX'.
--
-- This macro is defined in ISO C 9X.
--
-- - Macro: int FP_ILOGBNAN
-- `ilogb' returns this value if its argument is `NaN'. The numeric
-- value is either `INT_MIN' or `INT_MAX'.
--
-- This macro is defined in ISO C 9X.
--
-- These values are system specific. They might even be the same. The
--proper way to test the result of `ilogb' is as follows:
--
-- i = ilogb (f);
-- if (i == FP_ILOGB0 || i == FP_ILOGBNAN)
-- {
-- if (isnan (f))
-- {
-- /* Handle NaN. */
-- }
-- else if (f == 0.0)
-- {
-- /* Handle 0.0. */
-- }
-- else
-- {
-- /* Some other value with large exponent,
-- perhaps +Inf. */
-- }
-- }
--
-- - Function: double pow (double BASE, double POWER)
-- - Function: float powf (float BASE, float POWER)
-- - Function: long double powl (long double BASE, long double POWER)
-- These are general exponentiation functions, returning BASE raised
-- to POWER.
--
-- Mathematically, `pow' would return a complex number when BASE is
-- negative and POWER is not an integral value. `pow' can't do that,
-- so instead it signals a domain error. `pow' may also underflow or
-- overflow the destination type.
--
-- - Function: double sqrt (double X)
-- - Function: float sqrtf (float X)
-- - Function: long double sqrtl (long double X)
-- These functions return the nonnegative square root of X.
--
-- If X is negative, `sqrt' signals a domain error. Mathematically,
-- it should return a complex number.
--
-- - Function: double cbrt (double X)
-- - Function: float cbrtf (float X)
-- - Function: long double cbrtl (long double X)
-- These functions return the cube root of X. They cannot fail;
-- every representable real value has a representable real cube root.
--
-- - Function: double hypot (double X, double Y)
-- - Function: float hypotf (float X, float Y)
-- - Function: long double hypotl (long double X, long double Y)
-- These functions return `sqrt (X*X + Y*Y)'. This is the length of
-- the hypotenuse of a right triangle with sides of length X and Y,
-- or the distance of the point (X, Y) from the origin. Using this
-- function instead of the direct formula is wise, since the error is
-- much smaller. See also the function `cabs' in *Note Absolute
-- Value::.
--
-- - Function: double expm1 (double X)
-- - Function: float expm1f (float X)
-- - Function: long double expm1l (long double X)
-- These functions return a value equivalent to `exp (X) - 1'. They
-- are computed in a way that is accurate even if X is near zero--a
-- case where `exp (X) - 1' would be inaccurate due to subtraction of
-- two numbers that are nearly equal.
--
-- - Function: double log1p (double X)
-- - Function: float log1pf (float X)
-- - Function: long double log1pl (long double X)
-- These functions returns a value equivalent to `log (1 + X)'. They
-- are computed in a way that is accurate even if X is near zero.
--
-- ISO C 9X defines complex variants of some of the exponentiation and
--logarithm functions.
--
-- - Function: complex double cexp (complex double Z)
-- - Function: complex float cexpf (complex float Z)
-- - Function: complex long double cexpl (complex long double Z)
-- These functions return `e' (the base of natural logarithms) raised
-- to the power of Z. Mathematically this corresponds to the value
--
-- exp (z) = exp (creal (z)) * (cos (cimag (z)) + I * sin (cimag (z)))
--
-- - Function: complex double clog (complex double Z)
-- - Function: complex float clogf (complex float Z)
-- - Function: complex long double clogl (complex long double Z)
-- These functions return the natural logarithm of Z. Mathematically
-- this corresponds to the value
--
-- log (z) = log (cabs (z)) + I * carg (z)
--
-- `clog' has a pole at 0, and will signal overflow if Z equals or is
-- very close to 0. It is well-defined for all other values of Z.
--
-- - Function: complex double clog10 (complex double Z)
-- - Function: complex float clog10f (complex float Z)
-- - Function: complex long double clog10l (complex long double Z)
-- These functions return the base 10 logarithm of the complex value
-- Z. Mathematically this corresponds to the value
--
-- log (z) = log10 (cabs (z)) + I * carg (z)
--
-- These functions are GNU extensions.
--
-- - Function: complex double csqrt (complex double Z)
-- - Function: complex float csqrtf (complex float Z)
-- - Function: complex long double csqrtl (complex long double Z)
-- These functions return the complex square root of the argument Z.
-- Unlike the real-valued functions, they are defined for all values
-- of Z.
--
-- - Function: complex double cpow (complex double BASE, complex double
-- POWER)
-- - Function: complex float cpowf (complex float BASE, complex float
-- POWER)
-- - Function: complex long double cpowl (complex long double BASE,
-- complex long double POWER)
-- These functions return BASE raised to the power of POWER. This is
-- equivalent to `cexp (y * clog (x))'
--
--
--File: libc.info, Node: Hyperbolic Functions, Next: Special Functions, Prev: Exponents and Logarithms, Up: Mathematics
--
--Hyperbolic Functions
--====================
--
-- The functions in this section are related to the exponential
--functions; see *Note Exponents and Logarithms::.
--
-- - Function: double sinh (double X)
-- - Function: float sinhf (float X)
-- - Function: long double sinhl (long double X)
-- These functions return the hyperbolic sine of X, defined
-- mathematically as `(exp (X) - exp (-X)) / 2'. They may signal
-- overflow if X is too large.
--
-- - Function: double cosh (double X)
-- - Function: float coshf (float X)
-- - Function: long double coshl (long double X)
-- These function return the hyperbolic cosine of X, defined
-- mathematically as `(exp (X) + exp (-X)) / 2'. They may signal
-- overflow if X is too large.
--
-- - Function: double tanh (double X)
-- - Function: float tanhf (float X)
-- - Function: long double tanhl (long double X)
-- These functions return the hyperbolic tangent of X, defined
-- mathematically as `sinh (X) / cosh (X)'. They may signal overflow
-- if X is too large.
--
-- There are counterparts for the hyperbolic functions which take
--complex arguments.
--
-- - Function: complex double csinh (complex double Z)
-- - Function: complex float csinhf (complex float Z)
-- - Function: complex long double csinhl (complex long double Z)
-- These functions return the complex hyperbolic sine of Z, defined
-- mathematically as `(exp (Z) - exp (-Z)) / 2'.
--
-- - Function: complex double ccosh (complex double Z)
-- - Function: complex float ccoshf (complex float Z)
-- - Function: complex long double ccoshl (complex long double Z)
-- These functions return the complex hyperbolic cosine of Z, defined
-- mathematically as `(exp (Z) + exp (-Z)) / 2'.
--
-- - Function: complex double ctanh (complex double Z)
-- - Function: complex float ctanhf (complex float Z)
-- - Function: complex long double ctanhl (complex long double Z)
-- These functions return the complex hyperbolic tangent of Z,
-- defined mathematically as `csinh (Z) / ccosh (Z)'.
--
-- - Function: double asinh (double X)
-- - Function: float asinhf (float X)
-- - Function: long double asinhl (long double X)
-- These functions return the inverse hyperbolic sine of X--the value
-- whose hyperbolic sine is X.
--
-- - Function: double acosh (double X)
-- - Function: float acoshf (float X)
-- - Function: long double acoshl (long double X)
-- These functions return the inverse hyperbolic cosine of X--the
-- value whose hyperbolic cosine is X. If X is less than `1',
-- `acosh' signals a domain error.
--
-- - Function: double atanh (double X)
-- - Function: float atanhf (float X)
-- - Function: long double atanhl (long double X)
-- These functions return the inverse hyperbolic tangent of X--the
-- value whose hyperbolic tangent is X. If the absolute value of X
-- is greater than `1', `atanh' signals a domain error; if it is
-- equal to 1, `atanh' returns infinity.
--
-- - Function: complex double casinh (complex double Z)
-- - Function: complex float casinhf (complex float Z)
-- - Function: complex long double casinhl (complex long double Z)
-- These functions return the inverse complex hyperbolic sine of
-- Z--the value whose complex hyperbolic sine is Z.
--
-- - Function: complex double cacosh (complex double Z)
-- - Function: complex float cacoshf (complex float Z)
-- - Function: complex long double cacoshl (complex long double Z)
-- These functions return the inverse complex hyperbolic cosine of
-- Z--the value whose complex hyperbolic cosine is Z. Unlike the
-- real-valued functions, there are no restrictions on the value of Z.
--
-- - Function: complex double catanh (complex double Z)
-- - Function: complex float catanhf (complex float Z)
-- - Function: complex long double catanhl (complex long double Z)
-- These functions return the inverse complex hyperbolic tangent of
-- Z--the value whose complex hyperbolic tangent is Z. Unlike the
-- real-valued functions, there are no restrictions on the value of Z.
--
--
--File: libc.info, Node: Special Functions, Next: Pseudo-Random Numbers, Prev: Hyperbolic Functions, Up: Mathematics
--
--Special Functions
--=================
--
-- These are some more exotic mathematical functions, which are
--sometimes useful. Currently they only have real-valued versions.
--
-- - Function: double erf (double X)
-- - Function: float erff (float X)
-- - Function: long double erfl (long double X)
-- `erf' returns the error function of X. The error function is
-- defined as
-- erf (x) = 2/sqrt(pi) * integral from 0 to x of exp(-t^2) dt
--
-- - Function: double erfc (double X)
-- - Function: float erfcf (float X)
-- - Function: long double erfcl (long double X)
-- `erfc' returns `1.0 - erf(X)', but computed in a fashion that
-- avoids round-off error when X is large.
--
-- - Function: double lgamma (double X)
-- - Function: float lgammaf (float X)
-- - Function: long double lgammal (long double X)
-- `lgamma' returns the natural logarithm of the absolute value of
-- the gamma function of X. The gamma function is defined as
-- gamma (x) = integral from 0 to oo of t^(x-1) e^-t dt
--
-- The sign of the gamma function is stored in the global variable
-- SIGNGAM, which is declared in `math.h'. It is `1' if the
-- intermediate result was positive or zero, and, `-1' if it was
-- negative.
--
-- To compute the real gamma function you can use the `tgamma'
-- function or you can compute the values as follows:
-- lgam = lgamma(x);
-- gam = signgam*exp(lgam);
--
-- The gamma function has singularities at the nonpositive integers.
-- `lgamma' will raise the zero divide exception if evaluated at a
-- singularity.
--
-- - Function: double lgamma_r (double X, int *SIGNP)
-- - Function: float lgammaf_r (float X, int *SIGNP)
-- - Function: long double lgammal_r (long double X, int *SIGNP)
-- `lgamma_r' is just like `lgamma', but it stores the sign of the
-- intermediate result in the variable pointed to by SIGNP instead of
-- in the SIGNGAM global.
--
-- - Function: double gamma (double X)
-- - Function: float gammaf (float X)
-- - Function: long double gammal (long double X)
-- These functions exist for compatibility reasons. They are
-- equivalent to `lgamma' etc. It is better to use `lgamma' since
-- for one the name reflects better the actual computation and
-- `lgamma' is also standardized in ISO C 9x while `gamma' is not.
--
-- - Function: double tgamma (double X)
-- - Function: float tgammaf (float X)
-- - Function: long double tgammal (long double X)
-- `tgamma' applies the gamma function to X. The gamma function is
-- defined as
-- gamma (x) = integral from 0 to oo of t^(x-1) e^-t dt
--
-- This function was introduced in ISO C 9x.
--
-- - Function: double j0 (double X)
-- - Function: float j0f (float X)
-- - Function: long double j0l (long double X)
-- `j0' returns the Bessel function of the first kind of order 0 of
-- X. It may signal underflow if X is too large.
--
-- - Function: double j1 (double X)
-- - Function: float j1f (float X)
-- - Function: long double j1l (long double X)
-- `j1' returns the Bessel function of the first kind of order 1 of
-- X. It may signal underflow if X is too large.
--
-- - Function: double jn (int n, double X)
-- - Function: float jnf (int n, float X)
-- - Function: long double jnl (int n, long double X)
-- `jn' returns the Bessel function of the first kind of order N of
-- X. It may signal underflow if X is too large.
--
-- - Function: double y0 (double X)
-- - Function: float y0f (float X)
-- - Function: long double y0l (long double X)
-- `y0' returns the Bessel function of the second kind of order 0 of
-- X. It may signal underflow if X is too large. If X is negative,
-- `y0' signals a domain error; if it is zero, `y0' signals overflow
-- and returns -oo.
--
-- - Function: double y1 (double X)
-- - Function: float y1f (float X)
-- - Function: long double y1l (long double X)
-- `y1' returns the Bessel function of the second kind of order 1 of
-- X. It may signal underflow if X is too large. If X is negative,
-- `y1' signals a domain error; if it is zero, `y1' signals overflow
-- and returns -oo.
--
-- - Function: double yn (int n, double X)
-- - Function: float ynf (int n, float X)
-- - Function: long double ynl (int n, long double X)
-- `yn' returns the Bessel function of the second kind of order N of
-- X. It may signal underflow if X is too large. If X is negative,
-- `yn' signals a domain error; if it is zero, `yn' signals overflow
-- and returns -oo.
--
--
--File: libc.info, Node: Pseudo-Random Numbers, Next: FP Function Optimizations, Prev: Special Functions, Up: Mathematics
--
--Pseudo-Random Numbers
--=====================
--
-- This section describes the GNU facilities for generating a series of
--pseudo-random numbers. The numbers generated are not truly random;
--typically, they form a sequence that repeats periodically, with a period
--so large that you can ignore it for ordinary purposes. The random
--number generator works by remembering a "seed" value which it uses to
--compute the next random number and also to compute a new seed.
--
-- Although the generated numbers look unpredictable within one run of a
--program, the sequence of numbers is *exactly the same* from one run to
--the next. This is because the initial seed is always the same. This
--is convenient when you are debugging a program, but it is unhelpful if
--you want the program to behave unpredictably. If you want a different
--pseudo-random series each time your program runs, you must specify a
--different seed each time. For ordinary purposes, basing the seed on the
--current time works well.
--
-- You can get repeatable sequences of numbers on a particular machine
--type by specifying the same initial seed value for the random number
--generator. There is no standard meaning for a particular seed value;
--the same seed, used in different C libraries or on different CPU types,
--will give you different random numbers.
--
-- The GNU library supports the standard ISO C random number functions
--plus two other sets derived from BSD and SVID. The BSD and ISO C
--functions provide identical, somewhat limited functionality. If only a
--small number of random bits are required, we recommend you use the
--ISO C interface, `rand' and `srand'. The SVID functions provide a more
--flexible interface, which allows better random number generator
--algorithms, provides more random bits (up to 48) per call, and can
--provide random floating-point numbers. These functions are required by
--the XPG standard and therefore will be present in all modern Unix
--systems.
--
--* Menu:
--
--* ISO Random:: `rand' and friends.
--* BSD Random:: `random' and friends.
--* SVID Random:: `drand48' and friends.
--
--
--File: libc.info, Node: ISO Random, Next: BSD Random, Up: Pseudo-Random Numbers
--
--ISO C Random Number Functions
-------------------------------
--
-- This section describes the random number functions that are part of
--the ISO C standard.
--
-- To use these facilities, you should include the header file
--`stdlib.h' in your program.
--
-- - Macro: int RAND_MAX
-- The value of this macro is an integer constant representing the
-- largest value the `rand' function can return. In the GNU library,
-- it is `2147483647', which is the largest signed integer
-- representable in 32 bits. In other libraries, it may be as low as
-- `32767'.
--
-- - Function: int rand (void)
-- The `rand' function returns the next pseudo-random number in the
-- series. The value ranges from `0' to `RAND_MAX'.
--
-- - Function: void srand (unsigned int SEED)
-- This function establishes SEED as the seed for a new series of
-- pseudo-random numbers. If you call `rand' before a seed has been
-- established with `srand', it uses the value `1' as a default seed.
--
-- To produce a different pseudo-random series each time your program
-- is run, do `srand (time (0))'.
--
-- POSIX.1 extended the C standard functions to support reproducible
--random numbers in multi-threaded programs. However, the extension is
--badly designed and unsuitable for serious work.
--
-- - Function: int rand_r (unsigned int *SEED)
-- This function returns a random number in the range 0 to `RAND_MAX'
-- just as `rand' does. However, all its state is stored in the SEED
-- argument. This means the RNG's state can only have as many bits
-- as the type `unsigned int' has. This is far too few to provide a
-- good RNG.
--
-- If your program requires a reentrant RNG, we recommend you use the
-- reentrant GNU extensions to the SVID random number generator. The
-- POSIX.1 interface should only be used when the GNU extensions are
-- not available.
--
--
--File: libc.info, Node: BSD Random, Next: SVID Random, Prev: ISO Random, Up: Pseudo-Random Numbers
--
--BSD Random Number Functions
-----------------------------
--
-- This section describes a set of random number generation functions
--that are derived from BSD. There is no advantage to using these
--functions with the GNU C library; we support them for BSD compatibility
--only.
--
-- The prototypes for these functions are in `stdlib.h'.
--
-- - Function: int32_t random (void)
-- This function returns the next pseudo-random number in the
-- sequence. The value returned ranges from `0' to `RAND_MAX'.
--
-- *Note:* Historically this function returned a `long int' value.
-- On 64bit systems `long int' would have been larger than programs
-- expected, so `random' is now defined to return exactly 32 bits.
--
-- - Function: void srandom (unsigned int SEED)
-- The `srandom' function sets the state of the random number
-- generator based on the integer SEED. If you supply a SEED value
-- of `1', this will cause `random' to reproduce the default set of
-- random numbers.
--
-- To produce a different set of pseudo-random numbers each time your
-- program runs, do `srandom (time (0))'.
--
-- - Function: void * initstate (unsigned int SEED, void *STATE, size_t
-- SIZE)
-- The `initstate' function is used to initialize the random number
-- generator state. The argument STATE is an array of SIZE bytes,
-- used to hold the state information. It is initialized based on
-- SEED. The size must be between 8 and 256 bytes, and should be a
-- power of two. The bigger the STATE array, the better.
--
-- The return value is the previous value of the state information
-- array. You can use this value later as an argument to `setstate'
-- to restore that state.
--
-- - Function: void * setstate (void *STATE)
-- The `setstate' function restores the random number state
-- information STATE. The argument must have been the result of a
-- previous call to INITSTATE or SETSTATE.
--
-- The return value is the previous value of the state information
-- array. You can use this value later as an argument to `setstate'
-- to restore that state.
--
--
--File: libc.info, Node: SVID Random, Prev: BSD Random, Up: Pseudo-Random Numbers
--
--SVID Random Number Function
-----------------------------
--
-- The C library on SVID systems contains yet another kind of random
--number generator functions. They use a state of 48 bits of data. The
--user can choose among a collection of functions which return the random
--bits in different forms.
--
-- Generally there are two kinds of functions: those which use a state
--of the random number generator which is shared among several functions
--and by all threads of the process. The second group of functions
--require the user to handle the state.
--
-- All functions have in common that they use the same congruential
--formula with the same constants. The formula is
--
-- Y = (a * X + c) mod m
--
--where X is the state of the generator at the beginning and Y the state
--at the end. `a' and `c' are constants determining the way the
--generator work. By default they are
--
-- a = 0x5DEECE66D = 25214903917
-- c = 0xb = 11
--
--but they can also be changed by the user. `m' is of course 2^48 since
--the state consists of a 48 bit array.
--
-- - Function: double drand48 (void)
-- This function returns a `double' value in the range of `0.0' to
-- `1.0' (exclusive). The random bits are determined by the global
-- state of the random number generator in the C library.
--
-- Since the `double' type according to IEEE 754 has a 52 bit
-- mantissa this means 4 bits are not initialized by the random number
-- generator. These are (of course) chosen to be the least
-- significant bits and they are initialized to `0'.
--
-- - Function: double erand48 (unsigned short int XSUBI[3])
-- This function returns a `double' value in the range of `0.0' to
-- `1.0' (exclusive), similar to `drand48'. The argument is an array
-- describing the state of the random number generator.
--
-- This function can be called subsequently since it updates the
-- array to guarantee random numbers. The array should have been
-- initialized before using to get reproducible results.
--
-- - Function: long int lrand48 (void)
-- The `lrand48' functions return an integer value in the range of
-- `0' to `2^31' (exclusive). Even if the size of the `long int'
-- type can take more than 32 bits no higher numbers are returned.
-- The random bits are determined by the global state of the random
-- number generator in the C library.
--
-- - Function: long int nrand48 (unsigned short int XSUBI[3])
-- This function is similar to the `lrand48' function in that it
-- returns a number in the range of `0' to `2^31' (exclusive) but the
-- state of the random number generator used to produce the random
-- bits is determined by the array provided as the parameter to the
-- function.
--
-- The numbers in the array are afterwards updated so that subsequent
-- calls to this function yield to different results (as it is
-- expected by a random number generator). The array should have
-- been initialized before the first call to get reproducible results.
--
-- - Function: long int mrand48 (void)
-- The `mrand48' function is similar to `lrand48'. The only
-- difference is that the numbers returned are in the range `-2^31' to
-- `2^31' (exclusive).
--
-- - Function: long int jrand48 (unsigned short int XSUBI[3])
-- The `jrand48' function is similar to `nrand48'. The only
-- difference is that the numbers returned are in the range `-2^31' to
-- `2^31' (exclusive). For the `xsubi' parameter the same
-- requirements are necessary.
--
-- The internal state of the random number generator can be initialized
--in several ways. The functions differ in the completeness of the
--information provided.
--
-- - Function: void srand48 (long int SEEDVAL))
-- The `srand48' function sets the most significant 32 bits of the
-- state internal state of the random number generator to the least
-- significant 32 bits of the SEEDVAL parameter. The lower 16 bits
-- are initialized to the value `0x330E'. Even if the `long int'
-- type contains more the 32 bits only the lower 32 bits are used.
--
-- Due to this limitation the initialization of the state using this
-- function of not very useful. But it makes it easy to use a
-- construct like `srand48 (time (0))'.
--
-- A side-effect of this function is that the values `a' and `c' from
-- the internal state, which are used in the congruential formula,
-- are reset to the default values given above. This is of
-- importance once the user called the `lcong48' function (see below).
--
-- - Function: unsigned short int * seed48 (unsigned short int SEED16V[3])
-- The `seed48' function initializes all 48 bits of the state of the
-- internal random number generator from the content of the parameter
-- SEED16V. Here the lower 16 bits of the first element of SEE16V
-- initialize the least significant 16 bits of the internal state,
-- the lower 16 bits of `SEED16V[1]' initialize the mid-order 16 bits
-- of the state and the 16 lower bits of `SEED16V[2]' initialize the
-- most significant 16 bits of the state.
--
-- Unlike `srand48' this function lets the user initialize all 48 bits
-- of the state.
--
-- The value returned by `seed48' is a pointer to an array containing
-- the values of the internal state before the change. This might be
-- useful to restart the random number generator at a certain state.
-- Otherwise, the value can simply be ignored.
--
-- As for `srand48', the values `a' and `c' from the congruential
-- formula are reset to the default values.
--
-- There is one more function to initialize the random number generator
--which allows to specify even more information by allowing to change the
--parameters in the congruential formula.
--
-- - Function: void lcong48 (unsigned short int PARAM[7])
-- The `lcong48' function allows the user to change the complete state
-- of the random number generator. Unlike `srand48' and `seed48',
-- this function also changes the constants in the congruential
-- formula.
--
-- From the seven elements in the array PARAM the least significant
-- 16 bits of the entries `PARAM[0]' to `PARAM[2]' determine the
-- initial state, the least 16 bits of `PARAM[3]' to `PARAM[5]'
-- determine the 48 bit constant `a' and `PARAM[6]' determines the 16
-- bit value `c'.
--
-- All the above functions have in common that they use the global
--parameters for the congruential formula. In multi-threaded programs it
--might sometimes be useful to have different parameters in different
--threads. For this reason all the above functions have a counterpart
--which works on a description of the random number generator in the
--user-supplied buffer instead of the global state.
--
-- Please note that it is no problem if several threads use the global
--state if all threads use the functions which take a pointer to an array
--containing the state. The random numbers are computed following the
--same loop but if the state in the array is different all threads will
--get an individual random number generator.
--
-- The user supplied buffer must be of type `struct drand48_data'.
--This type should be regarded as opaque and no member should be used
--directly.
--
-- - Function: int drand48_r (struct drand48_data *BUFFER, double *RESULT)
-- This function is equivalent to the `drand48' function with the
-- difference it does not modify the global random number generator
-- parameters but instead the parameters is the buffer supplied by the
-- buffer through the pointer BUFFER. The random number is return in
-- the variable pointed to by RESULT.
--
-- The return value of the function indicate whether the call
-- succeeded. If the value is less than `0' an error occurred and
-- ERRNO is set to indicate the problem.
--
-- This function is a GNU extension and should not be used in portable
-- programs.
--
-- - Function: int erand48_r (unsigned short int XSUBI[3], struct
-- drand48_data *BUFFER, double *RESULT)
-- The `erand48_r' function works like the `erand48' and it takes an
-- argument BUFFER which describes the random number generator. The
-- state of the random number generator is taken from the `xsubi'
-- array, the parameters for the congruential formula from the global
-- random number generator data. The random number is return in the
-- variable pointed to by RESULT.
--
-- The return value is non-negative is the call succeeded.
--
-- This function is a GNU extension and should not be used in portable
-- programs.
--
-- - Function: int lrand48_r (struct drand48_data *BUFFER, double *RESULT)
-- This function is similar to `lrand48' and it takes a pointer to a
-- buffer describing the state of the random number generator as a
-- parameter just like `drand48'.
--
-- If the return value of the function is non-negative the variable
-- pointed to by RESULT contains the result. Otherwise an error
-- occurred.
--
-- This function is a GNU extension and should not be used in portable
-- programs.
--
-- - Function: int nrand48_r (unsigned short int XSUBI[3], struct
-- drand48_data *BUFFER, long int *RESULT)
-- The `nrand48_r' function works like `nrand48' in that it produces
-- a random number in range `0' to `2^31'. But instead of using the
-- global parameters for the congruential formula it uses the
-- information from the buffer pointed to by BUFFER. The state is
-- described by the values in XSUBI.
--
-- If the return value is non-negative the variable pointed to by
-- RESULT contains the result.
--
-- This function is a GNU extension and should not be used in portable
-- programs.
--
-- - Function: int mrand48_r (struct drand48_data *BUFFER, double *RESULT)
-- This function is similar to `mrand48' but as the other reentrant
-- function it uses the random number generator described by the
-- value in the buffer pointed to by BUFFER.
--
-- If the return value is non-negative the variable pointed to by
-- RESULT contains the result.
--
-- This function is a GNU extension and should not be used in portable
-- programs.
--
-- - Function: int jrand48_r (unsigned short int XSUBI[3], struct
-- drand48_data *BUFFER, long int *RESULT)
-- The `jrand48_r' function is similar to `jrand48'. But as the
-- other reentrant functions of this function family it uses the
-- congruential formula parameters from the buffer pointed to by
-- BUFFER.
--
-- If the return value is non-negative the variable pointed to by
-- RESULT contains the result.
--
-- This function is a GNU extension and should not be used in portable
-- programs.
--
-- Before any of the above functions should be used the buffer of type
--`struct drand48_data' should initialized. The easiest way is to fill
--the whole buffer with null bytes, e.g., using
--
-- memset (buffer, '\0', sizeof (struct drand48_data));
--
--Using any of the reentrant functions of this family now will
--automatically initialize the random number generator to the default
--values for the state and the parameters of the congruential formula.
--
-- The other possibility is too use any of the functions which
--explicitely initialize the buffer. Though it might be obvious how to
--initialize the buffer from the data given as parameter from the
--function it is highly recommended to use these functions since the
--result might not always be what you expect.
--
-- - Function: int srand48_r (long int SEEDVAL, struct drand48_data
-- *BUFFER)
-- The description of the random number generator represented by the
-- information in BUFFER is initialized similar to what the function
-- `srand48' does. The state is initialized from the parameter
-- SEEDVAL and the parameters for the congruential formula are
-- initialized to the default values.
--
-- If the return value is non-negative the function call succeeded.
--
-- This function is a GNU extension and should not be used in portable
-- programs.
--
-- - Function: int seed48_r (unsigned short int SEED16V[3], struct
-- drand48_data *BUFFER)
-- This function is similar to `srand48_r' but like `seed48' it
-- initializes all 48 bits of the state from the parameter SEED16V.
--
-- If the return value is non-negative the function call succeeded.
-- It does not return a pointer to the previous state of the random
-- number generator like the `seed48' function does. if the user
-- wants to preserve the state for a later rerun s/he can copy the
-- whole buffer pointed to by BUFFER.
--
-- This function is a GNU extension and should not be used in portable
-- programs.
--
-- - Function: int lcong48_r (unsigned short int PARAM[7], struct
-- drand48_data *BUFFER)
-- This function initializes all aspects of the random number
-- generator described in BUFFER by the data in PARAM. Here it is
-- especially true the function does more than just copying the
-- contents of PARAM of BUFFER. Some more actions are required and
-- therefore it is important to use this function and not initialized
-- the random number generator directly.
--
-- If the return value is non-negative the function call succeeded.
--
-- This function is a GNU extension and should not be used in portable
-- programs.
--
--
--File: libc.info, Node: FP Function Optimizations, Prev: Pseudo-Random Numbers, Up: Mathematics
--
--Is Fast Code or Small Code preferred?
--=====================================
--
-- If an application uses many floating point function it is often the
--case that the costs for the function calls itselfs are not neglectable.
--Modern processor implementation often can execute the operation itself
--very fast but the call means a disturbance of the control flow.
--
-- For this reason the GNU C Library provides optimizations for many of
--the frequently used math functions. When the GNU CC is used and the
--user activates the optimizer several new inline functions and macros get
--defined. These new functions and macros have the same names as the
--library function and so get used instead of the later. In case of
--inline functions the compiler will decide whether it is reasonable to
--use the inline function and this decision is usually correct.
--
-- For the generated code this means that no calls to the library
--functions are necessary. This increases the speed significantly. But
--the drawback is that the code size increases and this increase is not
--always neglectable.
--
-- The speed increase has one drawback: the inline functions might not
--set `errno' and might not have the same precission as the library
--functions.
--
-- In cases where the inline functions and macros are not wanted the
--symbol `__NO_MATH_INLINES' should be defined before any system header is
--included. This will make sure only library functions are used. Of
--course it can be determined for each single file in the project whether
--giving this option is preferred or not.
--
-- Not all hardware implements the entire IEEE 754 standard, or if it
--does, there may be a substantial performance penalty for using some of
--its features. For example, enabling traps on some processors forces
--the FPU to run unpipelined, which more than doubles calculation time.
--
--
--File: libc.info, Node: Arithmetic, Next: Date and Time, Prev: Mathematics, Up: Top
--
--Arithmetic Functions
--********************
--
-- This chapter contains information about functions for doing basic
--arithmetic operations, such as splitting a float into its integer and
--fractional parts or retrieving the imaginary part of a complex value.
--These functions are declared in the header files `math.h' and
--`complex.h'.
--
--* Menu:
--
--* Floating Point Numbers:: Basic concepts. IEEE 754.
--* Floating Point Classes:: The five kinds of floating-point number.
--* Floating Point Errors:: When something goes wrong in a calculation.
--* Rounding:: Controlling how results are rounded.
--* Control Functions:: Saving and restoring the FPU's state.
--* Arithmetic Functions:: Fundamental operations provided by the library.
--* Complex Numbers:: The types. Writing complex constants.
--* Operations on Complex:: Projection, conjugation, decomposition.
--* Integer Division:: Integer division with guaranteed rounding.
--* Parsing of Numbers:: Converting strings to numbers.
--* System V Number Conversion:: An archaic way to convert numbers to strings.
--
--
--File: libc.info, Node: Floating Point Numbers, Next: Floating Point Classes, Up: Arithmetic
--
--Floating Point Numbers
--======================
--
-- Most computer hardware has support for two different kinds of
--numbers: integers (...-3, -2, -1, 0, 1, 2, 3...) and floating-point
--numbers. Floating-point numbers have three parts: the "mantissa", the
--"exponent", and the "sign bit". The real number represented by a
--floating-point value is given by (s ? -1 : 1) * 2^e * M where s is the
--sign bit, e the exponent, and M the mantissa. *Note Floating Point
--Concepts::, for details. (It is possible to have a different "base"
--for the exponent, but all modern hardware uses 2.)
--
-- Floating-point numbers can represent a finite subset of the real
--numbers. While this subset is large enough for most purposes, it is
--important to remember that the only reals that can be represented
--exactly are rational numbers that have a terminating binary expansion
--shorter than the width of the mantissa. Even simple fractions such as
--1/5 can only be approximated by floating point.
--
-- Mathematical operations and functions frequently need to produce
--values that are not representable. Often these values can be
--approximated closely enough for practical purposes, but sometimes they
--can't. Historically there was no way to tell when the results of a
--calculation were inaccurate. Modern computers implement the IEEE 754
--standard for numerical computations, which defines a framework for
--indicating to the program when the results of calculation are not
--trustworthy. This framework consists of a set of "exceptions" that
--indicate why a result could not be represented, and the special values
--"infinity" and "not a number" (NaN).
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-28 glibc-2.1.3/manual/libc.info-28
---- ../glibc-2.1.3/manual/libc.info-28 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-28 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1161 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Floating Point Classes, Next: Floating Point Errors, Prev: Floating Point Numbers, Up: Arithmetic
--
--Floating-Point Number Classification Functions
--==============================================
--
-- ISO C 9x defines macros that let you determine what sort of
--floating-point number a variable holds.
--
-- - Macro: int fpclassify (*float-type* X)
-- This is a generic macro which works on all floating-point types and
-- which returns a value of type `int'. The possible values are:
--
-- `FP_NAN'
-- The floating-point number X is "Not a Number" (*note Infinity
-- and NaN::.)
--
-- `FP_INFINITE'
-- The value of X is either plus or minus infinity (*note
-- Infinity and NaN::.)
--
-- `FP_ZERO'
-- The value of X is zero. In floating-point formats like
-- IEEE 754, where zero can be signed, this value is also
-- returned if X is negative zero.
--
-- `FP_SUBNORMAL'
-- Numbers whose absolute value is too small to be represented
-- in the normal format are represented in an alternate,
-- "denormalized" format (*note Floating Point Concepts::.).
-- This format is less precise but can represent values closer
-- to zero. `fpclassify' returns this value for values of X in
-- this alternate format.
--
-- `FP_NORMAL'
-- This value is returned for all other values of X. It
-- indicates that there is nothing special about the number.
--
--
-- `fpclassify' is most useful if more than one property of a number
--must be tested. There are more specific macros which only test one
--property at a time. Generally these macros execute faster than
--`fpclassify', since there is special hardware support for them. You
--should therefore use the specific macros whenever possible.
--
-- - Macro: int isfinite (*float-type* X)
-- This macro returns a nonzero value if X is finite: not plus or
-- minus infinity, and not NaN. It is equivalent to
--
-- (fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE)
--
-- `isfinite' is implemented as a macro which accepts any
-- floating-point type.
--
-- - Macro: int isnormal (*float-type* X)
-- This macro returns a nonzero value if X is finite and normalized.
-- It is equivalent to
--
-- (fpclassify (x) == FP_NORMAL)
--
-- - Macro: int isnan (*float-type* X)
-- This macro returns a nonzero value if X is NaN. It is equivalent
-- to
--
-- (fpclassify (x) == FP_NAN)
--
-- Another set of floating-point classification functions was provided
--by BSD. The GNU C library also supports these functions; however, we
--recommend that you use the C9x macros in new code. Those are standard
--and will be available more widely. Also, since they are macros, you do
--not have to worry about the type of their argument.
--
-- - Function: int isinf (double X)
-- - Function: int isinff (float X)
-- - Function: int isinfl (long double X)
-- This function returns `-1' if X represents negative infinity, `1'
-- if X represents positive infinity, and `0' otherwise.
--
-- - Function: int isnan (double X)
-- - Function: int isnanf (float X)
-- - Function: int isnanl (long double X)
-- This function returns a nonzero value if X is a "not a number"
-- value, and zero otherwise.
--
-- *Note:* The `isnan' macro defined by ISO C 9x overrides the BSD
-- function. This is normally not a problem, because the two
-- routines behave identically. However, if you really need to get
-- the BSD function for some reason, you can write
--
-- (isnan) (x)
--
-- - Function: int finite (double X)
-- - Function: int finitef (float X)
-- - Function: int finitel (long double X)
-- This function returns a nonzero value if X is finite or a "not a
-- number" value, and zero otherwise.
--
-- - Function: double infnan (int ERROR)
-- This function is provided for compatibility with BSD. Its
-- argument is an error code, `EDOM' or `ERANGE'; `infnan' returns the
-- value that a math function would return if it set `errno' to that
-- value. *Note Math Error Reporting::. `-ERANGE' is also acceptable
-- as an argument, and corresponds to `-HUGE_VAL' as a value.
--
-- In the BSD library, on certain machines, `infnan' raises a fatal
-- signal in all cases. The GNU library does not do likewise,
-- because that does not fit the ISO C specification.
--
-- *Portability Note:* The functions listed in this section are BSD
--extensions.
--
--
--File: libc.info, Node: Floating Point Errors, Next: Rounding, Prev: Floating Point Classes, Up: Arithmetic
--
--Errors in Floating-Point Calculations
--=====================================
--
--* Menu:
--
--* FP Exceptions:: IEEE 754 math exceptions and how to detect them.
--* Infinity and NaN:: Special values returned by calculations.
--* Status bit operations:: Checking for exceptions after the fact.
--* Math Error Reporting:: How the math functions report errors.
--
--
--File: libc.info, Node: FP Exceptions, Next: Infinity and NaN, Up: Floating Point Errors
--
--FP Exceptions
---------------
--
-- The IEEE 754 standard defines five "exceptions" that can occur
--during a calculation. Each corresponds to a particular sort of error,
--such as overflow.
--
-- When exceptions occur (when exceptions are "raised", in the language
--of the standard), one of two things can happen. By default the
--exception is simply noted in the floating-point "status word", and the
--program continues as if nothing had happened. The operation produces a
--default value, which depends on the exception (see the table below).
--Your program can check the status word to find out which exceptions
--happened.
--
-- Alternatively, you can enable "traps" for exceptions. In that case,
--when an exception is raised, your program will receive the `SIGFPE'
--signal. The default action for this signal is to terminate the
--program. *Note Signal Handling::, for how you can change the effect of
--the signal.
--
-- In the System V math library, the user-defined function `matherr' is
--called when certain exceptions occur inside math library functions.
--However, the Unix98 standard deprecates this interface. We support it
--for historical compatibility, but recommend that you do not use it in
--new programs.
--
--The exceptions defined in IEEE 754 are:
--
--`Invalid Operation'
-- This exception is raised if the given operands are invalid for the
-- operation to be performed. Examples are (see IEEE 754, section 7):
-- 1. Addition or subtraction: oo - oo. (But oo + oo = oo).
--
-- 2. Multiplication: 0 * oo.
--
-- 3. Division: 0/0 or oo/oo.
--
-- 4. Remainder: x REM y, where y is zero or x is infinite.
--
-- 5. Square root if the operand is less then zero. More
-- generally, any mathematical function evaluated outside its
-- domain produces this exception.
--
-- 6. Conversion of a floating-point number to an integer or decimal
-- string, when the number cannot be represented in the target
-- format (due to overflow, infinity, or NaN).
--
-- 7. Conversion of an unrecognizable input string.
--
-- 8. Comparison via predicates involving < or >, when one or other
-- of the operands is NaN. You can prevent this exception by
-- using the unordered comparison functions instead; see *Note
-- FP Comparison Functions::.
--
-- If the exception does not trap, the result of the operation is NaN.
--
--`Division by Zero'
-- This exception is raised when a finite nonzero number is divided
-- by zero. If no trap occurs the result is either +oo or -oo,
-- depending on the signs of the operands.
--
--`Overflow'
-- This exception is raised whenever the result cannot be represented
-- as a finite value in the precision format of the destination. If
-- no trap occurs the result depends on the sign of the intermediate
-- result and the current rounding mode (IEEE 754, section 7.3):
-- 1. Round to nearest carries all overflows to oo with the sign of
-- the intermediate result.
--
-- 2. Round toward 0 carries all overflows to the largest
-- representable finite number with the sign of the intermediate
-- result.
--
-- 3. Round toward -oo carries positive overflows to the largest
-- representable finite number and negative overflows to -oo.
--
-- 4. Round toward oo carries negative overflows to the most
-- negative representable finite number and positive overflows
-- to oo.
--
-- Whenever the overflow exception is raised, the inexact exception
-- is also raised.
--
--`Underflow'
-- The underflow exception is raised when an intermediate result is
-- too small to be calculated accurately, or if the operation's
-- result rounded to the destination precision is too small to be
-- normalized.
--
-- When no trap is installed for the underflow exception, underflow is
-- signaled (via the underflow flag) only when both tininess and loss
-- of accuracy have been detected. If no trap handler is installed
-- the operation continues with an imprecise small value, or zero if
-- the destination precision cannot hold the small exact result.
--
--`Inexact'
-- This exception is signalled if a rounded result is not exact (such
-- as when calculating the square root of two) or a result overflows
-- without an overflow trap.
--
--
--File: libc.info, Node: Infinity and NaN, Next: Status bit operations, Prev: FP Exceptions, Up: Floating Point Errors
--
--Infinity and NaN
------------------
--
-- IEEE 754 floating point numbers can represent positive or negative
--infinity, and "NaN" (not a number). These three values arise from
--calculations whose result is undefined or cannot be represented
--accurately. You can also deliberately set a floating-point variable to
--any of them, which is sometimes useful. Some examples of calculations
--that produce infinity or NaN:
--
-- 1/0 = oo
-- log (0) = -oo
-- sqrt (-1) = NaN
--
-- When a calculation produces any of these values, an exception also
--occurs; see *Note FP Exceptions::.
--
-- The basic operations and math functions all accept infinity and NaN
--and produce sensible output. Infinities propagate through calculations
--as one would expect: for example, 2 + oo = oo, 4/oo = 0, atan (oo) =
--pi/2. NaN, on the other hand, infects any calculation that involves
--it. Unless the calculation would produce the same result no matter
--what real value replaced NaN, the result is NaN.
--
-- In comparison operations, positive infinity is larger than all values
--except itself and NaN, and negative infinity is smaller than all values
--except itself and NaN. NaN is "unordered": it is not equal to, greater
--than, or less than anything, *including itself*. `x == x' is false if
--the value of `x' is NaN. You can use this to test whether a value is
--NaN or not, but the recommended way to test for NaN is with the `isnan'
--function (*note Floating Point Classes::.). In addition, `<', `>',
--`<=', and `>=' will raise an exception when applied to NaNs.
--
-- `math.h' defines macros that allow you to explicitly set a variable
--to infinity or NaN.
--
-- - Macro: float INFINITY
-- An expression representing positive infinity. It is equal to the
-- value produced by mathematical operations like `1.0 / 0.0'.
-- `-INFINITY' represents negative infinity.
--
-- You can test whether a floating-point value is infinite by
-- comparing it to this macro. However, this is not recommended; you
-- should use the `isfinite' macro instead. *Note Floating Point
-- Classes::.
--
-- This macro was introduced in the ISO C 9X standard.
--
-- - Macro: float NAN
-- An expression representing a value which is "not a number". This
-- macro is a GNU extension, available only on machines that support
-- the "not a number" value--that is to say, on all machines that
-- support IEEE floating point.
--
-- You can use `#ifdef NAN' to test whether the machine supports NaN.
-- (Of course, you must arrange for GNU extensions to be visible,
-- such as by defining `_GNU_SOURCE', and then you must include
-- `math.h'.)
--
-- IEEE 754 also allows for another unusual value: negative zero. This
--value is produced when you divide a positive number by negative
--infinity, or when a negative result is smaller than the limits of
--representation. Negative zero behaves identically to zero in all
--calculations, unless you explicitly test the sign bit with `signbit' or
--`copysign'.
--
--
--File: libc.info, Node: Status bit operations, Next: Math Error Reporting, Prev: Infinity and NaN, Up: Floating Point Errors
--
--Examining the FPU status word
-------------------------------
--
-- ISO C 9x defines functions to query and manipulate the
--floating-point status word. You can use these functions to check for
--untrapped exceptions when it's convenient, rather than worrying about
--them in the middle of a calculation.
--
-- These constants represent the various IEEE 754 exceptions. Not all
--FPUs report all the different exceptions. Each constant is defined if
--and only if the FPU you are compiling for supports that exception, so
--you can test for FPU support with `#ifdef'. They are defined in
--`fenv.h'.
--
--`FE_INEXACT'
-- The inexact exception.
--
--`FE_DIVBYZERO'
-- The divide by zero exception.
--
--`FE_UNDERFLOW'
-- The underflow exception.
--
--`FE_OVERFLOW'
-- The overflow exception.
--
--`FE_INVALID'
-- The invalid exception.
--
-- The macro `FE_ALL_EXCEPT' is the bitwise OR of all exception macros
--which are supported by the FP implementation.
--
-- These functions allow you to clear exception flags, test for
--exceptions, and save and restore the set of exceptions flagged.
--
-- - Function: void feclearexcept (int EXCEPTS)
-- This function clears all of the supported exception flags
-- indicated by EXCEPTS.
--
-- - Function: int fetestexcept (int EXCEPTS)
-- Test whether the exception flags indicated by the parameter EXCEPT
-- are currently set. If any of them are, a nonzero value is returned
-- which specifies which exceptions are set. Otherwise the result is
-- zero.
--
-- To understand these functions, imagine that the status word is an
--integer variable named STATUS. `feclearexcept' is then equivalent to
--`status &= ~excepts' and `fetestexcept' is equivalent to `(status &
--excepts)'. The actual implementation may be very different, of course.
--
-- Exception flags are only cleared when the program explicitly
--requests it, by calling `feclearexcept'. If you want to check for
--exceptions from a set of calculations, you should clear all the flags
--first. Here is a simple example of the way to use `fetestexcept':
--
-- {
-- double f;
-- int raised;
-- feclearexcept (FE_ALL_EXCEPT);
-- f = compute ();
-- raised = fetestexcept (FE_OVERFLOW | FE_INVALID);
-- if (raised & FE_OVERFLOW) { /* ... */ }
-- if (raised & FE_INVALID) { /* ... */ }
-- /* ... */
-- }
--
-- You cannot explicitly set bits in the status word. You can, however,
--save the entire status word and restore it later. This is done with the
--following functions:
--
-- - Function: void fegetexceptflag (fexcept_t *FLAGP, int EXCEPTS)
-- This function stores in the variable pointed to by FLAGP an
-- implementation-defined value representing the current setting of
-- the exception flags indicated by EXCEPTS.
--
-- - Function: void fesetexceptflag (const fexcept_t *FLAGP, int
-- EXCEPTS) This function restores the flags for the exceptions
-- indicated by EXCEPTS to the values stored in the variable pointed
-- to by FLAGP.
--
-- Note that the value stored in `fexcept_t' bears no resemblance to
--the bit mask returned by `fetestexcept'. The type may not even be an
--integer. Do not attempt to modify an `fexcept_t' variable.
--
--
--File: libc.info, Node: Math Error Reporting, Prev: Status bit operations, Up: Floating Point Errors
--
--Error Reporting by Mathematical Functions
-------------------------------------------
--
-- Many of the math functions are defined only over a subset of the
--real or complex numbers. Even if they are mathematically defined,
--their result may be larger or smaller than the range representable by
--their return type. These are known as "domain errors", "overflows", and
--"underflows", respectively. Math functions do several things when one
--of these errors occurs. In this manual we will refer to the complete
--response as "signalling" a domain error, overflow, or underflow.
--
-- When a math function suffers a domain error, it raises the invalid
--exception and returns NaN. It also sets ERRNO to `EDOM'; this is for
--compatibility with old systems that do not support IEEE 754 exception
--handling. Likewise, when overflow occurs, math functions raise the
--overflow exception and return oo or -oo as appropriate. They also set
--ERRNO to `ERANGE'. When underflow occurs, the underflow exception is
--raised, and zero (appropriately signed) is returned. ERRNO may be set
--to `ERANGE', but this is not guaranteed.
--
-- Some of the math functions are defined mathematically to result in a
--complex value over parts of their domains. The most familiar example of
--this is taking the square root of a negative number. The complex math
--functions, such as `csqrt', will return the appropriate complex value
--in this case. The real-valued functions, such as `sqrt', will signal a
--domain error.
--
-- Some older hardware does not support infinities. On that hardware,
--overflows instead return a particular very large number (usually the
--largest representable number). `math.h' defines macros you can use to
--test for overflow on both old and new hardware.
--
-- - Macro: double HUGE_VAL
-- - Macro: float HUGE_VALF
-- - Macro: long double HUGE_VALL
-- An expression representing a particular very large number. On
-- machines that use IEEE 754 floating point format, `HUGE_VAL' is
-- infinity. On other machines, it's typically the largest positive
-- number that can be represented.
--
-- Mathematical functions return the appropriately typed version of
-- `HUGE_VAL' or `-HUGE_VAL' when the result is too large to be
-- represented.
--
--
--File: libc.info, Node: Rounding, Next: Control Functions, Prev: Floating Point Errors, Up: Arithmetic
--
--Rounding Modes
--==============
--
-- Floating-point calculations are carried out internally with extra
--precision, and then rounded to fit into the destination type. This
--ensures that results are as precise as the input data. IEEE 754
--defines four possible rounding modes:
--
--Round to nearest.
-- This is the default mode. It should be used unless there is a
-- specific need for one of the others. In this mode results are
-- rounded to the nearest representable value. If the result is
-- midway between two representable values, the even representable is
-- chosen. "Even" here means the lowest-order bit is zero. This
-- rounding mode prevents statistical bias and guarantees numeric
-- stability: round-off errors in a lengthy calculation will remain
-- smaller than half of `FLT_EPSILON'.
--
--Round toward plus Infinity.
-- All results are rounded to the smallest representable value which
-- is greater than the result.
--
--Round toward minus Infinity.
-- All results are rounded to the largest representable value which
-- is less than the result.
--
--Round toward zero.
-- All results are rounded to the largest representable value whose
-- magnitude is less than that of the result. In other words, if the
-- result is negative it is rounded up; if it is positive, it is
-- rounded down.
--
--`fenv.h' defines constants which you can use to refer to the various
--rounding modes. Each one will be defined if and only if the FPU
--supports the corresponding rounding mode.
--
--`FE_TONEAREST'
-- Round to nearest.
--
--`FE_UPWARD'
-- Round toward +oo.
--
--`FE_DOWNWARD'
-- Round toward -oo.
--
--`FE_TOWARDZERO'
-- Round toward zero.
--
-- Underflow is an unusual case. Normally, IEEE 754 floating point
--numbers are always normalized (*note Floating Point Concepts::.).
--Numbers smaller than 2^r (where r is the minimum exponent,
--`FLT_MIN_RADIX-1' for FLOAT) cannot be represented as normalized
--numbers. Rounding all such numbers to zero or 2^r would cause some
--algorithms to fail at 0. Therefore, they are left in denormalized
--form. That produces loss of precision, since some bits of the mantissa
--are stolen to indicate the decimal point.
--
-- If a result is too small to be represented as a denormalized number,
--it is rounded to zero. However, the sign of the result is preserved; if
--the calculation was negative, the result is "negative zero". Negative
--zero can also result from some operations on infinity, such as 4/-oo.
--Negative zero behaves identically to zero except when the `copysign' or
--`signbit' functions are used to check the sign bit directly.
--
-- At any time one of the above four rounding modes is selected. You
--can find out which one with this function:
--
-- - Function: int fegetround (void)
-- Returns the currently selected rounding mode, represented by one
-- of the values of the defined rounding mode macros.
--
--To change the rounding mode, use this function:
--
-- - Function: int fesetround (int ROUND)
-- Changes the currently selected rounding mode to ROUND. If ROUND
-- does not correspond to one of the supported rounding modes nothing
-- is changed. `fesetround' returns a nonzero value if it changed
-- the rounding mode, zero if the mode is not supported.
--
-- You should avoid changing the rounding mode if possible. It can be
--an expensive operation; also, some hardware requires you to compile your
--program differently for it to work. The resulting code may run slower.
--See your compiler documentation for details.
--
--
--File: libc.info, Node: Control Functions, Next: Arithmetic Functions, Prev: Rounding, Up: Arithmetic
--
--Floating-Point Control Functions
--================================
--
-- IEEE 754 floating-point implementations allow the programmer to
--decide whether traps will occur for each of the exceptions, by setting
--bits in the "control word". In C, traps result in the program
--receiving the `SIGFPE' signal; see *Note Signal Handling::.
--
-- *Note:* IEEE 754 says that trap handlers are given details of the
--exceptional situation, and can set the result value. C signals do not
--provide any mechanism to pass this information back and forth.
--Trapping exceptions in C is therefore not very useful.
--
-- It is sometimes necessary to save the state of the floating-point
--unit while you perform some calculation. The library provides functions
--which save and restore the exception flags, the set of exceptions that
--generate traps, and the rounding mode. This information is known as the
--"floating-point environment".
--
-- The functions to save and restore the floating-point environment all
--use a variable of type `fenv_t' to store information. This type is
--defined in `fenv.h'. Its size and contents are implementation-defined.
--You should not attempt to manipulate a variable of this type directly.
--
-- To save the state of the FPU, use one of these functions:
--
-- - Function: void fegetenv (fenv_t *ENVP)
-- Store the floating-point environment in the variable pointed to by
-- ENVP.
--
-- - Function: int feholdexcept (fenv_t *ENVP)
-- Store the current floating-point environment in the object pointed
-- to by ENVP. Then clear all exception flags, and set the FPU to
-- trap no exceptions. Not all FPUs support trapping no exceptions;
-- if `feholdexcept' cannot set this mode, it returns zero. If it
-- succeeds, it returns a nonzero value.
--
-- The functions which restore the floating-point environment can take
--two kinds of arguments:
--
-- * Pointers to `fenv_t' objects, which were initialized previously by
-- a call to `fegetenv' or `feholdexcept'.
--
-- * The special macro `FE_DFL_ENV' which represents the floating-point
-- environment as it was available at program start.
--
-- * Implementation defined macros with names starting with `FE_'.
--
-- If possible, the GNU C Library defines a macro `FE_NOMASK_ENV'
-- which represents an environment where every exception raised
-- causes a trap to occur. You can test for this macro using
-- `#ifdef'. It is only defined if `_GNU_SOURCE' is defined.
--
-- Some platforms might define other predefined environments.
--
--To set the floating-point environment, you can use either of these
--functions:
--
-- - Function: void fesetenv (const fenv_t *ENVP)
-- Set the floating-point environment to that described by ENVP.
--
-- - Function: void feupdateenv (const fenv_t *ENVP)
-- Like `fesetenv', this function sets the floating-point environment
-- to that described by ENVP. However, if any exceptions were
-- flagged in the status word before `feupdateenv' was called, they
-- remain flagged after the call. In other words, after `feupdateenv'
-- is called, the status word is the bitwise OR of the previous
-- status word and the one saved in ENVP.
--
--
--File: libc.info, Node: Arithmetic Functions, Next: Complex Numbers, Prev: Control Functions, Up: Arithmetic
--
--Arithmetic Functions
--====================
--
-- The C library provides functions to do basic operations on
--floating-point numbers. These include absolute value, maximum and
--minimum, normalization, bit twiddling, rounding, and a few others.
--
--* Menu:
--
--* Absolute Value:: Absolute values of integers and floats.
--* Normalization Functions:: Extracting exponents and putting them back.
--* Rounding Functions:: Rounding floats to integers.
--* Remainder Functions:: Remainders on division, precisely defined.
--* FP Bit Twiddling:: Sign bit adjustment. Adding epsilon.
--* FP Comparison Functions:: Comparisons without risk of exceptions.
--* Misc FP Arithmetic:: Max, min, positive difference, multiply-add.
--
--
--File: libc.info, Node: Absolute Value, Next: Normalization Functions, Up: Arithmetic Functions
--
--Absolute Value
----------------
--
-- These functions are provided for obtaining the "absolute value" (or
--"magnitude") of a number. The absolute value of a real number X is X
--if X is positive, -X if X is negative. For a complex number Z, whose
--real part is X and whose imaginary part is Y, the absolute value is
--`sqrt (X*X + Y*Y)'.
--
-- Prototypes for `abs', `labs' and `llabs' are in `stdlib.h';
--`imaxabs' is declared in `inttypes.h'; `fabs', `fabsf' and `fabsl' are
--declared in `math.h'. `cabs', `cabsf' and `cabsl' are declared in
--`complex.h'.
--
-- - Function: int abs (int NUMBER)
-- - Function: long int labs (long int NUMBER)
-- - Function: long long int llabs (long long int NUMBER)
-- - Function: intmax_t imaxabs (intmax_t NUMBER)
-- These functions return the absolute value of NUMBER.
--
-- Most computers use a two's complement integer representation, in
-- which the absolute value of `INT_MIN' (the smallest possible `int')
-- cannot be represented; thus, `abs (INT_MIN)' is not defined.
--
-- `llabs' and `imaxdiv' are new to ISO C 9x.
--
-- - Function: double fabs (double NUMBER)
-- - Function: float fabsf (float NUMBER)
-- - Function: long double fabsl (long double NUMBER)
-- This function returns the absolute value of the floating-point
-- number NUMBER.
--
-- - Function: double cabs (complex double Z)
-- - Function: float cabsf (complex float Z)
-- - Function: long double cabsl (complex long double Z)
-- These functions return the absolute value of the complex number Z
-- (*note Complex Numbers::.). The absolute value of a complex
-- number is:
--
-- sqrt (creal (Z) * creal (Z) + cimag (Z) * cimag (Z))
--
-- This function should always be used instead of the direct formula
-- because it takes special care to avoid losing precision. It may
-- also take advantage of hardware support for this operation. See
-- `hypot' in *Note Exponents and Logarithms::.
--
--
--File: libc.info, Node: Normalization Functions, Next: Rounding Functions, Prev: Absolute Value, Up: Arithmetic Functions
--
--Normalization Functions
-------------------------
--
-- The functions described in this section are primarily provided as a
--way to efficiently perform certain low-level manipulations on floating
--point numbers that are represented internally using a binary radix; see
--*Note Floating Point Concepts::. These functions are required to have
--equivalent behavior even if the representation does not use a radix of
--2, but of course they are unlikely to be particularly efficient in
--those cases.
--
-- All these functions are declared in `math.h'.
--
-- - Function: double frexp (double VALUE, int *EXPONENT)
-- - Function: float frexpf (float VALUE, int *EXPONENT)
-- - Function: long double frexpl (long double VALUE, int *EXPONENT)
-- These functions are used to split the number VALUE into a
-- normalized fraction and an exponent.
--
-- If the argument VALUE is not zero, the return value is VALUE times
-- a power of two, and is always in the range 1/2 (inclusive) to 1
-- (exclusive). The corresponding exponent is stored in `*EXPONENT';
-- the return value multiplied by 2 raised to this exponent equals
-- the original number VALUE.
--
-- For example, `frexp (12.8, &exponent)' returns `0.8' and stores
-- `4' in `exponent'.
--
-- If VALUE is zero, then the return value is zero and zero is stored
-- in `*EXPONENT'.
--
-- - Function: double ldexp (double VALUE, int EXPONENT)
-- - Function: float ldexpf (float VALUE, int EXPONENT)
-- - Function: long double ldexpl (long double VALUE, int EXPONENT)
-- These functions return the result of multiplying the floating-point
-- number VALUE by 2 raised to the power EXPONENT. (It can be used
-- to reassemble floating-point numbers that were taken apart by
-- `frexp'.)
--
-- For example, `ldexp (0.8, 4)' returns `12.8'.
--
-- The following functions, which come from BSD, provide facilities
--equivalent to those of `ldexp' and `frexp'.
--
-- - Function: double logb (double X)
-- - Function: float logbf (float X)
-- - Function: long double logbl (long double X)
-- These functions return the integer part of the base-2 logarithm of
-- X, an integer value represented in type `double'. This is the
-- highest integer power of `2' contained in X. The sign of X is
-- ignored. For example, `logb (3.5)' is `1.0' and `logb (4.0)' is
-- `2.0'.
--
-- When `2' raised to this power is divided into X, it gives a
-- quotient between `1' (inclusive) and `2' (exclusive).
--
-- If X is zero, the return value is minus infinity if the machine
-- supports infinities, and a very small number if it does not. If X
-- is infinity, the return value is infinity.
--
-- For finite X, the value returned by `logb' is one less than the
-- value that `frexp' would store into `*EXPONENT'.
--
-- - Function: double scalb (double VALUE, int EXPONENT)
-- - Function: float scalbf (float VALUE, int EXPONENT)
-- - Function: long double scalbl (long double VALUE, int EXPONENT)
-- The `scalb' function is the BSD name for `ldexp'.
--
-- - Function: long long int scalbn (double X, int n)
-- - Function: long long int scalbnf (float X, int n)
-- - Function: long long int scalbnl (long double X, int n)
-- `scalbn' is identical to `scalb', except that the exponent N is an
-- `int' instead of a floating-point number.
--
-- - Function: long long int scalbln (double X, long int n)
-- - Function: long long int scalblnf (float X, long int n)
-- - Function: long long int scalblnl (long double X, long int n)
-- `scalbln' is identical to `scalb', except that the exponent N is a
-- `long int' instead of a floating-point number.
--
-- - Function: long long int significand (double X)
-- - Function: long long int significandf (float X)
-- - Function: long long int significandl (long double X)
-- `significand' returns the mantissa of X scaled to the range [1, 2).
-- It is equivalent to `scalb (X, (double) -ilogb (X))'.
--
-- This function exists mainly for use in certain standardized tests
-- of IEEE 754 conformance.
--
--
--File: libc.info, Node: Rounding Functions, Next: Remainder Functions, Prev: Normalization Functions, Up: Arithmetic Functions
--
--Rounding Functions
--------------------
--
-- The functions listed here perform operations such as rounding and
--truncation of floating-point values. Some of these functions convert
--floating point numbers to integer values. They are all declared in
--`math.h'.
--
-- You can also convert floating-point numbers to integers simply by
--casting them to `int'. This discards the fractional part, effectively
--rounding towards zero. However, this only works if the result can
--actually be represented as an `int'--for very large numbers, this is
--impossible. The functions listed here return the result as a `double'
--instead to get around this problem.
--
-- - Function: double ceil (double X)
-- - Function: float ceilf (float X)
-- - Function: long double ceill (long double X)
-- These functions round X upwards to the nearest integer, returning
-- that value as a `double'. Thus, `ceil (1.5)' is `2.0'.
--
-- - Function: double floor (double X)
-- - Function: float floorf (float X)
-- - Function: long double floorl (long double X)
-- These functions round X downwards to the nearest integer,
-- returning that value as a `double'. Thus, `floor (1.5)' is `1.0'
-- and `floor (-1.5)' is `-2.0'.
--
-- - Function: double trunc (double X)
-- - Function: float truncf (float X)
-- - Function: long double truncl (long double X)
-- `trunc' is another name for `floor'
--
-- - Function: double rint (double X)
-- - Function: float rintf (float X)
-- - Function: long double rintl (long double X)
-- These functions round X to an integer value according to the
-- current rounding mode. *Note Floating Point Parameters::, for
-- information about the various rounding modes. The default
-- rounding mode is to round to the nearest integer; some machines
-- support other modes, but round-to-nearest is always used unless
-- you explicitly select another.
--
-- If X was not initially an integer, these functions raise the
-- inexact exception.
--
-- - Function: double nearbyint (double X)
-- - Function: float nearbyintf (float X)
-- - Function: long double nearbyintl (long double X)
-- These functions return the same value as the `rint' functions, but
-- do not raise the inexact exception if X is not an integer.
--
-- - Function: double round (double X)
-- - Function: float roundf (float X)
-- - Function: long double roundl (long double X)
-- These functions are similar to `rint', but they round halfway
-- cases away from zero instead of to the nearest even integer.
--
-- - Function: long int lrint (double X)
-- - Function: long int lrintf (float X)
-- - Function: long int lrintl (long double X)
-- These functions are just like `rint', but they return a `long int'
-- instead of a floating-point number.
--
-- - Function: long long int llrint (double X)
-- - Function: long long int llrintf (float X)
-- - Function: long long int llrintl (long double X)
-- These functions are just like `rint', but they return a `long long
-- int' instead of a floating-point number.
--
-- - Function: long int lround (double X)
-- - Function: long int lroundf (float X)
-- - Function: long int lroundl (long double X)
-- These functions are just like `round', but they return a `long
-- int' instead of a floating-point number.
--
-- - Function: long long int llround (double X)
-- - Function: long long int llroundf (float X)
-- - Function: long long int llroundl (long double X)
-- These functions are just like `round', but they return a `long
-- long int' instead of a floating-point number.
--
-- - Function: double modf (double VALUE, double *INTEGER-PART)
-- - Function: float modff (float VALUE, float *INTEGER-PART)
-- - Function: long double modfl (long double VALUE, long double
-- *INTEGER-PART)
-- These functions break the argument VALUE into an integer part and a
-- fractional part (between `-1' and `1', exclusive). Their sum
-- equals VALUE. Each of the parts has the same sign as VALUE, and
-- the integer part is always rounded toward zero.
--
-- `modf' stores the integer part in `*INTEGER-PART', and returns the
-- fractional part. For example, `modf (2.5, &intpart)' returns
-- `0.5' and stores `2.0' into `intpart'.
--
--
--File: libc.info, Node: Remainder Functions, Next: FP Bit Twiddling, Prev: Rounding Functions, Up: Arithmetic Functions
--
--Remainder Functions
---------------------
--
-- The functions in this section compute the remainder on division of
--two floating-point numbers. Each is a little different; pick the one
--that suits your problem.
--
-- - Function: double fmod (double NUMERATOR, double DENOMINATOR)
-- - Function: float fmodf (float NUMERATOR, float DENOMINATOR)
-- - Function: long double fmodl (long double NUMERATOR, long double
-- DENOMINATOR)
-- These functions compute the remainder from the division of
-- NUMERATOR by DENOMINATOR. Specifically, the return value is
-- `NUMERATOR - N * DENOMINATOR', where N is the quotient of
-- NUMERATOR divided by DENOMINATOR, rounded towards zero to an
-- integer. Thus, `fmod (6.5, 2.3)' returns `1.9', which is `6.5'
-- minus `4.6'.
--
-- The result has the same sign as the NUMERATOR and has magnitude
-- less than the magnitude of the DENOMINATOR.
--
-- If DENOMINATOR is zero, `fmod' signals a domain error.
--
-- - Function: double drem (double NUMERATOR, double DENOMINATOR)
-- - Function: float dremf (float NUMERATOR, float DENOMINATOR)
-- - Function: long double dreml (long double NUMERATOR, long double
-- DENOMINATOR)
-- These functions are like `fmod' except that they rounds the
-- internal quotient N to the nearest integer instead of towards zero
-- to an integer. For example, `drem (6.5, 2.3)' returns `-0.4',
-- which is `6.5' minus `6.9'.
--
-- The absolute value of the result is less than or equal to half the
-- absolute value of the DENOMINATOR. The difference between `fmod
-- (NUMERATOR, DENOMINATOR)' and `drem (NUMERATOR, DENOMINATOR)' is
-- always either DENOMINATOR, minus DENOMINATOR, or zero.
--
-- If DENOMINATOR is zero, `drem' signals a domain error.
--
-- - Function: double remainder (double NUMERATOR, double DENOMINATOR)
-- - Function: float remainderf (float NUMERATOR, float DENOMINATOR)
-- - Function: long double remainderl (long double NUMERATOR, long double
-- DENOMINATOR)
-- This function is another name for `drem'.
--
--
--File: libc.info, Node: FP Bit Twiddling, Next: FP Comparison Functions, Prev: Remainder Functions, Up: Arithmetic Functions
--
--Setting and modifying single bits of FP values
------------------------------------------------
--
-- There are some operations that are too complicated or expensive to
--perform by hand on floating-point numbers. ISO C 9x defines functions
--to do these operations, which mostly involve changing single bits.
--
-- - Function: double copysign (double X, double Y)
-- - Function: float copysignf (float X, float Y)
-- - Function: long double copysignl (long double X, long double Y)
-- These functions return X but with the sign of Y. They work even
-- if X or Y are NaN or zero. Both of these can carry a sign
-- (although not all implementations support it) and this is one of
-- the few operations that can tell the difference.
--
-- `copysign' never raises an exception.
--
-- This function is defined in IEC 559 (and the appendix with
-- recommended functions in IEEE 754/IEEE 854).
--
-- - Function: int signbit (*float-type* X)
-- `signbit' is a generic macro which can work on all floating-point
-- types. It returns a nonzero value if the value of X has its sign
-- bit set.
--
-- This is not the same as `x < 0.0', because IEEE 754 floating point
-- allows zero to be signed. The comparison `-0.0 < 0.0' is false,
-- but `signbit (-0.0)' will return a nonzero value.
--
-- - Function: double nextafter (double X, double Y)
-- - Function: float nextafterf (float X, float Y)
-- - Function: long double nextafterl (long double X, long double Y)
-- The `nextafter' function returns the next representable neighbor of
-- X in the direction towards Y. The size of the step between X and
-- the result depends on the type of the result. If X = Y the
-- function simply returns X. If either value is `NaN', `NaN' is
-- returned. Otherwise a value corresponding to the value of the
-- least significant bit in the mantissa is added or subtracted,
-- depending on the direction. `nextafter' will signal overflow or
-- underflow if the result goes outside of the range of normalized
-- numbers.
--
-- This function is defined in IEC 559 (and the appendix with
-- recommended functions in IEEE 754/IEEE 854).
--
-- - Function: double nexttoward (double X, long double Y)
-- - Function: float nexttowardf (float X, long double Y)
-- - Function: long double nexttowardl (long double X, long double Y)
-- These functions are identical to the corresponding versions of
-- `nextafter' except that their second argument is a `long double'.
--
-- - Function: double nan (const char *TAGP)
-- - Function: float nanf (const char *TAGP)
-- - Function: long double nanl (const char *TAGP)
-- The `nan' function returns a representation of NaN, provided that
-- NaN is supported by the target platform. `nan
-- ("N-CHAR-SEQUENCE")' is equivalent to `strtod
-- ("NAN(N-CHAR-SEQUENCE)")'.
--
-- The argument TAGP is used in an unspecified manner. On IEEE 754
-- systems, there are many representations of NaN, and TAGP selects
-- one. On other systems it may do nothing.
--
--
--File: libc.info, Node: FP Comparison Functions, Next: Misc FP Arithmetic, Prev: FP Bit Twiddling, Up: Arithmetic Functions
--
--Floating-Point Comparison Functions
-------------------------------------
--
-- The standard C comparison operators provoke exceptions when one or
--other of the operands is NaN. For example,
--
-- int v = a < 1.0;
--
--will raise an exception if A is NaN. (This does *not* happen with `=='
--and `!='; those merely return false and true, respectively, when NaN is
--examined.) Frequently this exception is undesirable. ISO C 9x
--therefore defines comparison functions that do not raise exceptions
--when NaN is examined. All of the functions are implemented as macros
--which allow their arguments to be of any floating-point type. The
--macros are guaranteed to evaluate their arguments only once.
--
-- - Macro: int isgreater (*real-floating* X, *real-floating* Y)
-- This macro determines whether the argument X is greater than Y.
-- It is equivalent to `(X) > (Y)', but no exception is raised if X
-- or Y are NaN.
--
-- - Macro: int isgreaterequal (*real-floating* X, *real-floating* Y)
-- This macro determines whether the argument X is greater than or
-- equal to Y. It is equivalent to `(X) >= (Y)', but no exception is
-- raised if X or Y are NaN.
--
-- - Macro: int isless (*real-floating* X, *real-floating* Y)
-- This macro determines whether the argument X is less than Y. It
-- is equivalent to `(X) < (Y)', but no exception is raised if X or Y
-- are NaN.
--
-- - Macro: int islessequal (*real-floating* X, *real-floating* Y)
-- This macro determines whether the argument X is less than or equal
-- to Y. It is equivalent to `(X) <= (Y)', but no exception is
-- raised if X or Y are NaN.
--
-- - Macro: int islessgreater (*real-floating* X, *real-floating* Y)
-- This macro determines whether the argument X is less or greater
-- than Y. It is equivalent to `(X) < (Y) || (X) > (Y)' (although it
-- only evaluates X and Y once), but no exception is raised if X or Y
-- are NaN.
--
-- This macro is not equivalent to `X != Y', because that expression
-- is true if X or Y are NaN.
--
-- - Macro: int isunordered (*real-floating* X, *real-floating* Y)
-- This macro determines whether its arguments are unordered. In
-- other words, it is true if X or Y are NaN, and false otherwise.
--
-- Not all machines provide hardware support for these operations. On
--machines that don't, the macros can be very slow. Therefore, you should
--not use these functions when NaN is not a concern.
--
-- *Note:* There are no macros `isequal' or `isunequal'. They are
--unnecessary, because the `==' and `!=' operators do *not* throw an
--exception if one or both of the operands are NaN.
--
--
--File: libc.info, Node: Misc FP Arithmetic, Prev: FP Comparison Functions, Up: Arithmetic Functions
--
--Miscellaneous FP arithmetic functions
---------------------------------------
--
-- The functions in this section perform miscellaneous but common
--operations that are awkward to express with C operators. On some
--processors these functions can use special machine instructions to
--perform these operations faster than the equivalent C code.
--
-- - Function: double fmin (double X, double Y)
-- - Function: float fminf (float X, float Y)
-- - Function: long double fminl (long double X, long double Y)
-- The `fmin' function returns the lesser of the two values X and Y.
-- It is similar to the expression
-- ((x) < (y) ? (x) : (y))
-- except that X and Y are only evaluated once.
--
-- If an argument is NaN, the other argument is returned. If both
-- arguments are NaN, NaN is returned.
--
-- - Function: double fmax (double X, double Y)
-- - Function: float fmaxf (float X, float Y)
-- - Function: long double fmaxl (long double X, long double Y)
-- The `fmax' function returns the greater of the two values X and Y.
--
-- If an argument is NaN, the other argument is returned. If both
-- arguments are NaN, NaN is returned.
--
-- - Function: double fdim (double X, double Y)
-- - Function: float fdimf (float X, float Y)
-- - Function: long double fdiml (long double X, long double Y)
-- The `fdim' function returns the positive difference between X and
-- Y. The positive difference is X - Y if X is greater than Y, and 0
-- otherwise.
--
-- If X, Y, or both are NaN, NaN is returned.
--
-- - Function: double fma (double X, double Y, double Z)
-- - Function: float fmaf (float X, float Y, float Z)
-- - Function: long double fmal (long double X, long double Y, long
-- double Z)
-- The `fma' function performs floating-point multiply-add. This is
-- the operation (X * Y) + Z, but the intermediate result is not
-- rounded to the destination type. This can sometimes improve the
-- precision of a calculation.
--
-- This function was introduced because some processors have a special
-- instruction to perform multiply-add. The C compiler cannot use it
-- directly, because the expression `x*y + z' is defined to round the
-- intermediate result. `fma' lets you choose when you want to round
-- only once.
--
-- On processors which do not implement multiply-add in hardware,
-- `fma' can be very slow since it must avoid intermediate rounding.
-- `math.h' defines the symbols `FP_FAST_FMA', `FP_FAST_FMAF', and
-- `FP_FAST_FMAL' when the corresponding version of `fma' is no
-- slower than the expression `x*y + z'. In the GNU C library, this
-- always means the operation is implemented in hardware.
--
--
--File: libc.info, Node: Complex Numbers, Next: Operations on Complex, Prev: Arithmetic Functions, Up: Arithmetic
--
--Complex Numbers
--===============
--
-- ISO C 9x introduces support for complex numbers in C. This is done
--with a new type qualifier, `complex'. It is a keyword if and only if
--`complex.h' has been included. There are three complex types,
--corresponding to the three real types: `float complex', `double
--complex', and `long double complex'.
--
-- To construct complex numbers you need a way to indicate the imaginary
--part of a number. There is no standard notation for an imaginary
--floating point constant. Instead, `complex.h' defines two macros that
--can be used to create complex numbers.
--
-- - Macro: const float complex _Complex_I
-- This macro is a representation of the complex number "0+1i".
-- Multiplying a real floating-point value by `_Complex_I' gives a
-- complex number whose value is purely imaginary. You can use this
-- to construct complex constants:
--
-- 3.0 + 4.0i = `3.0 + 4.0 * _Complex_I'
--
-- Note that `_Complex_I * _Complex_I' has the value `-1', but the
-- type of that value is `complex'.
--
--`_Complex_I' is a bit of a mouthful. `complex.h' also defines a
--shorter name for the same constant.
--
-- - Macro: const float complex I
-- This macro has exactly the same value as `_Complex_I'. Most of the
-- time it is preferable. However, it causes problems if you want to
-- use the identifier `I' for something else. You can safely write
--
-- #include <complex.h>
-- #undef I
--
-- if you need `I' for your own purposes. (In that case we recommend
-- you also define some other short name for `_Complex_I', such as
-- `J'.)
--
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-29 glibc-2.1.3/manual/libc.info-29
---- ../glibc-2.1.3/manual/libc.info-29 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-29 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1129 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Operations on Complex, Next: Integer Division, Prev: Complex Numbers, Up: Arithmetic
--
--Projections, Conjugates, and Decomposing of Complex Numbers
--===========================================================
--
-- ISO C 9x also defines functions that perform basic operations on
--complex numbers, such as decomposition and conjugation. The prototypes
--for all these functions are in `complex.h'. All functions are
--available in three variants, one for each of the three complex types.
--
-- - Function: double creal (complex double Z)
-- - Function: float crealf (complex float Z)
-- - Function: long double creall (complex long double Z)
-- These functions return the real part of the complex number Z.
--
-- - Function: double cimag (complex double Z)
-- - Function: float cimagf (complex float Z)
-- - Function: long double cimagl (complex long double Z)
-- These functions return the imaginary part of the complex number Z.
--
-- - Function: complex double conj (complex double Z)
-- - Function: complex float conjf (complex float Z)
-- - Function: complex long double conjl (complex long double Z)
-- These functions return the conjugate value of the complex number
-- Z. The conjugate of a complex number has the same real part and a
-- negated imaginary part. In other words, `conj(a + bi) = a + -bi'.
--
-- - Function: double carg (complex double Z)
-- - Function: float cargf (complex float Z)
-- - Function: long double cargl (complex long double Z)
-- These functions return the argument of the complex number Z. The
-- argument of a complex number is the angle in the complex plane
-- between the positive real axis and a line passing through zero and
-- the number. This angle is measured in the usual fashion and
-- ranges from 0 to 2pi.
--
-- `carg' has a branch cut along the positive real axis.
--
-- - Function: complex double cproj (complex double Z)
-- - Function: complex float cprojf (complex float Z)
-- - Function: complex long double cprojl (complex long double Z)
-- These functions return the projection of the complex value Z onto
-- the Riemann sphere. Values with a infinite imaginary part are
-- projected to positive infinity on the real axis, even if the real
-- part is NaN. If the real part is infinite, the result is
-- equivalent to
--
-- INFINITY + I * copysign (0.0, cimag (z))
--
--
--File: libc.info, Node: Integer Division, Next: Parsing of Numbers, Prev: Operations on Complex, Up: Arithmetic
--
--Integer Division
--================
--
-- This section describes functions for performing integer division.
--These functions are redundant when GNU CC is used, because in GNU C the
--`/' operator always rounds towards zero. But in other C
--implementations, `/' may round differently with negative arguments.
--`div' and `ldiv' are useful because they specify how to round the
--quotient: towards zero. The remainder has the same sign as the
--numerator.
--
-- These functions are specified to return a result R such that the
--value `R.quot*DENOMINATOR + R.rem' equals NUMERATOR.
--
-- To use these facilities, you should include the header file
--`stdlib.h' in your program.
--
-- - Data Type: div_t
-- This is a structure type used to hold the result returned by the
-- `div' function. It has the following members:
--
-- `int quot'
-- The quotient from the division.
--
-- `int rem'
-- The remainder from the division.
--
-- - Function: div_t div (int NUMERATOR, int DENOMINATOR)
-- This function `div' computes the quotient and remainder from the
-- division of NUMERATOR by DENOMINATOR, returning the result in a
-- structure of type `div_t'.
--
-- If the result cannot be represented (as in a division by zero), the
-- behavior is undefined.
--
-- Here is an example, albeit not a very useful one.
--
-- div_t result;
-- result = div (20, -6);
--
-- Now `result.quot' is `-3' and `result.rem' is `2'.
--
-- - Data Type: ldiv_t
-- This is a structure type used to hold the result returned by the
-- `ldiv' function. It has the following members:
--
-- `long int quot'
-- The quotient from the division.
--
-- `long int rem'
-- The remainder from the division.
--
-- (This is identical to `div_t' except that the components are of
-- type `long int' rather than `int'.)
--
-- - Function: ldiv_t ldiv (long int NUMERATOR, long int DENOMINATOR)
-- The `ldiv' function is similar to `div', except that the arguments
-- are of type `long int' and the result is returned as a structure
-- of type `ldiv_t'.
--
-- - Data Type: lldiv_t
-- This is a structure type used to hold the result returned by the
-- `lldiv' function. It has the following members:
--
-- `long long int quot'
-- The quotient from the division.
--
-- `long long int rem'
-- The remainder from the division.
--
-- (This is identical to `div_t' except that the components are of
-- type `long long int' rather than `int'.)
--
-- - Function: lldiv_t lldiv (long long int NUMERATOR, long long int
-- DENOMINATOR)
-- The `lldiv' function is like the `div' function, but the arguments
-- are of type `long long int' and the result is returned as a
-- structure of type `lldiv_t'.
--
-- The `lldiv' function was added in ISO C 9x.
--
-- - Data Type: imaxdiv_t
-- This is a structure type used to hold the result returned by the
-- `imaxdiv' function. It has the following members:
--
-- `intmax_t quot'
-- The quotient from the division.
--
-- `intmax_t rem'
-- The remainder from the division.
--
-- (This is identical to `div_t' except that the components are of
-- type `intmax_t' rather than `int'.)
--
-- - Function: imaxdiv_t imaxdiv (intmax_t NUMERATOR, intmax_t
-- DENOMINATOR)
-- The `imaxdiv' function is like the `div' function, but the
-- arguments are of type `intmax_t' and the result is returned as a
-- structure of type `imaxdiv_t'.
--
-- The `imaxdiv' function was added in ISO C 9x.
--
--
--File: libc.info, Node: Parsing of Numbers, Next: System V Number Conversion, Prev: Integer Division, Up: Arithmetic
--
--Parsing of Numbers
--==================
--
-- This section describes functions for "reading" integer and
--floating-point numbers from a string. It may be more convenient in some
--cases to use `sscanf' or one of the related functions; see *Note
--Formatted Input::. But often you can make a program more robust by
--finding the tokens in the string by hand, then converting the numbers
--one by one.
--
--* Menu:
--
--* Parsing of Integers:: Functions for conversion of integer values.
--* Parsing of Floats:: Functions for conversion of floating-point
-- values.
--
--
--File: libc.info, Node: Parsing of Integers, Next: Parsing of Floats, Up: Parsing of Numbers
--
--Parsing of Integers
---------------------
--
-- These functions are declared in `stdlib.h'.
--
-- - Function: long int strtol (const char *STRING, char **TAILPTR, int
-- BASE)
-- The `strtol' ("string-to-long") function converts the initial part
-- of STRING to a signed integer, which is returned as a value of
-- type `long int'.
--
-- This function attempts to decompose STRING as follows:
--
-- * A (possibly empty) sequence of whitespace characters. Which
-- characters are whitespace is determined by the `isspace'
-- function (*note Classification of Characters::.). These are
-- discarded.
--
-- * An optional plus or minus sign (`+' or `-').
--
-- * A nonempty sequence of digits in the radix specified by BASE.
--
-- If BASE is zero, decimal radix is assumed unless the series of
-- digits begins with `0' (specifying octal radix), or `0x' or
-- `0X' (specifying hexadecimal radix); in other words, the same
-- syntax used for integer constants in C.
--
-- Otherwise BASE must have a value between `2' and `35'. If
-- BASE is `16', the digits may optionally be preceded by `0x'
-- or `0X'. If base has no legal value the value returned is
-- `0l' and the global variable `errno' is set to `EINVAL'.
--
-- * Any remaining characters in the string. If TAILPTR is not a
-- null pointer, `strtol' stores a pointer to this tail in
-- `*TAILPTR'.
--
-- If the string is empty, contains only whitespace, or does not
-- contain an initial substring that has the expected syntax for an
-- integer in the specified BASE, no conversion is performed. In
-- this case, `strtol' returns a value of zero and the value stored in
-- `*TAILPTR' is the value of STRING.
--
-- In a locale other than the standard `"C"' locale, this function
-- may recognize additional implementation-dependent syntax.
--
-- If the string has valid syntax for an integer but the value is not
-- representable because of overflow, `strtol' returns either
-- `LONG_MAX' or `LONG_MIN' (*note Range of Type::.), as appropriate
-- for the sign of the value. It also sets `errno' to `ERANGE' to
-- indicate there was overflow.
--
-- You should not check for errors by examining the return value of
-- `strtol', because the string might be a valid representation of
-- `0l', `LONG_MAX', or `LONG_MIN'. Instead, check whether TAILPTR
-- points to what you expect after the number (e.g. `'\0'' if the
-- string should end after the number). You also need to clear ERRNO
-- before the call and check it afterward, in case there was overflow.
--
-- There is an example at the end of this section.
--
-- - Function: unsigned long int strtoul (const char *STRING, char
-- **TAILPTR, int BASE)
-- The `strtoul' ("string-to-unsigned-long") function is like
-- `strtol' except it returns an `unsigned long int' value. If the
-- number has a leading `-' sign, the return value is negated. The
-- syntax is the same as described above for `strtol'. The value
-- returned on overflow is `ULONG_MAX' (*note Range of Type::.).
--
-- `strtoul' sets ERRNO to `EINVAL' if BASE is out of range, or
-- `ERANGE' on overflow.
--
-- - Function: long long int strtoll (const char *STRING, char **TAILPTR,
-- int BASE)
-- The `strtoll' function is like `strtol' except that it returns a
-- `long long int' value, and accepts numbers with a correspondingly
-- larger range.
--
-- If the string has valid syntax for an integer but the value is not
-- representable because of overflow, `strtoll' returns either
-- `LONG_LONG_MAX' or `LONG_LONG_MIN' (*note Range of Type::.), as
-- appropriate for the sign of the value. It also sets `errno' to
-- `ERANGE' to indicate there was overflow.
--
-- The `strtoll' function was introduced in ISO C 9x.
--
-- - Function: long long int strtoq (const char *STRING, char **TAILPTR,
-- int BASE)
-- `strtoq' ("string-to-quad-word") is the BSD name for `strtoll'.
--
-- - Function: unsigned long long int strtoull (const char *STRING, char
-- **TAILPTR, int BASE)
-- The `strtoull' function is like `strtoul' except that it returns
-- an `unsigned long long int'. The value returned on overflow is
-- `ULONG_LONG_MAX' (*note Range of Type::.).
--
-- The `strtoull' function was introduced in ISO C 9x.
--
-- - Function: unsigned long long int strtouq (const char *STRING, char
-- **TAILPTR, int BASE)
-- `strtouq' is the BSD name for `strtoull'.
--
-- - Function: long int atol (const char *STRING)
-- This function is similar to the `strtol' function with a BASE
-- argument of `10', except that it need not detect overflow errors.
-- The `atol' function is provided mostly for compatibility with
-- existing code; using `strtol' is more robust.
--
-- - Function: int atoi (const char *STRING)
-- This function is like `atol', except that it returns an `int'.
-- The `atoi' function is also considered obsolete; use `strtol'
-- instead.
--
-- - Function: long long int atoll (const char *STRING)
-- This function is similar to `atol', except it returns a `long long
-- int'.
--
-- The `atoll' function was introduced in ISO C 9x. It too is
-- obsolete (despite having just been added); use `strtoll' instead.
--
-- Some locales specify a printed syntax for numbers other than the one
--that these functions understand. If you need to read numbers formatted
--in some other locale, you can use the `strtoX_l' functions. Each of
--the `strtoX' functions has a counterpart with `_l' added to its name.
--The `_l' counterparts take an additional argument: a pointer to an
--`locale_t' structure, which describes how the numbers to be read are
--formatted. *Note Locales::.
--
-- *Portability Note:* These functions are all GNU extensions. You can
--also use `scanf' or its relatives, which have the `'' flag for parsing
--numeric input according to the current locale (*note Numeric Input
--Conversions::.). This feature is standard.
--
-- Here is a function which parses a string as a sequence of integers
--and returns the sum of them:
--
-- int
-- sum_ints_from_string (char *string)
-- {
-- int sum = 0;
--
-- while (1) {
-- char *tail;
-- int next;
--
-- /* Skip whitespace by hand, to detect the end. */
-- while (isspace (*string)) string++;
-- if (*string == 0)
-- break;
--
-- /* There is more nonwhitespace, */
-- /* so it ought to be another number. */
-- errno = 0;
-- /* Parse it. */
-- next = strtol (string, &tail, 0);
-- /* Add it in, if not overflow. */
-- if (errno)
-- printf ("Overflow\n");
-- else
-- sum += next;
-- /* Advance past it. */
-- string = tail;
-- }
--
-- return sum;
-- }
--
--
--File: libc.info, Node: Parsing of Floats, Prev: Parsing of Integers, Up: Parsing of Numbers
--
--Parsing of Floats
-------------------
--
-- These functions are declared in `stdlib.h'.
--
-- - Function: double strtod (const char *STRING, char **TAILPTR)
-- The `strtod' ("string-to-double") function converts the initial
-- part of STRING to a floating-point number, which is returned as a
-- value of type `double'.
--
-- This function attempts to decompose STRING as follows:
--
-- * A (possibly empty) sequence of whitespace characters. Which
-- characters are whitespace is determined by the `isspace'
-- function (*note Classification of Characters::.). These are
-- discarded.
--
-- * An optional plus or minus sign (`+' or `-').
--
-- * A nonempty sequence of digits optionally containing a
-- decimal-point character--normally `.', but it depends on the
-- locale (*note General Numeric::.).
--
-- * An optional exponent part, consisting of a character `e' or
-- `E', an optional sign, and a sequence of digits.
--
-- * Any remaining characters in the string. If TAILPTR is not a
-- null pointer, a pointer to this tail of the string is stored
-- in `*TAILPTR'.
--
-- If the string is empty, contains only whitespace, or does not
-- contain an initial substring that has the expected syntax for a
-- floating-point number, no conversion is performed. In this case,
-- `strtod' returns a value of zero and the value returned in
-- `*TAILPTR' is the value of STRING.
--
-- In a locale other than the standard `"C"' or `"POSIX"' locales,
-- this function may recognize additional locale-dependent syntax.
--
-- If the string has valid syntax for a floating-point number but the
-- value is outside the range of a `double', `strtod' will signal
-- overflow or underflow as described in *Note Math Error Reporting::.
--
-- `strtod' recognizes four special input strings. The strings
-- `"inf"' and `"infinity"' are converted to oo, or to the largest
-- representable value if the floating-point format doesn't support
-- infinities. You can prepend a `"+"' or `"-"' to specify the sign.
-- Case is ignored when scanning these strings.
--
-- The strings `"nan"' and `"nan(CHARS...)"' are converted to NaN.
-- Again, case is ignored. If CHARS... are provided, they are used
-- in some unspecified fashion to select a particular representation
-- of NaN (there can be several).
--
-- Since zero is a valid result as well as the value returned on
-- error, you should check for errors in the same way as for
-- `strtol', by examining ERRNO and TAILPTR.
--
-- - Function: float strtof (const char *STRING, char **TAILPTR)
-- - Function: long double strtold (const char *STRING, char **TAILPTR)
-- These functions are analogous to `strtod', but return `float' and
-- `long double' values respectively. They report errors in the same
-- way as `strtod'. `strtof' can be substantially faster than
-- `strtod', but has less precision; conversely, `strtold' can be
-- much slower but has more precision (on systems where `long double'
-- is a separate type).
--
-- These functions are GNU extensions.
--
-- - Function: double atof (const char *STRING)
-- This function is similar to the `strtod' function, except that it
-- need not detect overflow and underflow errors. The `atof' function
-- is provided mostly for compatibility with existing code; using
-- `strtod' is more robust.
--
-- The GNU C library also provides `_l' versions of thse functions,
--which take an additional argument, the locale to use in conversion.
--*Note Parsing of Integers::.
--
--
--File: libc.info, Node: System V Number Conversion, Prev: Parsing of Numbers, Up: Arithmetic
--
--Old-fashioned System V number-to-string functions
--=================================================
--
-- The old System V C library provided three functions to convert
--numbers to strings, with unusual and hard-to-use semantics. The GNU C
--library also provides these functions and some natural extensions.
--
-- These functions are only available in glibc and on systems descended
--from AT&T Unix. Therefore, unless these functions do precisely what you
--need, it is better to use `sprintf', which is standard.
--
-- All these functions are defined in `stdlib.h'.
--
-- - Function: char * ecvt (double VALUE, int NDIGIT, int *DECPT, int
-- *NEG)
-- The function `ecvt' converts the floating-point number VALUE to a
-- string with at most NDIGIT decimal digits. The returned string
-- contains no decimal point or sign. The first digit of the string
-- is non-zero (unless VALUE is actually zero) and the last digit is
-- rounded to nearest. `*DECPT' is set to the index in the string of
-- the first digit after the decimal point. `*NEG' is set to a
-- nonzero value if VALUE is negative, zero otherwise.
--
-- If NDIGIT decimal digits would exceed the precision of a `double'
-- it is reduced to a system-specific value.
--
-- The returned string is statically allocated and overwritten by
-- each call to `ecvt'.
--
-- If VALUE is zero, it is implementation defined whether `*DECPT' is
-- `0' or `1'.
--
-- For example: `ecvt (12.3, 5, &d, &n)' returns `"12300"' and sets D
-- to `2' and N to `0'.
--
-- - Function: char * fcvt (double VALUE, int NDIGIT, int *DECPT, int
-- *NEG)
-- The function `fcvt' is like `ecvt', but NDIGIT specifies the
-- number of digits after the decimal point. If NDIGIT is less than
-- zero, VALUE is rounded to the NDIGIT+1'th place to the left of the
-- decimal point. For example, if NDIGIT is `-1', VALUE will be
-- rounded to the nearest 10. If NDIGIT is negative and larger than
-- the number of digits to the left of the decimal point in VALUE,
-- VALUE will be rounded to one significant digit.
--
-- If NDIGIT decimal digits would exceed the precision of a `double'
-- it is reduced to a system-specific value.
--
-- The returned string is statically allocated and overwritten by
-- each call to `fcvt'.
--
-- - Function: char * gcvt (double VALUE, int NDIGIT, char *BUF)
-- `gcvt' is functionally equivalent to `sprintf(buf, "%*g", ndigit,
-- value'. It is provided only for compatibility's sake. It returns
-- BUF.
--
-- If NDIGIT decimal digits would exceed the precision of a `double'
-- it is reduced to a system-specific value.
--
-- As extensions, the GNU C library provides versions of these three
--functions that take `long double' arguments.
--
-- - Function: char * qecvt (long double VALUE, int NDIGIT, int *DECPT,
-- int *NEG)
-- This function is equivalent to `ecvt' except that it takes a `long
-- double' for the first parameter and that NDIGIT is restricted by
-- the precision of a `long double'.
--
-- - Function: char * qfcvt (long double VALUE, int NDIGIT, int *DECPT,
-- int *NEG)
-- This function is equivalent to `fcvt' except that it takes a `long
-- double' for the first parameter and that NDIGIT is restricted by
-- the precision of a `long double'.
--
-- - Function: char * qgcvt (long double VALUE, int NDIGIT, char *BUF)
-- This function is equivalent to `gcvt' except that it takes a `long
-- double' for the first parameter and that NDIGIT is restricted by
-- the precision of a `long double'.
--
-- The `ecvt' and `fcvt' functions, and their `long double'
--equivalents, all return a string located in a static buffer which is
--overwritten by the next call to the function. The GNU C library
--provides another set of extended functions which write the converted
--string into a user-supplied buffer. These have the conventional `_r'
--suffix.
--
-- `gcvt_r' is not necessary, because `gcvt' already uses a
--user-supplied buffer.
--
-- - Function: char * ecvt_r (double VALUE, int NDIGIT, int *DECPT, int
-- *NEG, char *BUF, size_t LEN)
-- The `ecvt_r' function is the same as `ecvt', except that it places
-- its result into the user-specified buffer pointed to by BUF, with
-- length LEN.
--
-- This function is a GNU extension.
--
-- - Function: char * fcvt_r (double VALUE, int NDIGIT, int *DECPT, int
-- *NEG, char *BUF, size_t LEN)
-- The `fcvt_r' function is the same as `fcvt', except that it places
-- its result into the user-specified buffer pointed to by BUF, with
-- length LEN.
--
-- This function is a GNU extension.
--
-- - Function: char * qecvt_r (long double VALUE, int NDIGIT, int *DECPT,
-- int *NEG, char *BUF, size_t LEN)
-- The `qecvt_r' function is the same as `qecvt', except that it
-- places its result into the user-specified buffer pointed to by
-- BUF, with length LEN.
--
-- This function is a GNU extension.
--
-- - Function: char * qfcvt_r (long double VALUE, int NDIGIT, int *DECPT,
-- int *NEG, char *BUF, size_t LEN)
-- The `qfcvt_r' function is the same as `qfcvt', except that it
-- places its result into the user-specified buffer pointed to by
-- BUF, with length LEN.
--
-- This function is a GNU extension.
--
--
--File: libc.info, Node: Date and Time, Next: Non-Local Exits, Prev: Arithmetic, Up: Top
--
--Date and Time
--*************
--
-- This chapter describes functions for manipulating dates and times,
--including functions for determining what the current time is and
--conversion between different time representations.
--
-- The time functions fall into three main categories:
--
-- * Functions for measuring elapsed CPU time are discussed in *Note
-- Processor Time::.
--
-- * Functions for measuring absolute clock or calendar time are
-- discussed in *Note Calendar Time::.
--
-- * Functions for setting alarms and timers are discussed in *Note
-- Setting an Alarm::.
--
--* Menu:
--
--* Processor Time:: Measures processor time used by a program.
--* Calendar Time:: Manipulation of "real" dates and times.
--* Precision Time:: Manipulation and monitoring of high accuracy
-- time.
--* Setting an Alarm:: Sending a signal after a specified time.
--* Sleeping:: Waiting for a period of time.
--* Resource Usage:: Measuring various resources used.
--* Limits on Resources:: Specifying limits on resource usage.
--* Priority:: Reading or setting process run priority.
--
--
--File: libc.info, Node: Processor Time, Next: Calendar Time, Up: Date and Time
--
--Processor Time
--==============
--
-- If you're trying to optimize your program or measure its efficiency,
--it's very useful to be able to know how much "processor time" or "CPU
--time" it has used at any given point. Processor time is different from
--actual wall clock time because it doesn't include any time spent waiting
--for I/O or when some other process is running. Processor time is
--represented by the data type `clock_t', and is given as a number of
--"clock ticks" relative to an arbitrary base time marking the beginning
--of a single program invocation.
--
--* Menu:
--
--* Basic CPU Time:: The `clock' function.
--* Detailed CPU Time:: The `times' function.
--
--
--File: libc.info, Node: Basic CPU Time, Next: Detailed CPU Time, Up: Processor Time
--
--Basic CPU Time Inquiry
------------------------
--
-- To get the elapsed CPU time used by a process, you can use the
--`clock' function. This facility is declared in the header file
--`time.h'.
--
-- In typical usage, you call the `clock' function at the beginning and
--end of the interval you want to time, subtract the values, and then
--divide by `CLOCKS_PER_SEC' (the number of clock ticks per second), like
--this:
--
-- #include <time.h>
--
-- clock_t start, end;
-- double elapsed;
--
-- start = clock();
-- ... /* Do the work. */
-- end = clock();
-- elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
--
-- Different computers and operating systems vary wildly in how they
--keep track of processor time. It's common for the internal processor
--clock to have a resolution somewhere between hundredth and millionth of
--a second.
--
-- In the GNU system, `clock_t' is equivalent to `long int' and
--`CLOCKS_PER_SEC' is an integer value. But in other systems, both
--`clock_t' and the type of the macro `CLOCKS_PER_SEC' can be either
--integer or floating-point types. Casting processor time values to
--`double', as in the example above, makes sure that operations such as
--arithmetic and printing work properly and consistently no matter what
--the underlying representation is.
--
-- Note that the clock can wrap around. On a 32bit system with
--`CLOCKS_PER_SEC' set to one million a wrap around happens after around
--36 minutes.
--
-- - Macro: int CLOCKS_PER_SEC
-- The value of this macro is the number of clock ticks per second
-- measured by the `clock' function. POSIX requires that this value
-- is one million independend of the actual resolution.
--
-- - Macro: int CLK_TCK
-- This is an obsolete name for `CLOCKS_PER_SEC'.
--
-- - Data Type: clock_t
-- This is the type of the value returned by the `clock' function.
-- Values of type `clock_t' are in units of clock ticks.
--
-- - Function: clock_t clock (void)
-- This function returns the elapsed processor time. The base time is
-- arbitrary but doesn't change within a single process. If the
-- processor time is not available or cannot be represented, `clock'
-- returns the value `(clock_t)(-1)'.
--
--
--File: libc.info, Node: Detailed CPU Time, Prev: Basic CPU Time, Up: Processor Time
--
--Detailed Elapsed CPU Time Inquiry
-----------------------------------
--
-- The `times' function returns more detailed information about elapsed
--processor time in a `struct tms' object. You should include the header
--file `sys/times.h' to use this facility.
--
-- - Data Type: struct tms
-- The `tms' structure is used to return information about process
-- times. It contains at least the following members:
--
-- `clock_t tms_utime'
-- This is the CPU time used in executing the instructions of
-- the calling process.
--
-- `clock_t tms_stime'
-- This is the CPU time used by the system on behalf of the
-- calling process.
--
-- `clock_t tms_cutime'
-- This is the sum of the `tms_utime' values and the `tms_cutime'
-- values of all terminated child processes of the calling
-- process, whose status has been reported to the parent process
-- by `wait' or `waitpid'; see *Note Process Completion::. In
-- other words, it represents the total CPU time used in
-- executing the instructions of all the terminated child
-- processes of the calling process, excluding child processes
-- which have not yet been reported by `wait' or `waitpid'.
--
-- `clock_t tms_cstime'
-- This is similar to `tms_cutime', but represents the total CPU
-- time used by the system on behalf of all the terminated child
-- processes of the calling process.
--
-- All of the times are given in clock ticks. These are absolute
-- values; in a newly created process, they are all zero. *Note
-- Creating a Process::.
--
-- - Function: clock_t times (struct tms *BUFFER)
-- The `times' function stores the processor time information for the
-- calling process in BUFFER.
--
-- The return value is the same as the value of `clock()': the elapsed
-- real time relative to an arbitrary base. The base is a constant
-- within a particular process, and typically represents the time
-- since system start-up. A value of `(clock_t)(-1)' is returned to
-- indicate failure.
--
-- *Portability Note:* The `clock' function described in *Note Basic
--CPU Time::, is specified by the ISO C standard. The `times' function
--is a feature of POSIX.1. In the GNU system, the value returned by the
--`clock' function is equivalent to the sum of the `tms_utime' and
--`tms_stime' fields returned by `times'.
--
--
--File: libc.info, Node: Calendar Time, Next: Precision Time, Prev: Processor Time, Up: Date and Time
--
--Calendar Time
--=============
--
-- This section describes facilities for keeping track of dates and
--times according to the Gregorian calendar.
--
-- There are three representations for date and time information:
--
-- * "Calendar time" (the `time_t' data type) is a compact
-- representation, typically giving the number of seconds elapsed
-- since some implementation-specific base time.
--
-- * There is also a "high-resolution time" representation (the `struct
-- timeval' data type) that includes fractions of a second. Use this
-- time representation instead of ordinary calendar time when you
-- need greater precision.
--
-- * "Local time" or "broken-down time" (the `struct tm' data type)
-- represents the date and time as a set of components specifying the
-- year, month, and so on, for a specific time zone. This time
-- representation is usually used in conjunction with formatting date
-- and time values.
--
--* Menu:
--
--* Simple Calendar Time:: Facilities for manipulating calendar time.
--* High-Resolution Calendar:: A time representation with greater precision.
--* Broken-down Time:: Facilities for manipulating local time.
--* Formatting Date and Time:: Converting times to strings.
--* Parsing Date and Time:: Convert textual time and date information back
-- into broken-down time values.
--* TZ Variable:: How users specify the time zone.
--* Time Zone Functions:: Functions to examine or specify the time zone.
--* Time Functions Example:: An example program showing use of some of
-- the time functions.
--
--
--File: libc.info, Node: Simple Calendar Time, Next: High-Resolution Calendar, Up: Calendar Time
--
--Simple Calendar Time
----------------------
--
-- This section describes the `time_t' data type for representing
--calendar time, and the functions which operate on calendar time objects.
--These facilities are declared in the header file `time.h'.
--
-- - Data Type: time_t
-- This is the data type used to represent calendar time. When
-- interpreted as an absolute time value, it represents the number of
-- seconds elapsed since 00:00:00 on January 1, 1970, Coordinated
-- Universal Time. (This date is sometimes referred to as the
-- "epoch".) POSIX requires that this count ignore leap seconds, but
-- on some hosts this count includes leap seconds if you set `TZ' to
-- certain values (*note TZ Variable::.).
--
-- In the GNU C library, `time_t' is equivalent to `long int'. In
-- other systems, `time_t' might be either an integer or
-- floating-point type.
--
-- - Function: double difftime (time_t TIME1, time_t TIME0)
-- The `difftime' function returns the number of seconds elapsed
-- between time TIME1 and time TIME0, as a value of type `double'.
-- The difference ignores leap seconds unless leap second support is
-- enabled.
--
-- In the GNU system, you can simply subtract `time_t' values. But on
-- other systems, the `time_t' data type might use some other encoding
-- where subtraction doesn't work directly.
--
-- - Function: time_t time (time_t *RESULT)
-- The `time' function returns the current time as a value of type
-- `time_t'. If the argument RESULT is not a null pointer, the time
-- value is also stored in `*RESULT'. If the calendar time is not
-- available, the value `(time_t)(-1)' is returned.
--
--
--File: libc.info, Node: High-Resolution Calendar, Next: Broken-down Time, Prev: Simple Calendar Time, Up: Calendar Time
--
--High-Resolution Calendar
--------------------------
--
-- The `time_t' data type used to represent calendar times has a
--resolution of only one second. Some applications need more precision.
--
-- So, the GNU C library also contains functions which are capable of
--representing calendar times to a higher resolution than one second. The
--functions and the associated data types described in this section are
--declared in `sys/time.h'.
--
-- - Data Type: struct timeval
-- The `struct timeval' structure represents a calendar time. It has
-- the following members:
--
-- `long int tv_sec'
-- This represents the number of seconds since the epoch. It is
-- equivalent to a normal `time_t' value.
--
-- `long int tv_usec'
-- This is the fractional second value, represented as the
-- number of microseconds.
--
-- Some times struct timeval values are used for time intervals.
-- Then the `tv_sec' member is the number of seconds in the
-- interval, and `tv_usec' is the number of additional
-- microseconds.
--
-- - Data Type: struct timezone
-- The `struct timezone' structure is used to hold minimal information
-- about the local time zone. It has the following members:
--
-- `int tz_minuteswest'
-- This is the number of minutes west of UTC.
--
-- `int tz_dsttime'
-- If nonzero, daylight saving time applies during some part of
-- the year.
--
-- The `struct timezone' type is obsolete and should never be used.
-- Instead, use the facilities described in *Note Time Zone
-- Functions::.
--
-- It is often necessary to subtract two values of type
--`struct timeval'. Here is the best way to do this. It works even on
--some peculiar operating systems where the `tv_sec' member has an
--unsigned type.
--
-- /* Subtract the `struct timeval' values X and Y,
-- storing the result in RESULT.
-- Return 1 if the difference is negative, otherwise 0. */
--
-- int
-- timeval_subtract (result, x, y)
-- struct timeval *result, *x, *y;
-- {
-- /* Perform the carry for the later subtraction by updating Y. */
-- if (x->tv_usec < y->tv_usec) {
-- int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
-- y->tv_usec -= 1000000 * nsec;
-- y->tv_sec += nsec;
-- }
-- if (x->tv_usec - y->tv_usec > 1000000) {
-- int nsec = (x->tv_usec - y->tv_usec) / 1000000;
-- y->tv_usec += 1000000 * nsec;
-- y->tv_sec -= nsec;
-- }
--
-- /* Compute the time remaining to wait.
-- `tv_usec' is certainly positive. */
-- result->tv_sec = x->tv_sec - y->tv_sec;
-- result->tv_usec = x->tv_usec - y->tv_usec;
--
-- /* Return 1 if result is negative. */
-- return x->tv_sec < y->tv_sec;
-- }
--
-- - Function: int gettimeofday (struct timeval *TP, struct timezone *TZP)
-- The `gettimeofday' function returns the current date and time in
-- the `struct timeval' structure indicated by TP. Information about
-- the time zone is returned in the structure pointed at TZP. If the
-- TZP argument is a null pointer, time zone information is ignored.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error condition is defined for this function:
--
-- `ENOSYS'
-- The operating system does not support getting time zone
-- information, and TZP is not a null pointer. The GNU
-- operating system does not support using `struct timezone' to
-- represent time zone information; that is an obsolete feature
-- of 4.3 BSD. Instead, use the facilities described in *Note
-- Time Zone Functions::.
--
-- - Function: int settimeofday (const struct timeval *TP, const struct
-- timezone *TZP)
-- The `settimeofday' function sets the current date and time
-- according to the arguments. As for `gettimeofday', time zone
-- information is ignored if TZP is a null pointer.
--
-- You must be a privileged user in order to use `settimeofday'.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error conditions are defined for this function:
--
-- `EPERM'
-- This process cannot set the time because it is not privileged.
--
-- `ENOSYS'
-- The operating system does not support setting time zone
-- information, and TZP is not a null pointer.
--
-- - Function: int adjtime (const struct timeval *DELTA, struct timeval
-- *OLDDELTA)
-- This function speeds up or slows down the system clock in order to
-- make gradual adjustments in the current time. This ensures that
-- the time reported by the system clock is always monotonically
-- increasing, which might not happen if you simply set the current
-- time.
--
-- The DELTA argument specifies a relative adjustment to be made to
-- the current time. If negative, the system clock is slowed down
-- for a while until it has lost this much time. If positive, the
-- system clock is speeded up for a while.
--
-- If the OLDDELTA argument is not a null pointer, the `adjtime'
-- function returns information about any previous time adjustment
-- that has not yet completed.
--
-- This function is typically used to synchronize the clocks of
-- computers in a local network. You must be a privileged user to
-- use it. The return value is `0' on success and `-1' on failure.
-- The following `errno' error condition is defined for this function:
--
-- `EPERM'
-- You do not have privilege to set the time.
--
-- *Portability Note:* The `gettimeofday', `settimeofday', and
--`adjtime' functions are derived from BSD.
--
--
--File: libc.info, Node: Broken-down Time, Next: Formatting Date and Time, Prev: High-Resolution Calendar, Up: Calendar Time
--
--Broken-down Time
------------------
--
-- Calendar time is represented as a number of seconds. This is
--convenient for calculation, but has no resemblance to the way people
--normally represent dates and times. By contrast, "broken-down time" is
--a binary representation separated into year, month, day, and so on.
--Broken down time values are not useful for calculations, but they are
--useful for printing human readable time.
--
-- A broken-down time value is always relative to a choice of local time
--zone, and it also indicates which time zone was used.
--
-- The symbols in this section are declared in the header file `time.h'.
--
-- - Data Type: struct tm
-- This is the data type used to represent a broken-down time. The
-- structure contains at least the following members, which can
-- appear in any order:
--
-- `int tm_sec'
-- This is the number of seconds after the minute, normally in
-- the range `0' through `59'. (The actual upper limit is `60',
-- to allow for leap seconds if leap second support is
-- available.)
--
-- `int tm_min'
-- This is the number of minutes after the hour, in the range
-- `0' through `59'.
--
-- `int tm_hour'
-- This is the number of hours past midnight, in the range `0'
-- through `23'.
--
-- `int tm_mday'
-- This is the day of the month, in the range `1' through `31'.
--
-- `int tm_mon'
-- This is the number of months since January, in the range `0'
-- through `11'.
--
-- `int tm_year'
-- This is the number of years since `1900'.
--
-- `int tm_wday'
-- This is the number of days since Sunday, in the range `0'
-- through `6'.
--
-- `int tm_yday'
-- This is the number of days since January 1, in the range `0'
-- through `365'.
--
-- `int tm_isdst'
-- This is a flag that indicates whether Daylight Saving Time is
-- (or was, or will be) in effect at the time described. The
-- value is positive if Daylight Saving Time is in effect, zero
-- if it is not, and negative if the information is not
-- available.
--
-- `long int tm_gmtoff'
-- This field describes the time zone that was used to compute
-- this broken-down time value, including any adjustment for
-- daylight saving; it is the number of seconds that you must
-- add to UTC to get local time. You can also think of this as
-- the number of seconds east of UTC. For example, for U.S.
-- Eastern Standard Time, the value is `-5*60*60'. The
-- `tm_gmtoff' field is derived from BSD and is a GNU library
-- extension; it is not visible in a strict ISO C environment.
--
-- `const char *tm_zone'
-- This field is the name for the time zone that was used to
-- compute this broken-down time value. Like `tm_gmtoff', this
-- field is a BSD and GNU extension, and is not visible in a
-- strict ISO C environment.
--
-- - Function: struct tm * localtime (const time_t *TIME)
-- The `localtime' function converts the calendar time pointed to by
-- TIME to broken-down time representation, expressed relative to the
-- user's specified time zone.
--
-- The return value is a pointer to a static broken-down time
-- structure, which might be overwritten by subsequent calls to
-- `ctime', `gmtime', or `localtime'. (But no other library function
-- overwrites the contents of this object.)
--
-- The return value is the null pointer if TIME cannot be represented
-- as a broken-down time; typically this is because the year cannot
-- fit into an `int'.
--
-- Calling `localtime' has one other effect: it sets the variable
-- `tzname' with information about the current time zone. *Note Time
-- Zone Functions::.
--
-- Using the `localtime' function is a big problem in multi-threaded
--programs. The result is returned in a static buffer and this is used in
--all threads. POSIX.1c introduced a varient of this function.
--
-- - Function: struct tm * localtime_r (const time_t *TIME, struct tm
-- *RESULTP)
-- The `localtime_r' function works just like the `localtime'
-- function. It takes a pointer to a variable containing the
-- calendar time and converts it to the broken-down time format.
--
-- But the result is not placed in a static buffer. Instead it is
-- placed in the object of type `struct tm' to which the parameter
-- RESULTP points.
--
-- If the conversion is successful the function returns a pointer to
-- the object the result was written into, i.e., it returns RESULTP.
--
-- - Function: struct tm * gmtime (const time_t *TIME)
-- This function is similar to `localtime', except that the
-- broken-down time is expressed as Coordinated Universal Time
-- (UTC)--that is, as Greenwich Mean Time (GMT)--rather than relative
-- to the local time zone.
--
-- Recall that calendar times are *always* expressed in coordinated
-- universal time.
--
-- As for the `localtime' function we have the problem that the result
--is placed in a static variable. POSIX.1c also provides a replacement
--for `gmtime'.
--
-- - Function: struct tm * gmtime_r (const time_t *TIME, struct tm
-- *RESULTP)
-- This function is similar to `localtime_r', except that it converts
-- just like `gmtime' the given time as Coordinated Universal Time.
--
-- If the conversion is successful the function returns a pointer to
-- the object the result was written into, i.e., it returns RESULTP.
--
-- - Function: time_t mktime (struct tm *BROKENTIME)
-- The `mktime' function is used to convert a broken-down time
-- structure to a calendar time representation. It also "normalizes"
-- the contents of the broken-down time structure, by filling in the
-- day of week and day of year based on the other date and time
-- components.
--
-- The `mktime' function ignores the specified contents of the
-- `tm_wday' and `tm_yday' members of the broken-down time structure.
-- It uses the values of the other components to compute the
-- calendar time; it's permissible for these components to have
-- unnormalized values outside of their normal ranges. The last
-- thing that `mktime' does is adjust the components of the BROKENTIME
-- structure (including the `tm_wday' and `tm_yday').
--
-- If the specified broken-down time cannot be represented as a
-- calendar time, `mktime' returns a value of `(time_t)(-1)' and does
-- not modify the contents of BROKENTIME.
--
-- Calling `mktime' also sets the variable `tzname' with information
-- about the current time zone. *Note Time Zone Functions::.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-3 glibc-2.1.3/manual/libc.info-3
---- ../glibc-2.1.3/manual/libc.info-3 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-3 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1292 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Error Codes, Next: Error Messages, Prev: Checking for Errors, Up: Error Reporting
--
--Error Codes
--===========
--
-- The error code macros are defined in the header file `errno.h'. All
--of them expand into integer constant values. Some of these error codes
--can't occur on the GNU system, but they can occur using the GNU library
--on other systems.
--
-- - Macro: int EPERM
-- Operation not permitted; only the owner of the file (or other
-- resource) or processes with special privileges can perform the
-- operation.
--
-- - Macro: int ENOENT
-- No such file or directory. This is a "file doesn't exist" error
-- for ordinary files that are referenced in contexts where they are
-- expected to already exist.
--
-- - Macro: int ESRCH
-- No process matches the specified process ID.
--
-- - Macro: int EINTR
-- Interrupted function call; an asynchronous signal occurred and
-- prevented completion of the call. When this happens, you should
-- try the call again.
--
-- You can choose to have functions resume after a signal that is
-- handled, rather than failing with `EINTR'; see *Note Interrupted
-- Primitives::.
--
-- - Macro: int EIO
-- Input/output error; usually used for physical read or write errors.
--
-- - Macro: int ENXIO
-- No such device or address. The system tried to use the device
-- represented by a file you specified, and it couldn't find the
-- device. This can mean that the device file was installed
-- incorrectly, or that the physical device is missing or not
-- correctly attached to the computer.
--
-- - Macro: int E2BIG
-- Argument list too long; used when the arguments passed to a new
-- program being executed with one of the `exec' functions (*note
-- Executing a File::.) occupy too much memory space. This condition
-- never arises in the GNU system.
--
-- - Macro: int ENOEXEC
-- Invalid executable file format. This condition is detected by the
-- `exec' functions; see *Note Executing a File::.
--
-- - Macro: int EBADF
-- Bad file descriptor; for example, I/O on a descriptor that has been
-- closed or reading from a descriptor open only for writing (or vice
-- versa).
--
-- - Macro: int ECHILD
-- There are no child processes. This error happens on operations
-- that are supposed to manipulate child processes, when there aren't
-- any processes to manipulate.
--
-- - Macro: int EDEADLK
-- Deadlock avoided; allocating a system resource would have resulted
-- in a deadlock situation. The system does not guarantee that it
-- will notice all such situations. This error means you got lucky
-- and the system noticed; it might just hang. *Note File Locks::,
-- for an example.
--
-- - Macro: int ENOMEM
-- No memory available. The system cannot allocate more virtual
-- memory because its capacity is full.
--
-- - Macro: int EACCES
-- Permission denied; the file permissions do not allow the attempted
-- operation.
--
-- - Macro: int EFAULT
-- Bad address; an invalid pointer was detected. In the GNU system,
-- this error never happens; you get a signal instead.
--
-- - Macro: int ENOTBLK
-- A file that isn't a block special file was given in a situation
-- that requires one. For example, trying to mount an ordinary file
-- as a file system in Unix gives this error.
--
-- - Macro: int EBUSY
-- Resource busy; a system resource that can't be shared is already
-- in use. For example, if you try to delete a file that is the root
-- of a currently mounted filesystem, you get this error.
--
-- - Macro: int EEXIST
-- File exists; an existing file was specified in a context where it
-- only makes sense to specify a new file.
--
-- - Macro: int EXDEV
-- An attempt to make an improper link across file systems was
-- detected. This happens not only when you use `link' (*note Hard
-- Links::.) but also when you rename a file with `rename' (*note
-- Renaming Files::.).
--
-- - Macro: int ENODEV
-- The wrong type of device was given to a function that expects a
-- particular sort of device.
--
-- - Macro: int ENOTDIR
-- A file that isn't a directory was specified when a directory is
-- required.
--
-- - Macro: int EISDIR
-- File is a directory; you cannot open a directory for writing, or
-- create or remove hard links to it.
--
-- - Macro: int EINVAL
-- Invalid argument. This is used to indicate various kinds of
-- problems with passing the wrong argument to a library function.
--
-- - Macro: int EMFILE
-- The current process has too many files open and can't open any
-- more. Duplicate descriptors do count toward this limit.
--
-- In BSD and GNU, the number of open files is controlled by a
-- resource limit that can usually be increased. If you get this
-- error, you might want to increase the `RLIMIT_NOFILE' limit or
-- make it unlimited; *note Limits on Resources::..
--
-- - Macro: int ENFILE
-- There are too many distinct file openings in the entire system.
-- Note that any number of linked channels count as just one file
-- opening; see *Note Linked Channels::. This error never occurs in
-- the GNU system.
--
-- - Macro: int ENOTTY
-- Inappropriate I/O control operation, such as trying to set terminal
-- modes on an ordinary file.
--
-- - Macro: int ETXTBSY
-- An attempt to execute a file that is currently open for writing, or
-- write to a file that is currently being executed. Often using a
-- debugger to run a program is considered having it open for writing
-- and will cause this error. (The name stands for "text file
-- busy".) This is not an error in the GNU system; the text is
-- copied as necessary.
--
-- - Macro: int EFBIG
-- File too big; the size of a file would be larger than allowed by
-- the system.
--
-- - Macro: int ENOSPC
-- No space left on device; write operation on a file failed because
-- the disk is full.
--
-- - Macro: int ESPIPE
-- Invalid seek operation (such as on a pipe).
--
-- - Macro: int EROFS
-- An attempt was made to modify something on a read-only file system.
--
-- - Macro: int EMLINK
-- Too many links; the link count of a single file would become too
-- large. `rename' can cause this error if the file being renamed
-- already has as many links as it can take (*note Renaming Files::.).
--
-- - Macro: int EPIPE
-- Broken pipe; there is no process reading from the other end of a
-- pipe. Every library function that returns this error code also
-- generates a `SIGPIPE' signal; this signal terminates the program
-- if not handled or blocked. Thus, your program will never actually
-- see `EPIPE' unless it has handled or blocked `SIGPIPE'.
--
-- - Macro: int EDOM
-- Domain error; used by mathematical functions when an argument
-- value does not fall into the domain over which the function is
-- defined.
--
-- - Macro: int ERANGE
-- Range error; used by mathematical functions when the result value
-- is not representable because of overflow or underflow.
--
-- - Macro: int EAGAIN
-- Resource temporarily unavailable; the call might work if you try
-- again later. The macro `EWOULDBLOCK' is another name for `EAGAIN';
-- they are always the same in the GNU C library.
--
-- This error can happen in a few different situations:
--
-- * An operation that would block was attempted on an object that
-- has non-blocking mode selected. Trying the same operation
-- again will block until some external condition makes it
-- possible to read, write, or connect (whatever the operation).
-- You can use `select' to find out when the operation will be
-- possible; *note Waiting for I/O::..
--
-- *Portability Note:* In many older Unix systems, this condition
-- was indicated by `EWOULDBLOCK', which was a distinct error
-- code different from `EAGAIN'. To make your program portable,
-- you should check for both codes and treat them the same.
--
-- * A temporary resource shortage made an operation impossible.
-- `fork' can return this error. It indicates that the shortage
-- is expected to pass, so your program can try the call again
-- later and it may succeed. It is probably a good idea to
-- delay for a few seconds before trying it again, to allow time
-- for other processes to release scarce resources. Such
-- shortages are usually fairly serious and affect the whole
-- system, so usually an interactive program should report the
-- error to the user and return to its command loop.
--
-- - Macro: int EWOULDBLOCK
-- In the GNU C library, this is another name for `EAGAIN' (above).
-- The values are always the same, on every operating system.
--
-- C libraries in many older Unix systems have `EWOULDBLOCK' as a
-- separate error code.
--
-- - Macro: int EINPROGRESS
-- An operation that cannot complete immediately was initiated on an
-- object that has non-blocking mode selected. Some functions that
-- must always block (such as `connect'; *note Connecting::.) never
-- return `EAGAIN'. Instead, they return `EINPROGRESS' to indicate
-- that the operation has begun and will take some time. Attempts to
-- manipulate the object before the call completes return `EALREADY'.
-- You can use the `select' function to find out when the pending
-- operation has completed; *note Waiting for I/O::..
--
-- - Macro: int EALREADY
-- An operation is already in progress on an object that has
-- non-blocking mode selected.
--
-- - Macro: int ENOTSOCK
-- A file that isn't a socket was specified when a socket is required.
--
-- - Macro: int EMSGSIZE
-- The size of a message sent on a socket was larger than the
-- supported maximum size.
--
-- - Macro: int EPROTOTYPE
-- The socket type does not support the requested communications
-- protocol.
--
-- - Macro: int ENOPROTOOPT
-- You specified a socket option that doesn't make sense for the
-- particular protocol being used by the socket. *Note Socket
-- Options::.
--
-- - Macro: int EPROTONOSUPPORT
-- The socket domain does not support the requested communications
-- protocol (perhaps because the requested protocol is completely
-- invalid). *Note Creating a Socket::.
--
-- - Macro: int ESOCKTNOSUPPORT
-- The socket type is not supported.
--
-- - Macro: int EOPNOTSUPP
-- The operation you requested is not supported. Some socket
-- functions don't make sense for all types of sockets, and others
-- may not be implemented for all communications protocols. In the
-- GNU system, this error can happen for many calls when the object
-- does not support the particular operation; it is a generic
-- indication that the server knows nothing to do for that call.
--
-- - Macro: int EPFNOSUPPORT
-- The socket communications protocol family you requested is not
-- supported.
--
-- - Macro: int EAFNOSUPPORT
-- The address family specified for a socket is not supported; it is
-- inconsistent with the protocol being used on the socket. *Note
-- Sockets::.
--
-- - Macro: int EADDRINUSE
-- The requested socket address is already in use. *Note Socket
-- Addresses::.
--
-- - Macro: int EADDRNOTAVAIL
-- The requested socket address is not available; for example, you
-- tried to give a socket a name that doesn't match the local host
-- name. *Note Socket Addresses::.
--
-- - Macro: int ENETDOWN
-- A socket operation failed because the network was down.
--
-- - Macro: int ENETUNREACH
-- A socket operation failed because the subnet containing the remote
-- host was unreachable.
--
-- - Macro: int ENETRESET
-- A network connection was reset because the remote host crashed.
--
-- - Macro: int ECONNABORTED
-- A network connection was aborted locally.
--
-- - Macro: int ECONNRESET
-- A network connection was closed for reasons outside the control of
-- the local host, such as by the remote machine rebooting or an
-- unrecoverable protocol violation.
--
-- - Macro: int ENOBUFS
-- The kernel's buffers for I/O operations are all in use. In GNU,
-- this error is always synonymous with `ENOMEM'; you may get one or
-- the other from network operations.
--
-- - Macro: int EISCONN
-- You tried to connect a socket that is already connected. *Note
-- Connecting::.
--
-- - Macro: int ENOTCONN
-- The socket is not connected to anything. You get this error when
-- you try to transmit data over a socket, without first specifying a
-- destination for the data. For a connectionless socket (for
-- datagram protocols, such as UDP), you get `EDESTADDRREQ' instead.
--
-- - Macro: int EDESTADDRREQ
-- No default destination address was set for the socket. You get
-- this error when you try to transmit data over a connectionless
-- socket, without first specifying a destination for the data with
-- `connect'.
--
-- - Macro: int ESHUTDOWN
-- The socket has already been shut down.
--
-- - Macro: int ETOOMANYREFS
-- ???
--
-- - Macro: int ETIMEDOUT
-- A socket operation with a specified timeout received no response
-- during the timeout period.
--
-- - Macro: int ECONNREFUSED
-- A remote host refused to allow the network connection (typically
-- because it is not running the requested service).
--
-- - Macro: int ELOOP
-- Too many levels of symbolic links were encountered in looking up a
-- file name. This often indicates a cycle of symbolic links.
--
-- - Macro: int ENAMETOOLONG
-- Filename too long (longer than `PATH_MAX'; *note Limits for
-- Files::.) or host name too long (in `gethostname' or
-- `sethostname'; *note Host Identification::.).
--
-- - Macro: int EHOSTDOWN
-- The remote host for a requested network connection is down.
--
-- - Macro: int EHOSTUNREACH
-- The remote host for a requested network connection is not
-- reachable.
--
-- - Macro: int ENOTEMPTY
-- Directory not empty, where an empty directory was expected.
-- Typically, this error occurs when you are trying to delete a
-- directory.
--
-- - Macro: int EPROCLIM
-- This means that the per-user limit on new process would be
-- exceeded by an attempted `fork'. *Note Limits on Resources::, for
-- details on the `RLIMIT_NPROC' limit.
--
-- - Macro: int EUSERS
-- The file quota system is confused because there are too many users.
--
-- - Macro: int EDQUOT
-- The user's disk quota was exceeded.
--
-- - Macro: int ESTALE
-- Stale NFS file handle. This indicates an internal confusion in
-- the NFS system which is due to file system rearrangements on the
-- server host. Repairing this condition usually requires unmounting
-- and remounting the NFS file system on the local host.
--
-- - Macro: int EREMOTE
-- An attempt was made to NFS-mount a remote file system with a file
-- name that already specifies an NFS-mounted file. (This is an
-- error on some operating systems, but we expect it to work properly
-- on the GNU system, making this error code impossible.)
--
-- - Macro: int EBADRPC
-- ???
--
-- - Macro: int ERPCMISMATCH
-- ???
--
-- - Macro: int EPROGUNAVAIL
-- ???
--
-- - Macro: int EPROGMISMATCH
-- ???
--
-- - Macro: int EPROCUNAVAIL
-- ???
--
-- - Macro: int ENOLCK
-- No locks available. This is used by the file locking facilities;
-- see *Note File Locks::. This error is never generated by the GNU
-- system, but it can result from an operation to an NFS server
-- running another operating system.
--
-- - Macro: int EFTYPE
-- Inappropriate file type or format. The file was the wrong type
-- for the operation, or a data file had the wrong format.
--
-- On some systems `chmod' returns this error if you try to set the
-- sticky bit on a non-directory file; *note Setting Permissions::..
--
-- - Macro: int EAUTH
-- ???
--
-- - Macro: int ENEEDAUTH
-- ???
--
-- - Macro: int ENOSYS
-- Function not implemented. This indicates that the function called
-- is not implemented at all, either in the C library itself or in the
-- operating system. When you get this error, you can be sure that
-- this particular function will always fail with `ENOSYS' unless you
-- install a new version of the C library or the operating system.
--
-- - Macro: int ENOTSUP
-- Not supported. A function returns this error when certain
-- parameter values are valid, but the functionality they request is
-- not available. This can mean that the function does not implement
-- a particular command or option value or flag bit at all. For
-- functions that operate on some object given in a parameter, such
-- as a file descriptor or a port, it might instead mean that only
-- *that specific object* (file descriptor, port, etc.) is unable to
-- support the other parameters given; different file descriptors
-- might support different ranges of parameter values.
--
-- If the entire function is not available at all in the
-- implementation, it returns `ENOSYS' instead.
--
-- - Macro: int EILSEQ
-- While decoding a multibyte character the function came along an
-- invalid or an incomplete sequence of bytes or the given wide
-- character is invalid.
--
-- - Macro: int EBACKGROUND
-- In the GNU system, servers supporting the `term' protocol return
-- this error for certain operations when the caller is not in the
-- foreground process group of the terminal. Users do not usually
-- see this error because functions such as `read' and `write'
-- translate it into a `SIGTTIN' or `SIGTTOU' signal. *Note Job
-- Control::, for information on process groups and these signals.
--
-- - Macro: int EDIED
-- In the GNU system, opening a file returns this error when the file
-- is translated by a program and the translator program dies while
-- starting up, before it has connected to the file.
--
-- - Macro: int ED
-- The experienced user will know what is wrong.
--
-- - Macro: int EGREGIOUS
-- You did *what*?
--
-- - Macro: int EIEIO
-- Go home and have a glass of warm, dairy-fresh milk.
--
-- - Macro: int EGRATUITOUS
-- This error code has no purpose.
--
-- - Macro: int EBADMSG
--
-- - Macro: int EIDRM
--
-- - Macro: int EMULTIHOP
--
-- - Macro: int ENODATA
--
-- - Macro: int ENOLINK
--
-- - Macro: int ENOMSG
--
-- - Macro: int ENOSR
--
-- - Macro: int ENOSTR
--
-- - Macro: int EOVERFLOW
--
-- - Macro: int EPROTO
--
-- - Macro: int ETIME
--
-- *The following error codes are defined by the Linux/i386 kernel.
--They are not yet documented.*
--
-- - Macro: int ERESTART
--
-- - Macro: int ECHRNG
--
-- - Macro: int EL2NSYNC
--
-- - Macro: int EL3HLT
--
-- - Macro: int EL3RST
--
-- - Macro: int ELNRNG
--
-- - Macro: int EUNATCH
--
-- - Macro: int ENOCSI
--
-- - Macro: int EL2HLT
--
-- - Macro: int EBADE
--
-- - Macro: int EBADR
--
-- - Macro: int EXFULL
--
-- - Macro: int ENOANO
--
-- - Macro: int EBADRQC
--
-- - Macro: int EBADSLT
--
-- - Macro: int EDEADLOCK
--
-- - Macro: int EBFONT
--
-- - Macro: int ENONET
--
-- - Macro: int ENOPKG
--
-- - Macro: int EADV
--
-- - Macro: int ESRMNT
--
-- - Macro: int ECOMM
--
-- - Macro: int EDOTDOT
--
-- - Macro: int ENOTUNIQ
--
-- - Macro: int EBADFD
--
-- - Macro: int EREMCHG
--
-- - Macro: int ELIBACC
--
-- - Macro: int ELIBBAD
--
-- - Macro: int ELIBSCN
--
-- - Macro: int ELIBMAX
--
-- - Macro: int ELIBEXEC
--
-- - Macro: int ESTRPIPE
--
-- - Macro: int EUCLEAN
--
-- - Macro: int ENOTNAM
--
-- - Macro: int ENAVAIL
--
-- - Macro: int EISNAM
--
-- - Macro: int EREMOTEIO
--
-- - Macro: int ENOMEDIUM
--
-- - Macro: int EMEDIUMTYPE
--
--
--File: libc.info, Node: Error Messages, Prev: Error Codes, Up: Error Reporting
--
--Error Messages
--==============
--
-- The library has functions and variables designed to make it easy for
--your program to report informative error messages in the customary
--format about the failure of a library call. The functions `strerror'
--and `perror' give you the standard error message for a given error
--code; the variable `program_invocation_short_name' gives you convenient
--access to the name of the program that encountered the error.
--
-- - Function: char * strerror (int ERRNUM)
-- The `strerror' function maps the error code (*note Checking for
-- Errors::.) specified by the ERRNUM argument to a descriptive error
-- message string. The return value is a pointer to this string.
--
-- The value ERRNUM normally comes from the variable `errno'.
--
-- You should not modify the string returned by `strerror'. Also, if
-- you make subsequent calls to `strerror', the string might be
-- overwritten. (But it's guaranteed that no library function ever
-- calls `strerror' behind your back.)
--
-- The function `strerror' is declared in `string.h'.
--
-- - Function: char * strerror_r (int ERRNUM, char *BUF, size_t N)
-- The `strerror_r' function works like `strerror' but instead of
-- returning the error message in a statically allocated buffer
-- shared by all threads in the process, it returns a private copy
-- for the thread. This might be either some permanent global data or
-- a message string in the user supplied buffer starting at BUF with
-- the length of N bytes.
--
-- At most N characters are written (including the NUL byte) so it is
-- up to the user to select the buffer large enough.
--
-- This function should always be used in multi-threaded programs
-- since there is no way to guarantee the string returned by
-- `strerror' really belongs to the last call of the current thread.
--
-- This function `strerror_r' is a GNU extension and it is declared in
-- `string.h'.
--
-- - Function: void perror (const char *MESSAGE)
-- This function prints an error message to the stream `stderr'; see
-- *Note Standard Streams::.
--
-- If you call `perror' with a MESSAGE that is either a null pointer
-- or an empty string, `perror' just prints the error message
-- corresponding to `errno', adding a trailing newline.
--
-- If you supply a non-null MESSAGE argument, then `perror' prefixes
-- its output with this string. It adds a colon and a space
-- character to separate the MESSAGE from the error string
-- corresponding to `errno'.
--
-- The function `perror' is declared in `stdio.h'.
--
-- `strerror' and `perror' produce the exact same message for any given
--error code; the precise text varies from system to system. On the GNU
--system, the messages are fairly short; there are no multi-line messages
--or embedded newlines. Each error message begins with a capital letter
--and does not include any terminating punctuation.
--
-- *Compatibility Note:* The `strerror' function is a new feature of
--ISO C. Many older C systems do not support this function yet.
--
-- Many programs that don't read input from the terminal are designed to
--exit if any system call fails. By convention, the error message from
--such a program should start with the program's name, sans directories.
--You can find that name in the variable `program_invocation_short_name';
--the full file name is stored the variable `program_invocation_name':
--
-- - Variable: char * program_invocation_name
-- This variable's value is the name that was used to invoke the
-- program running in the current process. It is the same as
-- `argv[0]'. Note that this is not necessarily a useful file name;
-- often it contains no directory names. *Note Program Arguments::.
--
-- - Variable: char * program_invocation_short_name
-- This variable's value is the name that was used to invoke the
-- program running in the current process, with directory names
-- removed. (That is to say, it is the same as
-- `program_invocation_name' minus everything up to the last slash,
-- if any.)
--
-- The library initialization code sets up both of these variables
--before calling `main'.
--
-- *Portability Note:* These two variables are GNU extensions. If you
--want your program to work with non-GNU libraries, you must save the
--value of `argv[0]' in `main', and then strip off the directory names
--yourself. We added these extensions to make it possible to write
--self-contained error-reporting subroutines that require no explicit
--cooperation from `main'.
--
-- Here is an example showing how to handle failure to open a file
--correctly. The function `open_sesame' tries to open the named file for
--reading and returns a stream if successful. The `fopen' library
--function returns a null pointer if it couldn't open the file for some
--reason. In that situation, `open_sesame' constructs an appropriate
--error message using the `strerror' function, and terminates the
--program. If we were going to make some other library calls before
--passing the error code to `strerror', we'd have to save it in a local
--variable instead, because those other library functions might overwrite
--`errno' in the meantime.
--
-- #include <errno.h>
-- #include <stdio.h>
-- #include <stdlib.h>
-- #include <string.h>
--
-- FILE *
-- open_sesame (char *name)
-- {
-- FILE *stream;
--
-- errno = 0;
-- stream = fopen (name, "r");
-- if (stream == NULL)
-- {
-- fprintf (stderr, "%s: Couldn't open file %s; %s\n",
-- program_invocation_short_name, name, strerror (errno));
-- exit (EXIT_FAILURE);
-- }
-- else
-- return stream;
-- }
--
--
--File: libc.info, Node: Memory Allocation, Next: Character Handling, Prev: Error Reporting, Up: Top
--
--Memory Allocation
--*****************
--
-- The GNU system provides several methods for allocating memory space
--under explicit program control. They vary in generality and in
--efficiency.
--
--* Menu:
--
--* Memory Concepts:: An introduction to concepts and terminology.
--* Dynamic Allocation and C:: How to get different kinds of allocation in C.
--* Unconstrained Allocation:: The `malloc' facility allows fully general
-- dynamic allocation.
--* Allocation Debugging:: Finding memory leaks and not freed memory.
--* Obstacks:: Obstacks are less general than malloc
-- but more efficient and convenient.
--* Variable Size Automatic:: Allocation of variable-sized blocks
-- of automatic storage that are freed when the
-- calling function returns.
--
--
--File: libc.info, Node: Memory Concepts, Next: Dynamic Allocation and C, Up: Memory Allocation
--
--Dynamic Memory Allocation Concepts
--==================================
--
-- "Dynamic memory allocation" is a technique in which programs
--determine as they are running where to store some information. You need
--dynamic allocation when the number of memory blocks you need, or how
--long you continue to need them, depends on the data you are working on.
--
-- For example, you may need a block to store a line read from an input
--file; since there is no limit to how long a line can be, you must
--allocate the storage dynamically and make it dynamically larger as you
--read more of the line.
--
-- Or, you may need a block for each record or each definition in the
--input data; since you can't know in advance how many there will be, you
--must allocate a new block for each record or definition as you read it.
--
-- When you use dynamic allocation, the allocation of a block of memory
--is an action that the program requests explicitly. You call a function
--or macro when you want to allocate space, and specify the size with an
--argument. If you want to free the space, you do so by calling another
--function or macro. You can do these things whenever you want, as often
--as you want.
--
--
--File: libc.info, Node: Dynamic Allocation and C, Next: Unconstrained Allocation, Prev: Memory Concepts, Up: Memory Allocation
--
--Dynamic Allocation and C
--========================
--
-- The C language supports two kinds of memory allocation through the
--variables in C programs:
--
-- * "Static allocation" is what happens when you declare a static or
-- global variable. Each static or global variable defines one block
-- of space, of a fixed size. The space is allocated once, when your
-- program is started, and is never freed.
--
-- * "Automatic allocation" happens when you declare an automatic
-- variable, such as a function argument or a local variable. The
-- space for an automatic variable is allocated when the compound
-- statement containing the declaration is entered, and is freed when
-- that compound statement is exited.
--
-- In GNU C, the length of the automatic storage can be an expression
-- that varies. In other C implementations, it must be a constant.
--
-- Dynamic allocation is not supported by C variables; there is no
--storage class "dynamic", and there can never be a C variable whose
--value is stored in dynamically allocated space. The only way to refer
--to dynamically allocated space is through a pointer. Because it is less
--convenient, and because the actual process of dynamic allocation
--requires more computation time, programmers generally use dynamic
--allocation only when neither static nor automatic allocation will serve.
--
-- For example, if you want to allocate dynamically some space to hold a
--`struct foobar', you cannot declare a variable of type `struct foobar'
--whose contents are the dynamically allocated space. But you can
--declare a variable of pointer type `struct foobar *' and assign it the
--address of the space. Then you can use the operators `*' and `->' on
--this pointer variable to refer to the contents of the space:
--
-- {
-- struct foobar *ptr
-- = (struct foobar *) malloc (sizeof (struct foobar));
-- ptr->name = x;
-- ptr->next = current_foobar;
-- current_foobar = ptr;
-- }
--
--
--File: libc.info, Node: Unconstrained Allocation, Next: Allocation Debugging, Prev: Dynamic Allocation and C, Up: Memory Allocation
--
--Unconstrained Allocation
--========================
--
-- The most general dynamic allocation facility is `malloc'. It allows
--you to allocate blocks of memory of any size at any time, make them
--bigger or smaller at any time, and free the blocks individually at any
--time (or never).
--
--* Menu:
--
--* Basic Allocation:: Simple use of `malloc'.
--* Malloc Examples:: Examples of `malloc'. `xmalloc'.
--* Freeing after Malloc:: Use `free' to free a block you
-- got with `malloc'.
--* Changing Block Size:: Use `realloc' to make a block
-- bigger or smaller.
--* Allocating Cleared Space:: Use `calloc' to allocate a
-- block and clear it.
--* Efficiency and Malloc:: Efficiency considerations in use of
-- these functions.
--* Aligned Memory Blocks:: Allocating specially aligned memory:
-- `memalign' and `valloc'.
--* Malloc Tunable Parameters:: Use `mallopt' to adjust allocation
-- parameters.
--* Heap Consistency Checking:: Automatic checking for errors.
--* Hooks for Malloc:: You can use these hooks for debugging
-- programs that use `malloc'.
--* Statistics of Malloc:: Getting information about how much
-- memory your program is using.
--* Summary of Malloc:: Summary of `malloc' and related functions.
--
--
--File: libc.info, Node: Basic Allocation, Next: Malloc Examples, Up: Unconstrained Allocation
--
--Basic Storage Allocation
--------------------------
--
-- To allocate a block of memory, call `malloc'. The prototype for
--this function is in `stdlib.h'.
--
-- - Function: void * malloc (size_t SIZE)
-- This function returns a pointer to a newly allocated block SIZE
-- bytes long, or a null pointer if the block could not be allocated.
--
-- The contents of the block are undefined; you must initialize it
--yourself (or use `calloc' instead; *note Allocating Cleared Space::.).
--Normally you would cast the value as a pointer to the kind of object
--that you want to store in the block. Here we show an example of doing
--so, and of initializing the space with zeros using the library function
--`memset' (*note Copying and Concatenation::.):
--
-- struct foo *ptr;
-- ...
-- ptr = (struct foo *) malloc (sizeof (struct foo));
-- if (ptr == 0) abort ();
-- memset (ptr, 0, sizeof (struct foo));
--
-- You can store the result of `malloc' into any pointer variable
--without a cast, because ISO C automatically converts the type `void *'
--to another type of pointer when necessary. But the cast is necessary
--in contexts other than assignment operators or if you might want your
--code to run in traditional C.
--
-- Remember that when allocating space for a string, the argument to
--`malloc' must be one plus the length of the string. This is because a
--string is terminated with a null character that doesn't count in the
--"length" of the string but does need space. For example:
--
-- char *ptr;
-- ...
-- ptr = (char *) malloc (length + 1);
--
--*Note Representation of Strings::, for more information about this.
--
--
--File: libc.info, Node: Malloc Examples, Next: Freeing after Malloc, Prev: Basic Allocation, Up: Unconstrained Allocation
--
--Examples of `malloc'
----------------------
--
-- If no more space is available, `malloc' returns a null pointer. You
--should check the value of *every* call to `malloc'. It is useful to
--write a subroutine that calls `malloc' and reports an error if the
--value is a null pointer, returning only if the value is nonzero. This
--function is conventionally called `xmalloc'. Here it is:
--
-- void *
-- xmalloc (size_t size)
-- {
-- register void *value = malloc (size);
-- if (value == 0)
-- fatal ("virtual memory exhausted");
-- return value;
-- }
--
-- Here is a real example of using `malloc' (by way of `xmalloc'). The
--function `savestring' will copy a sequence of characters into a newly
--allocated null-terminated string:
--
-- char *
-- savestring (const char *ptr, size_t len)
-- {
-- register char *value = (char *) xmalloc (len + 1);
-- value[len] = '\0';
-- return (char *) memcpy (value, ptr, len);
-- }
--
-- The block that `malloc' gives you is guaranteed to be aligned so
--that it can hold any type of data. In the GNU system, the address is
--always a multiple of eight on most systems, and a multiple of 16 on
--64-bit systems. Only rarely is any higher boundary (such as a page
--boundary) necessary; for those cases, use `memalign' or `valloc' (*note
--Aligned Memory Blocks::.).
--
-- Note that the memory located after the end of the block is likely to
--be in use for something else; perhaps a block already allocated by
--another call to `malloc'. If you attempt to treat the block as longer
--than you asked for it to be, you are liable to destroy the data that
--`malloc' uses to keep track of its blocks, or you may destroy the
--contents of another block. If you have already allocated a block and
--discover you want it to be bigger, use `realloc' (*note Changing Block
--Size::.).
--
--
--File: libc.info, Node: Freeing after Malloc, Next: Changing Block Size, Prev: Malloc Examples, Up: Unconstrained Allocation
--
--Freeing Memory Allocated with `malloc'
----------------------------------------
--
-- When you no longer need a block that you got with `malloc', use the
--function `free' to make the block available to be allocated again. The
--prototype for this function is in `stdlib.h'.
--
-- - Function: void free (void *PTR)
-- The `free' function deallocates the block of storage pointed at by
-- PTR.
--
-- - Function: void cfree (void *PTR)
-- This function does the same thing as `free'. It's provided for
-- backward compatibility with SunOS; you should use `free' instead.
--
-- Freeing a block alters the contents of the block. *Do not expect to
--find any data (such as a pointer to the next block in a chain of
--blocks) in the block after freeing it.* Copy whatever you need out of
--the block before freeing it! Here is an example of the proper way to
--free all the blocks in a chain, and the strings that they point to:
--
-- struct chain
-- {
-- struct chain *next;
-- char *name;
-- }
--
-- void
-- free_chain (struct chain *chain)
-- {
-- while (chain != 0)
-- {
-- struct chain *next = chain->next;
-- free (chain->name);
-- free (chain);
-- chain = next;
-- }
-- }
--
-- Occasionally, `free' can actually return memory to the operating
--system and make the process smaller. Usually, all it can do is allow a
--later call to `malloc' to reuse the space. In the meantime, the space
--remains in your program as part of a free-list used internally by
--`malloc'.
--
-- There is no point in freeing blocks at the end of a program, because
--all of the program's space is given back to the system when the process
--terminates.
--
--
--File: libc.info, Node: Changing Block Size, Next: Allocating Cleared Space, Prev: Freeing after Malloc, Up: Unconstrained Allocation
--
--Changing the Size of a Block
------------------------------
--
-- Often you do not know for certain how big a block you will
--ultimately need at the time you must begin to use the block. For
--example, the block might be a buffer that you use to hold a line being
--read from a file; no matter how long you make the buffer initially, you
--may encounter a line that is longer.
--
-- You can make the block longer by calling `realloc'. This function
--is declared in `stdlib.h'.
--
-- - Function: void * realloc (void *PTR, size_t NEWSIZE)
-- The `realloc' function changes the size of the block whose address
-- is PTR to be NEWSIZE.
--
-- Since the space after the end of the block may be in use, `realloc'
-- may find it necessary to copy the block to a new address where
-- more free space is available. The value of `realloc' is the new
-- address of the block. If the block needs to be moved, `realloc'
-- copies the old contents.
--
-- If you pass a null pointer for PTR, `realloc' behaves just like
-- `malloc (NEWSIZE)'. This can be convenient, but beware that older
-- implementations (before ISO C) may not support this behavior, and
-- will probably crash when `realloc' is passed a null pointer.
--
-- Like `malloc', `realloc' may return a null pointer if no memory
--space is available to make the block bigger. When this happens, the
--original block is untouched; it has not been modified or relocated.
--
-- In most cases it makes no difference what happens to the original
--block when `realloc' fails, because the application program cannot
--continue when it is out of memory, and the only thing to do is to give
--a fatal error message. Often it is convenient to write and use a
--subroutine, conventionally called `xrealloc', that takes care of the
--error message as `xmalloc' does for `malloc':
--
-- void *
-- xrealloc (void *ptr, size_t size)
-- {
-- register void *value = realloc (ptr, size);
-- if (value == 0)
-- fatal ("Virtual memory exhausted");
-- return value;
-- }
--
-- You can also use `realloc' to make a block smaller. The reason you
--would do this is to avoid tying up a lot of memory space when only a
--little is needed. In several allocation implementations, making a
--block smaller sometimes necessitates copying it, so it can fail if no
--other space is available.
--
-- If the new size you specify is the same as the old size, `realloc'
--is guaranteed to change nothing and return the same address that you
--gave.
--
--
--File: libc.info, Node: Allocating Cleared Space, Next: Efficiency and Malloc, Prev: Changing Block Size, Up: Unconstrained Allocation
--
--Allocating Cleared Space
--------------------------
--
-- The function `calloc' allocates memory and clears it to zero. It is
--declared in `stdlib.h'.
--
-- - Function: void * calloc (size_t COUNT, size_t ELTSIZE)
-- This function allocates a block long enough to contain a vector of
-- COUNT elements, each of size ELTSIZE. Its contents are cleared to
-- zero before `calloc' returns.
--
-- You could define `calloc' as follows:
--
-- void *
-- calloc (size_t count, size_t eltsize)
-- {
-- size_t size = count * eltsize;
-- void *value = malloc (size);
-- if (value != 0)
-- memset (value, 0, size);
-- return value;
-- }
--
-- But in general, it is not guaranteed that `calloc' calls `malloc'
--internally. Therefore, if an application provides its own
--`malloc'/`realloc'/`free' outside the C library, it should always
--define `calloc', too.
--
--
--File: libc.info, Node: Efficiency and Malloc, Next: Aligned Memory Blocks, Prev: Allocating Cleared Space, Up: Unconstrained Allocation
--
--Efficiency Considerations for `malloc'
----------------------------------------
--
-- As apposed to other versions, the `malloc' in GNU libc does not
--round up block sizes to powers of two, neither for large nor for small
--sizes. Neighboring chunks can be coalesced on a `free' no matter what
--their size is. This makes the implementation suitable for all kinds of
--allocation patterns without generally incurring high memory waste
--through fragmentation.
--
-- Very large blocks (much larger than a page) are allocated with
--`mmap' (anonymous or via `/dev/zero') by this implementation. This has
--the great advantage that these chunks are returned to the system
--immediately when they are freed. Therefore, it cannot happen that a
--large chunk becomes "locked" in between smaller ones and even after
--calling `free' wastes memory. The size threshold for `mmap' to be used
--can be adjusted with `mallopt'. The use of `mmap' can also be disabled
--completely.
--
--
--File: libc.info, Node: Aligned Memory Blocks, Next: Malloc Tunable Parameters, Prev: Efficiency and Malloc, Up: Unconstrained Allocation
--
--Allocating Aligned Memory Blocks
----------------------------------
--
-- The address of a block returned by `malloc' or `realloc' in the GNU
--system is always a multiple of eight (or sixteen on 64-bit systems).
--If you need a block whose address is a multiple of a higher power of
--two than that, use `memalign' or `valloc'. These functions are
--declared in `stdlib.h'.
--
-- With the GNU library, you can use `free' to free the blocks that
--`memalign' and `valloc' return. That does not work in BSD,
--however--BSD does not provide any way to free such blocks.
--
-- - Function: void * memalign (size_t BOUNDARY, size_t SIZE)
-- The `memalign' function allocates a block of SIZE bytes whose
-- address is a multiple of BOUNDARY. The BOUNDARY must be a power
-- of two! The function `memalign' works by allocating a somewhat
-- larger block, and then returning an address within the block that
-- is on the specified boundary.
--
-- - Function: void * valloc (size_t SIZE)
-- Using `valloc' is like using `memalign' and passing the page size
-- as the value of the second argument. It is implemented like this:
--
-- void *
-- valloc (size_t size)
-- {
-- return memalign (getpagesize (), size);
-- }
--
--
--File: libc.info, Node: Malloc Tunable Parameters, Next: Heap Consistency Checking, Prev: Aligned Memory Blocks, Up: Unconstrained Allocation
--
--Malloc Tunable Parameters
---------------------------
--
-- You can adjust some parameters for dynamic memory allocation with the
--`mallopt' function. This function is the general SVID/XPG interface,
--defined in `malloc.h'.
--
-- - Function: int mallopt (int PARAM, int VALUE)
-- When calling `mallopt', the PARAM argument specifies the parameter
-- to be set, and VALUE the new value to be set. Possible choices
-- for PARAM, as defined in `malloc.h', are:
--
-- `M_TRIM_THRESHOLD'
-- This is the minimum size (in bytes) of the top-most,
-- releaseable chunk that will cause `sbrk' to be called with a
-- negative argument in order to return memory to the system.
--
-- `M_TOP_PAD'
-- This parameter determines the amount of extra memory to
-- obtain from the system when a call to `sbrk' is required. It
-- also specifies the number of bytes to retain when shrinking
-- the heap by calling `sbrk' with a negative argument. This
-- provides the necessary hysteresis in heap size such that
-- excessive amounts of system calls can be avoided.
--
-- `M_MMAP_THRESHOLD'
-- All chunks larger than this value are allocated outside the
-- normal heap, using the `mmap' system call. This way it is
-- guaranteed that the memory for these chunks can be returned
-- to the system on `free'.
--
-- `M_MMAP_MAX'
-- The maximum number of chunks to allocate with `mmap'.
-- Setting this to zero disables all use of `mmap'.
--
--
--
--File: libc.info, Node: Heap Consistency Checking, Next: Hooks for Malloc, Prev: Malloc Tunable Parameters, Up: Unconstrained Allocation
--
--Heap Consistency Checking
---------------------------
--
-- You can ask `malloc' to check the consistency of dynamic storage by
--using the `mcheck' function. This function is a GNU extension,
--declared in `mcheck.h'.
--
-- - Function: int mcheck (void (*ABORTFN) (enum mcheck_status STATUS))
-- Calling `mcheck' tells `malloc' to perform occasional consistency
-- checks. These will catch things such as writing past the end of a
-- block that was allocated with `malloc'.
--
-- The ABORTFN argument is the function to call when an inconsistency
-- is found. If you supply a null pointer, then `mcheck' uses a
-- default function which prints a message and calls `abort' (*note
-- Aborting a Program::.). The function you supply is called with
-- one argument, which says what sort of inconsistency was detected;
-- its type is described below.
--
-- It is too late to begin allocation checking once you have allocated
-- anything with `malloc'. So `mcheck' does nothing in that case.
-- The function returns `-1' if you call it too late, and `0'
-- otherwise (when it is successful).
--
-- The easiest way to arrange to call `mcheck' early enough is to use
-- the option `-lmcheck' when you link your program; then you don't
-- need to modify your program source at all. Alternately you might
-- use a debugger to insert a call to `mcheck' whenever the program is
-- started, for example these gdb commands will automatically call
-- `mcheck' whenever the program starts:
--
-- (gdb) break main
-- Breakpoint 1, main (argc=2, argv=0xbffff964) at whatever.c:10
-- (gdb) command 1
-- Type commands for when breakpoint 1 is hit, one per line.
-- End with a line saying just "end".
-- >call mcheck(0)
-- >continue
-- >end
-- (gdb) ...
--
-- This will however only work if no initialization function of any
-- object involved calls any of the `malloc' functions since `mcheck'
-- must be called before the first such function.
--
--
-- - Function: enum mcheck_status mprobe (void *POINTER)
-- The `mprobe' function lets you explicitly check for inconsistencies
-- in a particular allocated block. You must have already called
-- `mcheck' at the beginning of the program, to do its occasional
-- checks; calling `mprobe' requests an additional consistency check
-- to be done at the time of the call.
--
-- The argument POINTER must be a pointer returned by `malloc' or
-- `realloc'. `mprobe' returns a value that says what inconsistency,
-- if any, was found. The values are described below.
--
-- - Data Type: enum mcheck_status
-- This enumerated type describes what kind of inconsistency was
-- detected in an allocated block, if any. Here are the possible
-- values:
--
-- `MCHECK_DISABLED'
-- `mcheck' was not called before the first allocation. No
-- consistency checking can be done.
--
-- `MCHECK_OK'
-- No inconsistency detected.
--
-- `MCHECK_HEAD'
-- The data immediately before the block was modified. This
-- commonly happens when an array index or pointer is
-- decremented too far.
--
-- `MCHECK_TAIL'
-- The data immediately after the block was modified. This
-- commonly happens when an array index or pointer is
-- incremented too far.
--
-- `MCHECK_FREE'
-- The block was already freed.
--
-- Another possibility to check for and guard against bugs in the use of
--`malloc', `realloc' and `free' is to set the environment variable
--`MALLOC_CHECK_'. When `MALLOC_CHECK_' is set, a special (less
--efficient) implementation is used which is designed to be tolerant
--against simple errors, such as double calls of `free' with the same
--argument, or overruns of a single byte (off-by-one bugs). Not all such
--errors can be proteced against, however, and memory leaks can result.
--If `MALLOC_CHECK_' is set to `0', any detected heap corruption is
--silently ignored; if set to `1', a diagnostic is printed on `stderr';
--if set to `2', `abort' is called immediately. This can be useful
--because otherwise a crash may happen much later, and the true cause for
--the problem is then very hard to track down.
--
-- So, what's the difference between using `MALLOC_CHECK_' and linking
--with `-lmcheck'? `MALLOC_CHECK_' is orthognal with respect to
--`-lmcheck'. `-lmcheck' has been added for backward compatibility.
--Both `MALLOC_CHECK_' and `-lmcheck' should uncover the same bugs - but
--using `MALLOC_CHECK_' you don't need to recompile your application.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-30 glibc-2.1.3/manual/libc.info-30
---- ../glibc-2.1.3/manual/libc.info-30 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-30 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1213 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Formatting Date and Time, Next: Parsing Date and Time, Prev: Broken-down Time, Up: Calendar Time
--
--Formatting Date and Time
--------------------------
--
-- The functions described in this section format time values as
--strings. These functions are declared in the header file `time.h'.
--
-- - Function: char * asctime (const struct tm *BROKENTIME)
-- The `asctime' function converts the broken-down time value that
-- BROKENTIME points to into a string in a standard format:
--
-- "Tue May 21 13:46:22 1991\n"
--
-- The abbreviations for the days of week are: `Sun', `Mon', `Tue',
-- `Wed', `Thu', `Fri', and `Sat'.
--
-- The abbreviations for the months are: `Jan', `Feb', `Mar', `Apr',
-- `May', `Jun', `Jul', `Aug', `Sep', `Oct', `Nov', and `Dec'.
--
-- The return value points to a statically allocated string, which
-- might be overwritten by subsequent calls to `asctime' or `ctime'.
-- (But no other library function overwrites the contents of this
-- string.)
--
-- - Function: char * asctime_r (const struct tm *BROKENTIME, char
-- *BUFFER)
-- This function is similar to `asctime' but instead of placing the
-- result in a static buffer it writes the string in the buffer
-- pointed to by the parameter BUFFER. This buffer should have at
-- least room for 16 bytes.
--
-- If no error occurred the function returns a pointer to the string
-- the result was written into, i.e., it returns BUFFER. Otherwise
-- return `NULL'.
--
-- - Function: char * ctime (const time_t *TIME)
-- The `ctime' function is similar to `asctime', except that the time
-- value is specified as a `time_t' calendar time value rather than
-- in broken-down local time format. It is equivalent to
--
-- asctime (localtime (TIME))
--
-- `ctime' sets the variable `tzname', because `localtime' does so.
-- *Note Time Zone Functions::.
--
-- - Function: char * ctime_r (const time_t *TIME, char *BUFFER)
-- This function is similar to `ctime', only that it places the result
-- in the string pointed to by BUFFER. It is equivalent to (written
-- using gcc extensions, *note Statement Exprs: (gcc)Statement
-- Exprs.):
--
-- ({ struct tm tm; asctime_r (localtime_r (time, &tm), buf); })
--
-- If no error occurred the function returns a pointer to the string
-- the result was written into, i.e., it returns BUFFER. Otherwise
-- return `NULL'.
--
-- - Function: size_t strftime (char *S, size_t SIZE, const char
-- *TEMPLATE, const struct tm *BROKENTIME)
-- This function is similar to the `sprintf' function (*note
-- Formatted Input::.), but the conversion specifications that can
-- appear in the format template TEMPLATE are specialized for
-- printing components of the date and time BROKENTIME according to
-- the locale currently specified for time conversion (*note
-- Locales::.).
--
-- Ordinary characters appearing in the TEMPLATE are copied to the
-- output string S; this can include multibyte character sequences.
-- Conversion specifiers are introduced by a `%' character, followed
-- by an optional flag which can be one of the following. These flags
-- are all GNU extensions. The first three affect only the output of
-- numbers:
--
-- `_'
-- The number is padded with spaces.
--
-- `-'
-- The number is not padded at all.
--
-- `0'
-- The number is padded with zeros even if the format specifies
-- padding with spaces.
--
-- `^'
-- The output uses uppercase characters, but only if this is
-- possible (*note Case Conversion::.).
--
-- The default action is to pad the number with zeros to keep it a
-- constant width. Numbers that do not have a range indicated below
-- are never padded, since there is no natural width for them.
--
-- Following the flag an optional specification of the width is
-- possible. This is specified in decimal notation. If the natural
-- size of the output is of the field has less than the specified
-- number of characters, the result is written right adjusted and
-- space padded to the given size.
--
-- An optional modifier can follow the optional flag and width
-- specification. The modifiers, which are POSIX.2 extensions, are:
--
-- `E'
-- Use the locale's alternate representation for date and time.
-- This modifier applies to the `%c', `%C', `%x', `%X', `%y' and
-- `%Y' format specifiers. In a Japanese locale, for example,
-- `%Ex' might yield a date format based on the Japanese
-- Emperors' reigns.
--
-- `O'
-- Use the locale's alternate numeric symbols for numbers. This
-- modifier applies only to numeric format specifiers.
--
-- If the format supports the modifier but no alternate representation
-- is available, it is ignored.
--
-- The conversion specifier ends with a format specifier taken from
-- the following list. The whole `%' sequence is replaced in the
-- output string as follows:
--
-- `%a'
-- The abbreviated weekday name according to the current locale.
--
-- `%A'
-- The full weekday name according to the current locale.
--
-- `%b'
-- The abbreviated month name according to the current locale.
--
-- `%B'
-- The full month name according to the current locale.
--
-- `%c'
-- The preferred date and time representation for the current
-- locale.
--
-- `%C'
-- The century of the year. This is equivalent to the greatest
-- integer not greater than the year divided by 100.
--
-- This format is a POSIX.2 extension.
--
-- `%d'
-- The day of the month as a decimal number (range `01' through
-- `31').
--
-- `%D'
-- The date using the format `%m/%d/%y'.
--
-- This format is a POSIX.2 extension.
--
-- `%e'
-- The day of the month like with `%d', but padded with blank
-- (range ` 1' through `31').
--
-- This format is a POSIX.2 extension.
--
-- `%F'
-- The date using the format `%Y-%m-%d'. This is the form
-- specified in the ISO 8601 standard and is the preferred form
-- for all uses.
--
-- This format is a ISO C 9X extension.
--
-- `%g'
-- The year corresponding to the ISO week number, but without
-- the century (range `00' through `99'). This has the same
-- format and value as `%y', except that if the ISO week number
-- (see `%V') belongs to the previous or next year, that year is
-- used instead.
--
-- This format is a GNU extension.
--
-- `%G'
-- The year corresponding to the ISO week number. This has the
-- same format and value as `%Y', except that if the ISO week
-- number (see `%V') belongs to the previous or next year, that
-- year is used instead.
--
-- This format is a GNU extension.
--
-- `%h'
-- The abbreviated month name according to the current locale.
-- The action is the same as for `%b'.
--
-- This format is a POSIX.2 extension.
--
-- `%H'
-- The hour as a decimal number, using a 24-hour clock (range
-- `00' through `23').
--
-- `%I'
-- The hour as a decimal number, using a 12-hour clock (range
-- `01' through `12').
--
-- `%j'
-- The day of the year as a decimal number (range `001' through
-- `366').
--
-- `%k'
-- The hour as a decimal number, using a 24-hour clock like
-- `%H', but padded with blank (range ` 0' through `23').
--
-- This format is a GNU extension.
--
-- `%l'
-- The hour as a decimal number, using a 12-hour clock like
-- `%I', but padded with blank (range ` 1' through `12').
--
-- This format is a GNU extension.
--
-- `%m'
-- The month as a decimal number (range `01' through `12').
--
-- `%M'
-- The minute as a decimal number (range `00' through `59').
--
-- `%n'
-- A single `\n' (newline) character.
--
-- This format is a POSIX.2 extension.
--
-- `%p'
-- Either `AM' or `PM', according to the given time value; or the
-- corresponding strings for the current locale. Noon is
-- treated as `PM' and midnight as `AM'.
--
-- `%P'
-- Either `am' or `pm', according to the given time value; or the
-- corresponding strings for the current locale, printed in
-- lowercase characters. Noon is treated as `pm' and midnight
-- as `am'.
--
-- This format is a GNU extension.
--
-- `%r'
-- The complete time using the AM/PM format of the current
-- locale.
--
-- This format is a POSIX.2 extension.
--
-- `%R'
-- The hour and minute in decimal numbers using the format
-- `%H:%M'.
--
-- This format is a GNU extension.
--
-- `%s'
-- The number of seconds since the epoch, i.e., since 1970-01-01
-- 00:00:00 UTC. Leap seconds are not counted unless leap
-- second support is available.
--
-- This format is a GNU extension.
--
-- `%S'
-- The seconds as a decimal number (range `00' through `60').
--
-- `%t'
-- A single `\t' (tabulator) character.
--
-- This format is a POSIX.2 extension.
--
-- `%T'
-- The time using decimal numbers using the format `%H:%M:%S'.
--
-- This format is a POSIX.2 extension.
--
-- `%u'
-- The day of the week as a decimal number (range `1' through
-- `7'), Monday being `1'.
--
-- This format is a POSIX.2 extension.
--
-- `%U'
-- The week number of the current year as a decimal number
-- (range `00' through `53'), starting with the first Sunday as
-- the first day of the first week. Days preceding the first
-- Sunday in the year are considered to be in week `00'.
--
-- `%V'
-- The ISO 8601:1988 week number as a decimal number (range `01'
-- through `53'). ISO weeks start with Monday and end with
-- Sunday. Week `01' of a year is the first week which has the
-- majority of its days in that year; this is equivalent to the
-- week containing the year's first Thursday, and it is also
-- equivalent to the week containing January 4. Week `01' of a
-- year can contain days from the previous year. The week
-- before week `01' of a year is the last week (`52' or `53') of
-- the previous year even if it contains days from the new year.
--
-- This format is a POSIX.2 extension.
--
-- `%w'
-- The day of the week as a decimal number (range `0' through
-- `6'), Sunday being `0'.
--
-- `%W'
-- The week number of the current year as a decimal number
-- (range `00' through `53'), starting with the first Monday as
-- the first day of the first week. All days preceding the
-- first Monday in the year are considered to be in week `00'.
--
-- `%x'
-- The preferred date representation for the current locale, but
-- without the time.
--
-- `%X'
-- The preferred time representation for the current locale, but
-- with no date.
--
-- `%y'
-- The year without a century as a decimal number (range `00'
-- through `99'). This is equivalent to the year modulo 100.
--
-- `%Y'
-- The year as a decimal number, using the Gregorian calendar.
-- Years before the year `1' are numbered `0', `-1', and so on.
--
-- `%z'
-- RFC 822/ISO 8601:1988 style numeric time zone (e.g., `-0600'
-- or `+0100'), or nothing if no time zone is determinable.
--
-- This format is a GNU extension.
--
-- A full RFC 822 timestamp is generated by the format
-- `"%a, %d %b %Y %H:%M:%S %z"' (or the equivalent
-- `"%a, %d %b %Y %T %z"').
--
-- `%Z'
-- The time zone abbreviation (empty if the time zone can't be
-- determined).
--
-- `%%'
-- A literal `%' character.
--
-- The SIZE parameter can be used to specify the maximum number of
-- characters to be stored in the array S, including the terminating
-- null character. If the formatted time requires more than SIZE
-- characters, `strftime' returns zero and the content of the array S
-- is indetermined. Otherwise the return value indicates the number
-- of characters placed in the array S, not including the terminating
-- null character.
--
-- *Warning:* This convention for the return value which is prescribed
-- in ISO C can lead to problems in some situations. For certain
-- format strings and certain locales the output really can be the
-- empty string and this cannot be discovered by testing the return
-- value only. E.g., in most locales the AM/PM time format is not
-- supported (most of the world uses the 24 hour time
-- representation). In such locales `"%p"' will return the empty
-- string, i.e., the return value is zero. To detect situations like
-- this something similar to the following code should be used:
--
-- buf[0] = '\1';
-- len = strftime (buf, bufsize, format, tp);
-- if (len == 0 && buf[0] != '\0')
-- {
-- /* Something went wrong in the strftime call. */
-- ...
-- }
--
-- If S is a null pointer, `strftime' does not actually write
-- anything, but instead returns the number of characters it would
-- have written.
--
-- According to POSIX.1 every call to `strftime' implies a call to
-- `tzset'. So the contents of the environment variable `TZ' is
-- examined before any output is produced.
--
-- For an example of `strftime', see *Note Time Functions Example::.
--
--
--File: libc.info, Node: Parsing Date and Time, Next: TZ Variable, Prev: Formatting Date and Time, Up: Calendar Time
--
--Convert textual time and date information back
------------------------------------------------
--
-- The ISO C standard does not specify any functions which can convert
--the output of the `strftime' function back into a binary format. This
--lead to variety of more or less successful implementations with
--different interfaces over the years. Then the Unix standard got
--extended by two functions: `strptime' and `getdate'. Both have kind of
--strange interfaces but at least they are widely available.
--
--* Menu:
--
--* Low-Level Time String Parsing:: Interpret string according to given format.
--* General Time String Parsing:: User-friendly function to parse data and
-- time strings.
--
--
--File: libc.info, Node: Low-Level Time String Parsing, Next: General Time String Parsing, Up: Parsing Date and Time
--
--Interpret string according to given format
--..........................................
--
-- The first function is a rather low-level interface. It is
--nevertheless frequently used in user programs since it is better known.
--Its implementation and the interface though is heavily influenced by
--the `getdate' function which is defined and implemented in terms of
--calls to `strptime'.
--
-- - Function: char * strptime (const char *S, const char *FMT, struct tm
-- *TP)
-- The `strptime' function parses the input string S according to the
-- format string FMT and stores the found values in the structure TP.
--
-- The input string can be retrieved in any way. It does not matter
-- whether it was generated by a `strftime' call or made up directly
-- by a program. It is also not necessary that the content is in any
-- human-recognizable format. I.e., it is OK if a date is written
-- like `"02:1999:9"' which is not understandable without context.
-- As long the format string FMT matches the format of the input
-- string everything goes.
--
-- The format string consists of the same components as the format
-- string for the `strftime' function. The only difference is that
-- the flags `_', `-', `0', and `^' are not allowed. Several of the
-- formats which `strftime' handled differently do the same work in
-- `strptime' since differences like case of the output do not
-- matter. For symmetry reasons all formats are supported, though.
--
-- The modifiers `E' and `O' are also allowed everywhere the
-- `strftime' function allows them.
--
-- The formats are:
--
-- `%a'
-- `%A'
-- The weekday name according to the current locale, in
-- abbreviated form or the full name.
--
-- `%b'
-- `%B'
-- `%h'
-- The month name according to the current locale, in
-- abbreviated form or the full name.
--
-- `%c'
-- The date and time representation for the current locale.
--
-- `%Ec'
-- Like `%c' but the locale's alternative date and time format
-- is used.
--
-- `%C'
-- The century of the year.
--
-- It makes sense to use this format only if the format string
-- also contains the `%y' format.
--
-- `%EC'
-- The locale's representation of the period.
--
-- Unlike `%C' it makes sometimes sense to use this format since
-- in some cultures it is required to specify years relative to
-- periods instead of using the Gregorian years.
--
-- `%d'
--
-- `%e'
-- The day of the month as a decimal number (range `1' through
-- `31'). Leading zeroes are permitted but not required.
--
-- `%Od'
-- `%Oe'
-- Same as `%d' but the locale's alternative numeric symbols are
-- used.
--
-- Leading zeroes are permitted but not required.
--
-- `%D'
-- Equivalent to the use of `%m/%d/%y' in this place.
--
-- `%F'
-- Equivalent to the use of `%Y-%m-%d' which is the ISO 8601 date
-- format.
--
-- This is a GNU extension following an ISO C 9X extension to
-- `strftime'.
--
-- `%g'
-- The year corresponding to the ISO week number, but without
-- the century (range `00' through `99').
--
-- *Note:* This is not really implemented currently. The format
-- is recognized, input is consumed but no field in TM is set.
--
-- This format is a GNU extension following a GNU extension of
-- `strftime'.
--
-- `%G'
-- The year corresponding to the ISO week number.
--
-- *Note:* This is not really implemented currently. The format
-- is recognized, input is consumed but no field in TM is set.
--
-- This format is a GNU extension following a GNU extension of
-- `strftime'.
--
-- `%H'
-- `%k'
-- The hour as a decimal number, using a 24-hour clock (range
-- `00' through `23').
--
-- `%k' is a GNU extension following a GNU extension of
-- `strftime'.
--
-- `%OH'
-- Same as `%H' but using the locale's alternative numeric
-- symbols are used.
--
-- `%I'
-- `%l'
-- The hour as a decimal number, using a 12-hour clock (range
-- `01' through `12').
--
-- `%l' is a GNU extension following a GNU extension of
-- `strftime'.
--
-- `%OI'
-- Same as `%I' but using the locale's alternative numeric
-- symbols are used.
--
-- `%j'
-- The day of the year as a decimal number (range `1' through
-- `366').
--
-- Leading zeroes are permitted but not required.
--
-- `%m'
-- The month as a decimal number (range `1' through `12').
--
-- Leading zeroes are permitted but not required.
--
-- `%Om'
-- Same as `%m' but using the locale's alternative numeric
-- symbols are used.
--
-- `%M'
-- The minute as a decimal number (range `0' through `59').
--
-- Leading zeroes are permitted but not required.
--
-- `%OM'
-- Same as `%M' but using the locale's alternative numeric
-- symbols are used.
--
-- `%n'
-- `%t'
-- Matches any white space.
--
-- `%p'
--
-- `%P'
-- The locale-dependent equivalent to `AM' or `PM'.
--
-- This format is not useful unless `%I' or `%l' is also used.
-- Another complication is that the locale might not define
-- these values at all and therefore the conversion fails.
--
-- `%P' is a GNU extension following a GNU extension to
-- `strftime'.
--
-- `%r'
-- The complete time using the AM/PM format of the current
-- locale.
--
-- A complication is that the locale might not define this
-- format at all and therefore the conversion fails.
--
-- `%R'
-- The hour and minute in decimal numbers using the format
-- `%H:%M'.
--
-- `%R' is a GNU extension following a GNU extension to
-- `strftime'.
--
-- `%s'
-- The number of seconds since the epoch, i.e., since 1970-01-01
-- 00:00:00 UTC. Leap seconds are not counted unless leap
-- second support is available.
--
-- `%s' is a GNU extension following a GNU extension to
-- `strftime'.
--
-- `%S'
-- The seconds as a decimal number (range `0' through `61').
--
-- Leading zeroes are permitted but not required.
--
-- Please note the nonsense with `61' being allowed. This is
-- what the Unix specification says. They followed the stupid
-- decision once made to allow double leap seconds. These do
-- not exist but the myth persists.
--
-- `%OS'
-- Same as `%S' but using the locale's alternative numeric
-- symbols are used.
--
-- `%T'
-- Equivalent to the use of `%H:%M:%S' in this place.
--
-- `%u'
-- The day of the week as a decimal number (range `1' through
-- `7'), Monday being `1'.
--
-- Leading zeroes are permitted but not required.
--
-- *Note:* This is not really implemented currently. The format
-- is recognized, input is consumed but no field in TM is set.
--
-- `%U'
-- The week number of the current year as a decimal number
-- (range `0' through `53').
--
-- Leading zeroes are permitted but not required.
--
-- `%OU'
-- Same as `%U' but using the locale's alternative numeric
-- symbols are used.
--
-- `%V'
-- The ISO 8601:1988 week number as a decimal number (range `1'
-- through `53').
--
-- Leading zeroes are permitted but not required.
--
-- *Note:* This is not really implemented currently. The format
-- is recognized, input is consumed but no field in TM is set.
--
-- `%w'
-- The day of the week as a decimal number (range `0' through
-- `6'), Sunday being `0'.
--
-- Leading zeroes are permitted but not required.
--
-- *Note:* This is not really implemented currently. The format
-- is recognized, input is consumed but no field in TM is set.
--
-- `%Ow'
-- Same as `%w' but using the locale's alternative numeric
-- symbols are used.
--
-- `%W'
-- The week number of the current year as a decimal number
-- (range `0' through `53').
--
-- Leading zeroes are permitted but not required.
--
-- *Note:* This is not really implemented currently. The format
-- is recognized, input is consumed but no field in TM is set.
--
-- `%OW'
-- Same as `%W' but using the locale's alternative numeric
-- symbols are used.
--
-- `%x'
-- The date using the locale's date format.
--
-- `%Ex'
-- Like `%x' but the locale's alternative data representation is
-- used.
--
-- `%X'
-- The time using the locale's time format.
--
-- `%EX'
-- Like `%X' but the locale's alternative time representation is
-- used.
--
-- `%y'
-- The year without a century as a decimal number (range `0'
-- through `99').
--
-- Leading zeroes are permitted but not required.
--
-- Please note that it is at least questionable to use this
-- format without the `%C' format. The `strptime' function does
-- regard input values in the range 68 to 99 as the years 1969 to
-- 1999 and the values 0 to 68 as the years 2000 to 2068. But
-- maybe this heuristic fails for some input data.
--
-- Therefore it is best to avoid `%y' completely and use `%Y'
-- instead.
--
-- `%Ey'
-- The offset from `%EC' in the locale's alternative
-- representation.
--
-- `%Oy'
-- The offset of the year (from `%C') using the locale's
-- alternative numeric symbols.
--
-- `%Y'
-- The year as a decimal number, using the Gregorian calendar.
--
-- `%EY'
-- The full alternative year representation.
--
-- `%z'
-- Equivalent to the use of `%a, %d %b %Y %H:%M:%S %z' in this
-- place. This is the full ISO 8601 date and time format.
--
-- `%Z'
-- The timezone name.
--
-- *Note:* This is not really implemented currently. The format
-- is recognized, input is consumed but no field in TM is set.
--
-- `%%'
-- A literal `%' character.
--
-- All other characters in the format string must have a matching
-- character in the input string. Exceptions are white spaces in the
-- input string which can match zero or more white space characters
-- in the input string.
--
-- The `strptime' function processes the input string from right to
-- left. Each of the three possible input elements (white space,
-- literal, or format) are handled one after the other. If the input
-- cannot be matched to the format string the function stops. The
-- remainder of the format and input strings are not processed.
--
-- The return value of the function is a pointer to the first
-- character not processed in this function call. In case the input
-- string contains more characters than required by the format string
-- the return value points right after the last consumed input
-- character. In case the whole input string is consumed the return
-- value points to the NUL byte at the end of the string. If
-- `strptime' fails to match all of the format string and therefore
-- an error occurred the function returns `NULL'.
--
-- The specification of the function in the XPG standard is rather
--vague. It leaves out a few important pieces of information. Most
--important it does not specify what happens to those elements of TM
--which are not directly initialized by the different formats. Various
--implementations on different Unix systems vary here.
--
-- The GNU libc implementation does not touch those fields which are not
--directly initialized. Exceptions are the `tm_wday' and `tm_yday'
--elements which are recomputed if any of the year, month, or date
--elements changed. This has two implications:
--
-- * Before calling the `strptime' function for a new input string one
-- has to prepare the structure passed in as the TM. Normally this
-- will mean that all values are initialized to zero. Alternatively
-- one can use all fields to values like `INT_MAX' which allows to
-- determine which elements were set by the function call. Zero does
-- not work here since it is a valid value for many of the fields.
--
-- Careful initialization is necessary if one wants to find out
-- whether a certain field in TM was initialized by the function call.
--
-- * One can construct a `struct tm' value in several `strptime' calls
-- in a row. A useful application of this is for example the parsing
-- of two separate strings, one containing the date information, the
-- other the time information. By parsing both one after the other
-- without clearing the structure in between one can construct a
-- complete broken-down time.
--
-- The following example shows a function which parses a string which is
--supposed to contain the date information in either US style or ISO 8601
--form.
--
-- const char *
-- parse_date (const char *input, struct tm *tm)
-- {
-- const char *cp;
--
-- /* First clear the result structure. */
-- memset (tm, '\0', sizeof (*tm));
--
-- /* Try the ISO format first. */
-- cp = strptime (input, "%F", tm);
-- if (cp == NULL)
-- {
-- /* Does not match. Try the US form. */
-- cp = strptime (input, "%D", tm);
-- }
--
-- return cp;
-- }
--
--
--File: libc.info, Node: General Time String Parsing, Prev: Low-Level Time String Parsing, Up: Parsing Date and Time
--
--A user-friendlier way to parse times and dates
--..............................................
--
-- The Unix standard defines another function to parse date strings.
--The interface is, mildly said, weird. But if this function fits into
--the application to be written it is just fine. It is a problem when
--using this function in multi-threaded programs or in libraries since it
--returns a pointer to a static variable, uses a global variable, and a
--global state (an environment variable).
--
-- - Variable: getdate_err
-- This variable of type `int' will contain the error code of the last
-- unsuccessful call of the `getdate' function. Defined values are:
--
-- 1
-- The environment variable `DATEMSK' is not defined or null.
--
-- 2
-- The template file denoted by the `DATEMSK' environment
-- variable cannot be opened.
--
-- 3
-- Information about the template file cannot retrieved.
--
-- 4
-- The template file is no regular file.
--
-- 5
-- An I/O error occurred while reading the template file.
--
-- 6
-- Not enough memory available to execute the function.
--
-- 7
-- The template file contains no matching template.
--
-- 8
-- The input string is invalid for a template which would match
-- otherwise. This includes error like February 31st, or return
-- values which can be represented using `time_t'.
--
-- - Function: struct tm * getdate (const char *STRING)
-- The interface of the `getdate' function is the simplest possible
-- for a function to parse a string and return the value. STRING is
-- the input string and the result is passed to the user in a
-- statically allocated variable.
--
-- The details about how the string is processed is hidden from the
-- user. In fact, it can be outside the control of the program.
-- Which formats are recognized is controlled by the file named by
-- the environment variable `DATEMSK'. The content of the named file
-- should contain lines of valid format strings which could be passed
-- to `strptime'.
--
-- The `getdate' function reads these format strings one after the
-- other and tries to match the input string. The first line which
-- completely matches the input string is used.
--
-- Elements which were not initialized through the format string get
-- assigned the values of the time the `getdate' function is called.
--
-- The format elements recognized by `getdate' are the same as for
-- `strptime'. See above for an explanation. There are only a few
-- extension to the `strptime' behavior:
--
-- * If the `%Z' format is given the broken-down time is based on
-- the current time in the timezone matched, not in the current
-- timezone of the runtime environment.
--
-- *Note*: This is not implemented (currently). The problem is
-- that timezone names are not unique. If a fixed timezone is
-- assumed for a given string (say `EST' meaning US East Coast
-- time) uses for countries other than the USA will fail. So
-- far we have found no good solution for this.
--
-- * If only the weekday is specified the selected day depends on
-- the current date. If the current weekday is greater or equal
-- to the `tm_wday' value this weeks day is selected. Otherwise
-- next weeks day.
--
-- * A similar heuristic is used if only the month is given, not
-- the year. For value corresponding to the current or a later
-- month the current year s used. Otherwise the next year. The
-- first day of the month is assumed if it is not explicitly
-- specified.
--
-- * The current hour, minute, and second is used if the
-- appropriate value is not set through the format.
--
-- * If no date is given the date for the next day is used if the
-- time is smaller than the current time. Otherwise it is the
-- same day.
--
-- It should be noted that the format in the template file need not
-- only contain format elements. The following is a list of possible
-- format strings (taken from the Unix standard):
--
-- %m
-- %A %B %d, %Y %H:%M:%S
-- %A
-- %B
-- %m/%d/%y %I %p
-- %d,%m,%Y %H:%M
-- at %A the %dst of %B in %Y
-- run job at %I %p,%B %dnd
-- %A den %d. %B %Y %H.%M Uhr
--
-- As one can see the template list can contain very specific strings
-- like `run job at %I %p,%B %dnd'. Using the above list of
-- templates and assuming the current time is Mon Sep 22 12:19:47 EDT
-- 1986 we can get the following results for the given input.
--
-- Mon %a Mon Sep 22 12:19:47 EDT 1986
-- Sun %a Sun Sep 28 12:19:47 EDT 1986
-- Fri %a Fri Sep 26 12:19:47 EDT 1986
-- September %B Mon Sep 1 12:19:47 EDT 1986
-- January %B Thu Jan 1 12:19:47 EST 1987
-- December %B Mon Dec 1 12:19:47 EST 1986
-- Sep Mon %b %a Mon Sep 1 12:19:47 EDT 1986
-- Jan Fri %b %a Fri Jan 2 12:19:47 EST 1987
-- Dec Mon %b %a Mon Dec 1 12:19:47 EST 1986
-- Jan Wed 1989 %b %a %Y Wed Jan 4 12:19:47 EST 1989
-- Fri 9 %a %H Fri Sep 26 09:00:00 EDT 1986
-- Feb 10:30 %b %H:%S Sun Feb 1 10:00:30 EST 1987
-- 10:30 %H:%M Tue Sep 23 10:30:00 EDT 1986
-- 13:30 %H:%M Mon Sep 22 13:30:00 EDT 1986
--
-- The return value of the function is a pointer to a static variable
-- of type `struct tm' or a null pointer if an error occurred. The
-- result in the variable pointed to by the return value is only valid
-- until the next `getdate' call which makes this function unusable in
-- multi-threaded applications.
--
-- The `errno' variable is *not* changed. Error conditions are
-- signalled using the global variable `getdate_err'. See the
-- description above for a list of the possible error values.
--
-- *Warning:* The `getdate' function should *never* be used in
-- SUID-programs. The reason is obvious: using the `DATEMSK'
-- environment variable one can get the function to open any
-- arbitrary file and chances are high that with some bogus input
-- (such as a binary file) the program will crash.
--
-- - Function: int getdate_r (const char *STRING, struct tm *TP)
-- The `getdate_r' function is the reentrant counterpart of
-- `getdate'. It does not use the global variable `getdate_err' to
-- signal the error but instead the return value now is this error
-- code. The same error codes as described in the `getdate_err'
-- documentation above are used.
--
-- `getdate_r' also does not store the broken-down time in a static
-- variable. Instead it takes an second argument which must be a
-- pointer to a variable of type `struct tm' where the broken-down
-- can be stored.
--
-- This function is not defined in the Unix standard. Nevertheless
-- it is available on some other Unix systems as well.
--
-- As for `getdate' the warning for using this function in
-- SUID-programs applies to `getdate_r' as well.
--
--
--File: libc.info, Node: TZ Variable, Next: Time Zone Functions, Prev: Parsing Date and Time, Up: Calendar Time
--
--Specifying the Time Zone with `TZ'
------------------------------------
--
-- In POSIX systems, a user can specify the time zone by means of the
--`TZ' environment variable. For information about how to set
--environment variables, see *Note Environment Variables::. The functions
--for accessing the time zone are declared in `time.h'.
--
-- You should not normally need to set `TZ'. If the system is
--configured properly, the default time zone will be correct. You might
--set `TZ' if you are using a computer over the network from a different
--time zone, and would like times reported to you in the time zone that
--local for you, rather than what is local for the computer.
--
-- In POSIX.1 systems the value of the `TZ' variable can be of one of
--three formats. With the GNU C library, the most common format is the
--last one, which can specify a selection from a large database of time
--zone information for many regions of the world. The first two formats
--are used to describe the time zone information directly, which is both
--more cumbersome and less precise. But the POSIX.1 standard only
--specifies the details of the first two formats, so it is good to be
--familiar with them in case you come across a POSIX.1 system that doesn't
--support a time zone information database.
--
-- The first format is used when there is no Daylight Saving Time (or
--summer time) in the local time zone:
--
-- STD OFFSET
--
-- The STD string specifies the name of the time zone. It must be
--three or more characters long and must not contain a leading colon or
--embedded digits, commas, or plus or minus signs. There is no space
--character separating the time zone name from the OFFSET, so these
--restrictions are necessary to parse the specification correctly.
--
-- The OFFSET specifies the time value one must add to the local time
--to get a Coordinated Universal Time value. It has syntax like
--[`+'|`-']HH[`:'MM[`:'SS]]. This is positive if the local time zone is
--west of the Prime Meridian and negative if it is east. The hour must
--be between `0' and `23', and the minute and seconds between `0' and
--`59'.
--
-- For example, here is how we would specify Eastern Standard Time, but
--without any daylight saving time alternative:
--
-- EST+5
--
-- The second format is used when there is Daylight Saving Time:
--
-- STD OFFSET DST [OFFSET]`,'START[`/'TIME]`,'END[`/'TIME]
--
-- The initial STD and OFFSET specify the standard time zone, as
--described above. The DST string and OFFSET specify the name and offset
--for the corresponding daylight saving time zone; if the OFFSET is
--omitted, it defaults to one hour ahead of standard time.
--
-- The remainder of the specification describes when daylight saving
--time is in effect. The START field is when daylight saving time goes
--into effect and the END field is when the change is made back to
--standard time. The following formats are recognized for these fields:
--
--`JN'
-- This specifies the Julian day, with N between `1' and `365'.
-- February 29 is never counted, even in leap years.
--
--`N'
-- This specifies the Julian day, with N between `0' and `365'.
-- February 29 is counted in leap years.
--
--`MM.W.D'
-- This specifies day D of week W of month M. The day D must be
-- between `0' (Sunday) and `6'. The week W must be between `1' and
-- `5'; week `1' is the first week in which day D occurs, and week
-- `5' specifies the *last* D day in the month. The month M should be
-- between `1' and `12'.
--
-- The TIME fields specify when, in the local time currently in effect,
--the change to the other time occurs. If omitted, the default is
--`02:00:00'.
--
-- For example, here is how one would specify the Eastern time zone in
--the United States, including the appropriate daylight saving time and
--its dates of applicability. The normal offset from UTC is 5 hours;
--since this is west of the prime meridian, the sign is positive. Summer
--time begins on the first Sunday in April at 2:00am, and ends on the
--last Sunday in October at 2:00am.
--
-- EST+5EDT,M4.1.0/2,M10.5.0/2
--
-- The schedule of daylight saving time in any particular jurisdiction
--has changed over the years. To be strictly correct, the conversion of
--dates and times in the past should be based on the schedule that was in
--effect then. However, this format has no facilities to let you specify
--how the schedule has changed from year to year. The most you can do is
--specify one particular schedule--usually the present day schedule--and
--this is used to convert any date, no matter when. For precise time zone
--specifications, it is best to use the time zone information database
--(see below).
--
-- The third format looks like this:
--
-- :CHARACTERS
--
-- Each operating system interprets this format differently; in the GNU
--C library, CHARACTERS is the name of a file which describes the time
--zone.
--
-- If the `TZ' environment variable does not have a value, the
--operation chooses a time zone by default. In the GNU C library, the
--default time zone is like the specification `TZ=:/etc/localtime' (or
--`TZ=:/usr/local/etc/localtime', depending on how GNU C library was
--configured; *note Installation::.). Other C libraries use their own
--rule for choosing the default time zone, so there is little we can say
--about them.
--
-- If CHARACTERS begins with a slash, it is an absolute file name;
--otherwise the library looks for the file
--`/share/lib/zoneinfo/CHARACTERS'. The `zoneinfo' directory contains
--data files describing local time zones in many different parts of the
--world. The names represent major cities, with subdirectories for
--geographical areas; for example, `America/New_York', `Europe/London',
--`Asia/Hong_Kong'. These data files are installed by the system
--administrator, who also sets `/etc/localtime' to point to the data file
--for the local time zone. The GNU C library comes with a large database
--of time zone information for most regions of the world, which is
--maintained by a community of volunteers and put in the public domain.
--
--
--File: libc.info, Node: Time Zone Functions, Next: Time Functions Example, Prev: TZ Variable, Up: Calendar Time
--
--Functions and Variables for Time Zones
----------------------------------------
--
-- - Variable: char * tzname [2]
-- The array `tzname' contains two strings, which are the standard
-- names of the pair of time zones (standard and daylight saving)
-- that the user has selected. `tzname[0]' is the name of the
-- standard time zone (for example, `"EST"'), and `tzname[1]' is the
-- name for the time zone when daylight saving time is in use (for
-- example, `"EDT"'). These correspond to the STD and DST strings
-- (respectively) from the `TZ' environment variable. If daylight
-- saving time is never used, `tzname[1]' is the empty string.
--
-- The `tzname' array is initialized from the `TZ' environment
-- variable whenever `tzset', `ctime', `strftime', `mktime', or
-- `localtime' is called. If multiple abbreviations have been used
-- (e.g. `"EWT"' and `"EDT"' for U.S. Eastern War Time and Eastern
-- Daylight Time), the array contains the most recent abbreviation.
--
-- The `tzname' array is required for POSIX.1 compatibility, but in
-- GNU programs it is better to use the `tm_zone' member of the
-- broken-down time structure, since `tm_zone' reports the correct
-- abbreviation even when it is not the latest one.
--
-- Though the strings are declared as `char *' the user must stay away
-- from modifying these strings. Modifying the strings will almost
-- certainly lead to trouble.
--
--
-- - Function: void tzset (void)
-- The `tzset' function initializes the `tzname' variable from the
-- value of the `TZ' environment variable. It is not usually
-- necessary for your program to call this function, because it is
-- called automatically when you use the other time conversion
-- functions that depend on the time zone.
--
-- The following variables are defined for compatibility with System V
--Unix. Like `tzname', these variables are set by calling `tzset' or the
--other time conversion functions.
--
-- - Variable: long int timezone
-- This contains the difference between UTC and the latest local
-- standard time, in seconds west of UTC. For example, in the U.S.
-- Eastern time zone, the value is `5*60*60'. Unlike the `tm_gmtoff'
-- member of the broken-down time structure, this value is not
-- adjusted for daylight saving, and its sign is reversed. In GNU
-- programs it is better to use `tm_gmtoff', since it contains the
-- correct offset even when it is not the latest one.
--
-- - Variable: int daylight
-- This variable has a nonzero value if daylight savings time rules
-- apply. A nonzero value does not necessarily mean that daylight
-- savings time is now in effect; it means only that daylight savings
-- time is sometimes in effect.
--
--
--File: libc.info, Node: Time Functions Example, Prev: Time Zone Functions, Up: Calendar Time
--
--Time Functions Example
------------------------
--
-- Here is an example program showing the use of some of the local time
--and calendar time functions.
--
-- #include <time.h>
-- #include <stdio.h>
--
-- #define SIZE 256
--
-- int
-- main (void)
-- {
-- char buffer[SIZE];
-- time_t curtime;
-- struct tm *loctime;
--
-- /* Get the current time. */
-- curtime = time (NULL);
--
-- /* Convert it to local time representation. */
-- loctime = localtime (&curtime);
--
-- /* Print out the date and time in the standard format. */
-- fputs (asctime (loctime), stdout);
-- /* Print it out in a nice format. */
-- strftime (buffer, SIZE, "Today is %A, %B %d.\n", loctime);
-- fputs (buffer, stdout);
-- strftime (buffer, SIZE, "The time is %I:%M %p.\n", loctime);
-- fputs (buffer, stdout);
--
-- return 0;
-- }
--
-- It produces output like this:
--
-- Wed Jul 31 13:02:36 1991
-- Today is Wednesday, July 31.
-- The time is 01:02 PM.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-31 glibc-2.1.3/manual/libc.info-31
---- ../glibc-2.1.3/manual/libc.info-31 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-31 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1223 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Precision Time, Next: Setting an Alarm, Prev: Calendar Time, Up: Date and Time
--
--Precision Time
--==============
--
-- The `net_gettime' and `ntp_adjtime' functions provide an interface
--to monitor and manipulate high precision time. These functions are
--declared in `sys/timex.h'.
--
-- - Data Type: struct ntptimeval
-- This structure is used to monitor kernel time. It contains the
-- following members:
-- `struct timeval time'
-- This is the current time. The `struct timeval' data type is
-- described in *Note High-Resolution Calendar::.
--
-- `long int maxerror'
-- This is the maximum error, measured in microseconds. Unless
-- updated via `ntp_adjtime' periodically, this value will reach
-- some platform-specific maximum value.
--
-- `long int esterror'
-- This is the estimated error, measured in microseconds. This
-- value can be set by `ntp_adjtime' to indicate the estimated
-- offset of the local clock against the true time.
--
-- - Function: int ntp_gettime (struct ntptimeval *TPTR)
-- The `ntp_gettime' function sets the structure pointed to by TPTR
-- to current values. The elements of the structure afterwards
-- contain the values the timer implementation in the kernel assumes.
-- They might or might not be correct. If they are not a
-- `ntp_adjtime' call is necessary.
--
-- The return value is `0' on success and other values on failure.
-- The following `errno' error conditions are defined for this
-- function:
--
-- `TIME_ERROR'
-- The precision clock model is not properly set up at the
-- moment, thus the clock must be considered unsynchronized, and
-- the values should be treated with care.
--
-- - Data Type: struct timex
-- This structure is used to control and monitor kernel time in a
-- greater level of detail. It contains the following members:
-- `unsigned int modes'
-- This variable controls whether and which values are set.
-- Several symbolic constants have to be combined with *binary
-- or* to specify the effective mode. These constants start
-- with `MOD_'.
--
-- `long int offset'
-- This value indicates the current offset of the local clock
-- from the true time. The value is given in microseconds. If
-- bit `MOD_OFFSET' is set in `modes', the offset (and possibly
-- other dependent values) can be set. The offset's absolute
-- value must not exceed `MAXPHASE'.
--
-- `long int frequency'
-- This value indicates the difference in frequency between the
-- true time and the local clock. The value is expressed as
-- scaled PPM (parts per million, 0.0001%). The scaling is `1
-- << SHIFT_USEC'. The value can be set with bit
-- `MOD_FREQUENCY', but the absolute value must not exceed
-- `MAXFREQ'.
--
-- `long int maxerror'
-- This is the maximum error, measured in microseconds. A new
-- value can be set using bit `MOD_MAXERROR'. Unless updated via
-- `ntp_adjtime' periodically, this value will increase steadily
-- and reach some platform-specific maximum value.
--
-- `long int esterror'
-- This is the estimated error, measured in microseconds. This
-- value can be set using bit `MOD_ESTERROR'.
--
-- `int status'
-- This valiable reflects the various states of the clock
-- machinery. There are symbolic constants for the significant
-- bits, starting with `STA_'. Some of these flags can be
-- updated using the `MOD_STATUS' bit.
--
-- `long int constant'
-- This value represents the bandwidth or stiffness of the PLL
-- (phase locked loop) implemented in the kernel. The value can
-- be changed using bit `MOD_TIMECONST'.
--
-- `long int precision'
-- This value represents the accuracy or the maximum error when
-- reading the system clock. The value is expressed in
-- microseconds and can't be changed.
--
-- `long int tolerance'
-- This value represents the maximum frequency error of the
-- system clock in scaled PPM. This value is used to increase
-- the `maxerror' every second.
--
-- `long int ppsfreq'
-- This is the first of a few optional variables that are
-- present only if the system clock can use a PPS (pulse per
-- second) signal to discipline the local clock. The value is
-- expressed in scaled PPM and it denotes the difference in
-- frequency between the local clock and the PPS signal.
--
-- `long int jitter'
-- This value expresses a median filtered average of the PPS
-- signal's dispersion in microseconds.
--
-- `int int shift'
-- This value is a binary exponent for the duration of the PPS
-- calibration interval, ranging from `PPS_SHIFT' to
-- `PPS_SHIFTMAX'.
--
-- `long int stabil'
-- This value represents the median filtered dispersion of the
-- PPS frequency in scaled PPM.
--
-- `long int jitcnt'
-- This counter represents the numer of pulses where the jitter
-- exceeded the allowed maximum `MAXTIME'.
--
-- `long int calcnt'
-- This counter reflects the number of successful calibration
-- intervals.
--
-- `long int errcnt'
-- This counter represents the number of calibration errors
-- (caused by large offsets or jitter).
--
-- `long int stbcnt'
-- This counter denotes the number of of calibrations where the
-- stability exceeded the threshold.
--
-- - Function: int ntp_adjtime (struct timex *TPTR)
-- The `ntp_adjtime' function sets the structure specified by TPTR to
-- current values. In addition, values passed in TPTR can be used to
-- replace existing settings. To do this the `modes' element of the
-- `struct timex' must be set appropriately. Setting it to zero
-- selects reading the current state.
--
-- The return value is `0' on success and other values on failure.
-- The following `errno' error conditions are defined for this
-- function:
--
-- `TIME_ERROR'
-- The precision clock model is not properly set up at the
-- moment, thus the clock must be considered unsynchronized, and
-- the values should be treated with care. Another reason could
-- be that the specified new values are not allowed.
--
-- For more details see RFC1305 (Network Time Protocol, Version 3) and
-- related documents.
--
--
--File: libc.info, Node: Setting an Alarm, Next: Sleeping, Prev: Precision Time, Up: Date and Time
--
--Setting an Alarm
--================
--
-- The `alarm' and `setitimer' functions provide a mechanism for a
--process to interrupt itself at some future time. They do this by
--setting a timer; when the timer expires, the process receives a signal.
--
-- Each process has three independent interval timers available:
--
-- * A real-time timer that counts clock time. This timer sends a
-- `SIGALRM' signal to the process when it expires.
--
-- * A virtual timer that counts CPU time used by the process. This
-- timer sends a `SIGVTALRM' signal to the process when it expires.
--
-- * A profiling timer that counts both CPU time used by the process,
-- and CPU time spent in system calls on behalf of the process. This
-- timer sends a `SIGPROF' signal to the process when it expires.
--
-- This timer is useful for profiling in interpreters. The interval
-- timer mechanism does not have the fine granularity necessary for
-- profiling native code.
--
-- You can only have one timer of each kind set at any given time. If
--you set a timer that has not yet expired, that timer is simply reset to
--the new value.
--
-- You should establish a handler for the appropriate alarm signal using
--`signal' or `sigaction' before issuing a call to `setitimer' or
--`alarm'. Otherwise, an unusual chain of events could cause the timer
--to expire before your program establishes the handler, and in that case
--it would be terminated, since that is the default action for the alarm
--signals. *Note Signal Handling::.
--
-- The `setitimer' function is the primary means for setting an alarm.
--This facility is declared in the header file `sys/time.h'. The `alarm'
--function, declared in `unistd.h', provides a somewhat simpler interface
--for setting the real-time timer.
--
-- - Data Type: struct itimerval
-- This structure is used to specify when a timer should expire. It
-- contains the following members:
-- `struct timeval it_interval'
-- This is the interval between successive timer interrupts. If
-- zero, the alarm will only be sent once.
--
-- `struct timeval it_value'
-- This is the interval to the first timer interrupt. If zero,
-- the alarm is disabled.
--
-- The `struct timeval' data type is described in *Note
-- High-Resolution Calendar::.
--
-- - Function: int setitimer (int WHICH, struct itimerval *NEW, struct
-- itimerval *OLD)
-- The `setitimer' function sets the timer specified by WHICH
-- according to NEW. The WHICH argument can have a value of
-- `ITIMER_REAL', `ITIMER_VIRTUAL', or `ITIMER_PROF'.
--
-- If OLD is not a null pointer, `setitimer' returns information
-- about any previous unexpired timer of the same kind in the
-- structure it points to.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error conditions are defined for this function:
--
-- `EINVAL'
-- The timer interval was too large.
--
-- - Function: int getitimer (int WHICH, struct itimerval *OLD)
-- The `getitimer' function stores information about the timer
-- specified by WHICH in the structure pointed at by OLD.
--
-- The return value and error conditions are the same as for
-- `setitimer'.
--
--`ITIMER_REAL'
-- This constant can be used as the WHICH argument to the `setitimer'
-- and `getitimer' functions to specify the real-time timer.
--
--`ITIMER_VIRTUAL'
-- This constant can be used as the WHICH argument to the `setitimer'
-- and `getitimer' functions to specify the virtual timer.
--
--`ITIMER_PROF'
-- This constant can be used as the WHICH argument to the `setitimer'
-- and `getitimer' functions to specify the profiling timer.
--
-- - Function: unsigned int alarm (unsigned int SECONDS)
-- The `alarm' function sets the real-time timer to expire in SECONDS
-- seconds. If you want to cancel any existing alarm, you can do
-- this by calling `alarm' with a SECONDS argument of zero.
--
-- The return value indicates how many seconds remain before the
-- previous alarm would have been sent. If there is no previous
-- alarm, `alarm' returns zero.
--
-- The `alarm' function could be defined in terms of `setitimer' like
--this:
--
-- unsigned int
-- alarm (unsigned int seconds)
-- {
-- struct itimerval old, new;
-- new.it_interval.tv_usec = 0;
-- new.it_interval.tv_sec = 0;
-- new.it_value.tv_usec = 0;
-- new.it_value.tv_sec = (long int) seconds;
-- if (setitimer (ITIMER_REAL, &new, &old) < 0)
-- return 0;
-- else
-- return old.it_value.tv_sec;
-- }
--
-- There is an example showing the use of the `alarm' function in *Note
--Handler Returns::.
--
-- If you simply want your process to wait for a given number of
--seconds, you should use the `sleep' function. *Note Sleeping::.
--
-- You shouldn't count on the signal arriving precisely when the timer
--expires. In a multiprocessing environment there is typically some
--amount of delay involved.
--
-- *Portability Note:* The `setitimer' and `getitimer' functions are
--derived from BSD Unix, while the `alarm' function is specified by the
--POSIX.1 standard. `setitimer' is more powerful than `alarm', but
--`alarm' is more widely used.
--
--
--File: libc.info, Node: Sleeping, Next: Resource Usage, Prev: Setting an Alarm, Up: Date and Time
--
--Sleeping
--========
--
-- The function `sleep' gives a simple way to make the program wait for
--short periods of time. If your program doesn't use signals (except to
--terminate), then you can expect `sleep' to wait reliably for the
--specified amount of time. Otherwise, `sleep' can return sooner if a
--signal arrives; if you want to wait for a given period regardless of
--signals, use `select' (*note Waiting for I/O::.) and don't specify any
--descriptors to wait for.
--
-- - Function: unsigned int sleep (unsigned int SECONDS)
-- The `sleep' function waits for SECONDS or until a signal is
-- delivered, whichever happens first.
--
-- If `sleep' function returns because the requested time has
-- elapsed, it returns a value of zero. If it returns because of
-- delivery of a signal, its return value is the remaining time in
-- the sleep period.
--
-- The `sleep' function is declared in `unistd.h'.
--
-- Resist the temptation to implement a sleep for a fixed amount of
--time by using the return value of `sleep', when nonzero, to call
--`sleep' again. This will work with a certain amount of accuracy as
--long as signals arrive infrequently. But each signal can cause the
--eventual wakeup time to be off by an additional second or so. Suppose a
--few signals happen to arrive in rapid succession by bad luck--there is
--no limit on how much this could shorten or lengthen the wait.
--
-- Instead, compute the time at which the program should stop waiting,
--and keep trying to wait until that time. This won't be off by more
--than a second. With just a little more work, you can use `select' and
--make the waiting period quite accurate. (Of course, heavy system load
--can cause unavoidable additional delays--unless the machine is
--dedicated to one application, there is no way you can avoid this.)
--
-- On some systems, `sleep' can do strange things if your program uses
--`SIGALRM' explicitly. Even if `SIGALRM' signals are being ignored or
--blocked when `sleep' is called, `sleep' might return prematurely on
--delivery of a `SIGALRM' signal. If you have established a handler for
--`SIGALRM' signals and a `SIGALRM' signal is delivered while the process
--is sleeping, the action taken might be just to cause `sleep' to return
--instead of invoking your handler. And, if `sleep' is interrupted by
--delivery of a signal whose handler requests an alarm or alters the
--handling of `SIGALRM', this handler and `sleep' will interfere.
--
-- On the GNU system, it is safe to use `sleep' and `SIGALRM' in the
--same program, because `sleep' does not work by means of `SIGALRM'.
--
-- - Function: int nanosleep (const struct timespec *REQUESTED_TIME,
-- struct timespec *REMAINING)
-- If the resolution of seconds is not enough the `nanosleep' function
-- can be used. As the name suggests the sleeping period can be
-- specified in nanoseconds. The actual period of waiting time might
-- be longer since the requested time in the REQUESTED_TIME parameter
-- is rounded up to the next integer multiple of the actual
-- resolution of the system.
--
-- If the function returns because the time has elapsed the return
-- value is zero. If the function return -1 the global variable ERRNO
-- is set to the following values:
--
-- `EINTR'
-- The call was interrupted because a signal was delivered to
-- the thread. If the REMAINING parameter is not the null
-- pointer the structure pointed to by REMAINING is updated to
-- contain the remaining time.
--
-- `EINVAL'
-- The nanosecond value in the REQUESTED_TIME parameter contains
-- an illegal value. Either the value is negative or greater
-- than or equal to 1000 million.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `nanosleep' is called. If the thread gets canceled these
-- resources stay allocated until the program ends. To avoid this
-- calls to `nanosleep' should be protected using cancelation
-- handlers.
--
-- The `nanosleep' function is declared in `time.h'.
--
--
--File: libc.info, Node: Resource Usage, Next: Limits on Resources, Prev: Sleeping, Up: Date and Time
--
--Resource Usage
--==============
--
-- The function `getrusage' and the data type `struct rusage' are used
--for examining the usage figures of a process. They are declared in
--`sys/resource.h'.
--
-- - Function: int getrusage (int PROCESSES, struct rusage *RUSAGE)
-- This function reports the usage totals for processes specified by
-- PROCESSES, storing the information in `*RUSAGE'.
--
-- In most systems, PROCESSES has only two valid values:
--
-- `RUSAGE_SELF'
-- Just the current process.
--
-- `RUSAGE_CHILDREN'
-- All child processes (direct and indirect) that have
-- terminated already.
--
-- In the GNU system, you can also inquire about a particular child
-- process by specifying its process ID.
--
-- The return value of `getrusage' is zero for success, and `-1' for
-- failure.
--
-- `EINVAL'
-- The argument PROCESSES is not valid.
--
-- One way of getting usage figures for a particular child process is
--with the function `wait4', which returns totals for a child when it
--terminates. *Note BSD Wait Functions::.
--
-- - Data Type: struct rusage
-- This data type records a collection usage amounts for various
-- sorts of resources. It has the following members, and possibly
-- others:
--
-- `struct timeval ru_utime'
-- Time spent executing user instructions.
--
-- `struct timeval ru_stime'
-- Time spent in operating system code on behalf of PROCESSES.
--
-- `long int ru_maxrss'
-- The maximum resident set size used, in kilobytes. That is,
-- the maximum number of kilobytes that PROCESSES used in real
-- memory simultaneously.
--
-- `long int ru_ixrss'
-- An integral value expressed in kilobytes times ticks of
-- execution, which indicates the amount of memory used by text
-- that was shared with other processes.
--
-- `long int ru_idrss'
-- An integral value expressed the same way, which is the amount
-- of unshared memory used in data.
--
-- `long int ru_isrss'
-- An integral value expressed the same way, which is the amount
-- of unshared memory used in stack space.
--
-- `long int ru_minflt'
-- The number of page faults which were serviced without
-- requiring any I/O.
--
-- `long int ru_majflt'
-- The number of page faults which were serviced by doing I/O.
--
-- `long int ru_nswap'
-- The number of times PROCESSES was swapped entirely out of
-- main memory.
--
-- `long int ru_inblock'
-- The number of times the file system had to read from the disk
-- on behalf of PROCESSES.
--
-- `long int ru_oublock'
-- The number of times the file system had to write to the disk
-- on behalf of PROCESSES.
--
-- `long int ru_msgsnd'
-- Number of IPC messages sent.
--
-- `long ru_msgrcv'
-- Number of IPC messages received.
--
-- `long int ru_nsignals'
-- Number of signals received.
--
-- `long int ru_nvcsw'
-- The number of times PROCESSES voluntarily invoked a context
-- switch (usually to wait for some service).
--
-- `long int ru_nivcsw'
-- The number of times an involuntary context switch took place
-- (because the time slice expired, or another process of higher
-- priority became runnable).
--
-- An additional historical function for examining usage figures,
--`vtimes', is supported but not documented here. It is declared in
--`sys/vtimes.h'.
--
--
--File: libc.info, Node: Limits on Resources, Next: Priority, Prev: Resource Usage, Up: Date and Time
--
--Limiting Resource Usage
--=======================
--
-- You can specify limits for the resource usage of a process. When the
--process tries to exceed a limit, it may get a signal, or the system call
--by which it tried to do so may fail, depending on the limit. Each
--process initially inherits its limit values from its parent, but it can
--subsequently change them.
--
-- The symbols in this section are defined in `sys/resource.h'.
--
-- - Function: int getrlimit (int RESOURCE, struct rlimit *RLP)
-- Read the current value and the maximum value of resource RESOURCE
-- and store them in `*RLP'.
--
-- The return value is `0' on success and `-1' on failure. The only
-- possible `errno' error condition is `EFAULT'.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system this function is in fact `getrlimit64'. I.e., the
-- LFS interface transparently replaces the old interface.
--
-- - Function: int getrlimit64 (int RESOURCE, struct rlimit64 *RLP)
-- This function is similar to the `getrlimit' but its second
-- parameter is a pointer to a variable of type `struct rlimit64'
-- which allows this function to read values which wouldn't fit in the
-- member of a `struct rlimit'.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' on a 32
-- bits machine this function is available under the name `getrlimit'
-- and so transparently replaces the old interface.
--
-- - Function: int setrlimit (int RESOURCE, const struct rlimit *RLP)
-- Store the current value and the maximum value of resource RESOURCE
-- in `*RLP'.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error condition is possible:
--
-- `EPERM'
-- You tried to change the maximum permissible limit value, but
-- you don't have privileges to do so.
--
-- When the sources are compiled with `_FILE_OFFSET_BITS == 64' on a
-- 32 bits system this function is in fact `setrlimit64'. I.e., the
-- LFS interface transparently replaces the old interface.
--
-- - Function: int setrlimit64 (int RESOURCE, const struct rlimit64 *RLP)
-- This function is similar to the `setrlimit' but its second
-- parameter is a pointer to a variable of type `struct rlimit64'
-- which allows this function to set values which wouldn't fit in the
-- member of a `struct rlimit'.
--
-- If the sources are compiled with `_FILE_OFFSET_BITS == 64' on a 32
-- bits machine this function is available under the name `setrlimit'
-- and so transparently replaces the old interface.
--
-- - Data Type: struct rlimit
-- This structure is used with `getrlimit' to receive limit values,
-- and with `setrlimit' to specify limit values. It has two fields:
--
-- `rlim_t rlim_cur'
-- The current value of the limit in question. This is also
-- called the "soft limit".
--
-- `rlim_t rlim_max'
-- The maximum permissible value of the limit in question. You
-- cannot set the current value of the limit to a larger number
-- than this maximum. Only the super user can change the
-- maximum permissible value. This is also called the "hard
-- limit".
--
-- In `getrlimit', the structure is an output; it receives the current
-- values. In `setrlimit', it specifies the new values.
--
-- For the LFS functions a similar type is defined in `sys/resource.h'.
--
-- - Data Type: struct rlimit64
-- This structure is used with `getrlimit64' to receive limit values,
-- and with `setrlimit64' to specify limit values. It has two fields:
--
-- `rlim64_t rlim_cur'
-- The current value of the limit in question. This is also
-- called the "soft limit".
--
-- `rlim64_t rlim_max'
-- The maximum permissible value of the limit in question. You
-- cannot set the current value of the limit to a larger number
-- than this maximum. Only the super user can change the
-- maximum permissible value. This is also called the "hard
-- limit".
--
-- In `getrlimit64', the structure is an output; it receives the
-- current values. In `setrlimit64', it specifies the new values.
--
-- Here is a list of resources that you can specify a limit for. Those
--that are sizes are measured in bytes.
--
--`RLIMIT_CPU'
-- The maximum amount of cpu time the process can use. If it runs for
-- longer than this, it gets a signal: `SIGXCPU'. The value is
-- measured in seconds. *Note Operation Error Signals::.
--
--`RLIMIT_FSIZE'
-- The maximum size of file the process can create. Trying to write a
-- larger file causes a signal: `SIGXFSZ'. *Note Operation Error
-- Signals::.
--
--`RLIMIT_DATA'
-- The maximum size of data memory for the process. If the process
-- tries to allocate data memory beyond this amount, the allocation
-- function fails.
--
--`RLIMIT_STACK'
-- The maximum stack size for the process. If the process tries to
-- extend its stack past this size, it gets a `SIGSEGV' signal.
-- *Note Program Error Signals::.
--
--`RLIMIT_CORE'
-- The maximum size core file that this process can create. If the
-- process terminates and would dump a core file larger than this
-- maximum size, then no core file is created. So setting this limit
-- to zero prevents core files from ever being created.
--
--`RLIMIT_RSS'
-- The maximum amount of physical memory that this process should get.
-- This parameter is a guide for the system's scheduler and memory
-- allocator; the system may give the process more memory when there
-- is a surplus.
--
--`RLIMIT_MEMLOCK'
-- The maximum amount of memory that can be locked into physical
-- memory (so it will never be paged out).
--
--`RLIMIT_NPROC'
-- The maximum number of processes that can be created with the same
-- user ID. If you have reached the limit for your user ID, `fork'
-- will fail with `EAGAIN'. *Note Creating a Process::.
--
--`RLIMIT_NOFILE'
--`RLIMIT_OFILE'
-- The maximum number of files that the process can open. If it
-- tries to open more files than this, it gets error code `EMFILE'.
-- *Note Error Codes::. Not all systems support this limit; GNU
-- does, and 4.4 BSD does.
--
--`RLIM_NLIMITS'
-- The number of different resource limits. Any valid RESOURCE
-- operand must be less than `RLIM_NLIMITS'.
--
-- - Constant: int RLIM_INFINITY
-- This constant stands for a value of "infinity" when supplied as
-- the limit value in `setrlimit'.
--
-- Two historical functions for setting resource limits, `ulimit' and
--`vlimit', are not documented here. The latter is declared in
--`sys/vlimit.h' and comes from BSD.
--
--
--File: libc.info, Node: Priority, Prev: Limits on Resources, Up: Date and Time
--
--Process Priority
--================
--
-- When several processes try to run, their respective priorities
--determine what share of the CPU each process gets. This section
--describes how you can read and set the priority of a process. All
--these functions and macros are declared in `sys/resource.h'.
--
-- The range of valid priority values depends on the operating system,
--but typically it runs from `-20' to `20'. A lower priority value means
--the process runs more often. These constants describe the range of
--priority values:
--
--`PRIO_MIN'
-- The smallest valid priority value.
--
--`PRIO_MAX'
-- The largest valid priority value.
--
-- - Function: int getpriority (int CLASS, int ID)
-- Read the priority of a class of processes; CLASS and ID specify
-- which ones (see below). If the processes specified do not all
-- have the same priority, this returns the smallest value that any
-- of them has.
--
-- The return value is the priority value on success, and `-1' on
-- failure. The following `errno' error condition are possible for
-- this function:
--
-- `ESRCH'
-- The combination of CLASS and ID does not match any existing
-- process.
--
-- `EINVAL'
-- The value of CLASS is not valid.
--
-- When the return value is `-1', it could indicate failure, or it
-- could be the priority value. The only way to make certain is to
-- set `errno = 0' before calling `getpriority', then use `errno !=
-- 0' afterward as the criterion for failure.
--
-- - Function: int setpriority (int CLASS, int ID, int PRIORITY)
-- Set the priority of a class of processes to PRIORITY; CLASS and ID
-- specify which ones (see below).
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error condition are defined for this function:
--
-- `ESRCH'
-- The combination of CLASS and ID does not match any existing
-- process.
--
-- `EINVAL'
-- The value of CLASS is not valid.
--
-- `EPERM'
-- You tried to set the priority of some other user's process,
-- and you don't have privileges for that.
--
-- `EACCES'
-- You tried to lower the priority of a process, and you don't
-- have privileges for that.
--
-- The arguments CLASS and ID together specify a set of processes you
--are interested in. These are the possible values for CLASS:
--
--`PRIO_PROCESS'
-- Read or set the priority of one process. The argument ID is a
-- process ID.
--
--`PRIO_PGRP'
-- Read or set the priority of one process group. The argument ID is
-- a process group ID.
--
--`PRIO_USER'
-- Read or set the priority of one user's processes. The argument ID
-- is a user ID.
--
-- If the argument ID is 0, it stands for the current process, current
--process group, or the current user, according to CLASS.
--
-- - Function: int nice (int INCREMENT)
-- Increment the priority of the current process by INCREMENT. The
-- return value is the same as for `setpriority'.
--
-- Here is an equivalent definition for `nice':
--
-- int
-- nice (int increment)
-- {
-- int old = getpriority (PRIO_PROCESS, 0);
-- return setpriority (PRIO_PROCESS, 0, old + increment);
-- }
--
--
--File: libc.info, Node: Non-Local Exits, Next: Signal Handling, Prev: Date and Time, Up: Top
--
--Non-Local Exits
--***************
--
-- Sometimes when your program detects an unusual situation inside a
--deeply nested set of function calls, you would like to be able to
--immediately return to an outer level of control. This section
--describes how you can do such "non-local exits" using the `setjmp' and
--`longjmp' functions.
--
--* Menu:
--
--* Intro: Non-Local Intro. When and how to use these facilities.
--* Details: Non-Local Details. Functions for nonlocal exits.
--* Non-Local Exits and Signals:: Portability issues.
--
--
--File: libc.info, Node: Non-Local Intro, Next: Non-Local Details, Up: Non-Local Exits
--
--Introduction to Non-Local Exits
--===============================
--
-- As an example of a situation where a non-local exit can be useful,
--suppose you have an interactive program that has a "main loop" that
--prompts for and executes commands. Suppose the "read" command reads
--input from a file, doing some lexical analysis and parsing of the input
--while processing it. If a low-level input error is detected, it would
--be useful to be able to return immediately to the "main loop" instead
--of having to make each of the lexical analysis, parsing, and processing
--phases all have to explicitly deal with error situations initially
--detected by nested calls.
--
-- (On the other hand, if each of these phases has to do a substantial
--amount of cleanup when it exits--such as closing files, deallocating
--buffers or other data structures, and the like--then it can be more
--appropriate to do a normal return and have each phase do its own
--cleanup, because a non-local exit would bypass the intervening phases
--and their associated cleanup code entirely. Alternatively, you could
--use a non-local exit but do the cleanup explicitly either before or
--after returning to the "main loop".)
--
-- In some ways, a non-local exit is similar to using the `return'
--statement to return from a function. But while `return' abandons only
--a single function call, transferring control back to the point at which
--it was called, a non-local exit can potentially abandon many levels of
--nested function calls.
--
-- You identify return points for non-local exits calling the function
--`setjmp'. This function saves information about the execution
--environment in which the call to `setjmp' appears in an object of type
--`jmp_buf'. Execution of the program continues normally after the call
--to `setjmp', but if a exit is later made to this return point by
--calling `longjmp' with the corresponding `jmp_buf' object, control is
--transferred back to the point where `setjmp' was called. The return
--value from `setjmp' is used to distinguish between an ordinary return
--and a return made by a call to `longjmp', so calls to `setjmp' usually
--appear in an `if' statement.
--
-- Here is how the example program described above might be set up:
--
-- #include <setjmp.h>
-- #include <stdlib.h>
-- #include <stdio.h>
--
-- jmp_buf main_loop;
--
-- void
-- abort_to_main_loop (int status)
-- {
-- longjmp (main_loop, status);
-- }
--
-- int
-- main (void)
-- {
-- while (1)
-- if (setjmp (main_loop))
-- puts ("Back at main loop....");
-- else
-- do_command ();
-- }
--
--
-- void
-- do_command (void)
-- {
-- char buffer[128];
-- if (fgets (buffer, 128, stdin) == NULL)
-- abort_to_main_loop (-1);
-- else
-- exit (EXIT_SUCCESS);
-- }
--
-- The function `abort_to_main_loop' causes an immediate transfer of
--control back to the main loop of the program, no matter where it is
--called from.
--
-- The flow of control inside the `main' function may appear a little
--mysterious at first, but it is actually a common idiom with `setjmp'.
--A normal call to `setjmp' returns zero, so the "else" clause of the
--conditional is executed. If `abort_to_main_loop' is called somewhere
--within the execution of `do_command', then it actually appears as if
--the *same* call to `setjmp' in `main' were returning a second time with
--a value of `-1'.
--
-- So, the general pattern for using `setjmp' looks something like:
--
-- if (setjmp (BUFFER))
-- /* Code to clean up after premature return. */
-- ...
-- else
-- /* Code to be executed normally after setting up the return point. */
-- ...
--
--
--File: libc.info, Node: Non-Local Details, Next: Non-Local Exits and Signals, Prev: Non-Local Intro, Up: Non-Local Exits
--
--Details of Non-Local Exits
--==========================
--
-- Here are the details on the functions and data structures used for
--performing non-local exits. These facilities are declared in
--`setjmp.h'.
--
-- - Data Type: jmp_buf
-- Objects of type `jmp_buf' hold the state information to be
-- restored by a non-local exit. The contents of a `jmp_buf'
-- identify a specific place to return to.
--
-- - Macro: int setjmp (jmp_buf STATE)
-- When called normally, `setjmp' stores information about the
-- execution state of the program in STATE and returns zero. If
-- `longjmp' is later used to perform a non-local exit to this STATE,
-- `setjmp' returns a nonzero value.
--
-- - Function: void longjmp (jmp_buf STATE, int VALUE)
-- This function restores current execution to the state saved in
-- STATE, and continues execution from the call to `setjmp' that
-- established that return point. Returning from `setjmp' by means of
-- `longjmp' returns the VALUE argument that was passed to `longjmp',
-- rather than `0'. (But if VALUE is given as `0', `setjmp' returns
-- `1').
--
-- There are a lot of obscure but important restrictions on the use of
--`setjmp' and `longjmp'. Most of these restrictions are present because
--non-local exits require a fair amount of magic on the part of the C
--compiler and can interact with other parts of the language in strange
--ways.
--
-- The `setjmp' function is actually a macro without an actual function
--definition, so you shouldn't try to `#undef' it or take its address.
--In addition, calls to `setjmp' are safe in only the following contexts:
--
-- * As the test expression of a selection or iteration statement (such
-- as `if', `switch', or `while').
--
-- * As one operand of a equality or comparison operator that appears
-- as the test expression of a selection or iteration statement. The
-- other operand must be an integer constant expression.
--
-- * As the operand of a unary `!' operator, that appears as the test
-- expression of a selection or iteration statement.
--
-- * By itself as an expression statement.
--
-- Return points are valid only during the dynamic extent of the
--function that called `setjmp' to establish them. If you `longjmp' to a
--return point that was established in a function that has already
--returned, unpredictable and disastrous things are likely to happen.
--
-- You should use a nonzero VALUE argument to `longjmp'. While
--`longjmp' refuses to pass back a zero argument as the return value from
--`setjmp', this is intended as a safety net against accidental misuse
--and is not really good programming style.
--
-- When you perform a non-local exit, accessible objects generally
--retain whatever values they had at the time `longjmp' was called. The
--exception is that the values of automatic variables local to the
--function containing the `setjmp' call that have been changed since the
--call to `setjmp' are indeterminate, unless you have declared them
--`volatile'.
--
--
--File: libc.info, Node: Non-Local Exits and Signals, Prev: Non-Local Details, Up: Non-Local Exits
--
--Non-Local Exits and Signals
--===========================
--
-- In BSD Unix systems, `setjmp' and `longjmp' also save and restore
--the set of blocked signals; see *Note Blocking Signals::. However, the
--POSIX.1 standard requires `setjmp' and `longjmp' not to change the set
--of blocked signals, and provides an additional pair of functions
--(`sigsetjmp' and `siglongjmp') to get the BSD behavior.
--
-- The behavior of `setjmp' and `longjmp' in the GNU library is
--controlled by feature test macros; see *Note Feature Test Macros::. The
--default in the GNU system is the POSIX.1 behavior rather than the BSD
--behavior.
--
-- The facilities in this section are declared in the header file
--`setjmp.h'.
--
-- - Data Type: sigjmp_buf
-- This is similar to `jmp_buf', except that it can also store state
-- information about the set of blocked signals.
--
-- - Function: int sigsetjmp (sigjmp_buf STATE, int SAVESIGS)
-- This is similar to `setjmp'. If SAVESIGS is nonzero, the set of
-- blocked signals is saved in STATE and will be restored if a
-- `siglongjmp' is later performed with this STATE.
--
-- - Function: void siglongjmp (sigjmp_buf STATE, int VALUE)
-- This is similar to `longjmp' except for the type of its STATE
-- argument. If the `sigsetjmp' call that set this STATE used a
-- nonzero SAVESIGS flag, `siglongjmp' also restores the set of
-- blocked signals.
--
--
--File: libc.info, Node: Signal Handling, Next: Process Startup, Prev: Non-Local Exits, Up: Top
--
--Signal Handling
--***************
--
-- A "signal" is a software interrupt delivered to a process. The
--operating system uses signals to report exceptional situations to an
--executing program. Some signals report errors such as references to
--invalid memory addresses; others report asynchronous events, such as
--disconnection of a phone line.
--
-- The GNU C library defines a variety of signal types, each for a
--particular kind of event. Some kinds of events make it inadvisable or
--impossible for the program to proceed as usual, and the corresponding
--signals normally abort the program. Other kinds of signals that report
--harmless events are ignored by default.
--
-- If you anticipate an event that causes signals, you can define a
--handler function and tell the operating system to run it when that
--particular type of signal arrives.
--
-- Finally, one process can send a signal to another process; this
--allows a parent process to abort a child, or two related processes to
--communicate and synchronize.
--
--* Menu:
--
--* Concepts of Signals:: Introduction to the signal facilities.
--* Standard Signals:: Particular kinds of signals with
-- standard names and meanings.
--* Signal Actions:: Specifying what happens when a
-- particular signal is delivered.
--* Defining Handlers:: How to write a signal handler function.
--* Interrupted Primitives:: Signal handlers affect use of `open',
-- `read', `write' and other functions.
--* Generating Signals:: How to send a signal to a process.
--* Blocking Signals:: Making the system hold signals temporarily.
--* Waiting for a Signal:: Suspending your program until a signal
-- arrives.
--* Signal Stack:: Using a Separate Signal Stack.
--* BSD Signal Handling:: Additional functions for backward
-- compatibility with BSD.
--
--
--File: libc.info, Node: Concepts of Signals, Next: Standard Signals, Up: Signal Handling
--
--Basic Concepts of Signals
--=========================
--
-- This section explains basic concepts of how signals are generated,
--what happens after a signal is delivered, and how programs can handle
--signals.
--
--* Menu:
--
--* Kinds of Signals:: Some examples of what can cause a signal.
--* Signal Generation:: Concepts of why and how signals occur.
--* Delivery of Signal:: Concepts of what a signal does to the
-- process.
--
--
--File: libc.info, Node: Kinds of Signals, Next: Signal Generation, Up: Concepts of Signals
--
--Some Kinds of Signals
-----------------------
--
-- A signal reports the occurrence of an exceptional event. These are
--some of the events that can cause (or "generate", or "raise") a signal:
--
-- * A program error such as dividing by zero or issuing an address
-- outside the valid range.
--
-- * A user request to interrupt or terminate the program. Most
-- environments are set up to let a user suspend the program by
-- typing `C-z', or terminate it with `C-c'. Whatever key sequence
-- is used, the operating system sends the proper signal to interrupt
-- the process.
--
-- * The termination of a child process.
--
-- * Expiration of a timer or alarm.
--
-- * A call to `kill' or `raise' by the same process.
--
-- * A call to `kill' from another process. Signals are a limited but
-- useful form of interprocess communication.
--
-- * An attempt to perform an I/O operation that cannot be done.
-- Examples are reading from a pipe that has no writer (*note Pipes
-- and FIFOs::.), and reading or writing to a terminal in certain
-- situations (*note Job Control::.).
--
-- Each of these kinds of events (excepting explicit calls to `kill'
--and `raise') generates its own particular kind of signal. The various
--kinds of signals are listed and described in detail in *Note Standard
--Signals::.
--
--
--File: libc.info, Node: Signal Generation, Next: Delivery of Signal, Prev: Kinds of Signals, Up: Concepts of Signals
--
--Concepts of Signal Generation
-------------------------------
--
-- In general, the events that generate signals fall into three major
--categories: errors, external events, and explicit requests.
--
-- An error means that a program has done something invalid and cannot
--continue execution. But not all kinds of errors generate signals--in
--fact, most do not. For example, opening a nonexistent file is an error,
--but it does not raise a signal; instead, `open' returns `-1'. In
--general, errors that are necessarily associated with certain library
--functions are reported by returning a value that indicates an error.
--The errors which raise signals are those which can happen anywhere in
--the program, not just in library calls. These include division by zero
--and invalid memory addresses.
--
-- An external event generally has to do with I/O or other processes.
--These include the arrival of input, the expiration of a timer, and the
--termination of a child process.
--
-- An explicit request means the use of a library function such as
--`kill' whose purpose is specifically to generate a signal.
--
-- Signals may be generated "synchronously" or "asynchronously". A
--synchronous signal pertains to a specific action in the program, and is
--delivered (unless blocked) during that action. Most errors generate
--signals synchronously, and so do explicit requests by a process to
--generate a signal for that same process. On some machines, certain
--kinds of hardware errors (usually floating-point exceptions) are not
--reported completely synchronously, but may arrive a few instructions
--later.
--
-- Asynchronous signals are generated by events outside the control of
--the process that receives them. These signals arrive at unpredictable
--times during execution. External events generate signals
--asynchronously, and so do explicit requests that apply to some other
--process.
--
-- A given type of signal is either typically synchronous or typically
--asynchronous. For example, signals for errors are typically synchronous
--because errors generate signals synchronously. But any type of signal
--can be generated synchronously or asynchronously with an explicit
--request.
--
--
--File: libc.info, Node: Delivery of Signal, Prev: Signal Generation, Up: Concepts of Signals
--
--How Signals Are Delivered
---------------------------
--
-- When a signal is generated, it becomes "pending". Normally it
--remains pending for just a short period of time and then is "delivered"
--to the process that was signaled. However, if that kind of signal is
--currently "blocked", it may remain pending indefinitely--until signals
--of that kind are "unblocked". Once unblocked, it will be delivered
--immediately. *Note Blocking Signals::.
--
-- When the signal is delivered, whether right away or after a long
--delay, the "specified action" for that signal is taken. For certain
--signals, such as `SIGKILL' and `SIGSTOP', the action is fixed, but for
--most signals, the program has a choice: ignore the signal, specify a
--"handler function", or accept the "default action" for that kind of
--signal. The program specifies its choice using functions such as
--`signal' or `sigaction' (*note Signal Actions::.). We sometimes say
--that a handler "catches" the signal. While the handler is running,
--that particular signal is normally blocked.
--
-- If the specified action for a kind of signal is to ignore it, then
--any such signal which is generated is discarded immediately. This
--happens even if the signal is also blocked at the time. A signal
--discarded in this way will never be delivered, not even if the program
--subsequently specifies a different action for that kind of signal and
--then unblocks it.
--
-- If a signal arrives which the program has neither handled nor
--ignored, its "default action" takes place. Each kind of signal has its
--own default action, documented below (*note Standard Signals::.). For
--most kinds of signals, the default action is to terminate the process.
--For certain kinds of signals that represent "harmless" events, the
--default action is to do nothing.
--
-- When a signal terminates a process, its parent process can determine
--the cause of termination by examining the termination status code
--reported by the `wait' or `waitpid' functions. (This is discussed in
--more detail in *Note Process Completion::.) The information it can get
--includes the fact that termination was due to a signal, and the kind of
--signal involved. If a program you run from a shell is terminated by a
--signal, the shell typically prints some kind of error message.
--
-- The signals that normally represent program errors have a special
--property: when one of these signals terminates the process, it also
--writes a "core dump file" which records the state of the process at the
--time of termination. You can examine the core dump with a debugger to
--investigate what caused the error.
--
-- If you raise a "program error" signal by explicit request, and this
--terminates the process, it makes a core dump file just as if the signal
--had been due directly to an error.
--
--
--File: libc.info, Node: Standard Signals, Next: Signal Actions, Prev: Concepts of Signals, Up: Signal Handling
--
--Standard Signals
--================
--
-- This section lists the names for various standard kinds of signals
--and describes what kind of event they mean. Each signal name is a macro
--which stands for a positive integer--the "signal number" for that kind
--of signal. Your programs should never make assumptions about the
--numeric code for a particular kind of signal, but rather refer to them
--always by the names defined here. This is because the number for a
--given kind of signal can vary from system to system, but the meanings of
--the names are standardized and fairly uniform.
--
-- The signal names are defined in the header file `signal.h'.
--
-- - Macro: int NSIG
-- The value of this symbolic constant is the total number of signals
-- defined. Since the signal numbers are allocated consecutively,
-- `NSIG' is also one greater than the largest defined signal number.
--
--* Menu:
--
--* Program Error Signals:: Used to report serious program errors.
--* Termination Signals:: Used to interrupt and/or terminate the
-- program.
--* Alarm Signals:: Used to indicate expiration of timers.
--* Asynchronous I/O Signals:: Used to indicate input is available.
--* Job Control Signals:: Signals used to support job control.
--* Operation Error Signals:: Used to report operational system errors.
--* Miscellaneous Signals:: Miscellaneous Signals.
--* Signal Messages:: Printing a message describing a signal.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-32 glibc-2.1.3/manual/libc.info-32
---- ../glibc-2.1.3/manual/libc.info-32 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-32 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1213 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Program Error Signals, Next: Termination Signals, Up: Standard Signals
--
--Program Error Signals
-----------------------
--
-- The following signals are generated when a serious program error is
--detected by the operating system or the computer itself. In general,
--all of these signals are indications that your program is seriously
--broken in some way, and there's usually no way to continue the
--computation which encountered the error.
--
-- Some programs handle program error signals in order to tidy up before
--terminating; for example, programs that turn off echoing of terminal
--input should handle program error signals in order to turn echoing back
--on. The handler should end by specifying the default action for the
--signal that happened and then reraising it; this will cause the program
--to terminate with that signal, as if it had not had a handler. (*Note
--Termination in Handler::.)
--
-- Termination is the sensible ultimate outcome from a program error in
--most programs. However, programming systems such as Lisp that can load
--compiled user programs might need to keep executing even if a user
--program incurs an error. These programs have handlers which use
--`longjmp' to return control to the command level.
--
-- The default action for all of these signals is to cause the process
--to terminate. If you block or ignore these signals or establish
--handlers for them that return normally, your program will probably
--break horribly when such signals happen, unless they are generated by
--`raise' or `kill' instead of a real error.
--
-- When one of these program error signals terminates a process, it also
--writes a "core dump file" which records the state of the process at the
--time of termination. The core dump file is named `core' and is written
--in whichever directory is current in the process at the time. (On the
--GNU system, you can specify the file name for core dumps with the
--environment variable `COREFILE'.) The purpose of core dump files is so
--that you can examine them with a debugger to investigate what caused
--the error.
--
-- - Macro: int SIGFPE
-- The `SIGFPE' signal reports a fatal arithmetic error. Although the
-- name is derived from "floating-point exception", this signal
-- actually covers all arithmetic errors, including division by zero
-- and overflow. If a program stores integer data in a location
-- which is then used in a floating-point operation, this often
-- causes an "invalid operation" exception, because the processor
-- cannot recognize the data as a floating-point number.
--
-- Actual floating-point exceptions are a complicated subject because
-- there are many types of exceptions with subtly different meanings,
-- and the `SIGFPE' signal doesn't distinguish between them. The
-- `IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std
-- 754-1985 and ANSI/IEEE Std 854-1987)' defines various
-- floating-point exceptions and requires conforming computer systems
-- to report their occurrences. However, this standard does not
-- specify how the exceptions are reported, or what kinds of handling
-- and control the operating system can offer to the programmer.
--
-- BSD systems provide the `SIGFPE' handler with an extra argument that
--distinguishes various causes of the exception. In order to access this
--argument, you must define the handler to accept two arguments, which
--means you must cast it to a one-argument function type in order to
--establish the handler. The GNU library does provide this extra
--argument, but the value is meaningful only on operating systems that
--provide the information (BSD systems and GNU systems).
--
--`FPE_INTOVF_TRAP'
-- Integer overflow (impossible in a C program unless you enable
-- overflow trapping in a hardware-specific fashion).
--
--`FPE_INTDIV_TRAP'
-- Integer division by zero.
--
--`FPE_SUBRNG_TRAP'
-- Subscript-range (something that C programs never check for).
--
--`FPE_FLTOVF_TRAP'
-- Floating overflow trap.
--
--`FPE_FLTDIV_TRAP'
-- Floating/decimal division by zero.
--
--`FPE_FLTUND_TRAP'
-- Floating underflow trap. (Trapping on floating underflow is not
-- normally enabled.)
--
--`FPE_DECOVF_TRAP'
-- Decimal overflow trap. (Only a few machines have decimal
-- arithmetic and C never uses it.)
--
-- - Macro: int SIGILL
-- The name of this signal is derived from "illegal instruction"; it
-- usually means your program is trying to execute garbage or a
-- privileged instruction. Since the C compiler generates only valid
-- instructions, `SIGILL' typically indicates that the executable
-- file is corrupted, or that you are trying to execute data. Some
-- common ways of getting into the latter situation are by passing an
-- invalid object where a pointer to a function was expected, or by
-- writing past the end of an automatic array (or similar problems
-- with pointers to automatic variables) and corrupting other data on
-- the stack such as the return address of a stack frame.
--
-- `SIGILL' can also be generated when the stack overflows, or when
-- the system has trouble running the handler for a signal.
--
-- - Macro: int SIGSEGV
-- This signal is generated when a program tries to read or write
-- outside the memory that is allocated for it, or to write memory
-- that can only be read. (Actually, the signals only occur when the
-- program goes far enough outside to be detected by the system's
-- memory protection mechanism.) The name is an abbreviation for
-- "segmentation violation".
--
-- Common ways of getting a `SIGSEGV' condition include dereferencing
-- a null or uninitialized pointer, or when you use a pointer to step
-- through an array, but fail to check for the end of the array. It
-- varies among systems whether dereferencing a null pointer generates
-- `SIGSEGV' or `SIGBUS'.
--
-- - Macro: int SIGBUS
-- This signal is generated when an invalid pointer is dereferenced.
-- Like `SIGSEGV', this signal is typically the result of
-- dereferencing an uninitialized pointer. The difference between
-- the two is that `SIGSEGV' indicates an invalid access to valid
-- memory, while `SIGBUS' indicates an access to an invalid address.
-- In particular, `SIGBUS' signals often result from dereferencing a
-- misaligned pointer, such as referring to a four-word integer at an
-- address not divisible by four. (Each kind of computer has its own
-- requirements for address alignment.)
--
-- The name of this signal is an abbreviation for "bus error".
--
-- - Macro: int SIGABRT
-- This signal indicates an error detected by the program itself and
-- reported by calling `abort'. *Note Aborting a Program::.
--
-- - Macro: int SIGIOT
-- Generated by the PDP-11 "iot" instruction. On most machines, this
-- is just another name for `SIGABRT'.
--
-- - Macro: int SIGTRAP
-- Generated by the machine's breakpoint instruction, and possibly
-- other trap instructions. This signal is used by debuggers. Your
-- program will probably only see `SIGTRAP' if it is somehow
-- executing bad instructions.
--
-- - Macro: int SIGEMT
-- Emulator trap; this results from certain unimplemented instructions
-- which might be emulated in software, or the operating system's
-- failure to properly emulate them.
--
-- - Macro: int SIGSYS
-- Bad system call; that is to say, the instruction to trap to the
-- operating system was executed, but the code number for the system
-- call to perform was invalid.
--
--
--File: libc.info, Node: Termination Signals, Next: Alarm Signals, Prev: Program Error Signals, Up: Standard Signals
--
--Termination Signals
---------------------
--
-- These signals are all used to tell a process to terminate, in one way
--or another. They have different names because they're used for slightly
--different purposes, and programs might want to handle them differently.
--
-- The reason for handling these signals is usually so your program can
--tidy up as appropriate before actually terminating. For example, you
--might want to save state information, delete temporary files, or restore
--the previous terminal modes. Such a handler should end by specifying
--the default action for the signal that happened and then reraising it;
--this will cause the program to terminate with that signal, as if it had
--not had a handler. (*Note Termination in Handler::.)
--
-- The (obvious) default action for all of these signals is to cause the
--process to terminate.
--
-- - Macro: int SIGTERM
-- The `SIGTERM' signal is a generic signal used to cause program
-- termination. Unlike `SIGKILL', this signal can be blocked,
-- handled, and ignored. It is the normal way to politely ask a
-- program to terminate.
--
-- The shell command `kill' generates `SIGTERM' by default.
--
-- - Macro: int SIGINT
-- The `SIGINT' ("program interrupt") signal is sent when the user
-- types the INTR character (normally `C-c'). *Note Special
-- Characters::, for information about terminal driver support for
-- `C-c'.
--
-- - Macro: int SIGQUIT
-- The `SIGQUIT' signal is similar to `SIGINT', except that it's
-- controlled by a different key--the QUIT character, usually
-- `C-\'--and produces a core dump when it terminates the process,
-- just like a program error signal. You can think of this as a
-- program error condition "detected" by the user.
--
-- *Note Program Error Signals::, for information about core dumps.
-- *Note Special Characters::, for information about terminal driver
-- support.
--
-- Certain kinds of cleanups are best omitted in handling `SIGQUIT'.
-- For example, if the program creates temporary files, it should
-- handle the other termination requests by deleting the temporary
-- files. But it is better for `SIGQUIT' not to delete them, so that
-- the user can examine them in conjunction with the core dump.
--
-- - Macro: int SIGKILL
-- The `SIGKILL' signal is used to cause immediate program
-- termination. It cannot be handled or ignored, and is therefore
-- always fatal. It is also not possible to block this signal.
--
-- This signal is usually generated only by explicit request. Since
-- it cannot be handled, you should generate it only as a last
-- resort, after first trying a less drastic method such as `C-c' or
-- `SIGTERM'. If a process does not respond to any other termination
-- signals, sending it a `SIGKILL' signal will almost always cause it
-- to go away.
--
-- In fact, if `SIGKILL' fails to terminate a process, that by itself
-- constitutes an operating system bug which you should report.
--
-- The system will generate `SIGKILL' for a process itself under some
-- unusual conditions where the program cannot possible continue to
-- run (even to run a signal handler).
--
-- - Macro: int SIGHUP
-- The `SIGHUP' ("hang-up") signal is used to report that the user's
-- terminal is disconnected, perhaps because a network or telephone
-- connection was broken. For more information about this, see *Note
-- Control Modes::.
--
-- This signal is also used to report the termination of the
-- controlling process on a terminal to jobs associated with that
-- session; this termination effectively disconnects all processes in
-- the session from the controlling terminal. For more information,
-- see *Note Termination Internals::.
--
--
--File: libc.info, Node: Alarm Signals, Next: Asynchronous I/O Signals, Prev: Termination Signals, Up: Standard Signals
--
--Alarm Signals
---------------
--
-- These signals are used to indicate the expiration of timers. *Note
--Setting an Alarm::, for information about functions that cause these
--signals to be sent.
--
-- The default behavior for these signals is to cause program
--termination. This default is rarely useful, but no other default would
--be useful; most of the ways of using these signals would require
--handler functions in any case.
--
-- - Macro: int SIGALRM
-- This signal typically indicates expiration of a timer that
-- measures real or clock time. It is used by the `alarm' function,
-- for example.
--
-- - Macro: int SIGVTALRM
-- This signal typically indicates expiration of a timer that
-- measures CPU time used by the current process. The name is an
-- abbreviation for "virtual time alarm".
--
-- - Macro: int SIGPROF
-- This signal is typically indicates expiration of a timer that
-- measures both CPU time used by the current process, and CPU time
-- expended on behalf of the process by the system. Such a timer is
-- used to implement code profiling facilities, hence the name of
-- this signal.
--
--
--File: libc.info, Node: Asynchronous I/O Signals, Next: Job Control Signals, Prev: Alarm Signals, Up: Standard Signals
--
--Asynchronous I/O Signals
--------------------------
--
-- The signals listed in this section are used in conjunction with
--asynchronous I/O facilities. You have to take explicit action by
--calling `fcntl' to enable a particular file descriptor to generate
--these signals (*note Interrupt Input::.). The default action for these
--signals is to ignore them.
--
-- - Macro: int SIGIO
-- This signal is sent when a file descriptor is ready to perform
-- input or output.
--
-- On most operating systems, terminals and sockets are the only
-- kinds of files that can generate `SIGIO'; other kinds, including
-- ordinary files, never generate `SIGIO' even if you ask them to.
--
-- In the GNU system `SIGIO' will always be generated properly if you
-- successfully set asynchronous mode with `fcntl'.
--
-- - Macro: int SIGURG
-- This signal is sent when "urgent" or out-of-band data arrives on a
-- socket. *Note Out-of-Band Data::.
--
-- - Macro: int SIGPOLL
-- This is a System V signal name, more or less similar to `SIGIO'.
-- It is defined only for compatibility.
--
--
--File: libc.info, Node: Job Control Signals, Next: Operation Error Signals, Prev: Asynchronous I/O Signals, Up: Standard Signals
--
--Job Control Signals
---------------------
--
-- These signals are used to support job control. If your system
--doesn't support job control, then these macros are defined but the
--signals themselves can't be raised or handled.
--
-- You should generally leave these signals alone unless you really
--understand how job control works. *Note Job Control::.
--
-- - Macro: int SIGCHLD
-- This signal is sent to a parent process whenever one of its child
-- processes terminates or stops.
--
-- The default action for this signal is to ignore it. If you
-- establish a handler for this signal while there are child
-- processes that have terminated but not reported their status via
-- `wait' or `waitpid' (*note Process Completion::.), whether your
-- new handler applies to those processes or not depends on the
-- particular operating system.
--
-- - Macro: int SIGCLD
-- This is an obsolete name for `SIGCHLD'.
--
-- - Macro: int SIGCONT
-- You can send a `SIGCONT' signal to a process to make it continue.
-- This signal is special--it always makes the process continue if it
-- is stopped, before the signal is delivered. The default behavior
-- is to do nothing else. You cannot block this signal. You can set
-- a handler, but `SIGCONT' always makes the process continue
-- regardless.
--
-- Most programs have no reason to handle `SIGCONT'; they simply
-- resume execution without realizing they were ever stopped. You
-- can use a handler for `SIGCONT' to make a program do something
-- special when it is stopped and continued--for example, to reprint
-- a prompt when it is suspended while waiting for input.
--
-- - Macro: int SIGSTOP
-- The `SIGSTOP' signal stops the process. It cannot be handled,
-- ignored, or blocked.
--
-- - Macro: int SIGTSTP
-- The `SIGTSTP' signal is an interactive stop signal. Unlike
-- `SIGSTOP', this signal can be handled and ignored.
--
-- Your program should handle this signal if you have a special need
-- to leave files or system tables in a secure state when a process is
-- stopped. For example, programs that turn off echoing should handle
-- `SIGTSTP' so they can turn echoing back on before stopping.
--
-- This signal is generated when the user types the SUSP character
-- (normally `C-z'). For more information about terminal driver
-- support, see *Note Special Characters::.
--
-- - Macro: int SIGTTIN
-- A process cannot read from the user's terminal while it is running
-- as a background job. When any process in a background job tries to
-- read from the terminal, all of the processes in the job are sent a
-- `SIGTTIN' signal. The default action for this signal is to stop
-- the process. For more information about how this interacts with
-- the terminal driver, see *Note Access to the Terminal::.
--
-- - Macro: int SIGTTOU
-- This is similar to `SIGTTIN', but is generated when a process in a
-- background job attempts to write to the terminal or set its modes.
-- Again, the default action is to stop the process. `SIGTTOU' is
-- only generated for an attempt to write to the terminal if the
-- `TOSTOP' output mode is set; *note Output Modes::..
--
-- While a process is stopped, no more signals can be delivered to it
--until it is continued, except `SIGKILL' signals and (obviously)
--`SIGCONT' signals. The signals are marked as pending, but not
--delivered until the process is continued. The `SIGKILL' signal always
--causes termination of the process and can't be blocked, handled or
--ignored. You can ignore `SIGCONT', but it always causes the process to
--be continued anyway if it is stopped. Sending a `SIGCONT' signal to a
--process causes any pending stop signals for that process to be
--discarded. Likewise, any pending `SIGCONT' signals for a process are
--discarded when it receives a stop signal.
--
-- When a process in an orphaned process group (*note Orphaned Process
--Groups::.) receives a `SIGTSTP', `SIGTTIN', or `SIGTTOU' signal and
--does not handle it, the process does not stop. Stopping the process
--would probably not be very useful, since there is no shell program that
--will notice it stop and allow the user to continue it. What happens
--instead depends on the operating system you are using. Some systems
--may do nothing; others may deliver another signal instead, such as
--`SIGKILL' or `SIGHUP'. In the GNU system, the process dies with
--`SIGKILL'; this avoids the problem of many stopped, orphaned processes
--lying around the system.
--
--
--File: libc.info, Node: Operation Error Signals, Next: Miscellaneous Signals, Prev: Job Control Signals, Up: Standard Signals
--
--Operation Error Signals
-------------------------
--
-- These signals are used to report various errors generated by an
--operation done by the program. They do not necessarily indicate a
--programming error in the program, but an error that prevents an
--operating system call from completing. The default action for all of
--them is to cause the process to terminate.
--
-- - Macro: int SIGPIPE
-- Broken pipe. If you use pipes or FIFOs, you have to design your
-- application so that one process opens the pipe for reading before
-- another starts writing. If the reading process never starts, or
-- terminates unexpectedly, writing to the pipe or FIFO raises a
-- `SIGPIPE' signal. If `SIGPIPE' is blocked, handled or ignored,
-- the offending call fails with `EPIPE' instead.
--
-- Pipes and FIFO special files are discussed in more detail in *Note
-- Pipes and FIFOs::.
--
-- Another cause of `SIGPIPE' is when you try to output to a socket
-- that isn't connected. *Note Sending Data::.
--
-- - Macro: int SIGLOST
-- Resource lost. This signal is generated when you have an advisory
-- lock on an NFS file, and the NFS server reboots and forgets about
-- your lock.
--
-- In the GNU system, `SIGLOST' is generated when any server program
-- dies unexpectedly. It is usually fine to ignore the signal;
-- whatever call was made to the server that died just returns an
-- error.
--
-- - Macro: int SIGXCPU
-- CPU time limit exceeded. This signal is generated when the process
-- exceeds its soft resource limit on CPU time. *Note Limits on
-- Resources::.
--
-- - Macro: int SIGXFSZ
-- File size limit exceeded. This signal is generated when the
-- process attempts to extend a file so it exceeds the process's soft
-- resource limit on file size. *Note Limits on Resources::.
--
--
--File: libc.info, Node: Miscellaneous Signals, Next: Signal Messages, Prev: Operation Error Signals, Up: Standard Signals
--
--Miscellaneous Signals
-----------------------
--
-- These signals are used for various other purposes. In general, they
--will not affect your program unless it explicitly uses them for
--something.
--
-- - Macro: int SIGUSR1
-- - Macro: int SIGUSR2
-- The `SIGUSR1' and `SIGUSR2' signals are set aside for you to use
-- any way you want. They're useful for simple interprocess
-- communication, if you write a signal handler for them in the
-- program that receives the signal.
--
-- There is an example showing the use of `SIGUSR1' and `SIGUSR2' in
-- *Note Signaling Another Process::.
--
-- The default action is to terminate the process.
--
-- - Macro: int SIGWINCH
-- Window size change. This is generated on some systems (including
-- GNU) when the terminal driver's record of the number of rows and
-- columns on the screen is changed. The default action is to ignore
-- it.
--
-- If a program does full-screen display, it should handle `SIGWINCH'.
-- When the signal arrives, it should fetch the new screen size and
-- reformat its display accordingly.
--
-- - Macro: int SIGINFO
-- Information request. In 4.4 BSD and the GNU system, this signal
-- is sent to all the processes in the foreground process group of
-- the controlling terminal when the user types the STATUS character
-- in canonical mode; *note Signal Characters::..
--
-- If the process is the leader of the process group, the default
-- action is to print some status information about the system and
-- what the process is doing. Otherwise the default is to do nothing.
--
--
--File: libc.info, Node: Signal Messages, Prev: Miscellaneous Signals, Up: Standard Signals
--
--Signal Messages
-----------------
--
-- We mentioned above that the shell prints a message describing the
--signal that terminated a child process. The clean way to print a
--message describing a signal is to use the functions `strsignal' and
--`psignal'. These functions use a signal number to specify which kind
--of signal to describe. The signal number may come from the termination
--status of a child process (*note Process Completion::.) or it may come
--from a signal handler in the same process.
--
-- - Function: char * strsignal (int SIGNUM)
-- This function returns a pointer to a statically-allocated string
-- containing a message describing the signal SIGNUM. You should not
-- modify the contents of this string; and, since it can be rewritten
-- on subsequent calls, you should save a copy of it if you need to
-- reference it later.
--
-- This function is a GNU extension, declared in the header file
-- `string.h'.
--
-- - Function: void psignal (int SIGNUM, const char *MESSAGE)
-- This function prints a message describing the signal SIGNUM to the
-- standard error output stream `stderr'; see *Note Standard
-- Streams::.
--
-- If you call `psignal' with a MESSAGE that is either a null pointer
-- or an empty string, `psignal' just prints the message
-- corresponding to SIGNUM, adding a trailing newline.
--
-- If you supply a non-null MESSAGE argument, then `psignal' prefixes
-- its output with this string. It adds a colon and a space
-- character to separate the MESSAGE from the string corresponding to
-- SIGNUM.
--
-- This function is a BSD feature, declared in the header file
-- `signal.h'.
--
-- There is also an array `sys_siglist' which contains the messages for
--the various signal codes. This array exists on BSD systems, unlike
--`strsignal'.
--
--
--File: libc.info, Node: Signal Actions, Next: Defining Handlers, Prev: Standard Signals, Up: Signal Handling
--
--Specifying Signal Actions
--=========================
--
-- The simplest way to change the action for a signal is to use the
--`signal' function. You can specify a built-in action (such as to
--ignore the signal), or you can "establish a handler".
--
-- The GNU library also implements the more versatile `sigaction'
--facility. This section describes both facilities and gives suggestions
--on which to use when.
--
--* Menu:
--
--* Basic Signal Handling:: The simple `signal' function.
--* Advanced Signal Handling:: The more powerful `sigaction' function.
--* Signal and Sigaction:: How those two functions interact.
--* Sigaction Function Example:: An example of using the sigaction function.
--* Flags for Sigaction:: Specifying options for signal handling.
--* Initial Signal Actions:: How programs inherit signal actions.
--
--
--File: libc.info, Node: Basic Signal Handling, Next: Advanced Signal Handling, Up: Signal Actions
--
--Basic Signal Handling
-----------------------
--
-- The `signal' function provides a simple interface for establishing
--an action for a particular signal. The function and associated macros
--are declared in the header file `signal.h'.
--
-- - Data Type: sighandler_t
-- This is the type of signal handler functions. Signal handlers
-- take one integer argument specifying the signal number, and have
-- return type `void'. So, you should define handler functions like
-- this:
--
-- void HANDLER (int `signum') { ... }
--
-- The name `sighandler_t' for this data type is a GNU extension.
--
-- - Function: sighandler_t signal (int SIGNUM, sighandler_t ACTION)
-- The `signal' function establishes ACTION as the action for the
-- signal SIGNUM.
--
-- The first argument, SIGNUM, identifies the signal whose behavior
-- you want to control, and should be a signal number. The proper
-- way to specify a signal number is with one of the symbolic signal
-- names (*note Standard Signals::.)--don't use an explicit number,
-- because the numerical code for a given kind of signal may vary
-- from operating system to operating system.
--
-- The second argument, ACTION, specifies the action to use for the
-- signal SIGNUM. This can be one of the following:
--
-- `SIG_DFL'
-- `SIG_DFL' specifies the default action for the particular
-- signal. The default actions for various kinds of signals are
-- stated in *Note Standard Signals::.
--
-- `SIG_IGN'
-- `SIG_IGN' specifies that the signal should be ignored.
--
-- Your program generally should not ignore signals that
-- represent serious events or that are normally used to request
-- termination. You cannot ignore the `SIGKILL' or `SIGSTOP'
-- signals at all. You can ignore program error signals like
-- `SIGSEGV', but ignoring the error won't enable the program to
-- continue executing meaningfully. Ignoring user requests such
-- as `SIGINT', `SIGQUIT', and `SIGTSTP' is unfriendly.
--
-- When you do not wish signals to be delivered during a certain
-- part of the program, the thing to do is to block them, not
-- ignore them. *Note Blocking Signals::.
--
-- `HANDLER'
-- Supply the address of a handler function in your program, to
-- specify running this handler as the way to deliver the signal.
--
-- For more information about defining signal handler functions,
-- see *Note Defining Handlers::.
--
-- If you set the action for a signal to `SIG_IGN', or if you set it
-- to `SIG_DFL' and the default action is to ignore that signal, then
-- any pending signals of that type are discarded (even if they are
-- blocked). Discarding the pending signals means that they will
-- never be delivered, not even if you subsequently specify another
-- action and unblock this kind of signal.
--
-- The `signal' function returns the action that was previously in
-- effect for the specified SIGNUM. You can save this value and
-- restore it later by calling `signal' again.
--
-- If `signal' can't honor the request, it returns `SIG_ERR' instead.
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EINVAL'
-- You specified an invalid SIGNUM; or you tried to ignore or
-- provide a handler for `SIGKILL' or `SIGSTOP'.
--
-- *Compatibility Note:* A problem when working with the `signal'
--function is that it has a different semantic on BSD and SVID system.
--The difference is that on SVID systems the signal handler is
--deinstalled after an signal was delivered. On BSD systems the handler
--must be explicitly deinstalled. In the GNU C Library we use the BSD
--version by default. To use the SVID version you can either use the
--function `sysv_signal' (see below) or use the `_XOPEN_SOURCE' feature
--select macro (*note Feature Test Macros::.). Generally it should be
--avoided to use this functions due to the compatibility problems. It is
--better to use `sigaction' if it is available since the results are much
--more reliable.
--
-- Here is a simple example of setting up a handler to delete temporary
--files when certain fatal signals happen:
--
-- #include <signal.h>
--
-- void
-- termination_handler (int signum)
-- {
-- struct temp_file *p;
--
-- for (p = temp_file_list; p; p = p->next)
-- unlink (p->name);
-- }
--
-- int
-- main (void)
-- {
-- ...
-- if (signal (SIGINT, termination_handler) == SIG_IGN)
-- signal (SIGINT, SIG_IGN);
-- if (signal (SIGHUP, termination_handler) == SIG_IGN)
-- signal (SIGHUP, SIG_IGN);
-- if (signal (SIGTERM, termination_handler) == SIG_IGN)
-- signal (SIGTERM, SIG_IGN);
-- ...
-- }
--
--Note how if a given signal was previously set to be ignored, this code
--avoids altering that setting. This is because non-job-control shells
--often ignore certain signals when starting children, and it is important
--for the children to respect this.
--
-- We do not handle `SIGQUIT' or the program error signals in this
--example because these are designed to provide information for debugging
--(a core dump), and the temporary files may give useful information.
--
-- - Function: sighandler_t sysv_signal (int SIGNUM, sighandler_t ACTION)
-- The `sysv_signal' implements the behaviour of the standard
-- `signal' function as found on SVID systems. The difference to BSD
-- systems is that the handler is deinstalled after a delivery of a
-- signal.
--
-- *Compatibility Note:* As said above for `signal', this function
-- should be avoided when possible. `sigaction' is the preferred
-- method.
--
-- - Function: sighandler_t ssignal (int SIGNUM, sighandler_t ACTION)
-- The `ssignal' function does the same thing as `signal'; it is
-- provided only for compatibility with SVID.
--
-- - Macro: sighandler_t SIG_ERR
-- The value of this macro is used as the return value from `signal'
-- to indicate an error.
--
--
--File: libc.info, Node: Advanced Signal Handling, Next: Signal and Sigaction, Prev: Basic Signal Handling, Up: Signal Actions
--
--Advanced Signal Handling
--------------------------
--
-- The `sigaction' function has the same basic effect as `signal': to
--specify how a signal should be handled by the process. However,
--`sigaction' offers more control, at the expense of more complexity. In
--particular, `sigaction' allows you to specify additional flags to
--control when the signal is generated and how the handler is invoked.
--
-- The `sigaction' function is declared in `signal.h'.
--
-- - Data Type: struct sigaction
-- Structures of type `struct sigaction' are used in the `sigaction'
-- function to specify all the information about how to handle a
-- particular signal. This structure contains at least the following
-- members:
--
-- `sighandler_t sa_handler'
-- This is used in the same way as the ACTION argument to the
-- `signal' function. The value can be `SIG_DFL', `SIG_IGN', or
-- a function pointer. *Note Basic Signal Handling::.
--
-- `sigset_t sa_mask'
-- This specifies a set of signals to be blocked while the
-- handler runs. Blocking is explained in *Note Blocking for
-- Handler::. Note that the signal that was delivered is
-- automatically blocked by default before its handler is
-- started; this is true regardless of the value in `sa_mask'.
-- If you want that signal not to be blocked within its handler,
-- you must write code in the handler to unblock it.
--
-- `int sa_flags'
-- This specifies various flags which can affect the behavior of
-- the signal. These are described in more detail in *Note
-- Flags for Sigaction::.
--
-- - Function: int sigaction (int SIGNUM, const struct sigaction *ACTION,
-- struct sigaction *OLD-ACTION)
-- The ACTION argument is used to set up a new action for the signal
-- SIGNUM, while the OLD-ACTION argument is used to return
-- information about the action previously associated with this
-- symbol. (In other words, OLD-ACTION has the same purpose as the
-- `signal' function's return value--you can check to see what the
-- old action in effect for the signal was, and restore it later if
-- you want.)
--
-- Either ACTION or OLD-ACTION can be a null pointer. If OLD-ACTION
-- is a null pointer, this simply suppresses the return of
-- information about the old action. If ACTION is a null pointer,
-- the action associated with the signal SIGNUM is unchanged; this
-- allows you to inquire about how a signal is being handled without
-- changing that handling.
--
-- The return value from `sigaction' is zero if it succeeds, and `-1'
-- on failure. The following `errno' error conditions are defined
-- for this function:
--
-- `EINVAL'
-- The SIGNUM argument is not valid, or you are trying to trap
-- or ignore `SIGKILL' or `SIGSTOP'.
--
--
--File: libc.info, Node: Signal and Sigaction, Next: Sigaction Function Example, Prev: Advanced Signal Handling, Up: Signal Actions
--
--Interaction of `signal' and `sigaction'
-----------------------------------------
--
-- It's possible to use both the `signal' and `sigaction' functions
--within a single program, but you have to be careful because they can
--interact in slightly strange ways.
--
-- The `sigaction' function specifies more information than the
--`signal' function, so the return value from `signal' cannot express the
--full range of `sigaction' possibilities. Therefore, if you use
--`signal' to save and later reestablish an action, it may not be able to
--reestablish properly a handler that was established with `sigaction'.
--
-- To avoid having problems as a result, always use `sigaction' to save
--and restore a handler if your program uses `sigaction' at all. Since
--`sigaction' is more general, it can properly save and reestablish any
--action, regardless of whether it was established originally with
--`signal' or `sigaction'.
--
-- On some systems if you establish an action with `signal' and then
--examine it with `sigaction', the handler address that you get may not
--be the same as what you specified with `signal'. It may not even be
--suitable for use as an action argument with `signal'. But you can rely
--on using it as an argument to `sigaction'. This problem never happens
--on the GNU system.
--
-- So, you're better off using one or the other of the mechanisms
--consistently within a single program.
--
-- *Portability Note:* The basic `signal' function is a feature of
--ISO C, while `sigaction' is part of the POSIX.1 standard. If you are
--concerned about portability to non-POSIX systems, then you should use
--the `signal' function instead.
--
--
--File: libc.info, Node: Sigaction Function Example, Next: Flags for Sigaction, Prev: Signal and Sigaction, Up: Signal Actions
--
--`sigaction' Function Example
------------------------------
--
-- In *Note Basic Signal Handling::, we gave an example of establishing
--a simple handler for termination signals using `signal'. Here is an
--equivalent example using `sigaction':
--
-- #include <signal.h>
--
-- void
-- termination_handler (int signum)
-- {
-- struct temp_file *p;
--
-- for (p = temp_file_list; p; p = p->next)
-- unlink (p->name);
-- }
--
-- int
-- main (void)
-- {
-- ...
-- struct sigaction new_action, old_action;
--
-- /* Set up the structure to specify the new action. */
-- new_action.sa_handler = termination_handler;
-- sigemptyset (&new_action.sa_mask);
-- new_action.sa_flags = 0;
--
-- sigaction (SIGINT, NULL, &old_action);
-- if (old_action.sa_handler != SIG_IGN)
-- sigaction (SIGINT, &new_action, NULL);
-- sigaction (SIGHUP, NULL, &old_action);
-- if (old_action.sa_handler != SIG_IGN)
-- sigaction (SIGHUP, &new_action, NULL);
-- sigaction (SIGTERM, NULL, &old_action);
-- if (old_action.sa_handler != SIG_IGN)
-- sigaction (SIGTERM, &new_action, NULL);
-- ...
-- }
--
-- The program just loads the `new_action' structure with the desired
--parameters and passes it in the `sigaction' call. The usage of
--`sigemptyset' is described later; see *Note Blocking Signals::.
--
-- As in the example using `signal', we avoid handling signals
--previously set to be ignored. Here we can avoid altering the signal
--handler even momentarily, by using the feature of `sigaction' that lets
--us examine the current action without specifying a new one.
--
-- Here is another example. It retrieves information about the current
--action for `SIGINT' without changing that action.
--
-- struct sigaction query_action;
--
-- if (sigaction (SIGINT, NULL, &query_action) < 0)
-- /* `sigaction' returns -1 in case of error. */
-- else if (query_action.sa_handler == SIG_DFL)
-- /* `SIGINT' is handled in the default, fatal manner. */
-- else if (query_action.sa_handler == SIG_IGN)
-- /* `SIGINT' is ignored. */
-- else
-- /* A programmer-defined signal handler is in effect. */
--
--
--File: libc.info, Node: Flags for Sigaction, Next: Initial Signal Actions, Prev: Sigaction Function Example, Up: Signal Actions
--
--Flags for `sigaction'
-----------------------
--
-- The `sa_flags' member of the `sigaction' structure is a catch-all
--for special features. Most of the time, `SA_RESTART' is a good value
--to use for this field.
--
-- The value of `sa_flags' is interpreted as a bit mask. Thus, you
--should choose the flags you want to set, OR those flags together, and
--store the result in the `sa_flags' member of your `sigaction' structure.
--
-- Each signal number has its own set of flags. Each call to
--`sigaction' affects one particular signal number, and the flags that
--you specify apply only to that particular signal.
--
-- In the GNU C library, establishing a handler with `signal' sets all
--the flags to zero except for `SA_RESTART', whose value depends on the
--settings you have made with `siginterrupt'. *Note Interrupted
--Primitives::, to see what this is about.
--
-- These macros are defined in the header file `signal.h'.
--
-- - Macro: int SA_NOCLDSTOP
-- This flag is meaningful only for the `SIGCHLD' signal. When the
-- flag is set, the system delivers the signal for a terminated child
-- process but not for one that is stopped. By default, `SIGCHLD' is
-- delivered for both terminated children and stopped children.
--
-- Setting this flag for a signal other than `SIGCHLD' has no effect.
--
-- - Macro: int SA_ONSTACK
-- If this flag is set for a particular signal number, the system
-- uses the signal stack when delivering that kind of signal. *Note
-- Signal Stack::. If a signal with this flag arrives and you have
-- not set a signal stack, the system terminates the program with
-- `SIGILL'.
--
-- - Macro: int SA_RESTART
-- This flag controls what happens when a signal is delivered during
-- certain primitives (such as `open', `read' or `write'), and the
-- signal handler returns normally. There are two alternatives: the
-- library function can resume, or it can return failure with error
-- code `EINTR'.
--
-- The choice is controlled by the `SA_RESTART' flag for the
-- particular kind of signal that was delivered. If the flag is set,
-- returning from a handler resumes the library function. If the
-- flag is clear, returning from a handler makes the function fail.
-- *Note Interrupted Primitives::.
--
--
--File: libc.info, Node: Initial Signal Actions, Prev: Flags for Sigaction, Up: Signal Actions
--
--Initial Signal Actions
------------------------
--
-- When a new process is created (*note Creating a Process::.), it
--inherits handling of signals from its parent process. However, when
--you load a new process image using the `exec' function (*note Executing
--a File::.), any signals that you've defined your own handlers for
--revert to their `SIG_DFL' handling. (If you think about it a little,
--this makes sense; the handler functions from the old program are
--specific to that program, and aren't even present in the address space
--of the new program image.) Of course, the new program can establish
--its own handlers.
--
-- When a program is run by a shell, the shell normally sets the initial
--actions for the child process to `SIG_DFL' or `SIG_IGN', as
--appropriate. It's a good idea to check to make sure that the shell has
--not set up an initial action of `SIG_IGN' before you establish your own
--signal handlers.
--
-- Here is an example of how to establish a handler for `SIGHUP', but
--not if `SIGHUP' is currently ignored:
--
-- ...
-- struct sigaction temp;
--
-- sigaction (SIGHUP, NULL, &temp);
--
-- if (temp.sa_handler != SIG_IGN)
-- {
-- temp.sa_handler = handle_sighup;
-- sigemptyset (&temp.sa_mask);
-- sigaction (SIGHUP, &temp, NULL);
-- }
--
--
--File: libc.info, Node: Defining Handlers, Next: Interrupted Primitives, Prev: Signal Actions, Up: Signal Handling
--
--Defining Signal Handlers
--========================
--
-- This section describes how to write a signal handler function that
--can be established with the `signal' or `sigaction' functions.
--
-- A signal handler is just a function that you compile together with
--the rest of the program. Instead of directly invoking the function,
--you use `signal' or `sigaction' to tell the operating system to call it
--when a signal arrives. This is known as "establishing" the handler.
--*Note Signal Actions::.
--
-- There are two basic strategies you can use in signal handler
--functions:
--
-- * You can have the handler function note that the signal arrived by
-- tweaking some global data structures, and then return normally.
--
-- * You can have the handler function terminate the program or transfer
-- control to a point where it can recover from the situation that
-- caused the signal.
--
-- You need to take special care in writing handler functions because
--they can be called asynchronously. That is, a handler might be called
--at any point in the program, unpredictably. If two signals arrive
--during a very short interval, one handler can run within another. This
--section describes what your handler should do, and what you should
--avoid.
--
--* Menu:
--
--* Handler Returns:: Handlers that return normally, and what
-- this means.
--* Termination in Handler:: How handler functions terminate a program.
--* Longjmp in Handler:: Nonlocal transfer of control out of a
-- signal handler.
--* Signals in Handler:: What happens when signals arrive while
-- the handler is already occupied.
--* Merged Signals:: When a second signal arrives before the
-- first is handled.
--* Nonreentrancy:: Do not call any functions unless you know they
-- are reentrant with respect to signals.
--* Atomic Data Access:: A single handler can run in the middle of
-- reading or writing a single object.
--
--
--File: libc.info, Node: Handler Returns, Next: Termination in Handler, Up: Defining Handlers
--
--Signal Handlers that Return
-----------------------------
--
-- Handlers which return normally are usually used for signals such as
--`SIGALRM' and the I/O and interprocess communication signals. But a
--handler for `SIGINT' might also return normally after setting a flag
--that tells the program to exit at a convenient time.
--
-- It is not safe to return normally from the handler for a program
--error signal, because the behavior of the program when the handler
--function returns is not defined after a program error. *Note Program
--Error Signals::.
--
-- Handlers that return normally must modify some global variable in
--order to have any effect. Typically, the variable is one that is
--examined periodically by the program during normal operation. Its data
--type should be `sig_atomic_t' for reasons described in *Note Atomic
--Data Access::.
--
-- Here is a simple example of such a program. It executes the body of
--the loop until it has noticed that a `SIGALRM' signal has arrived.
--This technique is useful because it allows the iteration in progress
--when the signal arrives to complete before the loop exits.
--
-- #include <signal.h>
-- #include <stdio.h>
-- #include <stdlib.h>
--
-- /* This flag controls termination of the main loop. */
-- volatile sig_atomic_t keep_going = 1;
--
-- /* The signal handler just clears the flag and re-enables itself. */
-- void
-- catch_alarm (int sig)
-- {
-- keep_going = 0;
-- signal (sig, catch_alarm);
-- }
--
-- void
-- do_stuff (void)
-- {
-- puts ("Doing stuff while waiting for alarm....");
-- }
--
-- int
-- main (void)
-- {
-- /* Establish a handler for SIGALRM signals. */
-- signal (SIGALRM, catch_alarm);
--
-- /* Set an alarm to go off in a little while. */
-- alarm (2);
--
-- /* Check the flag once in a while to see when to quit. */
-- while (keep_going)
-- do_stuff ();
--
-- return EXIT_SUCCESS;
-- }
--
--
--File: libc.info, Node: Termination in Handler, Next: Longjmp in Handler, Prev: Handler Returns, Up: Defining Handlers
--
--Handlers That Terminate the Process
-------------------------------------
--
-- Handler functions that terminate the program are typically used to
--cause orderly cleanup or recovery from program error signals and
--interactive interrupts.
--
-- The cleanest way for a handler to terminate the process is to raise
--the same signal that ran the handler in the first place. Here is how
--to do this:
--
-- volatile sig_atomic_t fatal_error_in_progress = 0;
--
-- void
-- fatal_error_signal (int sig)
-- {
-- /* Since this handler is established for more than one kind of signal,
-- it might still get invoked recursively by delivery of some other kind
-- of signal. Use a static variable to keep track of that. */
-- if (fatal_error_in_progress)
-- raise (sig);
-- fatal_error_in_progress = 1;
--
-- /* Now do the clean up actions:
-- - reset terminal modes
-- - kill child processes
-- - remove lock files */
-- ...
--
-- /* Now reraise the signal. We reactivate the signal's
-- default handling, which is to terminate the process.
-- We could just call `exit' or `abort',
-- but reraising the signal sets the return status
-- from the process correctly. */
-- signal (sig, SIG_DFL);
-- raise (sig);
-- }
--
--
--File: libc.info, Node: Longjmp in Handler, Next: Signals in Handler, Prev: Termination in Handler, Up: Defining Handlers
--
--Nonlocal Control Transfer in Handlers
---------------------------------------
--
-- You can do a nonlocal transfer of control out of a signal handler
--using the `setjmp' and `longjmp' facilities (*note Non-Local Exits::.).
--
-- When the handler does a nonlocal control transfer, the part of the
--program that was running will not continue. If this part of the program
--was in the middle of updating an important data structure, the data
--structure will remain inconsistent. Since the program does not
--terminate, the inconsistency is likely to be noticed later on.
--
-- There are two ways to avoid this problem. One is to block the signal
--for the parts of the program that update important data structures.
--Blocking the signal delays its delivery until it is unblocked, once the
--critical updating is finished. *Note Blocking Signals::.
--
-- The other way to re-initialize the crucial data structures in the
--signal handler, or make their values consistent.
--
-- Here is a rather schematic example showing the reinitialization of
--one global variable.
--
-- #include <signal.h>
-- #include <setjmp.h>
--
-- jmp_buf return_to_top_level;
--
-- volatile sig_atomic_t waiting_for_input;
--
-- void
-- handle_sigint (int signum)
-- {
-- /* We may have been waiting for input when the signal arrived,
-- but we are no longer waiting once we transfer control. */
-- waiting_for_input = 0;
-- longjmp (return_to_top_level, 1);
-- }
--
-- int
-- main (void)
-- {
-- ...
-- signal (SIGINT, sigint_handler);
-- ...
-- while (1) {
-- prepare_for_command ();
-- if (setjmp (return_to_top_level) == 0)
-- read_and_execute_command ();
-- }
-- }
--
-- /* Imagine this is a subroutine used by various commands. */
-- char *
-- read_data ()
-- {
-- if (input_from_terminal) {
-- waiting_for_input = 1;
-- ...
-- waiting_for_input = 0;
-- } else {
-- ...
-- }
-- }
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-33 glibc-2.1.3/manual/libc.info-33
---- ../glibc-2.1.3/manual/libc.info-33 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-33 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1181 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Signals in Handler, Next: Merged Signals, Prev: Longjmp in Handler, Up: Defining Handlers
--
--Signals Arriving While a Handler Runs
---------------------------------------
--
-- What happens if another signal arrives while your signal handler
--function is running?
--
-- When the handler for a particular signal is invoked, that signal is
--automatically blocked until the handler returns. That means that if two
--signals of the same kind arrive close together, the second one will be
--held until the first has been handled. (The handler can explicitly
--unblock the signal using `sigprocmask', if you want to allow more
--signals of this type to arrive; see *Note Process Signal Mask::.)
--
-- However, your handler can still be interrupted by delivery of another
--kind of signal. To avoid this, you can use the `sa_mask' member of the
--action structure passed to `sigaction' to explicitly specify which
--signals should be blocked while the signal handler runs. These signals
--are in addition to the signal for which the handler was invoked, and
--any other signals that are normally blocked by the process. *Note
--Blocking for Handler::.
--
-- When the handler returns, the set of blocked signals is restored to
--the value it had before the handler ran. So using `sigprocmask' inside
--the handler only affects what signals can arrive during the execution of
--the handler itself, not what signals can arrive once the handler
--returns.
--
-- *Portability Note:* Always use `sigaction' to establish a handler
--for a signal that you expect to receive asynchronously, if you want
--your program to work properly on System V Unix. On this system, the
--handling of a signal whose handler was established with `signal'
--automatically sets the signal's action back to `SIG_DFL', and the
--handler must re-establish itself each time it runs. This practice,
--while inconvenient, does work when signals cannot arrive in succession.
--However, if another signal can arrive right away, it may arrive before
--the handler can re-establish itself. Then the second signal would
--receive the default handling, which could terminate the process.
--
--
--File: libc.info, Node: Merged Signals, Next: Nonreentrancy, Prev: Signals in Handler, Up: Defining Handlers
--
--Signals Close Together Merge into One
---------------------------------------
--
-- If multiple signals of the same type are delivered to your process
--before your signal handler has a chance to be invoked at all, the
--handler may only be invoked once, as if only a single signal had
--arrived. In effect, the signals merge into one. This situation can
--arise when the signal is blocked, or in a multiprocessing environment
--where the system is busy running some other processes while the signals
--are delivered. This means, for example, that you cannot reliably use a
--signal handler to count signals. The only distinction you can reliably
--make is whether at least one signal has arrived since a given time in
--the past.
--
-- Here is an example of a handler for `SIGCHLD' that compensates for
--the fact that the number of signals received may not equal the number of
--child processes generate them. It assumes that the program keeps track
--of all the child processes with a chain of structures as follows:
--
-- struct process
-- {
-- struct process *next;
-- /* The process ID of this child. */
-- int pid;
-- /* The descriptor of the pipe or pseudo terminal
-- on which output comes from this child. */
-- int input_descriptor;
-- /* Nonzero if this process has stopped or terminated. */
-- sig_atomic_t have_status;
-- /* The status of this child; 0 if running,
-- otherwise a status value from `waitpid'. */
-- int status;
-- };
--
-- struct process *process_list;
--
-- This example also uses a flag to indicate whether signals have
--arrived since some time in the past--whenever the program last cleared
--it to zero.
--
-- /* Nonzero means some child's status has changed
-- so look at `process_list' for the details. */
-- int process_status_change;
--
-- Here is the handler itself:
--
-- void
-- sigchld_handler (int signo)
-- {
-- int old_errno = errno;
--
-- while (1) {
-- register int pid;
-- int w;
-- struct process *p;
--
-- /* Keep asking for a status until we get a definitive result. */
-- do
-- {
-- errno = 0;
-- pid = waitpid (WAIT_ANY, &w, WNOHANG | WUNTRACED);
-- }
-- while (pid <= 0 && errno == EINTR);
--
-- if (pid <= 0) {
-- /* A real failure means there are no more
-- stopped or terminated child processes, so return. */
-- errno = old_errno;
-- return;
-- }
--
-- /* Find the process that signaled us, and record its status. */
--
-- for (p = process_list; p; p = p->next)
-- if (p->pid == pid) {
-- p->status = w;
-- /* Indicate that the `status' field
-- has data to look at. We do this only after storing it. */
-- p->have_status = 1;
--
-- /* If process has terminated, stop waiting for its output. */
-- if (WIFSIGNALED (w) || WIFEXITED (w))
-- if (p->input_descriptor)
-- FD_CLR (p->input_descriptor, &input_wait_mask);
--
-- /* The program should check this flag from time to time
-- to see if there is any news in `process_list'. */
-- ++process_status_change;
-- }
--
-- /* Loop around to handle all the processes
-- that have something to tell us. */
-- }
-- }
--
-- Here is the proper way to check the flag `process_status_change':
--
-- if (process_status_change) {
-- struct process *p;
-- process_status_change = 0;
-- for (p = process_list; p; p = p->next)
-- if (p->have_status) {
-- ... Examine `p->status' ...
-- }
-- }
--
--It is vital to clear the flag before examining the list; otherwise, if a
--signal were delivered just before the clearing of the flag, and after
--the appropriate element of the process list had been checked, the status
--change would go unnoticed until the next signal arrived to set the flag
--again. You could, of course, avoid this problem by blocking the signal
--while scanning the list, but it is much more elegant to guarantee
--correctness by doing things in the right order.
--
-- The loop which checks process status avoids examining `p->status'
--until it sees that status has been validly stored. This is to make sure
--that the status cannot change in the middle of accessing it. Once
--`p->have_status' is set, it means that the child process is stopped or
--terminated, and in either case, it cannot stop or terminate again until
--the program has taken notice. *Note Atomic Usage::, for more
--information about coping with interruptions during accessings of a
--variable.
--
-- Here is another way you can test whether the handler has run since
--the last time you checked. This technique uses a counter which is never
--changed outside the handler. Instead of clearing the count, the program
--remembers the previous value and sees whether it has changed since the
--previous check. The advantage of this method is that different parts of
--the program can check independently, each part checking whether there
--has been a signal since that part last checked.
--
-- sig_atomic_t process_status_change;
--
-- sig_atomic_t last_process_status_change;
--
-- ...
-- {
-- sig_atomic_t prev = last_process_status_change;
-- last_process_status_change = process_status_change;
-- if (last_process_status_change != prev) {
-- struct process *p;
-- for (p = process_list; p; p = p->next)
-- if (p->have_status) {
-- ... Examine `p->status' ...
-- }
-- }
-- }
--
--
--File: libc.info, Node: Nonreentrancy, Next: Atomic Data Access, Prev: Merged Signals, Up: Defining Handlers
--
--Signal Handling and Nonreentrant Functions
--------------------------------------------
--
-- Handler functions usually don't do very much. The best practice is
--to write a handler that does nothing but set an external variable that
--the program checks regularly, and leave all serious work to the program.
--This is best because the handler can be called at asynchronously, at
--unpredictable times--perhaps in the middle of a primitive function, or
--even between the beginning and the end of a C operator that requires
--multiple instructions. The data structures being manipulated might
--therefore be in an inconsistent state when the handler function is
--invoked. Even copying one `int' variable into another can take two
--instructions on most machines.
--
-- This means you have to be very careful about what you do in a signal
--handler.
--
-- * If your handler needs to access any global variables from your
-- program, declare those variables `volatile'. This tells the
-- compiler that the value of the variable might change
-- asynchronously, and inhibits certain optimizations that would be
-- invalidated by such modifications.
--
-- * If you call a function in the handler, make sure it is "reentrant"
-- with respect to signals, or else make sure that the signal cannot
-- interrupt a call to a related function.
--
-- A function can be non-reentrant if it uses memory that is not on the
--stack.
--
-- * If a function uses a static variable or a global variable, or a
-- dynamically-allocated object that it finds for itself, then it is
-- non-reentrant and any two calls to the function can interfere.
--
-- For example, suppose that the signal handler uses `gethostbyname'.
-- This function returns its value in a static object, reusing the
-- same object each time. If the signal happens to arrive during a
-- call to `gethostbyname', or even after one (while the program is
-- still using the value), it will clobber the value that the program
-- asked for.
--
-- However, if the program does not use `gethostbyname' or any other
-- function that returns information in the same object, or if it
-- always blocks signals around each use, then you are safe.
--
-- There are a large number of library functions that return values
-- in a fixed object, always reusing the same object in this fashion,
-- and all of them cause the same problem. The description of a
-- function in this manual always mentions this behavior.
--
-- * If a function uses and modifies an object that you supply, then it
-- is potentially non-reentrant; two calls can interfere if they use
-- the same object.
--
-- This case arises when you do I/O using streams. Suppose that the
-- signal handler prints a message with `fprintf'. Suppose that the
-- program was in the middle of an `fprintf' call using the same
-- stream when the signal was delivered. Both the signal handler's
-- message and the program's data could be corrupted, because both
-- calls operate on the same data structure--the stream itself.
--
-- However, if you know that the stream that the handler uses cannot
-- possibly be used by the program at a time when signals can arrive,
-- then you are safe. It is no problem if the program uses some
-- other stream.
--
-- * On most systems, `malloc' and `free' are not reentrant, because
-- they use a static data structure which records what memory blocks
-- are free. As a result, no library functions that allocate or free
-- memory are reentrant. This includes functions that allocate space
-- to store a result.
--
-- The best way to avoid the need to allocate memory in a handler is
-- to allocate in advance space for signal handlers to use.
--
-- The best way to avoid freeing memory in a handler is to flag or
-- record the objects to be freed, and have the program check from
-- time to time whether anything is waiting to be freed. But this
-- must be done with care, because placing an object on a chain is
-- not atomic, and if it is interrupted by another signal handler
-- that does the same thing, you could "lose" one of the objects.
--
-- * Any function that modifies `errno' is non-reentrant, but you can
-- correct for this: in the handler, save the original value of
-- `errno' and restore it before returning normally. This prevents
-- errors that occur within the signal handler from being confused
-- with errors from system calls at the point the program is
-- interrupted to run the handler.
--
-- This technique is generally applicable; if you want to call in a
-- handler a function that modifies a particular object in memory,
-- you can make this safe by saving and restoring that object.
--
-- * Merely reading from a memory object is safe provided that you can
-- deal with any of the values that might appear in the object at a
-- time when the signal can be delivered. Keep in mind that
-- assignment to some data types requires more than one instruction,
-- which means that the handler could run "in the middle of" an
-- assignment to the variable if its type is not atomic. *Note
-- Atomic Data Access::.
--
-- * Merely writing into a memory object is safe as long as a sudden
-- change in the value, at any time when the handler might run, will
-- not disturb anything.
--
--
--File: libc.info, Node: Atomic Data Access, Prev: Nonreentrancy, Up: Defining Handlers
--
--Atomic Data Access and Signal Handling
----------------------------------------
--
-- Whether the data in your application concerns atoms, or mere text,
--you have to be careful about the fact that access to a single datum is
--not necessarily "atomic". This means that it can take more than one
--instruction to read or write a single object. In such cases, a signal
--handler might in the middle of reading or writing the object.
--
-- There are three ways you can cope with this problem. You can use
--data types that are always accessed atomically; you can carefully
--arrange that nothing untoward happens if an access is interrupted, or
--you can block all signals around any access that had better not be
--interrupted (*note Blocking Signals::.).
--
--* Menu:
--
--* Non-atomic Example:: A program illustrating interrupted access.
--* Types: Atomic Types. Data types that guarantee no interruption.
--* Usage: Atomic Usage. Proving that interruption is harmless.
--
--
--File: libc.info, Node: Non-atomic Example, Next: Atomic Types, Up: Atomic Data Access
--
--Problems with Non-Atomic Access
--...............................
--
-- Here is an example which shows what can happen if a signal handler
--runs in the middle of modifying a variable. (Interrupting the reading
--of a variable can also lead to paradoxical results, but here we only
--show writing.)
--
-- #include <signal.h>
-- #include <stdio.h>
--
-- struct two_words { int a, b; } memory;
--
-- void
-- handler(int signum)
-- {
-- printf ("%d,%d\n", memory.a, memory.b);
-- alarm (1);
-- }
-- int
-- main (void)
-- {
-- static struct two_words zeros = { 0, 0 }, ones = { 1, 1 };
-- signal (SIGALRM, handler);
-- memory = zeros;
-- alarm (1);
-- while (1)
-- {
-- memory = zeros;
-- memory = ones;
-- }
-- }
--
-- This program fills `memory' with zeros, ones, zeros, ones,
--alternating forever; meanwhile, once per second, the alarm signal
--handler prints the current contents. (Calling `printf' in the handler
--is safe in this program because it is certainly not being called outside
--the handler when the signal happens.)
--
-- Clearly, this program can print a pair of zeros or a pair of ones.
--But that's not all it can do! On most machines, it takes several
--instructions to store a new value in `memory', and the value is stored
--one word at a time. If the signal is delivered in between these
--instructions, the handler might find that `memory.a' is zero and
--`memory.b' is one (or vice versa).
--
-- On some machines it may be possible to store a new value in `memory'
--with just one instruction that cannot be interrupted. On these
--machines, the handler will always print two zeros or two ones.
--
--
--File: libc.info, Node: Atomic Types, Next: Atomic Usage, Prev: Non-atomic Example, Up: Atomic Data Access
--
--Atomic Types
--............
--
-- To avoid uncertainty about interrupting access to a variable, you can
--use a particular data type for which access is always atomic:
--`sig_atomic_t'. Reading and writing this data type is guaranteed to
--happen in a single instruction, so there's no way for a handler to run
--"in the middle" of an access.
--
-- The type `sig_atomic_t' is always an integer data type, but which
--one it is, and how many bits it contains, may vary from machine to
--machine.
--
-- - Data Type: sig_atomic_t
-- This is an integer data type. Objects of this type are always
-- accessed atomically.
--
-- In practice, you can assume that `int' and other integer types no
--longer than `int' are atomic. You can also assume that pointer types
--are atomic; that is very convenient. Both of these are true on all of
--the machines that the GNU C library supports, and on all POSIX systems
--we know of.
--
--
--File: libc.info, Node: Atomic Usage, Prev: Atomic Types, Up: Atomic Data Access
--
--Atomic Usage Patterns
--.....................
--
-- Certain patterns of access avoid any problem even if an access is
--interrupted. For example, a flag which is set by the handler, and
--tested and cleared by the main program from time to time, is always safe
--even if access actually requires two instructions. To show that this is
--so, we must consider each access that could be interrupted, and show
--that there is no problem if it is interrupted.
--
-- An interrupt in the middle of testing the flag is safe because
--either it's recognized to be nonzero, in which case the precise value
--doesn't matter, or it will be seen to be nonzero the next time it's
--tested.
--
-- An interrupt in the middle of clearing the flag is no problem because
--either the value ends up zero, which is what happens if a signal comes
--in just before the flag is cleared, or the value ends up nonzero, and
--subsequent events occur as if the signal had come in just after the flag
--was cleared. As long as the code handles both of these cases properly,
--it can also handle a signal in the middle of clearing the flag. (This
--is an example of the sort of reasoning you need to do to figure out
--whether non-atomic usage is safe.)
--
-- Sometimes you can insure uninterrupted access to one object by
--protecting its use with another object, perhaps one whose type
--guarantees atomicity. *Note Merged Signals::, for an example.
--
--
--File: libc.info, Node: Interrupted Primitives, Next: Generating Signals, Prev: Defining Handlers, Up: Signal Handling
--
--Primitives Interrupted by Signals
--=================================
--
-- A signal can arrive and be handled while an I/O primitive such as
--`open' or `read' is waiting for an I/O device. If the signal handler
--returns, the system faces the question: what should happen next?
--
-- POSIX specifies one approach: make the primitive fail right away.
--The error code for this kind of failure is `EINTR'. This is flexible,
--but usually inconvenient. Typically, POSIX applications that use signal
--handlers must check for `EINTR' after each library function that can
--return it, in order to try the call again. Often programmers forget to
--check, which is a common source of error.
--
-- The GNU library provides a convenient way to retry a call after a
--temporary failure, with the macro `TEMP_FAILURE_RETRY':
--
-- - Macro: TEMP_FAILURE_RETRY (EXPRESSION)
-- This macro evaluates EXPRESSION once. If it fails and reports
-- error code `EINTR', `TEMP_FAILURE_RETRY' evaluates it again, and
-- over and over until the result is not a temporary failure.
--
-- The value returned by `TEMP_FAILURE_RETRY' is whatever value
-- EXPRESSION produced.
--
-- BSD avoids `EINTR' entirely and provides a more convenient approach:
--to restart the interrupted primitive, instead of making it fail. If
--you choose this approach, you need not be concerned with `EINTR'.
--
-- You can choose either approach with the GNU library. If you use
--`sigaction' to establish a signal handler, you can specify how that
--handler should behave. If you specify the `SA_RESTART' flag, return
--from that handler will resume a primitive; otherwise, return from that
--handler will cause `EINTR'. *Note Flags for Sigaction::.
--
-- Another way to specify the choice is with the `siginterrupt'
--function. *Note BSD Handler::.
--
-- When you don't specify with `sigaction' or `siginterrupt' what a
--particular handler should do, it uses a default choice. The default
--choice in the GNU library depends on the feature test macros you have
--defined. If you define `_BSD_SOURCE' or `_GNU_SOURCE' before calling
--`signal', the default is to resume primitives; otherwise, the default
--is to make them fail with `EINTR'. (The library contains alternate
--versions of the `signal' function, and the feature test macros
--determine which one you really call.) *Note Feature Test Macros::.
--
-- The description of each primitive affected by this issue lists
--`EINTR' among the error codes it can return.
--
-- There is one situation where resumption never happens no matter which
--choice you make: when a data-transfer function such as `read' or
--`write' is interrupted by a signal after transferring part of the data.
--In this case, the function returns the number of bytes already
--transferred, indicating partial success.
--
-- This might at first appear to cause unreliable behavior on
--record-oriented devices (including datagram sockets; *note
--Datagrams::.), where splitting one `read' or `write' into two would
--read or write two records. Actually, there is no problem, because
--interruption after a partial transfer cannot happen on such devices;
--they always transfer an entire record in one burst, with no waiting
--once data transfer has started.
--
--
--File: libc.info, Node: Generating Signals, Next: Blocking Signals, Prev: Interrupted Primitives, Up: Signal Handling
--
--Generating Signals
--==================
--
-- Besides signals that are generated as a result of a hardware trap or
--interrupt, your program can explicitly send signals to itself or to
--another process.
--
--* Menu:
--
--* Signaling Yourself:: A process can send a signal to itself.
--* Signaling Another Process:: Send a signal to another process.
--* Permission for kill:: Permission for using `kill'.
--* Kill Example:: Using `kill' for Communication.
--
--
--File: libc.info, Node: Signaling Yourself, Next: Signaling Another Process, Up: Generating Signals
--
--Signaling Yourself
--------------------
--
-- A process can send itself a signal with the `raise' function. This
--function is declared in `signal.h'.
--
-- - Function: int raise (int SIGNUM)
-- The `raise' function sends the signal SIGNUM to the calling
-- process. It returns zero if successful and a nonzero value if it
-- fails. About the only reason for failure would be if the value of
-- SIGNUM is invalid.
--
-- - Function: int gsignal (int SIGNUM)
-- The `gsignal' function does the same thing as `raise'; it is
-- provided only for compatibility with SVID.
--
-- One convenient use for `raise' is to reproduce the default behavior
--of a signal that you have trapped. For instance, suppose a user of your
--program types the SUSP character (usually `C-z'; *note Special
--Characters::.) to send it an interactive stop signal (`SIGTSTP'), and
--you want to clean up some internal data buffers before stopping. You
--might set this up like this:
--
-- #include <signal.h>
--
-- /* When a stop signal arrives, set the action back to the default
-- and then resend the signal after doing cleanup actions. */
--
-- void
-- tstp_handler (int sig)
-- {
-- signal (SIGTSTP, SIG_DFL);
-- /* Do cleanup actions here. */
-- ...
-- raise (SIGTSTP);
-- }
--
-- /* When the process is continued again, restore the signal handler. */
--
-- void
-- cont_handler (int sig)
-- {
-- signal (SIGCONT, cont_handler);
-- signal (SIGTSTP, tstp_handler);
-- }
-- /* Enable both handlers during program initialization. */
--
-- int
-- main (void)
-- {
-- signal (SIGCONT, cont_handler);
-- signal (SIGTSTP, tstp_handler);
-- ...
-- }
--
-- *Portability note:* `raise' was invented by the ISO C committee.
--Older systems may not support it, so using `kill' may be more portable.
--*Note Signaling Another Process::.
--
--
--File: libc.info, Node: Signaling Another Process, Next: Permission for kill, Prev: Signaling Yourself, Up: Generating Signals
--
--Signaling Another Process
---------------------------
--
-- The `kill' function can be used to send a signal to another process.
--In spite of its name, it can be used for a lot of things other than
--causing a process to terminate. Some examples of situations where you
--might want to send signals between processes are:
--
-- * A parent process starts a child to perform a task--perhaps having
-- the child running an infinite loop--and then terminates the child
-- when the task is no longer needed.
--
-- * A process executes as part of a group, and needs to terminate or
-- notify the other processes in the group when an error or other
-- event occurs.
--
-- * Two processes need to synchronize while working together.
--
-- This section assumes that you know a little bit about how processes
--work. For more information on this subject, see *Note Processes::.
--
-- The `kill' function is declared in `signal.h'.
--
-- - Function: int kill (pid_t PID, int SIGNUM)
-- The `kill' function sends the signal SIGNUM to the process or
-- process group specified by PID. Besides the signals listed in
-- *Note Standard Signals::, SIGNUM can also have a value of zero to
-- check the validity of the PID.
--
-- The PID specifies the process or process group to receive the
-- signal:
--
-- `PID > 0'
-- The process whose identifier is PID.
--
-- `PID == 0'
-- All processes in the same process group as the sender.
--
-- `PID < -1'
-- The process group whose identifier is -PID.
--
-- `PID == -1'
-- If the process is privileged, send the signal to all
-- processes except for some special system processes.
-- Otherwise, send the signal to all processes with the same
-- effective user ID.
--
-- A process can send a signal to itself with a call like
-- `kill (getpid(), SIGNUM)'. If `kill' is used by a process to send
-- a signal to itself, and the signal is not blocked, then `kill'
-- delivers at least one signal (which might be some other pending
-- unblocked signal instead of the signal SIGNUM) to that process
-- before it returns.
--
-- The return value from `kill' is zero if the signal can be sent
-- successfully. Otherwise, no signal is sent, and a value of `-1' is
-- returned. If PID specifies sending a signal to several processes,
-- `kill' succeeds if it can send the signal to at least one of them.
-- There's no way you can tell which of the processes got the signal
-- or whether all of them did.
--
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EINVAL'
-- The SIGNUM argument is an invalid or unsupported number.
--
-- `EPERM'
-- You do not have the privilege to send a signal to the process
-- or any of the processes in the process group named by PID.
--
-- `ESCRH'
-- The PID argument does not refer to an existing process or
-- group.
--
-- - Function: int killpg (int PGID, int SIGNUM)
-- This is similar to `kill', but sends signal SIGNUM to the process
-- group PGID. This function is provided for compatibility with BSD;
-- using `kill' to do this is more portable.
--
-- As a simple example of `kill', the call `kill (getpid (), SIG)' has
--the same effect as `raise (SIG)'.
--
--
--File: libc.info, Node: Permission for kill, Next: Kill Example, Prev: Signaling Another Process, Up: Generating Signals
--
--Permission for using `kill'
-----------------------------
--
-- There are restrictions that prevent you from using `kill' to send
--signals to any random process. These are intended to prevent antisocial
--behavior such as arbitrarily killing off processes belonging to another
--user. In typical use, `kill' is used to pass signals between parent,
--child, and sibling processes, and in these situations you normally do
--have permission to send signals. The only common exception is when you
--run a setuid program in a child process; if the program changes its
--real UID as well as its effective UID, you may not have permission to
--send a signal. The `su' program does this.
--
-- Whether a process has permission to send a signal to another process
--is determined by the user IDs of the two processes. This concept is
--discussed in detail in *Note Process Persona::.
--
-- Generally, for a process to be able to send a signal to another
--process, either the sending process must belong to a privileged user
--(like `root'), or the real or effective user ID of the sending process
--must match the real or effective user ID of the receiving process. If
--the receiving process has changed its effective user ID from the
--set-user-ID mode bit on its process image file, then the owner of the
--process image file is used in place of its current effective user ID.
--In some implementations, a parent process might be able to send signals
--to a child process even if the user ID's don't match, and other
--implementations might enforce other restrictions.
--
-- The `SIGCONT' signal is a special case. It can be sent if the
--sender is part of the same session as the receiver, regardless of user
--IDs.
--
--
--File: libc.info, Node: Kill Example, Prev: Permission for kill, Up: Generating Signals
--
--Using `kill' for Communication
--------------------------------
--
-- Here is a longer example showing how signals can be used for
--interprocess communication. This is what the `SIGUSR1' and `SIGUSR2'
--signals are provided for. Since these signals are fatal by default,
--the process that is supposed to receive them must trap them through
--`signal' or `sigaction'.
--
-- In this example, a parent process forks a child process and then
--waits for the child to complete its initialization. The child process
--tells the parent when it is ready by sending it a `SIGUSR1' signal,
--using the `kill' function.
--
-- #include <signal.h>
-- #include <stdio.h>
-- #include <sys/types.h>
-- #include <unistd.h>
--
-- /* When a `SIGUSR1' signal arrives, set this variable. */
-- volatile sig_atomic_t usr_interrupt = 0;
--
-- void
-- synch_signal (int sig)
-- {
-- usr_interrupt = 1;
-- }
--
-- /* The child process executes this function. */
-- void
-- child_function (void)
-- {
-- /* Perform initialization. */
-- printf ("I'm here!!! My pid is %d.\n", (int) getpid ());
--
-- /* Let parent know you're done. */
-- kill (getppid (), SIGUSR1);
--
-- /* Continue with execution. */
-- puts ("Bye, now....");
-- exit (0);
-- }
--
-- int
-- main (void)
-- {
-- struct sigaction usr_action;
-- sigset_t block_mask;
-- pid_t child_id;
--
-- /* Establish the signal handler. */
-- sigfillset (&block_mask);
-- usr_action.sa_handler = synch_signal;
-- usr_action.sa_mask = block_mask;
-- usr_action.sa_flags = 0;
-- sigaction (SIGUSR1, &usr_action, NULL);
--
-- /* Create the child process. */
-- child_id = fork ();
-- if (child_id == 0)
-- child_function (); /* Does not return. */
-- /* Busy wait for the child to send a signal. */
-- while (!usr_interrupt)
-- ;
--
-- /* Now continue execution. */
-- puts ("That's all, folks!");
--
-- return 0;
-- }
--
-- This example uses a busy wait, which is bad, because it wastes CPU
--cycles that other programs could otherwise use. It is better to ask the
--system to wait until the signal arrives. See the example in *Note
--Waiting for a Signal::.
--
--
--File: libc.info, Node: Blocking Signals, Next: Waiting for a Signal, Prev: Generating Signals, Up: Signal Handling
--
--Blocking Signals
--================
--
-- Blocking a signal means telling the operating system to hold it and
--deliver it later. Generally, a program does not block signals
--indefinitely--it might as well ignore them by setting their actions to
--`SIG_IGN'. But it is useful to block signals briefly, to prevent them
--from interrupting sensitive operations. For instance:
--
-- * You can use the `sigprocmask' function to block signals while you
-- modify global variables that are also modified by the handlers for
-- these signals.
--
-- * You can set `sa_mask' in your `sigaction' call to block certain
-- signals while a particular signal handler runs. This way, the
-- signal handler can run without being interrupted itself by signals.
--
--* Menu:
--
--* Why Block:: The purpose of blocking signals.
--* Signal Sets:: How to specify which signals to
-- block.
--* Process Signal Mask:: Blocking delivery of signals to your
-- process during normal execution.
--* Testing for Delivery:: Blocking to Test for Delivery of
-- a Signal.
--* Blocking for Handler:: Blocking additional signals while a
-- handler is being run.
--* Checking for Pending Signals:: Checking for Pending Signals
--* Remembering a Signal:: How you can get almost the same
-- effect as blocking a signal, by
-- handling it and setting a flag
-- to be tested later.
--
--
--File: libc.info, Node: Why Block, Next: Signal Sets, Up: Blocking Signals
--
--Why Blocking Signals is Useful
--------------------------------
--
-- Temporary blocking of signals with `sigprocmask' gives you a way to
--prevent interrupts during critical parts of your code. If signals
--arrive in that part of the program, they are delivered later, after you
--unblock them.
--
-- One example where this is useful is for sharing data between a signal
--handler and the rest of the program. If the type of the data is not
--`sig_atomic_t' (*note Atomic Data Access::.), then the signal handler
--could run when the rest of the program has only half finished reading
--or writing the data. This would lead to confusing consequences.
--
-- To make the program reliable, you can prevent the signal handler from
--running while the rest of the program is examining or modifying that
--data--by blocking the appropriate signal around the parts of the
--program that touch the data.
--
-- Blocking signals is also necessary when you want to perform a certain
--action only if a signal has not arrived. Suppose that the handler for
--the signal sets a flag of type `sig_atomic_t'; you would like to test
--the flag and perform the action if the flag is not set. This is
--unreliable. Suppose the signal is delivered immediately after you test
--the flag, but before the consequent action: then the program will
--perform the action even though the signal has arrived.
--
-- The only way to test reliably for whether a signal has yet arrived
--is to test while the signal is blocked.
--
--
--File: libc.info, Node: Signal Sets, Next: Process Signal Mask, Prev: Why Block, Up: Blocking Signals
--
--Signal Sets
-------------
--
-- All of the signal blocking functions use a data structure called a
--"signal set" to specify what signals are affected. Thus, every
--activity involves two stages: creating the signal set, and then passing
--it as an argument to a library function.
--
-- These facilities are declared in the header file `signal.h'.
--
-- - Data Type: sigset_t
-- The `sigset_t' data type is used to represent a signal set.
-- Internally, it may be implemented as either an integer or structure
-- type.
--
-- For portability, use only the functions described in this section
-- to initialize, change, and retrieve information from `sigset_t'
-- objects--don't try to manipulate them directly.
--
-- There are two ways to initialize a signal set. You can initially
--specify it to be empty with `sigemptyset' and then add specified
--signals individually. Or you can specify it to be full with
--`sigfillset' and then delete specified signals individually.
--
-- You must always initialize the signal set with one of these two
--functions before using it in any other way. Don't try to set all the
--signals explicitly because the `sigset_t' object might include some
--other information (like a version field) that needs to be initialized as
--well. (In addition, it's not wise to put into your program an
--assumption that the system has no signals aside from the ones you know
--about.)
--
-- - Function: int sigemptyset (sigset_t *SET)
-- This function initializes the signal set SET to exclude all of the
-- defined signals. It always returns `0'.
--
-- - Function: int sigfillset (sigset_t *SET)
-- This function initializes the signal set SET to include all of the
-- defined signals. Again, the return value is `0'.
--
-- - Function: int sigaddset (sigset_t *SET, int SIGNUM)
-- This function adds the signal SIGNUM to the signal set SET. All
-- `sigaddset' does is modify SET; it does not block or unblock any
-- signals.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error condition is defined for this function:
--
-- `EINVAL'
-- The SIGNUM argument doesn't specify a valid signal.
--
-- - Function: int sigdelset (sigset_t *SET, int SIGNUM)
-- This function removes the signal SIGNUM from the signal set SET.
-- All `sigdelset' does is modify SET; it does not block or unblock
-- any signals. The return value and error conditions are the same
-- as for `sigaddset'.
--
-- Finally, there is a function to test what signals are in a signal
--set:
--
-- - Function: int sigismember (const sigset_t *SET, int SIGNUM)
-- The `sigismember' function tests whether the signal SIGNUM is a
-- member of the signal set SET. It returns `1' if the signal is in
-- the set, `0' if not, and `-1' if there is an error.
--
-- The following `errno' error condition is defined for this function:
--
-- `EINVAL'
-- The SIGNUM argument doesn't specify a valid signal.
--
--
--File: libc.info, Node: Process Signal Mask, Next: Testing for Delivery, Prev: Signal Sets, Up: Blocking Signals
--
--Process Signal Mask
---------------------
--
-- The collection of signals that are currently blocked is called the
--"signal mask". Each process has its own signal mask. When you create
--a new process (*note Creating a Process::.), it inherits its parent's
--mask. You can block or unblock signals with total flexibility by
--modifying the signal mask.
--
-- The prototype for the `sigprocmask' function is in `signal.h'.
--
-- - Function: int sigprocmask (int HOW, const sigset_t *SET, sigset_t
-- *OLDSET)
-- The `sigprocmask' function is used to examine or change the calling
-- process's signal mask. The HOW argument determines how the signal
-- mask is changed, and must be one of the following values:
--
-- `SIG_BLOCK'
-- Block the signals in `set'--add them to the existing mask. In
-- other words, the new mask is the union of the existing mask
-- and SET.
--
-- `SIG_UNBLOCK'
-- Unblock the signals in SET--remove them from the existing
-- mask.
--
-- `SIG_SETMASK'
-- Use SET for the mask; ignore the previous value of the mask.
--
-- The last argument, OLDSET, is used to return information about the
-- old process signal mask. If you just want to change the mask
-- without looking at it, pass a null pointer as the OLDSET argument.
-- Similarly, if you want to know what's in the mask without changing
-- it, pass a null pointer for SET (in this case the HOW argument is
-- not significant). The OLDSET argument is often used to remember
-- the previous signal mask in order to restore it later. (Since the
-- signal mask is inherited over `fork' and `exec' calls, you can't
-- predict what its contents are when your program starts running.)
--
-- If invoking `sigprocmask' causes any pending signals to be
-- unblocked, at least one of those signals is delivered to the
-- process before `sigprocmask' returns. The order in which pending
-- signals are delivered is not specified, but you can control the
-- order explicitly by making multiple `sigprocmask' calls to unblock
-- various signals one at a time.
--
-- The `sigprocmask' function returns `0' if successful, and `-1' to
-- indicate an error. The following `errno' error conditions are
-- defined for this function:
--
-- `EINVAL'
-- The HOW argument is invalid.
--
-- You can't block the `SIGKILL' and `SIGSTOP' signals, but if the
-- signal set includes these, `sigprocmask' just ignores them instead
-- of returning an error status.
--
-- Remember, too, that blocking program error signals such as `SIGFPE'
-- leads to undesirable results for signals generated by an actual
-- program error (as opposed to signals sent with `raise' or `kill').
-- This is because your program may be too broken to be able to
-- continue executing to a point where the signal is unblocked again.
-- *Note Program Error Signals::.
--
--
--File: libc.info, Node: Testing for Delivery, Next: Blocking for Handler, Prev: Process Signal Mask, Up: Blocking Signals
--
--Blocking to Test for Delivery of a Signal
-------------------------------------------
--
-- Now for a simple example. Suppose you establish a handler for
--`SIGALRM' signals that sets a flag whenever a signal arrives, and your
--main program checks this flag from time to time and then resets it.
--You can prevent additional `SIGALRM' signals from arriving in the
--meantime by wrapping the critical part of the code with calls to
--`sigprocmask', like this:
--
-- /* This variable is set by the SIGALRM signal handler. */
-- volatile sig_atomic_t flag = 0;
--
-- int
-- main (void)
-- {
-- sigset_t block_alarm;
--
-- ...
--
-- /* Initialize the signal mask. */
-- sigemptyset (&block_alarm);
-- sigaddset (&block_alarm, SIGALRM);
-- while (1)
-- {
-- /* Check if a signal has arrived; if so, reset the flag. */
-- sigprocmask (SIG_BLOCK, &block_alarm, NULL);
-- if (flag)
-- {
-- ACTIONS-IF-NOT-ARRIVED
-- flag = 0;
-- }
-- sigprocmask (SIG_UNBLOCK, &block_alarm, NULL);
--
-- ...
-- }
-- }
--
--
--File: libc.info, Node: Blocking for Handler, Next: Checking for Pending Signals, Prev: Testing for Delivery, Up: Blocking Signals
--
--Blocking Signals for a Handler
--------------------------------
--
-- When a signal handler is invoked, you usually want it to be able to
--finish without being interrupted by another signal. From the moment the
--handler starts until the moment it finishes, you must block signals that
--might confuse it or corrupt its data.
--
-- When a handler function is invoked on a signal, that signal is
--automatically blocked (in addition to any other signals that are already
--in the process's signal mask) during the time the handler is running.
--If you set up a handler for `SIGTSTP', for instance, then the arrival
--of that signal forces further `SIGTSTP' signals to wait during the
--execution of the handler.
--
-- However, by default, other kinds of signals are not blocked; they can
--arrive during handler execution.
--
-- The reliable way to block other kinds of signals during the
--execution of the handler is to use the `sa_mask' member of the
--`sigaction' structure.
--
-- Here is an example:
--
-- #include <signal.h>
-- #include <stddef.h>
--
-- void catch_stop ();
--
-- void
-- install_handler (void)
-- {
-- struct sigaction setup_action;
-- sigset_t block_mask;
--
-- sigemptyset (&block_mask);
-- /* Block other terminal-generated signals while handler runs. */
-- sigaddset (&block_mask, SIGINT);
-- sigaddset (&block_mask, SIGQUIT);
-- setup_action.sa_handler = catch_stop;
-- setup_action.sa_mask = block_mask;
-- setup_action.sa_flags = 0;
-- sigaction (SIGTSTP, &setup_action, NULL);
-- }
--
-- This is more reliable than blocking the other signals explicitly in
--the code for the handler. If you block signals explicitly in the
--handler, you can't avoid at least a short interval at the beginning of
--the handler where they are not yet blocked.
--
-- You cannot remove signals from the process's current mask using this
--mechanism. However, you can make calls to `sigprocmask' within your
--handler to block or unblock signals as you wish.
--
-- In any case, when the handler returns, the system restores the mask
--that was in place before the handler was entered. If any signals that
--become unblocked by this restoration are pending, the process will
--receive those signals immediately, before returning to the code that was
--interrupted.
--
--
--File: libc.info, Node: Checking for Pending Signals, Next: Remembering a Signal, Prev: Blocking for Handler, Up: Blocking Signals
--
--Checking for Pending Signals
------------------------------
--
-- You can find out which signals are pending at any time by calling
--`sigpending'. This function is declared in `signal.h'.
--
-- - Function: int sigpending (sigset_t *SET)
-- The `sigpending' function stores information about pending signals
-- in SET. If there is a pending signal that is blocked from
-- delivery, then that signal is a member of the returned set. (You
-- can test whether a particular signal is a member of this set using
-- `sigismember'; see *Note Signal Sets::.)
--
-- The return value is `0' if successful, and `-1' on failure.
--
-- Testing whether a signal is pending is not often useful. Testing
--when that signal is not blocked is almost certainly bad design.
--
-- Here is an example.
--
-- #include <signal.h>
-- #include <stddef.h>
--
-- sigset_t base_mask, waiting_mask;
--
-- sigemptyset (&base_mask);
-- sigaddset (&base_mask, SIGINT);
-- sigaddset (&base_mask, SIGTSTP);
--
-- /* Block user interrupts while doing other processing. */
-- sigprocmask (SIG_SETMASK, &base_mask, NULL);
-- ...
--
-- /* After a while, check to see whether any signals are pending. */
-- sigpending (&waiting_mask);
-- if (sigismember (&waiting_mask, SIGINT)) {
-- /* User has tried to kill the process. */
-- }
-- else if (sigismember (&waiting_mask, SIGTSTP)) {
-- /* User has tried to stop the process. */
-- }
--
-- Remember that if there is a particular signal pending for your
--process, additional signals of that same type that arrive in the
--meantime might be discarded. For example, if a `SIGINT' signal is
--pending when another `SIGINT' signal arrives, your program will
--probably only see one of them when you unblock this signal.
--
-- *Portability Note:* The `sigpending' function is new in POSIX.1.
--Older systems have no equivalent facility.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-34 glibc-2.1.3/manual/libc.info-34
---- ../glibc-2.1.3/manual/libc.info-34 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-34 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1256 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Remembering a Signal, Prev: Checking for Pending Signals, Up: Blocking Signals
--
--Remembering a Signal to Act On Later
--------------------------------------
--
-- Instead of blocking a signal using the library facilities, you can
--get almost the same results by making the handler set a flag to be
--tested later, when you "unblock". Here is an example:
--
-- /* If this flag is nonzero, don't handle the signal right away. */
-- volatile sig_atomic_t signal_pending;
--
-- /* This is nonzero if a signal arrived and was not handled. */
-- volatile sig_atomic_t defer_signal;
--
-- void
-- handler (int signum)
-- {
-- if (defer_signal)
-- signal_pending = signum;
-- else
-- ... /* "Really" handle the signal. */
-- }
--
-- ...
--
-- void
-- update_mumble (int frob)
-- {
-- /* Prevent signals from having immediate effect. */
-- defer_signal++;
-- /* Now update `mumble', without worrying about interruption. */
-- mumble.a = 1;
-- mumble.b = hack ();
-- mumble.c = frob;
-- /* We have updated `mumble'. Handle any signal that came in. */
-- defer_signal--;
-- if (defer_signal == 0 && signal_pending != 0)
-- raise (signal_pending);
-- }
--
-- Note how the particular signal that arrives is stored in
--`signal_pending'. That way, we can handle several types of
--inconvenient signals with the same mechanism.
--
-- We increment and decrement `defer_signal' so that nested critical
--sections will work properly; thus, if `update_mumble' were called with
--`signal_pending' already nonzero, signals would be deferred not only
--within `update_mumble', but also within the caller. This is also why
--we do not check `signal_pending' if `defer_signal' is still nonzero.
--
-- The incrementing and decrementing of `defer_signal' require more
--than one instruction; it is possible for a signal to happen in the
--middle. But that does not cause any problem. If the signal happens
--early enough to see the value from before the increment or decrement,
--that is equivalent to a signal which came before the beginning of the
--increment or decrement, which is a case that works properly.
--
-- It is absolutely vital to decrement `defer_signal' before testing
--`signal_pending', because this avoids a subtle bug. If we did these
--things in the other order, like this,
--
-- if (defer_signal == 1 && signal_pending != 0)
-- raise (signal_pending);
-- defer_signal--;
--
--then a signal arriving in between the `if' statement and the decrement
--would be effectively "lost" for an indefinite amount of time. The
--handler would merely set `defer_signal', but the program having already
--tested this variable, it would not test the variable again.
--
-- Bugs like these are called "timing errors". They are especially bad
--because they happen only rarely and are nearly impossible to reproduce.
--You can't expect to find them with a debugger as you would find a
--reproducible bug. So it is worth being especially careful to avoid
--them.
--
-- (You would not be tempted to write the code in this order, given the
--use of `defer_signal' as a counter which must be tested along with
--`signal_pending'. After all, testing for zero is cleaner than testing
--for one. But if you did not use `defer_signal' as a counter, and gave
--it values of zero and one only, then either order might seem equally
--simple. This is a further advantage of using a counter for
--`defer_signal': it will reduce the chance you will write the code in
--the wrong order and create a subtle bug.)
--
--
--File: libc.info, Node: Waiting for a Signal, Next: Signal Stack, Prev: Blocking Signals, Up: Signal Handling
--
--Waiting for a Signal
--====================
--
-- If your program is driven by external events, or uses signals for
--synchronization, then when it has nothing to do it should probably wait
--until a signal arrives.
--
--* Menu:
--
--* Using Pause:: The simple way, using `pause'.
--* Pause Problems:: Why the simple way is often not very good.
--* Sigsuspend:: Reliably waiting for a specific signal.
--
--
--File: libc.info, Node: Using Pause, Next: Pause Problems, Up: Waiting for a Signal
--
--Using `pause'
---------------
--
-- The simple way to wait until a signal arrives is to call `pause'.
--Please read about its disadvantages, in the following section, before
--you use it.
--
-- - Function: int pause ()
-- The `pause' function suspends program execution until a signal
-- arrives whose action is either to execute a handler function, or to
-- terminate the process.
--
-- If the signal causes a handler function to be executed, then
-- `pause' returns. This is considered an unsuccessful return (since
-- "successful" behavior would be to suspend the program forever), so
-- the return value is `-1'. Even if you specify that other
-- primitives should resume when a system handler returns (*note
-- Interrupted Primitives::.), this has no effect on `pause'; it
-- always fails when a signal is handled.
--
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EINTR'
-- The function was interrupted by delivery of a signal.
--
-- If the signal causes program termination, `pause' doesn't return
-- (obviously).
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `pause' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `pause' should be protected using cancelation handlers.
--
-- The `pause' function is declared in `unistd.h'.
--
--
--File: libc.info, Node: Pause Problems, Next: Sigsuspend, Prev: Using Pause, Up: Waiting for a Signal
--
--Problems with `pause'
-----------------------
--
-- The simplicity of `pause' can conceal serious timing errors that can
--make a program hang mysteriously.
--
-- It is safe to use `pause' if the real work of your program is done
--by the signal handlers themselves, and the "main program" does nothing
--but call `pause'. Each time a signal is delivered, the handler will do
--the next batch of work that is to be done, and then return, so that the
--main loop of the program can call `pause' again.
--
-- You can't safely use `pause' to wait until one more signal arrives,
--and then resume real work. Even if you arrange for the signal handler
--to cooperate by setting a flag, you still can't use `pause' reliably.
--Here is an example of this problem:
--
-- /* `usr_interrupt' is set by the signal handler. */
-- if (!usr_interrupt)
-- pause ();
--
-- /* Do work once the signal arrives. */
-- ...
--
--This has a bug: the signal could arrive after the variable
--`usr_interrupt' is checked, but before the call to `pause'. If no
--further signals arrive, the process would never wake up again.
--
-- You can put an upper limit on the excess waiting by using `sleep' in
--a loop, instead of using `pause'. (*Note Sleeping::, for more about
--`sleep'.) Here is what this looks like:
--
-- /* `usr_interrupt' is set by the signal handler.
-- while (!usr_interrupt)
-- sleep (1);
--
-- /* Do work once the signal arrives. */
-- ...
--
-- For some purposes, that is good enough. But with a little more
--complexity, you can wait reliably until a particular signal handler is
--run, using `sigsuspend'. *Note Sigsuspend::.
--
--
--File: libc.info, Node: Sigsuspend, Prev: Pause Problems, Up: Waiting for a Signal
--
--Using `sigsuspend'
--------------------
--
-- The clean and reliable way to wait for a signal to arrive is to
--block it and then use `sigsuspend'. By using `sigsuspend' in a loop,
--you can wait for certain kinds of signals, while letting other kinds of
--signals be handled by their handlers.
--
-- - Function: int sigsuspend (const sigset_t *SET)
-- This function replaces the process's signal mask with SET and then
-- suspends the process until a signal is delivered whose action is
-- either to terminate the process or invoke a signal handling
-- function. In other words, the program is effectively suspended
-- until one of the signals that is not a member of SET arrives.
--
-- If the process is woken up by deliver of a signal that invokes a
-- handler function, and the handler function returns, then
-- `sigsuspend' also returns.
--
-- The mask remains SET only as long as `sigsuspend' is waiting. The
-- function `sigsuspend' always restores the previous signal mask
-- when it returns.
--
-- The return value and error conditions are the same as for `pause'.
--
-- With `sigsuspend', you can replace the `pause' or `sleep' loop in
--the previous section with something completely reliable:
--
-- sigset_t mask, oldmask;
--
-- ...
--
-- /* Set up the mask of signals to temporarily block. */
-- sigemptyset (&mask);
-- sigaddset (&mask, SIGUSR1);
--
-- ...
--
-- /* Wait for a signal to arrive. */
-- sigprocmask (SIG_BLOCK, &mask, &oldmask);
-- while (!usr_interrupt)
-- sigsuspend (&oldmask);
-- sigprocmask (SIG_UNBLOCK, &mask, NULL);
--
-- This last piece of code is a little tricky. The key point to
--remember here is that when `sigsuspend' returns, it resets the process's
--signal mask to the original value, the value from before the call to
--`sigsuspend'--in this case, the `SIGUSR1' signal is once again blocked.
--The second call to `sigprocmask' is necessary to explicitly unblock
--this signal.
--
-- One other point: you may be wondering why the `while' loop is
--necessary at all, since the program is apparently only waiting for one
--`SIGUSR1' signal. The answer is that the mask passed to `sigsuspend'
--permits the process to be woken up by the delivery of other kinds of
--signals, as well--for example, job control signals. If the process is
--woken up by a signal that doesn't set `usr_interrupt', it just suspends
--itself again until the "right" kind of signal eventually arrives.
--
-- This technique takes a few more lines of preparation, but that is
--needed just once for each kind of wait criterion you want to use. The
--code that actually waits is just four lines.
--
--
--File: libc.info, Node: Signal Stack, Next: BSD Signal Handling, Prev: Waiting for a Signal, Up: Signal Handling
--
--Using a Separate Signal Stack
--=============================
--
-- A signal stack is a special area of memory to be used as the
--execution stack during signal handlers. It should be fairly large, to
--avoid any danger that it will overflow in turn; the macro `SIGSTKSZ' is
--defined to a canonical size for signal stacks. You can use `malloc' to
--allocate the space for the stack. Then call `sigaltstack' or
--`sigstack' to tell the system to use that space for the signal stack.
--
-- You don't need to write signal handlers differently in order to use a
--signal stack. Switching from one stack to the other happens
--automatically. (Some non-GNU debuggers on some machines may get
--confused if you examine a stack trace while a handler that uses the
--signal stack is running.)
--
-- There are two interfaces for telling the system to use a separate
--signal stack. `sigstack' is the older interface, which comes from 4.2
--BSD. `sigaltstack' is the newer interface, and comes from 4.4 BSD.
--The `sigaltstack' interface has the advantage that it does not require
--your program to know which direction the stack grows, which depends on
--the specific machine and operating system.
--
-- - Data Type: struct sigaltstack
-- This structure describes a signal stack. It contains the
-- following members:
--
-- `void *ss_sp'
-- This points to the base of the signal stack.
--
-- `size_t ss_size'
-- This is the size (in bytes) of the signal stack which `ss_sp'
-- points to. You should set this to however much space you
-- allocated for the stack.
--
-- There are two macros defined in `signal.h' that you should
-- use in calculating this size:
--
-- `SIGSTKSZ'
-- This is the canonical size for a signal stack. It is
-- judged to be sufficient for normal uses.
--
-- `MINSIGSTKSZ'
-- This is the amount of signal stack space the operating
-- system needs just to implement signal delivery. The
-- size of a signal stack *must* be greater than this.
--
-- For most cases, just using `SIGSTKSZ' for `ss_size' is
-- sufficient. But if you know how much stack space your
-- program's signal handlers will need, you may want to use
-- a different size. In this case, you should allocate
-- `MINSIGSTKSZ' additional bytes for the signal stack and
-- increase `ss_size' accordingly.
--
-- `int ss_flags'
-- This field contains the bitwise OR of these flags:
--
-- `SS_DISABLE'
-- This tells the system that it should not use the signal
-- stack.
--
-- `SS_ONSTACK'
-- This is set by the system, and indicates that the signal
-- stack is currently in use. If this bit is not set, then
-- signals will be delivered on the normal user stack.
--
-- - Function: int sigaltstack (const struct sigaltstack *STACK, struct
-- sigaltstack *OLDSTACK)
-- The `sigaltstack' function specifies an alternate stack for use
-- during signal handling. When a signal is received by the process
-- and its action indicates that the signal stack is used, the system
-- arranges a switch to the currently installed signal stack while
-- the handler for that signal is executed.
--
-- If OLDSTACK is not a null pointer, information about the currently
-- installed signal stack is returned in the location it points to.
-- If STACK is not a null pointer, then this is installed as the new
-- stack for use by signal handlers.
--
-- The return value is `0' on success and `-1' on failure. If
-- `sigaltstack' fails, it sets `errno' to one of these values:
--
-- `EINVAL'
-- You tried to disable a stack that was in fact currently in
-- use.
--
-- `ENOMEM'
-- The size of the alternate stack was too small. It must be
-- greater than `MINSIGSTKSZ'.
--
-- Here is the older `sigstack' interface. You should use
--`sigaltstack' instead on systems that have it.
--
-- - Data Type: struct sigstack
-- This structure describes a signal stack. It contains the
-- following members:
--
-- `void *ss_sp'
-- This is the stack pointer. If the stack grows downwards on
-- your machine, this should point to the top of the area you
-- allocated. If the stack grows upwards, it should point to
-- the bottom.
--
-- `int ss_onstack'
-- This field is true if the process is currently using this
-- stack.
--
-- - Function: int sigstack (const struct sigstack *STACK, struct
-- sigstack *OLDSTACK)
-- The `sigstack' function specifies an alternate stack for use during
-- signal handling. When a signal is received by the process and its
-- action indicates that the signal stack is used, the system
-- arranges a switch to the currently installed signal stack while
-- the handler for that signal is executed.
--
-- If OLDSTACK is not a null pointer, information about the currently
-- installed signal stack is returned in the location it points to.
-- If STACK is not a null pointer, then this is installed as the new
-- stack for use by signal handlers.
--
-- The return value is `0' on success and `-1' on failure.
--
--
--File: libc.info, Node: BSD Signal Handling, Prev: Signal Stack, Up: Signal Handling
--
--BSD Signal Handling
--===================
--
-- This section describes alternative signal handling functions derived
--from BSD Unix. These facilities were an advance, in their time; today,
--they are mostly obsolete, and supported mainly for compatibility with
--BSD Unix.
--
-- There are many similarities between the BSD and POSIX signal handling
--facilities, because the POSIX facilities were inspired by the BSD
--facilities. Besides having different names for all the functions to
--avoid conflicts, the main differences between the two are:
--
-- * BSD Unix represents signal masks as an `int' bit mask, rather than
-- as a `sigset_t' object.
--
-- * The BSD facilities use a different default for whether an
-- interrupted primitive should fail or resume. The POSIX facilities
-- make system calls fail unless you specify that they should resume.
-- With the BSD facility, the default is to make system calls resume
-- unless you say they should fail. *Note Interrupted Primitives::.
--
-- The BSD facilities are declared in `signal.h'.
--
--* Menu:
--
--* BSD Handler:: BSD Function to Establish a Handler.
--* Blocking in BSD:: BSD Functions for Blocking Signals.
--
--
--File: libc.info, Node: BSD Handler, Next: Blocking in BSD, Up: BSD Signal Handling
--
--BSD Function to Establish a Handler
-------------------------------------
--
-- - Data Type: struct sigvec
-- This data type is the BSD equivalent of `struct sigaction' (*note
-- Advanced Signal Handling::.); it is used to specify signal actions
-- to the `sigvec' function. It contains the following members:
--
-- `sighandler_t sv_handler'
-- This is the handler function.
--
-- `int sv_mask'
-- This is the mask of additional signals to be blocked while
-- the handler function is being called.
--
-- `int sv_flags'
-- This is a bit mask used to specify various flags which affect
-- the behavior of the signal. You can also refer to this field
-- as `sv_onstack'.
--
-- These symbolic constants can be used to provide values for the
--`sv_flags' field of a `sigvec' structure. This field is a bit mask
--value, so you bitwise-OR the flags of interest to you together.
--
-- - Macro: int SV_ONSTACK
-- If this bit is set in the `sv_flags' field of a `sigvec'
-- structure, it means to use the signal stack when delivering the
-- signal.
--
-- - Macro: int SV_INTERRUPT
-- If this bit is set in the `sv_flags' field of a `sigvec'
-- structure, it means that system calls interrupted by this kind of
-- signal should not be restarted if the handler returns; instead,
-- the system calls should return with a `EINTR' error status. *Note
-- Interrupted Primitives::.
--
-- - Macro: int SV_RESETHAND
-- If this bit is set in the `sv_flags' field of a `sigvec'
-- structure, it means to reset the action for the signal back to
-- `SIG_DFL' when the signal is received.
--
-- - Function: int sigvec (int SIGNUM, const struct sigvec *ACTION,struct
-- sigvec *OLD-ACTION)
-- This function is the equivalent of `sigaction' (*note Advanced
-- Signal Handling::.); it installs the action ACTION for the signal
-- SIGNUM, returning information about the previous action in effect
-- for that signal in OLD-ACTION.
--
-- - Function: int siginterrupt (int SIGNUM, int FAILFLAG)
-- This function specifies which approach to use when certain
-- primitives are interrupted by handling signal SIGNUM. If FAILFLAG
-- is false, signal SIGNUM restarts primitives. If FAILFLAG is true,
-- handling SIGNUM causes these primitives to fail with error code
-- `EINTR'. *Note Interrupted Primitives::.
--
--
--File: libc.info, Node: Blocking in BSD, Prev: BSD Handler, Up: BSD Signal Handling
--
--BSD Functions for Blocking Signals
------------------------------------
--
-- - Macro: int sigmask (int SIGNUM)
-- This macro returns a signal mask that has the bit for signal SIGNUM
-- set. You can bitwise-OR the results of several calls to `sigmask'
-- together to specify more than one signal. For example,
--
-- (sigmask (SIGTSTP) | sigmask (SIGSTOP)
-- | sigmask (SIGTTIN) | sigmask (SIGTTOU))
--
-- specifies a mask that includes all the job-control stop signals.
--
-- - Function: int sigblock (int MASK)
-- This function is equivalent to `sigprocmask' (*note Process Signal
-- Mask::.) with a HOW argument of `SIG_BLOCK': it adds the signals
-- specified by MASK to the calling process's set of blocked signals.
-- The return value is the previous set of blocked signals.
--
-- - Function: int sigsetmask (int MASK)
-- This function equivalent to `sigprocmask' (*note Process Signal
-- Mask::.) with a HOW argument of `SIG_SETMASK': it sets the calling
-- process's signal mask to MASK. The return value is the previous
-- set of blocked signals.
--
-- - Function: int sigpause (int MASK)
-- This function is the equivalent of `sigsuspend' (*note Waiting for
-- a Signal::.): it sets the calling process's signal mask to MASK,
-- and waits for a signal to arrive. On return the previous set of
-- blocked signals is restored.
--
--
--File: libc.info, Node: Process Startup, Next: Processes, Prev: Signal Handling, Up: Top
--
--Process Startup and Termination
--*******************************
--
-- "Processes" are the primitive units for allocation of system
--resources. Each process has its own address space and (usually) one
--thread of control. A process executes a program; you can have multiple
--processes executing the same program, but each process has its own copy
--of the program within its own address space and executes it
--independently of the other copies.
--
-- This chapter explains what your program should do to handle the
--startup of a process, to terminate its process, and to receive
--information (arguments and the environment) from the parent process.
--
--* Menu:
--
--* Program Arguments:: Parsing your program's command-line arguments.
--* Environment Variables:: How to access parameters inherited from
-- a parent process.
--* Program Termination:: How to cause a process to terminate and
-- return status information to its parent.
--
--
--File: libc.info, Node: Program Arguments, Next: Environment Variables, Up: Process Startup
--
--Program Arguments
--=================
--
-- The system starts a C program by calling the function `main'. It is
--up to you to write a function named `main'--otherwise, you won't even
--be able to link your program without errors.
--
-- In ISO C you can define `main' either to take no arguments, or to
--take two arguments that represent the command line arguments to the
--program, like this:
--
-- int main (int ARGC, char *ARGV[])
--
-- The command line arguments are the whitespace-separated tokens given
--in the shell command used to invoke the program; thus, in `cat foo
--bar', the arguments are `foo' and `bar'. The only way a program can
--look at its command line arguments is via the arguments of `main'. If
--`main' doesn't take arguments, then you cannot get at the command line.
--
-- The value of the ARGC argument is the number of command line
--arguments. The ARGV argument is a vector of C strings; its elements
--are the individual command line argument strings. The file name of the
--program being run is also included in the vector as the first element;
--the value of ARGC counts this element. A null pointer always follows
--the last element: `ARGV[ARGC]' is this null pointer.
--
-- For the command `cat foo bar', ARGC is 3 and ARGV has three
--elements, `"cat"', `"foo"' and `"bar"'.
--
-- In Unix systems you can define `main' a third way, using three
--arguments:
--
-- int main (int ARGC, char *ARGV[], char *ENVP)
--
-- The first two arguments are just the same. The third argument ENVP
--gives the process's environment; it is the same as the value of
--`environ'. *Note Environment Variables::. POSIX.1 does not allow this
--three-argument form, so to be portable it is best to write `main' to
--take two arguments, and use the value of `environ'.
--
--* Menu:
--
--* Argument Syntax:: By convention, options start with a hyphen.
--* Parsing Program Arguments:: Ways to parse program options and arguments.
--
--
--File: libc.info, Node: Argument Syntax, Next: Parsing Program Arguments, Up: Program Arguments
--
--Program Argument Syntax Conventions
-------------------------------------
--
-- POSIX recommends these conventions for command line arguments.
--`getopt' (*note Getopt::.) and `argp_parse' (*note Argp::.) make it
--easy to implement them.
--
-- * Arguments are options if they begin with a hyphen delimiter (`-').
--
-- * Multiple options may follow a hyphen delimiter in a single token if
-- the options do not take arguments. Thus, `-abc' is equivalent to
-- `-a -b -c'.
--
-- * Option names are single alphanumeric characters (as for `isalnum';
-- *note Classification of Characters::.).
--
-- * Certain options require an argument. For example, the `-o' command
-- of the `ld' command requires an argument--an output file name.
--
-- * An option and its argument may or may not appear as separate
-- tokens. (In other words, the whitespace separating them is
-- optional.) Thus, `-o foo' and `-ofoo' are equivalent.
--
-- * Options typically precede other non-option arguments.
--
-- The implementations of `getopt' and `argp_parse' in the GNU C
-- library normally make it appear as if all the option arguments were
-- specified before all the non-option arguments for the purposes of
-- parsing, even if the user of your program intermixed option and
-- non-option arguments. They do this by reordering the elements of
-- the ARGV array. This behavior is nonstandard; if you want to
-- suppress it, define the `_POSIX_OPTION_ORDER' environment variable.
-- *Note Standard Environment::.
--
-- * The argument `--' terminates all options; any following arguments
-- are treated as non-option arguments, even if they begin with a
-- hyphen.
--
-- * A token consisting of a single hyphen character is interpreted as
-- an ordinary non-option argument. By convention, it is used to
-- specify input from or output to the standard input and output
-- streams.
--
-- * Options may be supplied in any order, or appear multiple times.
-- The interpretation is left up to the particular application
-- program.
--
-- GNU adds "long options" to these conventions. Long options consist
--of `--' followed by a name made of alphanumeric characters and dashes.
--Option names are typically one to three words long, with hyphens to
--separate words. Users can abbreviate the option names as long as the
--abbreviations are unique.
--
-- To specify an argument for a long option, write `--NAME=VALUE'.
--This syntax enables a long option to accept an argument that is itself
--optional.
--
-- Eventually, the GNU system will provide completion for long option
--names in the shell.
--
--
--File: libc.info, Node: Parsing Program Arguments, Prev: Argument Syntax, Up: Program Arguments
--
--Parsing Program Arguments
---------------------------
--
-- If the syntax for the command line arguments to your program is
--simple enough, you can simply pick the arguments off from ARGV by hand.
--But unless your program takes a fixed number of arguments, or all of the
--arguments are interpreted in the same way (as file names, for example),
--you are usually better off using `getopt' (*note Getopt::.) or
--`argp_parse' (*note Argp::.) to do the parsing.
--
-- `getopt' is more standard (the short-option only version of it is a
--part of the POSIX standard), but using `argp_parse' is often easier,
--both for very simple and very complex option structures, because it
--does more of the dirty work for you.
--
--* Menu:
--
--* Getopt:: Parsing program options using `getopt'.
--* Argp:: Parsing program options using `argp_parse'.
--* Suboptions:: Some programs need more detailed options.
--* Suboptions Example:: This shows how it could be done for `mount'.
--
--
--File: libc.info, Node: Getopt, Next: Argp, Up: Parsing Program Arguments
--
--Parsing program options using `getopt'
--======================================
--
-- The `getopt' and `getopt_long' functions automate some of the chore
--involved in parsing typical unix command line options.
--
--* Menu:
--
--* Using Getopt:: Using the `getopt' function.
--* Example of Getopt:: An example of parsing options with `getopt'.
--* Getopt Long Options:: GNU suggests utilities accept long-named
-- options; here is one way to do.
--* Getopt Long Option Example:: An example of using `getopt_long'.
--
--
--File: libc.info, Node: Using Getopt, Next: Example of Getopt, Up: Getopt
--
--Using the `getopt' function
-----------------------------
--
-- Here are the details about how to call the `getopt' function. To
--use this facility, your program must include the header file `unistd.h'.
--
-- - Variable: int opterr
-- If the value of this variable is nonzero, then `getopt' prints an
-- error message to the standard error stream if it encounters an
-- unknown option character or an option with a missing required
-- argument. This is the default behavior. If you set this variable
-- to zero, `getopt' does not print any messages, but it still
-- returns the character `?' to indicate an error.
--
-- - Variable: int optopt
-- When `getopt' encounters an unknown option character or an option
-- with a missing required argument, it stores that option character
-- in this variable. You can use this for providing your own
-- diagnostic messages.
--
-- - Variable: int optind
-- This variable is set by `getopt' to the index of the next element
-- of the ARGV array to be processed. Once `getopt' has found all of
-- the option arguments, you can use this variable to determine where
-- the remaining non-option arguments begin. The initial value of
-- this variable is `1'.
--
-- - Variable: char * optarg
-- This variable is set by `getopt' to point at the value of the
-- option argument, for those options that accept arguments.
--
-- - Function: int getopt (int ARGC, char **ARGV, const char *OPTIONS)
-- The `getopt' function gets the next option argument from the
-- argument list specified by the ARGV and ARGC arguments. Normally
-- these values come directly from the arguments received by `main'.
--
-- The OPTIONS argument is a string that specifies the option
-- characters that are valid for this program. An option character
-- in this string can be followed by a colon (`:') to indicate that
-- it takes a required argument. If an option character is followed
-- by two colons (`::'), its argument is optional; this is a GNU
-- extension.
--
-- If the OPTIONS argument string begins with a hyphen (`-'), this is
-- treated specially. It permits arguments that are not options to be
-- returned as if they were associated with option character `\0'.
--
-- The `getopt' function returns the option character for the next
-- command line option. When no more option arguments are available,
-- it returns `-1'. There may still be more non-option arguments; you
-- must compare the external variable `optind' against the ARGC
-- parameter to check this.
--
-- If the option has an argument, `getopt' returns the argument by
-- storing it in the variable OPTARG. You don't ordinarily need to
-- copy the `optarg' string, since it is a pointer into the original
-- ARGV array, not into a static area that might be overwritten.
--
-- If `getopt' finds an option character in ARGV that was not
-- included in OPTIONS, or a missing option argument, it returns `?'
-- and sets the external variable `optopt' to the actual option
-- character. If the first character of OPTIONS is a colon (`:'),
-- then `getopt' returns `:' instead of `?' to indicate a missing
-- option argument. In addition, if the external variable `opterr'
-- is nonzero (which is the default), `getopt' prints an error
-- message.
--
--
--File: libc.info, Node: Example of Getopt, Next: Getopt Long Options, Prev: Using Getopt, Up: Getopt
--
--Example of Parsing Arguments with `getopt'
--------------------------------------------
--
-- Here is an example showing how `getopt' is typically used. The key
--points to notice are:
--
-- * Normally, `getopt' is called in a loop. When `getopt' returns
-- `-1', indicating no more options are present, the loop terminates.
--
-- * A `switch' statement is used to dispatch on the return value from
-- `getopt'. In typical use, each case just sets a variable that is
-- used later in the program.
--
-- * A second loop is used to process the remaining non-option
-- arguments.
--
-- #include <unistd.h>
-- #include <stdio.h>
--
-- int
-- main (int argc, char **argv)
-- {
-- int aflag = 0;
-- int bflag = 0;
-- char *cvalue = NULL;
-- int index;
-- int c;
--
-- opterr = 0;
--
-- while ((c = getopt (argc, argv, "abc:")) != -1)
-- switch (c)
-- {
-- case 'a':
-- aflag = 1;
-- break;
-- case 'b':
-- bflag = 1;
-- break;
-- case 'c':
-- cvalue = optarg;
-- break;
-- case '?':
-- if (isprint (optopt))
-- fprintf (stderr, "Unknown option `-%c'.\n", optopt);
-- else
-- fprintf (stderr,
-- "Unknown option character `\\x%x'.\n",
-- optopt);
-- return 1;
-- default:
-- abort ();
-- }
--
-- printf ("aflag = %d, bflag = %d, cvalue = %s\n",
-- aflag, bflag, cvalue);
--
-- for (index = optind; index < argc; index++)
-- printf ("Non-option argument %s\n", argv[index]);
-- return 0;
-- }
--
-- Here are some examples showing what this program prints with
--different combinations of arguments:
--
-- % testopt
-- aflag = 0, bflag = 0, cvalue = (null)
--
-- % testopt -a -b
-- aflag = 1, bflag = 1, cvalue = (null)
--
-- % testopt -ab
-- aflag = 1, bflag = 1, cvalue = (null)
--
-- % testopt -c foo
-- aflag = 0, bflag = 0, cvalue = foo
--
-- % testopt -cfoo
-- aflag = 0, bflag = 0, cvalue = foo
--
-- % testopt arg1
-- aflag = 0, bflag = 0, cvalue = (null)
-- Non-option argument arg1
--
-- % testopt -a arg1
-- aflag = 1, bflag = 0, cvalue = (null)
-- Non-option argument arg1
--
-- % testopt -c foo arg1
-- aflag = 0, bflag = 0, cvalue = foo
-- Non-option argument arg1
--
-- % testopt -a -- -b
-- aflag = 1, bflag = 0, cvalue = (null)
-- Non-option argument -b
--
-- % testopt -a -
-- aflag = 1, bflag = 0, cvalue = (null)
-- Non-option argument -
--
--
--File: libc.info, Node: Getopt Long Options, Next: Getopt Long Option Example, Prev: Example of Getopt, Up: Getopt
--
--Parsing Long Options with `getopt_long'
-----------------------------------------
--
-- To accept GNU-style long options as well as single-character options,
--use `getopt_long' instead of `getopt'. This function is declared in
--`getopt.h', not `unistd.h'. You should make every program accept long
--options if it uses any options, for this takes little extra work and
--helps beginners remember how to use the program.
--
-- - Data Type: struct option
-- This structure describes a single long option name for the sake of
-- `getopt_long'. The argument LONGOPTS must be an array of these
-- structures, one for each long option. Terminate the array with an
-- element containing all zeros.
--
-- The `struct option' structure has these fields:
--
-- `const char *name'
-- This field is the name of the option. It is a string.
--
-- `int has_arg'
-- This field says whether the option takes an argument. It is
-- an integer, and there are three legitimate values:
-- `no_argument', `required_argument' and `optional_argument'.
--
-- `int *flag'
-- `int val'
-- These fields control how to report or act on the option when
-- it occurs.
--
-- If `flag' is a null pointer, then the `val' is a value which
-- identifies this option. Often these values are chosen to
-- uniquely identify particular long options.
--
-- If `flag' is not a null pointer, it should be the address of
-- an `int' variable which is the flag for this option. The
-- value in `val' is the value to store in the flag to indicate
-- that the option was seen.
--
-- - Function: int getopt_long (int ARGC, char **ARGV, const char
-- *SHORTOPTS, struct option *LONGOPTS, int *INDEXPTR)
-- Decode options from the vector ARGV (whose length is ARGC). The
-- argument SHORTOPTS describes the short options to accept, just as
-- it does in `getopt'. The argument LONGOPTS describes the long
-- options to accept (see above).
--
-- When `getopt_long' encounters a short option, it does the same
-- thing that `getopt' would do: it returns the character code for the
-- option, and stores the options argument (if it has one) in
-- `optarg'.
--
-- When `getopt_long' encounters a long option, it takes actions based
-- on the `flag' and `val' fields of the definition of that option.
--
-- If `flag' is a null pointer, then `getopt_long' returns the
-- contents of `val' to indicate which option it found. You should
-- arrange distinct values in the `val' field for options with
-- different meanings, so you can decode these values after
-- `getopt_long' returns. If the long option is equivalent to a short
-- option, you can use the short option's character code in `val'.
--
-- If `flag' is not a null pointer, that means this option should just
-- set a flag in the program. The flag is a variable of type `int'
-- that you define. Put the address of the flag in the `flag' field.
-- Put in the `val' field the value you would like this option to
-- store in the flag. In this case, `getopt_long' returns `0'.
--
-- For any long option, `getopt_long' tells you the index in the array
-- LONGOPTS of the options definition, by storing it into
-- `*INDEXPTR'. You can get the name of the option with
-- `LONGOPTS[*INDEXPTR].name'. So you can distinguish among long
-- options either by the values in their `val' fields or by their
-- indices. You can also distinguish in this way among long options
-- that set flags.
--
-- When a long option has an argument, `getopt_long' puts the argument
-- value in the variable `optarg' before returning. When the option
-- has no argument, the value in `optarg' is a null pointer. This is
-- how you can tell whether an optional argument was supplied.
--
-- When `getopt_long' has no more options to handle, it returns `-1',
-- and leaves in the variable `optind' the index in ARGV of the next
-- remaining argument.
--
--
--File: libc.info, Node: Getopt Long Option Example, Prev: Getopt Long Options, Up: Getopt
--
--Example of Parsing Long Options with `getopt_long'
----------------------------------------------------
--
-- #include <stdio.h>
-- #include <stdlib.h>
-- #include <getopt.h>
--
-- /* Flag set by `--verbose'. */
-- static int verbose_flag;
--
-- int
-- main (argc, argv)
-- int argc;
-- char **argv;
-- {
-- int c;
--
-- while (1)
-- {
-- static struct option long_options[] =
-- {
-- /* These options set a flag. */
-- {"verbose", 0, &verbose_flag, 1},
-- {"brief", 0, &verbose_flag, 0},
-- /* These options don't set a flag.
-- We distinguish them by their indices. */
-- {"add", 1, 0, 0},
-- {"append", 0, 0, 0},
-- {"delete", 1, 0, 0},
-- {"create", 0, 0, 0},
-- {"file", 1, 0, 0},
-- {0, 0, 0, 0}
-- };
-- /* `getopt_long' stores the option index here. */
-- int option_index = 0;
--
-- c = getopt_long (argc, argv, "abc:d:",
-- long_options, &option_index);
--
-- /* Detect the end of the options. */
-- if (c == -1)
-- break;
--
-- switch (c)
-- {
-- case 0:
-- /* If this option set a flag, do nothing else now. */
-- if (long_options[option_index].flag != 0)
-- break;
-- printf ("option %s", long_options[option_index].name);
-- if (optarg)
-- printf (" with arg %s", optarg);
-- printf ("\n");
-- break;
--
-- case 'a':
-- puts ("option -a\n");
-- break;
--
-- case 'b':
-- puts ("option -b\n");
-- break;
--
-- case 'c':
-- printf ("option -c with value `%s'\n", optarg);
-- break;
--
-- case 'd':
-- printf ("option -d with value `%s'\n", optarg);
-- break;
--
-- case '?':
-- /* `getopt_long' already printed an error message. */
-- break;
--
-- default:
-- abort ();
-- }
-- }
--
-- /* Instead of reporting `--verbose'
-- and `--brief' as they are encountered,
-- we report the final status resulting from them. */
-- if (verbose_flag)
-- puts ("verbose flag is set");
--
-- /* Print any remaining command line arguments (not options). */
-- if (optind < argc)
-- {
-- printf ("non-option ARGV-elements: ");
-- while (optind < argc)
-- printf ("%s ", argv[optind++]);
-- putchar ('\n');
-- }
--
-- exit (0);
-- }
--
--
--File: libc.info, Node: Argp, Next: Suboptions, Prev: Getopt, Up: Parsing Program Arguments
--
--Parsing Program Options with Argp
--=================================
--
-- "Argp" is an interface for parsing unix-style argument vectors
--(*note Program Arguments::.).
--
-- Unlike the more common `getopt' interface, it provides many related
--convenience features in addition to parsing options, such as
--automatically producing output in response to `--help' and `--version'
--options (as defined by the GNU coding standards). Doing these things
--in argp results in a more consistent look for programs that use it, and
--makes less likely that implementors will neglect to implement them or
--keep them up-to-date.
--
-- Argp also provides the ability to merge several independently defined
--option parsers into one, mediating conflicts between them, and making
--the result appear seamless. A library can export an argp option parser,
--which programs can easily use in conjunction with their own option
--parser. This results in less work for user programs (indeed, some may
--use only argument parsers exported by libraries, and have no options of
--their own), and more consistent option-parsing for the abstractions
--implemented by the library.
--
-- The header file `<argp.h>' should be included to use argp.
--
--The `argp_parse' Function
---------------------------
--
-- The main interface to argp is the `argp_parse' function; often, a
--call to `argp_parse' is the only argument-parsing code needed in `main'
--(*note Program Arguments::.).
--
-- - Function: error_t argp_parse (const struct argp *ARGP, int ARGC,
-- char **ARGV, unsigned FLAGS, int *ARG_INDEX, void *INPUT)
-- The `argp_parse' function parses the arguments in ARGV, of length
-- ARGC, using the argp parser ARGP (*note Argp Parsers::.); a value
-- of zero is the same as a `struct argp' containing all zeros.
-- FLAGS is a set of flag bits that modify the parsing behavior
-- (*note Argp Flags::.). INPUT is passed through to the argp parser
-- ARGP, and has meaning defined by it; a typical usage is to pass a
-- pointer to a structure which can be used for specifying parameters
-- to the parser and passing back results from it.
--
-- Unless the `ARGP_NO_EXIT' or `ARGP_NO_HELP' flags are included in
-- FLAGS, calling `argp_parse' may result in the program exiting--for
-- instance when an unknown option is encountered. *Note Program
-- Termination::.
--
-- The return value is zero for successful parsing, or a unix error
-- code (*note Error Codes::.) if an error was detected. Different
-- argp parsers may return arbitrary error codes, but standard ones
-- are `ENOMEM' if a memory allocation error occurred, or `EINVAL' if
-- an unknown option or option argument was encountered.
--
--* Menu:
--
--* Globals: Argp Global Variables. Global argp parameters.
--* Parsers: Argp Parsers. Defining parsers for use with `argp_parse'.
--* Flags: Argp Flags. Flags that modify the behavior of `argp_parse'.
--* Help: Argp Help. Printing help messages when not parsing.
--* Examples: Argp Examples. Simple examples of programs using argp.
--* Customization: Argp User Customization.
-- Users may control the `--help' output format.
--
--
--File: libc.info, Node: Argp Global Variables, Next: Argp Parsers, Up: Argp
--
--Argp Global Variables
-----------------------
--
-- These variables make it very easy for every user program to implement
--the `--version' option and provide a bug-reporting address in the
--`--help' output (which is implemented by argp regardless).
--
-- - Variable: const char * argp_program_version
-- If defined or set by the user program to a non-zero value, then a
-- `--version' option is added when parsing with `argp_parse' (unless
-- the `ARGP_NO_HELP' flag is used), which will print this string
-- followed by a newline and exit (unless the `ARGP_NO_EXIT' flag is
-- used).
--
-- - Variable: const char * argp_program_bug_address
-- If defined or set by the user program to a non-zero value,
-- `argp_program_bug_address' should point to string that is the
-- bug-reporting address for the program. It will be printed at the
-- end of the standard output for the `--help' option, embedded in a
-- sentence that says something like `Report bugs to ADDRESS.'.
--
-- - Variable: argp_program_version_hook
-- If defined or set by the user program to a non-zero value, then a
-- `--version' option is added when parsing with `argp_parse' (unless
-- the `ARGP_NO_HELP' flag is used), which calls this function to
-- print the version, and then exits with a status of 0 (unless the
-- `ARGP_NO_EXIT' flag is used). It should point to a function with
-- the following type signature:
--
-- void PRINT-VERSION (FILE *STREAM, struct argp_state *STATE)
--
-- *Note Argp Parsing State::, for an explanation of STATE.
--
-- This variable takes precedent over `argp_program_version', and is
-- useful if a program has version information that cannot be easily
-- specified as a simple string.
--
-- - Variable: error_t argp_err_exit_status
-- The exit status that argp will use when exiting due to a parsing
-- error. If not defined or set by the user program, this defaults to
-- `EX_USAGE' from `<sysexits.h>'.
--
--
--File: libc.info, Node: Argp Parsers, Next: Argp Flags, Prev: Argp Global Variables, Up: Argp
--
--Specifying Argp Parsers
-------------------------
--
-- The first argument to the `argp_parse' function is a pointer to a
--`struct argp', which known as an "argp parser":
--
-- - Data Type: struct argp
-- This structure specifies how to parse a given set of options and
-- arguments, perhaps in conjunction with other argp parsers. It has
-- the following fields:
--
-- `const struct argp_option *options'
-- A pointer to a vector of `argp_option' structures specifying
-- which options this argp parser understands; it may be zero if
-- there are no options at all. *Note Argp Option Vectors::.
--
-- `argp_parser_t parser'
-- A pointer to a function that defines actions for this parser;
-- it is called for each option parsed, and at other
-- well-defined points in the parsing process. A value of zero
-- is the same as a pointer to a function that always returns
-- `ARGP_ERR_UNKNOWN'. *Note Argp Parser Functions::.
--
-- `const char *args_doc'
-- If non-zero, a string describing what non-option arguments
-- are wanted by this parser; it is only used to print the
-- `Usage:' message. If it contains newlines, the strings
-- separated by them are considered alternative usage patterns,
-- and printed on separate lines (lines after the first are
-- prefix by ` or: ' instead of `Usage:').
--
-- `const char *doc'
-- If non-zero, a string containing extra text to be printed
-- before and after the options in a long help message, with the
-- two sections separated by a vertical tab (`'\v'', `'\013'')
-- character. By convention, the documentation before the
-- options is just a short string saying what the program does,
-- and that afterwards is longer, describing the behavior in
-- more detail.
--
-- `const struct argp_child *children'
-- A pointer to a vector of `argp_children' structures specifying
-- additional argp parsers that should be combined with this one.
-- *Note Argp Children::.
--
-- `char *(*help_filter)(int KEY, const char *TEXT, void *INPUT)'
-- If non-zero, a pointer to a function to filter the output of
-- help messages. *Note Argp Help Filtering::.
--
-- The `options', `parser', `args_doc', and `doc' fields are usually
--all that are needed. If an argp parser is defined as an initialized C
--variable, only the used fields need be specified in the
--initializer--the rest will default to zero due to the way C structure
--initialization works (this fact is exploited for most argp structures,
--grouping the most-used fields near the beginning, so that unused fields
--can simply be left unspecified).
--
--* Menu:
--
--* Options: Argp Option Vectors. Specifying options in an argp parser.
--* Argp Parser Functions:: Defining actions for an argp parser.
--* Children: Argp Children. Combining multiple argp parsers.
--* Help Filtering: Argp Help Filtering. Customizing help output for an argp parser.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-35 glibc-2.1.3/manual/libc.info-35
---- ../glibc-2.1.3/manual/libc.info-35 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-35 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1239 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Argp Option Vectors, Next: Argp Parser Functions, Prev: Argp Parsers, Up: Argp Parsers
--
--Specifying Options in an Argp Parser
--------------------------------------
--
-- The `options' field in a `struct argp' points to a vector of `struct
--argp_option' structures, each of which specifies an option that argp
--parser supports (actually, sometimes multiple entries may used for a
--single option if it has many names). It should be terminated by an
--entry with zero in all fields (note that when using an initialized C
--array for options, writing `{ 0 }' is enough to achieve this).
--
-- - Data Type: struct argp_option
-- This structure specifies a single option that an argp parser
-- understands, and how to parse and document it. It has the
-- following fields:
--
-- `const char *name'
-- The long name for this option, corresponding to the long
-- option `--NAME'; this field can be zero if this option only
-- has a short name. To specify multiple names for an option,
-- additional entries may follow this one, with the
-- `OPTION_ALIAS' flag set (*note Argp Option Flags::.).
--
-- `int key'
-- The integer key that is provided to the argp parser's parsing
-- function when this option is being parsed. Also, if KEY has
-- a value that is a printable ASCII character (i.e., `isascii
-- (KEY)' is true), it *also* specifies a short option `-CHAR',
-- where CHAR is the ASCII character with the code KEY.
--
-- `const char *arg'
-- If non-zero, this is the name of an argument associated with
-- this option, which must be provided (e.g., with the
-- `--NAME=VALUE' or `-CHAR VALUE' syntaxes) unless the
-- `OPTION_ARG_OPTIONAL' flag (*note Argp Option Flags::.) is
-- set, in which case it *may* be provided.
--
-- `int flags'
-- Flags associated with this option (some of which are referred
-- to above). *Note Argp Option Flags::.
--
-- `const char *doc'
-- A documentation string for this option, for printing in help
-- messages.
--
-- If both the `name' and `key' fields are zero, this string
-- will be printed out-dented from the normal option column,
-- making it useful as a group header (it will be the first
-- thing printed in its group); in this usage, it's conventional
-- to end the string with a `:' character.
--
-- `int group'
-- The group this option is in.
--
-- In a long help message, options are sorted alphabetically
-- within each group, and the groups presented in the order 0,
-- 1, 2, ..., N, -M, ..., -2, -1. Every entry in an options
-- array with this field 0 will inherit the group number of the
-- previous entry, or zero if it's the first one, unless its a
-- group header (`name' and `key' fields both zero), in which
-- case, the previous entry + 1 is the default. Automagic
-- options such as `--help' are put into group -1.
--
-- Note that because of C structure initialization rules, this
-- field often need not be specified, because 0 is the right
-- value.
--
--* Menu:
--
--* Flags: Argp Option Flags. Flags for options.
--
--
--File: libc.info, Node: Argp Option Flags, Up: Argp Option Vectors
--
--Flags for Argp Options
--......................
--
-- The following flags may be or'd together in the `flags' field of a
--`struct argp_option', and control various aspects of how that option is
--parsed or displayed in help messages:
--
--`OPTION_ARG_OPTIONAL'
-- The argument associated with this option is optional.
--
--`OPTION_HIDDEN'
-- This option isn't displayed in any help messages.
--
--`OPTION_ALIAS'
-- This option is an alias for the closest previous non-alias option.
-- This means that it will be displayed in the same help entry, and
-- will inherit fields other than `name' and `key' from the aliased
-- option.
--
--`OPTION_DOC'
-- This option isn't actually an option (and so should be ignored by
-- the actual option parser), but rather an arbitrary piece of
-- documentation that should be displayed in much the same manner as
-- the options (known as a "documentation option").
--
-- If this flag is set, then the option `name' field is displayed
-- unmodified (e.g., no `--' prefix is added) at the left-margin
-- (where a *short* option would normally be displayed), and the
-- documentation string in the normal place. For purposes of
-- sorting, any leading whitespace and punctuation is ignored, except
-- that if the first non-whitespace character is not `-', this entry
-- is displayed after all options (and `OPTION_DOC' entries with a
-- leading `-') in the same group.
--
--`OPTION_NO_USAGE'
-- This option shouldn't be included in `long' usage messages (but is
-- still included in help messages). This is mainly intended for
-- options that are completely documented in an argp's `args_doc'
-- field (*note Argp Parsers::.), in which case including the option
-- in the generic usage list would be redundant.
--
-- For instance, if `args_doc' is `"FOO BAR\n-x BLAH"', and the `-x'
-- option's purpose is to distinguish these two cases, `-x' should
-- probably be marked `OPTION_NO_USAGE'.
--
--
--File: libc.info, Node: Argp Parser Functions, Next: Argp Children, Prev: Argp Option Vectors, Up: Argp Parsers
--
--Argp Parser Functions
-----------------------
--
-- The function pointed to by the `parser' field in a `struct argp'
--(*note Argp Parsers::.) defines what actions take place in response to
--each option or argument that is parsed, and is also used as a hook, to
--allow a parser to do something at certain other points during parsing.
--
-- Argp parser functions have the following type signature:
--
-- error_t PARSER (int KEY, char *ARG, struct argp_state *STATE)
--
--where the arguments are as follows:
--
--KEY
-- For each option that is parsed, PARSER is called with a value of
-- KEY from that option's `key' field in the option vector (*note
-- Argp Option Vectors::.). PARSER is also called at other times
-- with special reserved keys, such as `ARGP_KEY_ARG' for non-option
-- arguments. *Note Argp Special Keys::.
--
--ARG
-- If KEY is an option, ARG is the value given for it, or zero if no
-- value was specified. Only options that have a non-zero `arg'
-- field can ever have a value, and those must *always* have a value,
-- unless the `OPTION_ARG_OPTIONAL' flag was specified (if the input
-- being parsed specifies a value for an option that doesn't allow
-- one, an error results before PARSER ever gets called).
--
-- If KEY is `ARGP_KEY_ARG', ARG is a non-option argument; other
-- special keys always have a zero ARG.
--
--STATE
-- STATE points to a `struct argp_state', containing useful
-- information about the current parsing state for use by PARSER.
-- *Note Argp Parsing State::.
--
-- When PARSER is called, it should perform whatever action is
--appropriate for KEY, and return either `0' for success,
--`ARGP_ERR_UNKNOWN', if the value of KEY is not handled by this parser
--function, or a unix error code if a real error occurred (*note Error
--Codes::.).
--
-- - Macro: int ARGP_ERR_UNKNOWN
-- Argp parser functions should return `ARGP_ERR_UNKNOWN' for any KEY
-- value they do not recognize, or for non-option arguments (`KEY ==
-- ARGP_KEY_ARG') that they do not which to handle.
--
-- A typical parser function uses a switch statement on KEY:
--
-- error_t
-- parse_opt (int key, char *arg, struct argp_state *state)
-- {
-- switch (key)
-- {
-- case OPTION_KEY:
-- ACTION
-- break;
-- ...
-- default:
-- return ARGP_ERR_UNKNOWN;
-- }
-- return 0;
-- }
--
--* Menu:
--
--* Keys: Argp Special Keys. Special values for the KEY argument.
--* State: Argp Parsing State. What the STATE argument refers to.
--* Functions: Argp Helper Functions. Functions to help during argp parsing.
--
--
--File: libc.info, Node: Argp Special Keys, Next: Argp Parsing State, Up: Argp Parser Functions
--
--Special Keys for Argp Parser Functions
--......................................
--
-- In addition to key values corresponding to user options, the KEY
--argument to argp parser functions may have a number of other special
--values (ARG and STATE refer to parser function arguments; *note Argp
--Parser Functions::.):
--
--`ARGP_KEY_ARG'
-- This is not an option at all, but rather a command line argument,
-- whose value is pointed to by ARG.
--
-- When there are multiple parser functions (due to argp parsers being
-- combined), it's impossible to know which one wants to handle an
-- argument, so each is called in turn, until one returns 0 or an
-- error other than `ARGP_ERR_UNKNOWN'; if an argument is handled by
-- no one, `argp_parse' immediately returns success, without parsing
-- any more arguments.
--
-- Once a parser function returns success for this key, that fact is
-- recorded, and the `ARGP_KEY_NO_ARGS' case won't be used.
-- *However*, if while processing the argument, a parser function
-- decrements the `next' field of its STATE argument, the option
-- won't be considered processed; this is to allow you to actually
-- modify the argument (perhaps into an option), and have it
-- processed again.
--
--`ARGP_KEY_ARGS'
-- If a parser function returns `ARGP_ERR_UNKNOWN' for
-- `ARGP_KEY_ARG', it is immediately called again with the key
-- `ARGP_KEY_ARGS', which has a similar meaning, but is slightly more
-- convenient for consuming all remaining arguments. ARG is 0, and
-- the tail of the argument vector may be found at `STATE->argv +
-- STATE->next'. If success is returned for this key, and
-- `STATE->next' is unchanged, then all remaining arguments are
-- considered to have been consumed, otherwise, the amount by which
-- `STATE->next' has been adjust indicates how many were used. For
-- instance, here's an example that uses both, for different args:
--
-- ...
-- case ARGP_KEY_ARG:
-- if (STATE->arg_num == 0)
-- /* First argument */
-- first_arg = ARG;
-- else
-- /* Let the next case parse it. */
-- return ARGP_KEY_UNKNOWN;
-- break;
-- case ARGP_KEY_ARGS:
-- remaining_args = STATE->argv + STATE->next;
-- num_remaining_args = STATE->argc - STATE->next;
-- break;
--
--`ARGP_KEY_END'
-- There are no more command line arguments at all.
--
--`ARGP_KEY_NO_ARGS'
-- Because it's common to want to do some special processing if there
-- aren't any non-option args, parser functions are called with this
-- key if they didn't successfully process any non-option arguments.
-- Called just before `ARGP_KEY_END' (where more general validity
-- checks on previously parsed arguments can take place).
--
--`ARGP_KEY_INIT'
-- Passed in before any parsing is done. Afterwards, the values of
-- each element of the `child_input' field of STATE, if any, are
-- copied to each child's state to be the initial value of the `input'
-- when *their* parsers are called.
--
--`ARGP_KEY_SUCCESS'
-- Passed in when parsing has successfully been completed (even if
-- there are still arguments remaining).
--
--`ARGP_KEY_ERROR'
-- Passed in if an error has occurred, and parsing terminated (in
-- which case a call with a key of `ARGP_KEY_SUCCESS' is never made).
--
--`ARGP_KEY_FINI'
-- The final key ever seen by any parser (even after
-- `ARGP_KEY_SUCCESS' and `ARGP_KEY_ERROR'). Any resources allocated
-- by `ARGP_KEY_INIT' may be freed here (although sometimes certain
-- resources allocated there are to be returned to the caller after a
-- successful parse; in that case, those particular resources can be
-- freed in the `ARGP_KEY_ERROR' case).
--
-- In all cases, `ARGP_KEY_INIT' is the first key seen by parser
--functions, and `ARGP_KEY_FINI' the last (unless an error was returned
--by the parser for `ARGP_KEY_INIT'). Other keys can occur in one the
--following orders (OPT refers to an arbitrary option key):
--
--OPT... `ARGP_KEY_NO_ARGS' `ARGP_KEY_END' `ARGP_KEY_SUCCESS'
-- The arguments being parsed contained no non-option arguments at
-- all.
--
--( OPT | `ARGP_KEY_ARG' )... `ARGP_KEY_END' `ARGP_KEY_SUCCESS'
-- All non-option arguments were successfully handled by a parser
-- function (there may be multiple parser functions if multiple argp
-- parsers were combined).
--
--( OPT | `ARGP_KEY_ARG' )... `ARGP_KEY_SUCCESS'
-- Some non-option argument was unrecognized.
--
-- This occurs when every parser function returns `ARGP_KEY_UNKNOWN'
-- for an argument, in which case parsing stops at that argument. If
-- a non-zero value for ARG_INDEX was passed to `argp_parse', the
-- index of this argument is returned in it, otherwise an error
-- occurs.
--
-- If an error occurs (either detected by argp, or because a parser
--function returned an error value), then each parser is called with
--`ARGP_KEY_ERROR', and no further calls are made except the final call
--with `ARGP_KEY_FINI'.
--
--
--File: libc.info, Node: Argp Helper Functions, Prev: Argp Parsing State, Up: Argp Parser Functions
--
--Functions For Use in Argp Parsers
--.................................
--
-- Argp provides a number of functions for the user of argp parser
--functions (*note Argp Parser Functions::.), mostly for producing error
--messages. These take as their first argument the STATE argument to the
--parser function (*note Argp Parsing State::.).
--
-- - Function: void argp_usage (const struct argp_state *STATE)
-- Output the standard usage message for the argp parser referred to
-- by STATE to `STATE->err_stream' and terminate the program with
-- `exit (argp_err_exit_status)' (*note Argp Global Variables::.).
--
-- - Function: void argp_error (const struct argp_state *STATE, const
-- char *FMT, ...)
-- Print the printf format string FMT and following args, preceded by
-- the program name and `:', and followed by a `Try ... --help'
-- message, and terminate the program with an exit status of
-- `argp_err_exit_status' (*note Argp Global Variables::.).
--
-- - Function: void argp_failure (const struct argp_state *STATE, int
-- STATUS, int ERRNUM, const char *FMT, ...)
-- Similarly to the standard gnu error-reporting function `error',
-- print the printf format string FMT and following args, preceded by
-- the program name and `:', and followed by the standard unix error
-- text for ERRNUM if it is non-zero; then if STATUS is non-zero,
-- terminate the program with that as its exit status.
--
-- The difference between this function and `argp_error' is that
-- `argp_error' is for *parsing errors*, whereas `argp_failure' is
-- for other problems that occur during parsing but don't reflect a
-- syntactic problem with the input--such as illegal values for
-- options, bad phase of the moon, etc.
--
-- - Function: void argp_state_help (const struct argp_state *STATE, FILE
-- *STREAM, unsigned FLAGS)
-- Output a help message for the argp parser referred to by STATE to
-- STREAM. The FLAGS argument determines what sort of help message
-- is produced. *Note Argp Help Flags::.
--
-- Error output is sent to `STATE->err_stream', and the program name
--printed is `STATE->name'.
--
-- The output or program termination behavior of these functions may be
--suppressed if the `ARGP_NO_EXIT' or `ARGP_NO_ERRS' flags, respectively,
--were passed to `argp_parse'. *Note Argp Flags::.
--
-- This behavior is useful if an argp parser is exported for use by
--other programs (e.g., by a library), and may be used in a context where
--it is not desirable to terminate the program in response to parsing
--errors. In argp parsers intended for such general use, calls to any of
--these functions should be followed by code return of an appropriate
--error code for the case where the program *doesn't* terminate; for
--example:
--
-- if (BAD ARGUMENT SYNTAX)
-- {
-- argp_usage (STATE);
-- return EINVAL;
-- }
--
--If it's known that a parser function will only be used when
--`ARGP_NO_EXIT' is not set, the return may be omitted.
--
--
--File: libc.info, Node: Argp Parsing State, Next: Argp Helper Functions, Prev: Argp Special Keys, Up: Argp Parser Functions
--
--Argp Parsing State
--..................
--
-- The third argument to argp parser functions (*note Argp Parser
--Functions::.) is a pointer to a `struct argp_state', which contains
--information about the state of the option parsing.
--
-- - Data Type: struct argp_state
-- This structure has the following fields, which may be modified as
-- noted:
--
-- `const struct argp *const root_argp'
-- The top level argp parser being parsed. Note that this is
-- often *not* the same `struct argp' passed into `argp_parse' by
-- the invoking program (*note Argp::.), but instead an internal
-- argp parser that contains options implemented by `argp_parse'
-- itself (such as `--help').
--
-- `int argc'
-- `char **argv'
-- The argument vector being parsed. May be modified.
--
-- `int next'
-- The index in `argv' of the next argument to be parsed. May
-- be modified.
--
-- One way to consume all remaining arguments in the input is to
-- set `STATE->next = STATE->argc' (perhaps after recording the
-- value of the `next' field to find the consumed arguments).
-- Also, you can cause the current option to be re-parsed by
-- decrementing this field, and then modifying
-- `STATE->argv[STATE->next]' to be the option that should be
-- reexamined.
--
-- `unsigned flags'
-- The flags supplied to `argp_parse'. May be modified,
-- although some flags may only take effect when `argp_parse' is
-- first invoked. *Note Argp Flags::.
--
-- `unsigned arg_num'
-- While calling a parsing function with the KEY argument
-- `ARGP_KEY_ARG', this is the number of the current arg,
-- starting at 0, and incremented after each such call returns.
-- At all other times, this is the number of such arguments that
-- have been processed.
--
-- `int quoted'
-- If non-zero, the index in `argv' of the first argument
-- following a special `--' argument (which prevents anything
-- following being interpreted as an option). Only set once
-- argument parsing has proceeded past this point.
--
-- `void *input'
-- An arbitrary pointer passed in from the caller of
-- `argp_parse', in the INPUT argument.
--
-- `void **child_inputs'
-- Values to pass to child parsers. This vector will be the
-- same length as the number of children in the current parser,
-- and each child parser will be given the value of
-- `STATE->child_inputs[I]' as *its* `STATE->input' field, where
-- I is the index of the child in the this parser's `children'
-- field. *Note Argp Children::.
--
-- `void *hook'
-- For the parser function's use. Initialized to 0, but
-- otherwise ignored by argp.
--
-- `char *name'
-- The name used when printing messages. This is initialized to
-- `argv[0]', or `program_invocation_name' if that is
-- unavailable.
--
-- `FILE *err_stream'
-- `FILE *out_stream'
-- Stdio streams used when argp prints something; error messages
-- are printed to `err_stream', and all other output (such as
-- `--help' output) to `out_stream'. These are initialized to
-- `stderr' and `stdout' respectively (*note Standard
-- Streams::.).
--
-- `void *pstate'
-- Private, for use by the argp implementation.
--
--
--File: libc.info, Node: Argp Children, Next: Argp Help Filtering, Prev: Argp Parser Functions, Up: Argp Parsers
--
--Combining Multiple Argp Parsers
---------------------------------
--
-- The `children' field in a `struct argp' allows other argp parsers to
--be combined with the referencing one to parse a single set of
--arguments. It should point to a vector of `struct argp_child',
--terminated by an entry having a value of zero in the `argp' field.
--
-- Where conflicts between combined parsers arise (for instance, if two
--specify an option with the same name), they are resolved in favor of
--the parent argp parsers, or earlier argp parsers in the list of
--children.
--
-- - Data Type: struct argp_child
-- An entry in the list of subsidiary argp parsers pointed to by the
-- `children' field in a `struct argp'. The fields are as follows:
--
-- `const struct argp *argp'
-- The child argp parser, or zero to end the list.
--
-- `int flags'
-- Flags for this child.
--
-- `const char *header'
-- If non-zero, an optional header to be printed in help output
-- before the child options. As a side-effect, a non-zero value
-- forces the child options to be grouped together; to achieve
-- this effect without actually printing a header string, use a
-- value of `""'. As with header strings specified in an option
-- entry, the value conventionally has `:' as the last
-- character. *Note Argp Option Vectors::.
--
-- `int group'
-- Where to group the child options relative to the other
-- (`consolidated') options in the parent argp parser. The
-- values are the same as the `group' field in `struct
-- argp_option' (*note Argp Option Vectors::.), but all
-- child-groupings follow parent options at a particular group
-- level. If both this field and `header' are zero, then the
-- child's options aren't grouped together at all, but rather
-- merged with the parent options (merging the child's grouping
-- levels with the parents).
--
--
--File: libc.info, Node: Argp Flags, Next: Argp Help, Prev: Argp Parsers, Up: Argp
--
--Flags for `argp_parse'
------------------------
--
-- The default behavior of `argp_parse' is designed to be convenient
--for the most common case of parsing program command line argument. To
--modify these defaults, the following flags may be or'd together in the
--FLAGS argument to `argp_parse':
--
--`ARGP_PARSE_ARGV0'
-- Don't ignore the first element of the ARGV argument to
-- `argp_parse'. Normally (and always unless `ARGP_NO_ERRS' is set)
-- the first element of the argument vector is skipped for option
-- parsing purposes, as it corresponds to the program name in a
-- command line.
--
--`ARGP_NO_ERRS'
-- Don't print error messages for unknown options to `stderr'; unless
-- this flag is set, `ARGP_PARSE_ARGV0' is ignored, as `argv[0]' is
-- used as the program name in the error messages. This flag implies
-- `ARGP_NO_EXIT' (on the assumption that silent exiting upon errors
-- is bad behaviour).
--
--`ARGP_NO_ARGS'
-- Don't parse any non-option args. Normally non-option args are
-- parsed by calling the parse functions with a key of
-- `ARGP_KEY_ARG', and the actual arg as the value. This flag
-- needn't normally be set, as the normal behavior is to stop parsing
-- as soon as some argument isn't accepted by a parsing function.
-- *Note Argp Parser Functions::.
--
--`ARGP_IN_ORDER'
-- Parse options and arguments in the same order they occur on the
-- command line--normally they're rearranged so that all options come
-- first
--
--`ARGP_NO_HELP'
-- Don't provide the standard long option `--help', which ordinarily
-- causes usage and option help information to be output to `stdout',
-- and `exit (0)' called.
--
--`ARGP_NO_EXIT'
-- Don't exit on errors (they may still result in error messages).
--
--`ARGP_LONG_ONLY'
-- Use the gnu getopt `long-only' rules for parsing arguments. This
-- allows long-options to be recognized with only a single `-' (for
-- instances, `-help'), but results in a generally somewhat less
-- useful interface, that conflicts with the way most GNU programs
-- work. For this reason, its use is discouraged.
--
--`ARGP_SILENT'
-- Turns off any message-printing/exiting options, specifically
-- `ARGP_NO_EXIT', `ARGP_NO_ERRS', and `ARGP_NO_HELP'.
--
--
--File: libc.info, Node: Argp Help Filtering, Prev: Argp Children, Up: Argp Parsers
--
--Customizing Argp Help Output
------------------------------
--
-- The `help_filter' field in a `struct argp' is a pointer to a
--function to filter the text of help messages before displaying them.
--They have a function signature like:
--
-- char *HELP-FILTER (int KEY, const char *TEXT, void *INPUT)
--
--where KEY is either a key from an option, in which case TEXT is that
--option's help text (*note Argp Option Vectors::.), or one of the
--special keys with names beginning with `ARGP_KEY_HELP_', describing
--which other help text TEXT is (*note Argp Help Filter Keys::.).
--
-- The function should return either TEXT, if it should be used as-is,
--a replacement string, which should be allocated using `malloc', and
--will be freed by argp, or zero, meaning `print nothing'. The value of
--TEXT supplied is *after* any translation has been done, so if any of
--the replacement text also needs translation, that should be done by the
--filter function. INPUT is either the input supplied to `argp_parse',
--or zero, if `argp_help' was called directly by the user.
--
--* Menu:
--
--* Keys: Argp Help Filter Keys. Special KEY values for help filter functions.
--
--
--File: libc.info, Node: Argp Help Filter Keys, Up: Argp Help Filtering
--
--Special Keys for Argp Help Filter Functions
--...........................................
--
-- The following special values may be passed to an argp help filter
--function as the first argument, in addition to key values for user
--options, and specify which help text the TEXT argument contains:
--
--`ARGP_KEY_HELP_PRE_DOC'
-- Help text preceding options.
--
--`ARGP_KEY_HELP_POST_DOC'
-- Help text following options.
--
--`ARGP_KEY_HELP_HEADER'
-- Option header string.
--
--`ARGP_KEY_HELP_EXTRA'
-- After all other documentation; TEXT is zero for this key.
--
--`ARGP_KEY_HELP_DUP_ARGS_NOTE'
-- The explanatory note emitted when duplicate option arguments have
-- been suppressed.
--
--`ARGP_KEY_HELP_ARGS_DOC'
-- The argument doc string (the `args_doc' field from the argp parser;
-- *note Argp Parsers::.).
--
--
--File: libc.info, Node: Argp Help, Next: Argp Examples, Prev: Argp Flags, Up: Argp
--
--The `argp_help' Function
--------------------------
--
-- Normally programs using argp need not worry too much about printing
--argument-usage-type help messages, because the standard `--help' option
--is handled automatically by argp, and the typical error cases can be
--handled using `argp_usage' and `argp_error' (*note Argp Helper
--Functions::.).
--
-- However, if it's desirable to print a standard help message in some
--context other than parsing the program options, argp offers the
--`argp_help' interface.
--
-- - Function: void argp_help (const struct argp *ARGP, FILE *STREAM,
-- unsigned FLAGS, char *NAME)
-- Output a help message for the argp parser ARGP to STREAM. What
-- sort of messages is printed is determined by FLAGS.
--
-- Any options such as `--help' that are implemented automatically by
-- argp itself will *not* be present in the help output; for this
-- reason, it is better to use `argp_state_help' if calling from
-- within an argp parser function. *Note Argp Helper Functions::.
--
--* Menu:
--
--* Flags: Argp Help Flags. Specifying what sort of help message to print.
--
--
--File: libc.info, Node: Argp Help Flags, Up: Argp Help
--
--Flags for the `argp_help' Function
------------------------------------
--
-- When calling `argp_help' (*note Argp Help::.), or `argp_state_help'
--(*note Argp Helper Functions::.), exactly what is output is determined
--by the FLAGS argument, which should consist of any of the following
--flags, or'd together:
--
--`ARGP_HELP_USAGE'
-- A unix `Usage:' message that explicitly lists all options.
--
--`ARGP_HELP_SHORT_USAGE'
-- A unix `Usage:' message that displays only an appropriate
-- placeholder to indicate where the options go; useful for showing
-- the non-option argument syntax.
--
--`ARGP_HELP_SEE'
-- A `Try ... for more help' message; `...' contains the program name
-- and `--help'.
--
--`ARGP_HELP_LONG'
-- A verbose option help message that gives each option understood
-- along with its documentation string.
--
--`ARGP_HELP_PRE_DOC'
-- The part of the argp parser doc string that precedes the verbose
-- option help.
--
--`ARGP_HELP_POST_DOC'
-- The part of the argp parser doc string that follows the verbose
-- option help.
--
--`ARGP_HELP_DOC'
-- `(ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)'
--
--`ARGP_HELP_BUG_ADDR'
-- A message saying where to report bugs for this program, if the
-- `argp_program_bug_address' variable contains one.
--
--`ARGP_HELP_LONG_ONLY'
-- Modify any output appropriately to reflect `ARGP_LONG_ONLY' mode.
--
-- The following flags are only understood when used with
--`argp_state_help', and control whether the function returns after
--printing its output, or terminates the program:
--
--`ARGP_HELP_EXIT_ERR'
-- Terminate the program with `exit (argp_err_exit_status)'.
--
--`ARGP_HELP_EXIT_OK'
-- Terminate the program with `exit (0)'.
--
-- The following flags are combinations of the basic ones for printing
--standard messages:
--
--`ARGP_HELP_STD_ERR'
-- Assuming an error message for a parsing error has already printed,
-- prints a note on how to get help, and terminates the program with
-- an error.
--
--`ARGP_HELP_STD_USAGE'
-- Prints a standard usage message and terminates the program with an
-- error. This is used when no more specific error message is
-- appropriate.
--
--`ARGP_HELP_STD_HELP'
-- Prints the standard response for a `--help' option, and terminates
-- the program successfully.
--
--
--File: libc.info, Node: Argp Examples, Next: Argp User Customization, Prev: Argp Help, Up: Argp
--
--Argp Examples
---------------
--
-- These example programs demonstrate the basic usage of argp.
--
--* Menu:
--
--* 1: Argp Example 1. A minimal program using argp.
--* 2: Argp Example 2. A program using only default options.
--* 3: Argp Example 3. A simple program with user options.
--* 4: Argp Example 4. Combining multiple argp parsers.
--
--
--File: libc.info, Node: Argp Example 1, Next: Argp Example 2, Up: Argp Examples
--
--A Minimal Program Using Argp
--............................
--
-- This is (probably) the smallest possible program that uses argp. It
--won't do much except give an error messages and exit when there are any
--arguments, and print a (rather pointless) message for `--help'.
--
-- /* Argp example #1 - a minimal program using argp */
--
-- /* This is (probably) the smallest possible program that
-- uses argp. It won't do much except give an error
-- messages and exit when there are any arguments, and print
-- a (rather pointless) messages for -help. */
--
-- #include <argp.h>
--
-- int main (int argc, char **argv)
-- {
-- argp_parse (0, argc, argv, 0, 0, 0);
-- exit (0);
-- }
--
--
--File: libc.info, Node: Argp Example 2, Next: Argp Example 3, Prev: Argp Example 1, Up: Argp Examples
--
--A Program Using Argp with Only Default Options
--..............................................
--
-- This program doesn't use any options or arguments, but uses argp to
--be compliant with the GNU standard command line format.
--
-- In addition to making sure no arguments are given, and implementing a
--`--help' option, this example will have a `--version' option, and will
--put the given documentation string and bug address in the `--help'
--output, as per GNU standards.
--
-- The variable `argp' contains the argument parser specification;
--adding fields to this structure is the way most parameters are passed to
--`argp_parse' (the first three fields are usually used, but not in this
--small program). There are also two global variables that argp knows
--about defined here, `argp_program_version' and
--`argp_program_bug_address' (they are global variables because they will
--almost always be constant for a given program, even if it uses
--different argument parsers for various tasks).
--
-- /* Argp example #2 - a pretty minimal program using argp */
--
-- /* This program doesn't use any options or arguments, but uses
-- argp to be compliant with the GNU standard command line
-- format.
--
-- In addition to making sure no arguments are given, and
-- implementing a -help option, this example will have a
-- -version option, and will put the given documentation string
-- and bug address in the -help output, as per GNU standards.
--
-- The variable ARGP contains the argument parser specification;
-- adding fields to this structure is the way most parameters are
-- passed to argp_parse (the first three fields are usually used,
-- but not in this small program). There are also two global
-- variables that argp knows about defined here,
-- ARGP_PROGRAM_VERSION and ARGP_PROGRAM_BUG_ADDRESS (they are
-- global variables becuase they will almost always be constant
-- for a given program, even if it uses different argument
-- parsers for various tasks). */
--
-- #include <argp.h>
--
-- const char *argp_program_version =
-- "argp-ex2 1.0";
-- const char *argp_program_bug_address =
-- "<bug-gnu-utils@gnu.org>";
--
-- /* Program documentation. */
-- static char doc[] =
-- "Argp example #2 -- a pretty minimal program using argp";
--
-- /* Our argpument parser. The `options', `parser', and
-- `args_doc' fields are zero because we have neither options or
-- arguments; `doc' and `argp_program_bug_address' will be
-- used in the output for `--help', and the `--version'
-- option will print out `argp_program_version'. */
-- static struct argp argp = { 0, 0, 0, doc };
--
-- int main (int argc, char **argv)
-- {
-- argp_parse (&argp, argc, argv, 0, 0, 0);
-- exit (0);
-- }
--
--
--File: libc.info, Node: Argp Example 3, Next: Argp Example 4, Prev: Argp Example 2, Up: Argp Examples
--
--A Program Using Argp with User Options
--......................................
--
-- This program uses the same features as example 2, and adds user
--options and arguments.
--
-- We now use the first four fields in `argp' (*note Argp Parsers::.),
--and specifies `parse_opt' as the parser function (*note Argp Parser
--Functions::.).
--
-- Note that in this example, `main' uses a structure to communicate
--with the `parse_opt' function, a pointer to which it passes in the
--`input' argument to `argp_parse' (*note Argp::.), and is retrieved by
--`parse_opt' through the `input' field in its `state' argument (*note
--Argp Parsing State::.). Of course, it's also possible to use global
--variables instead, but using a structure like this is somewhat more
--flexible and clean.
--
-- /* Argp example #3 - a program with options and arguments using argp */
--
-- /* This program uses the same features as example 2, and uses options and
-- arguments.
--
-- We now use the first four fields in ARGP, so here's a description of them:
-- OPTIONS - A pointer to a vector of struct argp_option (see below)
-- PARSER - A function to parse a single option, called by argp
-- ARGS_DOC - A string describing how the non-option arguments should look
-- DOC - A descriptive string about this program; if it contains a
-- vertical tab character (\v), the part after it will be
-- printed *following* the options
--
-- The function PARSER takes the following arguments:
-- KEY - An integer specifying which option this is (taken
-- from the KEY field in each struct argp_option), or
-- a special key specifying something else; the only
-- special keys we use here are ARGP_KEY_ARG, meaning
-- a non-option argument, and ARGP_KEY_END, meaning
-- that all argumens have been parsed
-- ARG - For an option KEY, the string value of its
-- argument, or NULL if it has none
-- STATE- A pointer to a struct argp_state, containing
-- various useful information about the parsing state; used here
-- are the INPUT field, which reflects the INPUT argument to
-- argp_parse, and the ARG_NUM field, which is the number of the
-- current non-option argument being parsed
-- It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the
-- given KEY wasn't recognized, or an errno value indicating some other
-- error.
--
-- Note that in this example, main uses a structure to communicate with the
-- parse_opt function, a pointer to which it passes in the INPUT argument to
-- argp_parse. Of course, it's also possible to use global variables
-- instead, but this is somewhat more flexible.
--
-- The OPTIONS field contains a pointer to a vector of struct argp_option's;
-- that structure has the following fields (if you assign your option
-- structures using array initialization like this example, unspecified
-- fields will be defaulted to 0, and need not be specified):
-- NAME - The name of this option's long option (may be zero)
-- KEY - The KEY to pass to the PARSER function when parsing this option,
-- *and* the name of this option's short option, if it is a
-- printable ascii character
-- ARG - The name of this option's argument, if any
-- FLAGS - Flags describing this option; some of them are:
-- OPTION_ARG_OPTIONAL - The argument to this option is optional
-- OPTION_ALIAS - This option is an alias for the
-- previous option
-- OPTION_HIDDEN - Don't show this option in -help output
-- DOC - A documentation string for this option, shown in -help output
--
-- An options vector should be terminated by an option with all fields zero. */
--
-- #include <argp.h>
--
-- const char *argp_program_version =
-- "argp-ex3 1.0";
-- const char *argp_program_bug_address =
-- "<bug-gnu-utils@gnu.org>";
--
-- /* Program documentation. */
-- static char doc[] =
-- "Argp example #3 -- a program with options and arguments using argp";
--
-- /* A description of the arguments we accept. */
-- static char args_doc[] = "ARG1 ARG2";
--
-- /* The options we understand. */
-- static struct argp_option options[] = {
-- {"verbose", 'v', 0, 0, "Produce verbose output" },
-- {"quiet", 'q', 0, 0, "Don't produce any output" },
-- {"silent", 's', 0, OPTION_ALIAS },
-- {"output", 'o', "FILE", 0,
-- "Output to FILE instead of standard output" },
-- { 0 }
-- };
--
-- /* Used by `main' to communicate with `parse_opt'. */
-- struct arguments
-- {
-- char *args[2]; /* ARG1 & ARG2 */
-- int silent, verbose;
-- char *output_file;
-- };
--
-- /* Parse a single option. */
-- static error_t
-- parse_opt (int key, char *arg, struct argp_state *state)
-- {
-- /* Get the INPUT argument from `argp_parse', which we
-- know is a pointer to our arguments structure. */
-- struct arguments *arguments = state->input;
--
-- switch (key)
-- {
-- case 'q': case 's':
-- arguments->silent = 1;
-- break;
-- case 'v':
-- arguments->verbose = 1;
-- break;
-- case 'o':
-- arguments->output_file = arg;
-- break;
--
-- case ARGP_KEY_ARG:
-- if (state->arg_num >= 2)
-- /* Too many arguments. */
-- argp_usage (state);
--
-- arguments->args[state->arg_num] = arg;
--
-- break;
--
-- case ARGP_KEY_END:
-- if (state->arg_num < 2)
-- /* Not enough arguments. */
-- argp_usage (state);
-- break;
--
-- default:
-- return ARGP_ERR_UNKNOWN;
-- }
-- return 0;
-- }
--
-- /* Our argp parser. */
-- static struct argp argp = { options, parse_opt, args_doc, doc };
--
-- int main (int argc, char **argv)
-- {
-- struct arguments arguments;
--
-- /* Default values. */
-- arguments.silent = 0;
-- arguments.verbose = 0;
-- arguments.output_file = "-";
--
-- /* Parse our arguments; every option seen by `parse_opt' will
-- be reflected in `arguments'. */
-- argp_parse (&argp, argc, argv, 0, 0, &arguments);
--
-- printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n"
-- "VERBOSE = %s\nSILENT = %s\n",
-- arguments.args[0], arguments.args[1],
-- arguments.output_file,
-- arguments.verbose ? "yes" : "no",
-- arguments.silent ? "yes" : "no");
--
-- exit (0);
-- }
--
--
--File: libc.info, Node: Argp Example 4, Prev: Argp Example 3, Up: Argp Examples
--
--A Program Using Multiple Combined Argp Parsers
--..............................................
--
-- This program uses the same features as example 3, but has more
--options, and somewhat more structure in the `--help' output. It also
--shows how you can `steal' the remainder of the input arguments past a
--certain point, for programs that accept a list of items, and the special
--KEY value `ARGP_KEY_NO_ARGS', which is only given if no non-option
--arguments were supplied to the program (*note Argp Special Keys::.).
--
-- For structuring the help output, two features are used: *headers*,
--which are entries in the options vector (*note Argp Option Vectors::.)
--with the first four fields being zero, and a two part documentation
--string (in the variable `doc'), which allows documentation both before
--and after the options (*note Argp Parsers::.); the two parts of `doc'
--are separated by a vertical-tab character (`'\v'', or `'\013''). By
--convention, the documentation before the options is just a short string
--saying what the program does, and that afterwards is longer, describing
--the behavior in more detail. All documentation strings are
--automatically filled for output, although newlines may be included to
--force a line break at a particular point. All documentation strings
--are also passed to the `gettext' function, for possible translation
--into the current locale.
--
-- /* Argp example #4 - a program with somewhat more complicated options */
--
-- /* This program uses the same features as example 3, but has more
-- options, and somewhat more structure in the -help output. It
-- also shows how you can `steal' the remainder of the input
-- arguments past a certain point, for programs that accept a
-- list of items. It also shows the special argp KEY value
-- ARGP_KEY_NO_ARGS, which is only given if no non-option
-- arguments were supplied to the program.
--
-- For structuring the help output, two features are used,
-- *headers* which are entries in the options vector with the
-- first four fields being zero, and a two part documentation
-- string (in the variable DOC), which allows documentation both
-- before and after the options; the two parts of DOC are
-- separated by a vertical-tab character ('\v', or '\013'). By
-- convention, the documentation before the options is just a
-- short string saying what the program does, and that afterwards
-- is longer, describing the behavior in more detail. All
-- documentation strings are automatically filled for output,
-- although newlines may be included to force a line break at a
-- particular point. All documenation strings are also passed to
-- the `gettext' function, for possible translation into the
-- current locale. */
--
-- #include <stdlib.h>
-- #include <error.h>
-- #include <argp.h>
--
-- const char *argp_program_version =
-- "argp-ex4 1.0";
-- const char *argp_program_bug_address =
-- "<bug-gnu-utils@prep.ai.mit.edu>";
--
-- /* Program documentation. */
-- static char doc[] =
-- "Argp example #4 -- a program with somewhat more complicated\
-- options\
-- \vThis part of the documentation comes *after* the options;\
-- note that the text is automatically filled, but it's possible\
-- to force a line-break, e.g.\n<-- here.";
--
-- /* A description of the arguments we accept. */
-- static char args_doc[] = "ARG1 [STRING...]";
--
-- /* Keys for options without short-options. */
-- #define OPT_ABORT 1 /* -abort */
--
-- /* The options we understand. */
-- static struct argp_option options[] = {
-- {"verbose", 'v', 0, 0, "Produce verbose output" },
-- {"quiet", 'q', 0, 0, "Don't produce any output" },
-- {"silent", 's', 0, OPTION_ALIAS },
-- {"output", 'o', "FILE", 0,
-- "Output to FILE instead of standard output" },
--
-- {0,0,0,0, "The following options should be grouped together:" },
-- {"repeat", 'r', "COUNT", OPTION_ARG_OPTIONAL,
-- "Repeat the output COUNT (default 10) times"},
-- {"abort", OPT_ABORT, 0, 0, "Abort before showing any output"},
--
-- { 0 }
-- };
--
-- /* Used by `main' to communicate with `parse_opt'. */
-- struct arguments
-- {
-- char *arg1; /* ARG1 */
-- char **strings; /* [STRING...] */
-- int silent, verbose, abort; /* `-s', `-v', `--abort' */
-- char *output_file; /* FILE arg to `--output' */
-- int repeat_count; /* COUNT arg to `--repeat' */
-- };
--
-- /* Parse a single option. */
-- static error_t
-- parse_opt (int key, char *arg, struct argp_state *state)
-- {
-- /* Get the `input' argument from `argp_parse', which we
-- know is a pointer to our arguments structure. */
-- struct arguments *arguments = state->input;
--
-- switch (key)
-- {
-- case 'q': case 's':
-- arguments->silent = 1;
-- break;
-- case 'v':
-- arguments->verbose = 1;
-- break;
-- case 'o':
-- arguments->output_file = arg;
-- break;
-- case 'r':
-- arguments->repeat_count = arg ? atoi (arg) : 10;
-- break;
-- case OPT_ABORT:
-- arguments->abort = 1;
-- break;
--
-- case ARGP_KEY_NO_ARGS:
-- argp_usage (state);
--
-- case ARGP_KEY_ARG:
-- /* Here we know that `state->arg_num == 0', since we
-- force argument parsing to end before any more arguments can
-- get here. */
-- arguments->arg1 = arg;
--
-- /* Now we consume all the rest of the arguments.
-- `state->next' is the index in `state->argv' of the
-- next argument to be parsed, which is the first STRING
-- we're interested in, so we can just use
-- `&state->argv[state->next]' as the value for
-- arguments->strings.
--
-- *In addition*, by setting `state->next' to the end
-- of the arguments, we can force argp to stop parsing here and
-- return. */
-- arguments->strings = &state->argv[state->next];
-- state->next = state->argc;
--
-- break;
--
-- default:
-- return ARGP_ERR_UNKNOWN;
-- }
-- return 0;
-- }
--
-- /* Our argp parser. */
-- static struct argp argp = { options, parse_opt, args_doc, doc };
--
-- int main (int argc, char **argv)
-- {
-- int i, j;
-- struct arguments arguments;
--
-- /* Default values. */
-- arguments.silent = 0;
-- arguments.verbose = 0;
-- arguments.output_file = "-";
-- arguments.repeat_count = 1;
-- arguments.abort = 0;
--
-- /* Parse our arguments; every option seen by `parse_opt' will be
-- reflected in `arguments'. */
-- argp_parse (&argp, argc, argv, 0, 0, &arguments);
--
-- if (arguments.abort)
-- error (10, 0, "ABORTED");
--
-- for (i = 0; i < arguments.repeat_count; i++)
-- {
-- printf ("ARG1 = %s\n", arguments.arg1);
-- printf ("STRINGS = ");
-- for (j = 0; arguments.strings[j]; j++)
-- printf (j == 0 ? "%s" : ", %s", arguments.strings[j]);
-- printf ("\n");
-- printf ("OUTPUT_FILE = %s\nVERBOSE = %s\nSILENT = %s\n",
-- arguments.output_file,
-- arguments.verbose ? "yes" : "no",
-- arguments.silent ? "yes" : "no");
-- }
--
-- exit (0);
-- }
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-36 glibc-2.1.3/manual/libc.info-36
---- ../glibc-2.1.3/manual/libc.info-36 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-36 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1096 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Argp User Customization, Prev: Argp Examples, Up: Argp
--
--Argp User Customization
-------------------------
--
-- The way formatting of argp `--help' output may be controlled to some
--extent by a program's users, by setting the `ARGP_HELP_FMT' environment
--variable to a comma-separated list (whitespace is ignored) of the
--following tokens:
--
--`dup-args'
--`no-dup-args'
-- Turn "duplicate-argument-mode" on or off. In duplicate argument
-- mode, if an option which accepts an argument has multiple names,
-- the argument is shown for each name; otherwise, it is only shown
-- for the first long option, and a note is emitted later so the user
-- knows that it applies to the other names as well. The default is
-- `no-dup-args', which is less consistent, but prettier.
--
--`dup-args-note'
--
--`no-dup-args-note'
-- Enable or disable the note informing the user of suppressed option
-- argument duplication. The default is `dup-args-note'.
--
--`short-opt-col=N'
-- Show the first short option in column N (default 2).
--
--`long-opt-col=N'
-- Show the first long option in column N (default 6).
--
--`doc-opt-col=N'
-- Show `documentation options' (*note Argp Option Flags::.) in column
-- N (default 2).
--
--`opt-doc-col=N'
-- Show the documentation for options starting in column N (default
-- 29).
--
--`header-col=N'
-- Indent group headers (which document groups of options) to column
-- N (default 1).
--
--`usage-indent=N'
-- Indent continuation lines in `Usage:' messages to column N
-- (default 12).
--
--`rmargin=N'
-- Word wrap help output at or before column N (default 79).
--
--
--File: libc.info, Node: Suboptions, Next: Suboptions Example, Prev: Argp, Up: Parsing Program Arguments
--
--Parsing of Suboptions
--.....................
--
-- Having a single level of options is sometimes not enough. There
--might be too many options which have to be available or a set of
--options is closely related.
--
-- For this case some programs use suboptions. One of the most
--prominent programs is certainly `mount'(8). The `-o' option take one
--argument which itself is a comma separated list of options. To ease the
--programming of code like this the function `getsubopt' is available.
--
-- - Function: int getsubopt (char **OPTIONP, const char* const *TOKENS,
-- char **VALUEP)
-- The OPTIONP parameter must be a pointer to a variable containing
-- the address of the string to process. When the function returns
-- the reference is updated to point to the next suboption or to the
-- terminating `\0' character if there is no more suboption available.
--
-- The TOKENS parameter references an array of strings containing the
-- known suboptions. All strings must be `\0' terminated and to mark
-- the end a null pointer must be stored. When `getsubopt' finds a
-- possible legal suboption it compares it with all strings available
-- in the TOKENS array and returns the index in the string as the
-- indicator.
--
-- In case the suboption has an associated value introduced by a `='
-- character, a pointer to the value is returned in VALUEP. The
-- string is `\0' terminated. If no argument is available VALUEP is
-- set to the null pointer. By doing this the caller can check
-- whether a necessary value is given or whether no unexpected value
-- is present.
--
-- In case the next suboption in the string is not mentioned in the
-- TOKENS array the starting address of the suboption including a
-- possible value is returned in VALUEP and the return value of the
-- function is `-1'.
--
--
--File: libc.info, Node: Suboptions Example, Prev: Suboptions, Up: Parsing Program Arguments
--
--Parsing of Suboptions Example
-------------------------------
--
-- The code which might appear in the `mount'(8) program is a perfect
--example of the use of `getsubopt':
--
-- #include <stdio.h>
-- #include <stdlib.h>
--
-- int do_all;
-- const char *type;
-- int read_size;
-- int write_size;
-- int read_only;
--
-- enum
-- {
-- RO_OPTION = 0,
-- RW_OPTION,
-- READ_SIZE_OPTION,
-- WRITE_SIZE_OPTION
-- };
--
-- const char *mount_opts[] =
-- {
-- [RO_OPTION] = "ro",
-- [RW_OPTION] = "rw",
-- [READ_SIZE_OPTION] = "rsize",
-- [WRITE_SIZE_OPTION] = "wsize"
-- };
--
-- int
-- main (int argc, char *argv[])
-- {
-- char *subopts, *value;
-- int opt;
--
-- while ((opt = getopt (argc, argv, "at:o:")) != -1)
-- switch (opt)
-- {
-- case 'a':
-- do_all = 1;
-- break;
-- case 't':
-- type = optarg;
-- break;
-- case 'o':
-- subopts = optarg;
-- while (*subopts != '\0')
-- switch (getsubopt (&subopts, mount_opts, &value))
-- {
-- case RO_OPTION:
-- read_only = 1;
-- break;
-- case RW_OPTION:
-- read_only = 0;
-- break;
-- case READ_SIZE_OPTION:
-- if (value == NULL)
-- abort ();
-- read_size = atoi (value);
-- break;
-- case WRITE_SIZE_OPTION:
-- if (value == NULL)
-- abort ();
-- write_size = atoi (value);
-- break;
-- default:
-- /* Unknown suboption. */
-- printf ("Unknown suboption `%s'\n", value);
-- break;
-- }
-- break;
-- default:
-- abort ();
-- }
--
-- /* Do the real work. */
--
-- return 0;
-- }
--
--
--File: libc.info, Node: Environment Variables, Next: Program Termination, Prev: Program Arguments, Up: Process Startup
--
--Environment Variables
--=====================
--
-- When a program is executed, it receives information about the
--context in which it was invoked in two ways. The first mechanism uses
--the ARGV and ARGC arguments to its `main' function, and is discussed in
--*Note Program Arguments::. The second mechanism uses "environment
--variables" and is discussed in this section.
--
-- The ARGV mechanism is typically used to pass command-line arguments
--specific to the particular program being invoked. The environment, on
--the other hand, keeps track of information that is shared by many
--programs, changes infrequently, and that is less frequently used.
--
-- The environment variables discussed in this section are the same
--environment variables that you set using assignments and the `export'
--command in the shell. Programs executed from the shell inherit all of
--the environment variables from the shell.
--
-- Standard environment variables are used for information about the
--user's home directory, terminal type, current locale, and so on; you
--can define additional variables for other purposes. The set of all
--environment variables that have values is collectively known as the
--"environment".
--
-- Names of environment variables are case-sensitive and must not
--contain the character `='. System-defined environment variables are
--invariably uppercase.
--
-- The values of environment variables can be anything that can be
--represented as a string. A value must not contain an embedded null
--character, since this is assumed to terminate the string.
--
--* Menu:
--
--* Environment Access:: How to get and set the values of
-- environment variables.
--* Standard Environment:: These environment variables have
-- standard interpretations.
--
--
--File: libc.info, Node: Environment Access, Next: Standard Environment, Up: Environment Variables
--
--Environment Access
--------------------
--
-- The value of an environment variable can be accessed with the
--`getenv' function. This is declared in the header file `stdlib.h'.
--All of the following functions can be safely used in multi-threaded
--programs. It is made sure that concurrent modifications to the
--environment do not lead to errors.
--
-- - Function: char * getenv (const char *NAME)
-- This function returns a string that is the value of the environment
-- variable NAME. You must not modify this string. In some non-Unix
-- systems not using the GNU library, it might be overwritten by
-- subsequent calls to `getenv' (but not by any other library
-- function). If the environment variable NAME is not defined, the
-- value is a null pointer.
--
-- - Function: int putenv (const char *STRING)
-- The `putenv' function adds or removes definitions from the
-- environment. If the STRING is of the form `NAME=VALUE', the
-- definition is added to the environment. Otherwise, the STRING is
-- interpreted as the name of an environment variable, and any
-- definition for this variable in the environment is removed.
--
-- This function is part of the extended Unix interface. Since it
-- was also available in old SVID libraries you should define either
-- _XOPEN_SOURCE or _SVID_SOURCE before including any header.
--
-- - Function: int setenv (const char *NAME, const char *VALUE, int
-- REPLACE)
-- The `setenv' function can be used to add a new definition to the
-- environment. The entry with the name NAME is replaced by the
-- value `NAME=VALUE'. Please note that this is also true if VALUE
-- is the empty string. A null pointer for the VALUE parameter is
-- illegal. If the environment already contains an entry with key
-- NAME the REPLACE parameter controls the action. If replace is
-- zero, nothing happens. otherwise the old entry is replaced by the
-- new one.
--
-- Please note that you cannot remove an entry completely using this
-- function.
--
-- This function is part of the BSD library. The GNU C Library
-- provides this function for compatibility but it may not be
-- available on other systems.
--
-- - Function: void unsetenv (const char *NAME)
-- Using this function one can remove an entry completely from the
-- environment. If the environment contains an entry with the key
-- NAME this whole entry is removed. A call to this function is
-- equivalent to a call to `putenv' when the VALUE part of the string
-- is empty.
--
-- This function is part of the BSD library. The GNU C Library
-- provides this function for compatibility but it may not be
-- available on other systems.
--
-- There is one more function to modify the whole environment. This
--function is said to be used in the POSIX.9 (POSIX bindings for Fortran
--77) and so one should expect it did made it into POSIX.1. But this
--never happened. But we still provide this function as a GNU extension
--to enable writing standard compliant Fortran environments.
--
-- - Function: int clearenv (void)
-- The `clearenv' function removes all entries from the environment.
-- Using `putenv' and `setenv' new entries can be added again later.
--
-- If the function is successful it returns `0'. Otherwise the return
-- value is nonzero.
--
-- You can deal directly with the underlying representation of
--environment objects to add more variables to the environment (for
--example, to communicate with another program you are about to execute;
--*note Executing a File::.).
--
-- - Variable: char ** environ
-- The environment is represented as an array of strings. Each
-- string is of the format `NAME=VALUE'. The order in which strings
-- appear in the environment is not significant, but the same NAME
-- must not appear more than once. The last element of the array is
-- a null pointer.
--
-- This variable is declared in the header file `unistd.h'.
--
-- If you just want to get the value of an environment variable, use
-- `getenv'.
--
-- Unix systems, and the GNU system, pass the initial value of
--`environ' as the third argument to `main'. *Note Program Arguments::.
--
--
--File: libc.info, Node: Standard Environment, Prev: Environment Access, Up: Environment Variables
--
--Standard Environment Variables
--------------------------------
--
-- These environment variables have standard meanings. This doesn't
--mean that they are always present in the environment; but if these
--variables *are* present, they have these meanings. You shouldn't try
--to use these environment variable names for some other purpose.
--
--`HOME'
-- This is a string representing the user's "home directory", or
-- initial default working directory.
--
-- The user can set `HOME' to any value. If you need to make sure to
-- obtain the proper home directory for a particular user, you should
-- not use `HOME'; instead, look up the user's name in the user
-- database (*note User Database::.).
--
-- For most purposes, it is better to use `HOME', precisely because
-- this lets the user specify the value.
--
--`LOGNAME'
-- This is the name that the user used to log in. Since the value in
-- the environment can be tweaked arbitrarily, this is not a reliable
-- way to identify the user who is running a process; a function like
-- `getlogin' (*note Who Logged In::.) is better for that purpose.
--
-- For most purposes, it is better to use `LOGNAME', precisely because
-- this lets the user specify the value.
--
--`PATH'
-- A "path" is a sequence of directory names which is used for
-- searching for a file. The variable `PATH' holds a path used for
-- searching for programs to be run.
--
-- The `execlp' and `execvp' functions (*note Executing a File::.)
-- use this environment variable, as do many shells and other
-- utilities which are implemented in terms of those functions.
--
-- The syntax of a path is a sequence of directory names separated by
-- colons. An empty string instead of a directory name stands for the
-- current directory (*note Working Directory::.).
--
-- A typical value for this environment variable might be a string
-- like:
--
-- :/bin:/etc:/usr/bin:/usr/new/X11:/usr/new:/usr/local/bin
--
-- This means that if the user tries to execute a program named `foo',
-- the system will look for files named `foo', `/bin/foo',
-- `/etc/foo', and so on. The first of these files that exists is
-- the one that is executed.
--
--`TERM'
-- This specifies the kind of terminal that is receiving program
-- output. Some programs can make use of this information to take
-- advantage of special escape sequences or terminal modes supported
-- by particular kinds of terminals. Many programs which use the
-- termcap library (*note Find: (termcap)Finding a Terminal
-- Description.) use the `TERM' environment variable, for example.
--
--`TZ'
-- This specifies the time zone. *Note TZ Variable::, for
-- information about the format of this string and how it is used.
--
--`LANG'
-- This specifies the default locale to use for attribute categories
-- where neither `LC_ALL' nor the specific environment variable for
-- that category is set. *Note Locales::, for more information about
-- locales.
--
--`LC_ALL'
-- If this environment variable is set it overrides the selection for
-- all the locales done using the other `LC_*' environment variables.
-- The value of the other `LC_*' environment variables is simply
-- ignored in this case.
--
--`LC_COLLATE'
-- This specifies what locale to use for string sorting.
--
--`LC_CTYPE'
-- This specifies what locale to use for character sets and character
-- classification.
--
--`LC_MESSAGES'
-- This specifies what locale to use for printing messages and to
-- parse responses.
--
--`LC_MONETARY'
-- This specifies what locale to use for formatting monetary values.
--
--`LC_NUMERIC'
-- This specifies what locale to use for formatting numbers.
--
--`LC_TIME'
-- This specifies what locale to use for formatting date/time values.
--
--`NLSPATH'
-- This specifies the directories in which the `catopen' function
-- looks for message translation catalogs.
--
--`_POSIX_OPTION_ORDER'
-- If this environment variable is defined, it suppresses the usual
-- reordering of command line arguments by `getopt' and `argp_parse'.
-- *Note Argument Syntax::.
--
--
--File: libc.info, Node: Program Termination, Prev: Environment Variables, Up: Process Startup
--
--Program Termination
--===================
--
-- The usual way for a program to terminate is simply for its `main'
--function to return. The "exit status value" returned from the `main'
--function is used to report information back to the process's parent
--process or shell.
--
-- A program can also terminate normally by calling the `exit' function.
--
-- In addition, programs can be terminated by signals; this is
--discussed in more detail in *Note Signal Handling::. The `abort'
--function causes a signal that kills the program.
--
--* Menu:
--
--* Normal Termination:: If a program calls `exit', a
-- process terminates normally.
--* Exit Status:: The `exit status' provides information
-- about why the process terminated.
--* Cleanups on Exit:: A process can run its own cleanup
-- functions upon normal termination.
--* Aborting a Program:: The `abort' function causes
-- abnormal program termination.
--* Termination Internals:: What happens when a process terminates.
--
--
--File: libc.info, Node: Normal Termination, Next: Exit Status, Up: Program Termination
--
--Normal Termination
--------------------
--
-- A process terminates normally when the program calls `exit'.
--Returning from `main' is equivalent to calling `exit', and the value
--that `main' returns is used as the argument to `exit'.
--
-- - Function: void exit (int STATUS)
-- The `exit' function terminates the process with status STATUS.
-- This function does not return.
--
-- Normal termination causes the following actions:
--
-- 1. Functions that were registered with the `atexit' or `on_exit'
-- functions are called in the reverse order of their registration.
-- This mechanism allows your application to specify its own
-- "cleanup" actions to be performed at program termination.
-- Typically, this is used to do things like saving program state
-- information in a file, or unlocking locks in shared data bases.
--
-- 2. All open streams are closed, writing out any buffered output data.
-- See *Note Closing Streams::. In addition, temporary files opened
-- with the `tmpfile' function are removed; see *Note Temporary
-- Files::.
--
-- 3. `_exit' is called, terminating the program. *Note Termination
-- Internals::.
--
--
--File: libc.info, Node: Exit Status, Next: Cleanups on Exit, Prev: Normal Termination, Up: Program Termination
--
--Exit Status
-------------
--
-- When a program exits, it can return to the parent process a small
--amount of information about the cause of termination, using the "exit
--status". This is a value between 0 and 255 that the exiting process
--passes as an argument to `exit'.
--
-- Normally you should use the exit status to report very broad
--information about success or failure. You can't provide a lot of
--detail about the reasons for the failure, and most parent processes
--would not want much detail anyway.
--
-- There are conventions for what sorts of status values certain
--programs should return. The most common convention is simply 0 for
--success and 1 for failure. Programs that perform comparison use a
--different convention: they use status 1 to indicate a mismatch, and
--status 2 to indicate an inability to compare. Your program should
--follow an existing convention if an existing convention makes sense for
--it.
--
-- A general convention reserves status values 128 and up for special
--purposes. In particular, the value 128 is used to indicate failure to
--execute another program in a subprocess. This convention is not
--universally obeyed, but it is a good idea to follow it in your programs.
--
-- *Warning:* Don't try to use the number of errors as the exit status.
--This is actually not very useful; a parent process would generally not
--care how many errors occurred. Worse than that, it does not work,
--because the status value is truncated to eight bits. Thus, if the
--program tried to report 256 errors, the parent would receive a report
--of 0 errors--that is, success.
--
-- For the same reason, it does not work to use the value of `errno' as
--the exit status--these can exceed 255.
--
-- *Portability note:* Some non-POSIX systems use different conventions
--for exit status values. For greater portability, you can use the
--macros `EXIT_SUCCESS' and `EXIT_FAILURE' for the conventional status
--value for success and failure, respectively. They are declared in the
--file `stdlib.h'.
--
-- - Macro: int EXIT_SUCCESS
-- This macro can be used with the `exit' function to indicate
-- successful program completion.
--
-- On POSIX systems, the value of this macro is `0'. On other
-- systems, the value might be some other (possibly non-constant)
-- integer expression.
--
-- - Macro: int EXIT_FAILURE
-- This macro can be used with the `exit' function to indicate
-- unsuccessful program completion in a general sense.
--
-- On POSIX systems, the value of this macro is `1'. On other
-- systems, the value might be some other (possibly non-constant)
-- integer expression. Other nonzero status values also indicate
-- failures. Certain programs use different nonzero status values to
-- indicate particular kinds of "non-success". For example, `diff'
-- uses status value `1' to mean that the files are different, and
-- `2' or more to mean that there was difficulty in opening the files.
--
--
--File: libc.info, Node: Cleanups on Exit, Next: Aborting a Program, Prev: Exit Status, Up: Program Termination
--
--Cleanups on Exit
------------------
--
-- Your program can arrange to run its own cleanup functions if normal
--termination happens. If you are writing a library for use in various
--application programs, then it is unreliable to insist that all
--applications call the library's cleanup functions explicitly before
--exiting. It is much more robust to make the cleanup invisible to the
--application, by setting up a cleanup function in the library itself
--using `atexit' or `on_exit'.
--
-- - Function: int atexit (void (*FUNCTION) (void))
-- The `atexit' function registers the function FUNCTION to be called
-- at normal program termination. The FUNCTION is called with no
-- arguments.
--
-- The return value from `atexit' is zero on success and nonzero if
-- the function cannot be registered.
--
-- - Function: int on_exit (void (*FUNCTION)(int STATUS, void *ARG), void
-- *ARG)
-- This function is a somewhat more powerful variant of `atexit'. It
-- accepts two arguments, a function FUNCTION and an arbitrary
-- pointer ARG. At normal program termination, the FUNCTION is
-- called with two arguments: the STATUS value passed to `exit', and
-- the ARG.
--
-- This function is included in the GNU C library only for
-- compatibility for SunOS, and may not be supported by other
-- implementations.
--
-- Here's a trivial program that illustrates the use of `exit' and
--`atexit':
--
-- #include <stdio.h>
-- #include <stdlib.h>
--
-- void
-- bye (void)
-- {
-- puts ("Goodbye, cruel world....");
-- }
--
-- int
-- main (void)
-- {
-- atexit (bye);
-- exit (EXIT_SUCCESS);
-- }
--
--When this program is executed, it just prints the message and exits.
--
--
--File: libc.info, Node: Aborting a Program, Next: Termination Internals, Prev: Cleanups on Exit, Up: Program Termination
--
--Aborting a Program
--------------------
--
-- You can abort your program using the `abort' function. The prototype
--for this function is in `stdlib.h'.
--
-- - Function: void abort (void)
-- The `abort' function causes abnormal program termination. This
-- does not execute cleanup functions registered with `atexit' or
-- `on_exit'.
--
-- This function actually terminates the process by raising a
-- `SIGABRT' signal, and your program can include a handler to
-- intercept this signal; see *Note Signal Handling::.
--
-- *Future Change Warning:* Proposed Federal censorship regulations may
--prohibit us from giving you information about the possibility of
--calling this function. We would be required to say that this is not an
--acceptable way of terminating a program.
--
--
--File: libc.info, Node: Termination Internals, Prev: Aborting a Program, Up: Program Termination
--
--Termination Internals
-----------------------
--
-- The `_exit' function is the primitive used for process termination
--by `exit'. It is declared in the header file `unistd.h'.
--
-- - Function: void _exit (int STATUS)
-- The `_exit' function is the primitive for causing a process to
-- terminate with status STATUS. Calling this function does not
-- execute cleanup functions registered with `atexit' or `on_exit'.
--
-- - Function: void _Exit (int STATUS)
-- The `_Exit' function is the ISO C equivalent to `_exit'. The
-- ISO C committee members were not sure whether the definitions of
-- `_exit' and `_Exit' were compatible so they have not used the
-- POSIX name.
--
-- This function was introduced in ISO C9x and is declared in
-- `stdlib.h'.
--
-- When a process terminates for any reason--either by an explicit
--termination call, or termination as a result of a signal--the following
--things happen:
--
-- * All open file descriptors in the process are closed. *Note
-- Low-Level I/O::. Note that streams are not flushed automatically
-- when the process terminates; see *Note I/O on Streams::.
--
-- * The low-order 8 bits of the return status code are saved to be
-- reported back to the parent process via `wait' or `waitpid'; see
-- *Note Process Completion::.
--
-- * Any child processes of the process being terminated are assigned a
-- new parent process. (On most systems, including GNU, this is the
-- `init' process, with process ID 1.)
--
-- * A `SIGCHLD' signal is sent to the parent process.
--
-- * If the process is a session leader that has a controlling
-- terminal, then a `SIGHUP' signal is sent to each process in the
-- foreground job, and the controlling terminal is disassociated from
-- that session. *Note Job Control::.
--
-- * If termination of a process causes a process group to become
-- orphaned, and any member of that process group is stopped, then a
-- `SIGHUP' signal and a `SIGCONT' signal are sent to each process in
-- the group. *Note Job Control::.
--
--
--File: libc.info, Node: Processes, Next: Job Control, Prev: Process Startup, Up: Top
--
--Processes
--*********
--
-- "Processes" are the primitive units for allocation of system
--resources. Each process has its own address space and (usually) one
--thread of control. A process executes a program; you can have multiple
--processes executing the same program, but each process has its own copy
--of the program within its own address space and executes it
--independently of the other copies.
--
-- Processes are organized hierarchically. Each process has a "parent
--process" which explicitly arranged to create it. The processes created
--by a given parent are called its "child processes". A child inherits
--many of its attributes from the parent process.
--
-- This chapter describes how a program can create, terminate, and
--control child processes. Actually, there are three distinct operations
--involved: creating a new child process, causing the new process to
--execute a program, and coordinating the completion of the child process
--with the original program.
--
-- The `system' function provides a simple, portable mechanism for
--running another program; it does all three steps automatically. If you
--need more control over the details of how this is done, you can use the
--primitive functions to do each step individually instead.
--
--* Menu:
--
--* Running a Command:: The easy way to run another program.
--* Process Creation Concepts:: An overview of the hard way to do it.
--* Process Identification:: How to get the process ID of a process.
--* Creating a Process:: How to fork a child process.
--* Executing a File:: How to make a process execute another program.
--* Process Completion:: How to tell when a child process has completed.
--* Process Completion Status:: How to interpret the status value
-- returned from a child process.
--* BSD Wait Functions:: More functions, for backward compatibility.
--* Process Creation Example:: A complete example program.
--
--
--File: libc.info, Node: Running a Command, Next: Process Creation Concepts, Up: Processes
--
--Running a Command
--=================
--
-- The easy way to run another program is to use the `system' function.
--This function does all the work of running a subprogram, but it
--doesn't give you much control over the details: you have to wait until
--the subprogram terminates before you can do anything else.
--
-- - Function: int system (const char *COMMAND)
-- This function executes COMMAND as a shell command. In the GNU C
-- library, it always uses the default shell `sh' to run the command.
-- In particular, it searches the directories in `PATH' to find
-- programs to execute. The return value is `-1' if it wasn't
-- possible to create the shell process, and otherwise is the status
-- of the shell process. *Note Process Completion::, for details on
-- how this status code can be interpreted.
--
-- If the COMMAND argument is a null pointer a non-zero return value
-- indicates that a command processor is available and this function
-- can be used at all.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `system' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `system' should be protected using cancelation handlers.
--
-- The `system' function is declared in the header file `stdlib.h'.
--
-- *Portability Note:* Some C implementations may not have any notion
--of a command processor that can execute other programs. You can
--determine whether a command processor exists by executing
--`system (NULL)'; if the return value is nonzero, a command processor is
--available.
--
-- The `popen' and `pclose' functions (*note Pipe to a Subprocess::.)
--are closely related to the `system' function. They allow the parent
--process to communicate with the standard input and output channels of
--the command being executed.
--
--
--File: libc.info, Node: Process Creation Concepts, Next: Process Identification, Prev: Running a Command, Up: Processes
--
--Process Creation Concepts
--=========================
--
-- This section gives an overview of processes and of the steps
--involved in creating a process and making it run another program.
--
-- Each process is named by a "process ID" number. A unique process ID
--is allocated to each process when it is created. The "lifetime" of a
--process ends when its termination is reported to its parent process; at
--that time, all of the process resources, including its process ID, are
--freed.
--
-- Processes are created with the `fork' system call (so the operation
--of creating a new process is sometimes called "forking" a process).
--The "child process" created by `fork' is a copy of the original "parent
--process", except that it has its own process ID.
--
-- After forking a child process, both the parent and child processes
--continue to execute normally. If you want your program to wait for a
--child process to finish executing before continuing, you must do this
--explicitly after the fork operation, by calling `wait' or `waitpid'
--(*note Process Completion::.). These functions give you limited
--information about why the child terminated--for example, its exit
--status code.
--
-- A newly forked child process continues to execute the same program as
--its parent process, at the point where the `fork' call returns. You
--can use the return value from `fork' to tell whether the program is
--running in the parent process or the child.
--
-- Having several processes run the same program is only occasionally
--useful. But the child can execute another program using one of the
--`exec' functions; see *Note Executing a File::. The program that the
--process is executing is called its "process image". Starting execution
--of a new program causes the process to forget all about its previous
--process image; when the new program exits, the process exits too,
--instead of returning to the previous process image.
--
--
--File: libc.info, Node: Process Identification, Next: Creating a Process, Prev: Process Creation Concepts, Up: Processes
--
--Process Identification
--======================
--
-- The `pid_t' data type represents process IDs. You can get the
--process ID of a process by calling `getpid'. The function `getppid'
--returns the process ID of the parent of the current process (this is
--also known as the "parent process ID"). Your program should include
--the header files `unistd.h' and `sys/types.h' to use these functions.
--
-- - Data Type: pid_t
-- The `pid_t' data type is a signed integer type which is capable of
-- representing a process ID. In the GNU library, this is an `int'.
--
-- - Function: pid_t getpid (void)
-- The `getpid' function returns the process ID of the current
-- process.
--
-- - Function: pid_t getppid (void)
-- The `getppid' function returns the process ID of the parent of the
-- current process.
--
--
--File: libc.info, Node: Creating a Process, Next: Executing a File, Prev: Process Identification, Up: Processes
--
--Creating a Process
--==================
--
-- The `fork' function is the primitive for creating a process. It is
--declared in the header file `unistd.h'.
--
-- - Function: pid_t fork (void)
-- The `fork' function creates a new process.
--
-- If the operation is successful, there are then both parent and
-- child processes and both see `fork' return, but with different
-- values: it returns a value of `0' in the child process and returns
-- the child's process ID in the parent process.
--
-- If process creation failed, `fork' returns a value of `-1' in the
-- parent process. The following `errno' error conditions are
-- defined for `fork':
--
-- `EAGAIN'
-- There aren't enough system resources to create another
-- process, or the user already has too many processes running.
-- This means exceeding the `RLIMIT_NPROC' resource limit, which
-- can usually be increased; *note Limits on Resources::..
--
-- `ENOMEM'
-- The process requires more space than the system can supply.
--
-- The specific attributes of the child process that differ from the
--parent process are:
--
-- * The child process has its own unique process ID.
--
-- * The parent process ID of the child process is the process ID of its
-- parent process.
--
-- * The child process gets its own copies of the parent process's open
-- file descriptors. Subsequently changing attributes of the file
-- descriptors in the parent process won't affect the file
-- descriptors in the child, and vice versa. *Note Control
-- Operations::. However, the file position associated with each
-- descriptor is shared by both processes; *note File Position::..
--
-- * The elapsed processor times for the child process are set to zero;
-- see *Note Processor Time::.
--
-- * The child doesn't inherit file locks set by the parent process.
-- *Note Control Operations::.
--
-- * The child doesn't inherit alarms set by the parent process. *Note
-- Setting an Alarm::.
--
-- * The set of pending signals (*note Delivery of Signal::.) for the
-- child process is cleared. (The child process inherits its mask of
-- blocked signals and signal actions from the parent process.)
--
-- - Function: pid_t vfork (void)
-- The `vfork' function is similar to `fork' but on some systems it
-- is more efficient; however, there are restrictions you must follow
-- to use it safely.
--
-- While `fork' makes a complete copy of the calling process's address
-- space and allows both the parent and child to execute
-- independently, `vfork' does not make this copy. Instead, the
-- child process created with `vfork' shares its parent's address
-- space until it calls `_exit' or one of the `exec' functions. In
-- the meantime, the parent process suspends execution.
--
-- You must be very careful not to allow the child process created
-- with `vfork' to modify any global data or even local variables
-- shared with the parent. Furthermore, the child process cannot
-- return from (or do a long jump out of) the function that called
-- `vfork'! This would leave the parent process's control
-- information very confused. If in doubt, use `fork' instead.
--
-- Some operating systems don't really implement `vfork'. The GNU C
-- library permits you to use `vfork' on all systems, but actually
-- executes `fork' if `vfork' isn't available. If you follow the
-- proper precautions for using `vfork', your program will still work
-- even if the system uses `fork' instead.
--
--
--File: libc.info, Node: Executing a File, Next: Process Completion, Prev: Creating a Process, Up: Processes
--
--Executing a File
--================
--
-- This section describes the `exec' family of functions, for executing
--a file as a process image. You can use these functions to make a child
--process execute a new program after it has been forked.
--
-- The functions in this family differ in how you specify the arguments,
--but otherwise they all do the same thing. They are declared in the
--header file `unistd.h'.
--
-- - Function: int execv (const char *FILENAME, char *const ARGV[])
-- The `execv' function executes the file named by FILENAME as a new
-- process image.
--
-- The ARGV argument is an array of null-terminated strings that is
-- used to provide a value for the `argv' argument to the `main'
-- function of the program to be executed. The last element of this
-- array must be a null pointer. By convention, the first element of
-- this array is the file name of the program sans directory names.
-- *Note Program Arguments::, for full details on how programs can
-- access these arguments.
--
-- The environment for the new process image is taken from the
-- `environ' variable of the current process image; see *Note
-- Environment Variables::, for information about environments.
--
-- - Function: int execl (const char *FILENAME, const char *ARG0, ...)
-- This is similar to `execv', but the ARGV strings are specified
-- individually instead of as an array. A null pointer must be
-- passed as the last such argument.
--
-- - Function: int execve (const char *FILENAME, char *const ARGV[], char
-- *const ENV[])
-- This is similar to `execv', but permits you to specify the
-- environment for the new program explicitly as the ENV argument.
-- This should be an array of strings in the same format as for the
-- `environ' variable; see *Note Environment Access::.
--
-- - Function: int execle (const char *FILENAME, const char *ARG0, char
-- *const ENV[], ...)
-- This is similar to `execl', but permits you to specify the
-- environment for the new program explicitly. The environment
-- argument is passed following the null pointer that marks the last
-- ARGV argument, and should be an array of strings in the same
-- format as for the `environ' variable.
--
-- - Function: int execvp (const char *FILENAME, char *const ARGV[])
-- The `execvp' function is similar to `execv', except that it
-- searches the directories listed in the `PATH' environment variable
-- (*note Standard Environment::.) to find the full file name of a
-- file from FILENAME if FILENAME does not contain a slash.
--
-- This function is useful for executing system utility programs,
-- because it looks for them in the places that the user has chosen.
-- Shells use it to run the commands that users type.
--
-- - Function: int execlp (const char *FILENAME, const char *ARG0, ...)
-- This function is like `execl', except that it performs the same
-- file name searching as the `execvp' function.
--
-- The size of the argument list and environment list taken together
--must not be greater than `ARG_MAX' bytes. *Note General Limits::. In
--the GNU system, the size (which compares against `ARG_MAX') includes,
--for each string, the number of characters in the string, plus the size
--of a `char *', plus one, rounded up to a multiple of the size of a
--`char *'. Other systems may have somewhat different rules for counting.
--
-- These functions normally don't return, since execution of a new
--program causes the currently executing program to go away completely.
--A value of `-1' is returned in the event of a failure. In addition to
--the usual file name errors (*note File Name Errors::.), the following
--`errno' error conditions are defined for these functions:
--
--`E2BIG'
-- The combined size of the new program's argument list and
-- environment list is larger than `ARG_MAX' bytes. The GNU system
-- has no specific limit on the argument list size, so this error
-- code cannot result, but you may get `ENOMEM' instead if the
-- arguments are too big for available memory.
--
--`ENOEXEC'
-- The specified file can't be executed because it isn't in the right
-- format.
--
--`ENOMEM'
-- Executing the specified file requires more storage than is
-- available.
--
-- If execution of the new file succeeds, it updates the access time
--field of the file as if the file had been read. *Note File Times::,
--for more details about access times of files.
--
-- The point at which the file is closed again is not specified, but is
--at some point before the process exits or before another process image
--is executed.
--
-- Executing a new process image completely changes the contents of
--memory, copying only the argument and environment strings to new
--locations. But many other attributes of the process are unchanged:
--
-- * The process ID and the parent process ID. *Note Process Creation
-- Concepts::.
--
-- * Session and process group membership. *Note Concepts of Job
-- Control::.
--
-- * Real user ID and group ID, and supplementary group IDs. *Note
-- Process Persona::.
--
-- * Pending alarms. *Note Setting an Alarm::.
--
-- * Current working directory and root directory. *Note Working
-- Directory::. In the GNU system, the root directory is not copied
-- when executing a setuid program; instead the system default root
-- directory is used for the new program.
--
-- * File mode creation mask. *Note Setting Permissions::.
--
-- * Process signal mask; see *Note Process Signal Mask::.
--
-- * Pending signals; see *Note Blocking Signals::.
--
-- * Elapsed processor time associated with the process; see *Note
-- Processor Time::.
--
-- If the set-user-ID and set-group-ID mode bits of the process image
--file are set, this affects the effective user ID and effective group ID
--(respectively) of the process. These concepts are discussed in detail
--in *Note Process Persona::.
--
-- Signals that are set to be ignored in the existing process image are
--also set to be ignored in the new process image. All other signals are
--set to the default action in the new process image. For more
--information about signals, see *Note Signal Handling::.
--
-- File descriptors open in the existing process image remain open in
--the new process image, unless they have the `FD_CLOEXEC'
--(close-on-exec) flag set. The files that remain open inherit all
--attributes of the open file description from the existing process image,
--including file locks. File descriptors are discussed in *Note
--Low-Level I/O::.
--
-- Streams, by contrast, cannot survive through `exec' functions,
--because they are located in the memory of the process itself. The new
--process image has no streams except those it creates afresh. Each of
--the streams in the pre-`exec' process image has a descriptor inside it,
--and these descriptors do survive through `exec' (provided that they do
--not have `FD_CLOEXEC' set). The new process image can reconnect these
--to new streams using `fdopen' (*note Descriptors and Streams::.).
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-37 glibc-2.1.3/manual/libc.info-37
---- ../glibc-2.1.3/manual/libc.info-37 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-37 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1308 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Process Completion, Next: Process Completion Status, Prev: Executing a File, Up: Processes
--
--Process Completion
--==================
--
-- The functions described in this section are used to wait for a child
--process to terminate or stop, and determine its status. These functions
--are declared in the header file `sys/wait.h'.
--
-- - Function: pid_t waitpid (pid_t PID, int *STATUS-PTR, int OPTIONS)
-- The `waitpid' function is used to request status information from a
-- child process whose process ID is PID. Normally, the calling
-- process is suspended until the child process makes status
-- information available by terminating.
--
-- Other values for the PID argument have special interpretations. A
-- value of `-1' or `WAIT_ANY' requests status information for any
-- child process; a value of `0' or `WAIT_MYPGRP' requests
-- information for any child process in the same process group as the
-- calling process; and any other negative value - PGID requests
-- information for any child process whose process group ID is PGID.
--
-- If status information for a child process is available
-- immediately, this function returns immediately without waiting.
-- If more than one eligible child process has status information
-- available, one of them is chosen randomly, and its status is
-- returned immediately. To get the status from the other eligible
-- child processes, you need to call `waitpid' again.
--
-- The OPTIONS argument is a bit mask. Its value should be the
-- bitwise OR (that is, the `|' operator) of zero or more of the
-- `WNOHANG' and `WUNTRACED' flags. You can use the `WNOHANG' flag
-- to indicate that the parent process shouldn't wait; and the
-- `WUNTRACED' flag to request status information from stopped
-- processes as well as processes that have terminated.
--
-- The status information from the child process is stored in the
-- object that STATUS-PTR points to, unless STATUS-PTR is a null
-- pointer.
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `waitpid' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `waitpid' should be protected using cancelation handlers.
--
-- The return value is normally the process ID of the child process
-- whose status is reported. If there are child processes but none
-- of them is waiting to be noticed, `waitpid' will block until one
-- is. However, if the `WNOHANG' option was specified, `waitpid'
-- will return zero instead of blocking.
--
-- If a specific PID to wait for was given to `waitpid', it will
-- ignore all other children (if any). Therefore if there are
-- children waiting to be noticed but the child whose PID was
-- specified is not one of them, `waitpid' will block or return zero
-- as described above.
--
-- A value of `-1' is returned in case of error. The following
-- `errno' error conditions are defined for this function:
--
-- `EINTR'
-- The function was interrupted by delivery of a signal to the
-- calling process. *Note Interrupted Primitives::.
--
-- `ECHILD'
-- There are no child processes to wait for, or the specified PID
-- is not a child of the calling process.
--
-- `EINVAL'
-- An invalid value was provided for the OPTIONS argument.
--
-- These symbolic constants are defined as values for the PID argument
--to the `waitpid' function.
--
--`WAIT_ANY'
-- This constant macro (whose value is `-1') specifies that `waitpid'
-- should return status information about any child process.
--
--`WAIT_MYPGRP'
-- This constant (with value `0') specifies that `waitpid' should
-- return status information about any child process in the same
-- process group as the calling process.
--
-- These symbolic constants are defined as flags for the OPTIONS
--argument to the `waitpid' function. You can bitwise-OR the flags
--together to obtain a value to use as the argument.
--
--`WNOHANG'
-- This flag specifies that `waitpid' should return immediately
-- instead of waiting, if there is no child process ready to be
-- noticed.
--
--`WUNTRACED'
-- This flag specifies that `waitpid' should report the status of any
-- child processes that have been stopped as well as those that have
-- terminated.
--
-- - Function: pid_t wait (int *STATUS-PTR)
-- This is a simplified version of `waitpid', and is used to wait
-- until any one child process terminates. The call:
--
-- wait (&status)
--
-- is exactly equivalent to:
--
-- waitpid (-1, &status, 0)
--
-- This function is a cancelation point in multi-threaded programs.
-- This is a problem if the thread allocates some resources (like
-- memory, file descriptors, semaphores or whatever) at the time
-- `wait' is called. If the thread gets canceled these resources
-- stay allocated until the program ends. To avoid this calls to
-- `wait' should be protected using cancelation handlers.
--
-- - Function: pid_t wait4 (pid_t PID, int *STATUS-PTR, int OPTIONS,
-- struct rusage *USAGE)
-- If USAGE is a null pointer, `wait4' is equivalent to `waitpid
-- (PID, STATUS-PTR, OPTIONS)'.
--
-- If USAGE is not null, `wait4' stores usage figures for the child
-- process in `*RUSAGE' (but only if the child has terminated, not if
-- it has stopped). *Note Resource Usage::.
--
-- This function is a BSD extension.
--
-- Here's an example of how to use `waitpid' to get the status from all
--child processes that have terminated, without ever waiting. This
--function is designed to be a handler for `SIGCHLD', the signal that
--indicates that at least one child process has terminated.
--
-- void
-- sigchld_handler (int signum)
-- {
-- int pid, status, serrno;
-- serrno = errno;
-- while (1)
-- {
-- pid = waitpid (WAIT_ANY, &status, WNOHANG);
-- if (pid < 0)
-- {
-- perror ("waitpid");
-- break;
-- }
-- if (pid == 0)
-- break;
-- notice_termination (pid, status);
-- }
-- errno = serrno;
-- }
--
--
--File: libc.info, Node: Process Completion Status, Next: BSD Wait Functions, Prev: Process Completion, Up: Processes
--
--Process Completion Status
--=========================
--
-- If the exit status value (*note Program Termination::.) of the child
--process is zero, then the status value reported by `waitpid' or `wait'
--is also zero. You can test for other kinds of information encoded in
--the returned status value using the following macros. These macros are
--defined in the header file `sys/wait.h'.
--
-- - Macro: int WIFEXITED (int STATUS)
-- This macro returns a nonzero value if the child process terminated
-- normally with `exit' or `_exit'.
--
-- - Macro: int WEXITSTATUS (int STATUS)
-- If `WIFEXITED' is true of STATUS, this macro returns the low-order
-- 8 bits of the exit status value from the child process. *Note
-- Exit Status::.
--
-- - Macro: int WIFSIGNALED (int STATUS)
-- This macro returns a nonzero value if the child process terminated
-- because it received a signal that was not handled. *Note Signal
-- Handling::.
--
-- - Macro: int WTERMSIG (int STATUS)
-- If `WIFSIGNALED' is true of STATUS, this macro returns the signal
-- number of the signal that terminated the child process.
--
-- - Macro: int WCOREDUMP (int STATUS)
-- This macro returns a nonzero value if the child process terminated
-- and produced a core dump.
--
-- - Macro: int WIFSTOPPED (int STATUS)
-- This macro returns a nonzero value if the child process is stopped.
--
-- - Macro: int WSTOPSIG (int STATUS)
-- If `WIFSTOPPED' is true of STATUS, this macro returns the signal
-- number of the signal that caused the child process to stop.
--
--
--File: libc.info, Node: BSD Wait Functions, Next: Process Creation Example, Prev: Process Completion Status, Up: Processes
--
--BSD Process Wait Functions
--==========================
--
-- The GNU library also provides these related facilities for
--compatibility with BSD Unix. BSD uses the `union wait' data type to
--represent status values rather than an `int'. The two representations
--are actually interchangeable; they describe the same bit patterns. The
--GNU C Library defines macros such as `WEXITSTATUS' so that they will
--work on either kind of object, and the `wait' function is defined to
--accept either type of pointer as its STATUS-PTR argument.
--
-- These functions are declared in `sys/wait.h'.
--
-- - Data Type: union wait
-- This data type represents program termination status values. It
-- has the following members:
--
-- `int w_termsig'
-- The value of this member is the same as that of the
-- `WTERMSIG' macro.
--
-- `int w_coredump'
-- The value of this member is the same as that of the
-- `WCOREDUMP' macro.
--
-- `int w_retcode'
-- The value of this member is the same as that of the
-- `WEXITSTATUS' macro.
--
-- `int w_stopsig'
-- The value of this member is the same as that of the
-- `WSTOPSIG' macro.
--
-- Instead of accessing these members directly, you should use the
-- equivalent macros.
--
-- The `wait3' function is the predecessor to `wait4', which is more
--flexible. `wait3' is now obsolete.
--
-- - Function: pid_t wait3 (union wait *STATUS-PTR, int OPTIONS, struct
-- rusage *USAGE)
-- If USAGE is a null pointer, `wait3' is equivalent to `waitpid (-1,
-- STATUS-PTR, OPTIONS)'.
--
-- If USAGE is not null, `wait3' stores usage figures for the child
-- process in `*RUSAGE' (but only if the child has terminated, not if
-- it has stopped). *Note Resource Usage::.
--
--
--File: libc.info, Node: Process Creation Example, Prev: BSD Wait Functions, Up: Processes
--
--Process Creation Example
--========================
--
-- Here is an example program showing how you might write a function
--similar to the built-in `system'. It executes its COMMAND argument
--using the equivalent of `sh -c COMMAND'.
--
-- #include <stddef.h>
-- #include <stdlib.h>
-- #include <unistd.h>
-- #include <sys/types.h>
-- #include <sys/wait.h>
--
-- /* Execute the command using this shell program. */
-- #define SHELL "/bin/sh"
-- int
-- my_system (const char *command)
-- {
-- int status;
-- pid_t pid;
--
-- pid = fork ();
-- if (pid == 0)
-- {
-- /* This is the child process. Execute the shell command. */
-- execl (SHELL, SHELL, "-c", command, NULL);
-- _exit (EXIT_FAILURE);
-- }
-- else if (pid < 0)
-- /* The fork failed. Report failure. */
-- status = -1;
-- else
-- /* This is the parent process. Wait for the child to complete. */
-- if (waitpid (pid, &status, 0) != pid)
-- status = -1;
-- return status;
-- }
--
-- There are a couple of things you should pay attention to in this
--example.
--
-- Remember that the first `argv' argument supplied to the program
--represents the name of the program being executed. That is why, in the
--call to `execl', `SHELL' is supplied once to name the program to
--execute and a second time to supply a value for `argv[0]'.
--
-- The `execl' call in the child process doesn't return if it is
--successful. If it fails, you must do something to make the child
--process terminate. Just returning a bad status code with `return'
--would leave two processes running the original program. Instead, the
--right behavior is for the child process to report failure to its parent
--process.
--
-- Call `_exit' to accomplish this. The reason for using `_exit'
--instead of `exit' is to avoid flushing fully buffered streams such as
--`stdout'. The buffers of these streams probably contain data that was
--copied from the parent process by the `fork', data that will be output
--eventually by the parent process. Calling `exit' in the child would
--output the data twice. *Note Termination Internals::.
--
--
--File: libc.info, Node: Job Control, Next: Name Service Switch, Prev: Processes, Up: Top
--
--Job Control
--***********
--
-- "Job control" refers to the protocol for allowing a user to move
--between multiple "process groups" (or "jobs") within a single "login
--session". The job control facilities are set up so that appropriate
--behavior for most programs happens automatically and they need not do
--anything special about job control. So you can probably ignore the
--material in this chapter unless you are writing a shell or login
--program.
--
-- You need to be familiar with concepts relating to process creation
--(*note Process Creation Concepts::.) and signal handling (*note Signal
--Handling::.) in order to understand this material presented in this
--chapter.
--
--* Menu:
--
--* Concepts of Job Control:: Jobs can be controlled by a shell.
--* Job Control is Optional:: Not all POSIX systems support job control.
--* Controlling Terminal:: How a process gets its controlling terminal.
--* Access to the Terminal:: How processes share the controlling terminal.
--* Orphaned Process Groups:: Jobs left after the user logs out.
--* Implementing a Shell:: What a shell must do to implement job control.
--* Functions for Job Control:: Functions to control process groups.
--
--
--File: libc.info, Node: Concepts of Job Control, Next: Job Control is Optional, Up: Job Control
--
--Concepts of Job Control
--=======================
--
-- The fundamental purpose of an interactive shell is to read commands
--from the user's terminal and create processes to execute the programs
--specified by those commands. It can do this using the `fork' (*note
--Creating a Process::.) and `exec' (*note Executing a File::.) functions.
--
-- A single command may run just one process--but often one command uses
--several processes. If you use the `|' operator in a shell command, you
--explicitly request several programs in their own processes. But even
--if you run just one program, it can use multiple processes internally.
--For example, a single compilation command such as `cc -c foo.c'
--typically uses four processes (though normally only two at any given
--time). If you run `make', its job is to run other programs in separate
--processes.
--
-- The processes belonging to a single command are called a "process
--group" or "job". This is so that you can operate on all of them at
--once. For example, typing `C-c' sends the signal `SIGINT' to terminate
--all the processes in the foreground process group.
--
-- A "session" is a larger group of processes. Normally all the
--processes that stem from a single login belong to the same session.
--
-- Every process belongs to a process group. When a process is
--created, it becomes a member of the same process group and session as
--its parent process. You can put it in another process group using the
--`setpgid' function, provided the process group belongs to the same
--session.
--
-- The only way to put a process in a different session is to make it
--the initial process of a new session, or a "session leader", using the
--`setsid' function. This also puts the session leader into a new
--process group, and you can't move it out of that process group again.
--
-- Usually, new sessions are created by the system login program, and
--the session leader is the process running the user's login shell.
--
-- A shell that supports job control must arrange to control which job
--can use the terminal at any time. Otherwise there might be multiple
--jobs trying to read from the terminal at once, and confusion about which
--process should receive the input typed by the user. To prevent this,
--the shell must cooperate with the terminal driver using the protocol
--described in this chapter.
--
-- The shell can give unlimited access to the controlling terminal to
--only one process group at a time. This is called the "foreground job"
--on that controlling terminal. Other process groups managed by the shell
--that are executing without such access to the terminal are called
--"background jobs".
--
-- If a background job needs to read from its controlling terminal, it
--is "stopped" by the terminal driver; if the `TOSTOP' mode is set,
--likewise for writing. The user can stop a foreground job by typing the
--SUSP character (*note Special Characters::.) and a program can stop any
--job by sending it a `SIGSTOP' signal. It's the responsibility of the
--shell to notice when jobs stop, to notify the user about them, and to
--provide mechanisms for allowing the user to interactively continue
--stopped jobs and switch jobs between foreground and background.
--
-- *Note Access to the Terminal::, for more information about I/O to the
--controlling terminal,
--
--
--File: libc.info, Node: Job Control is Optional, Next: Controlling Terminal, Prev: Concepts of Job Control, Up: Job Control
--
--Job Control is Optional
--=======================
--
-- Not all operating systems support job control. The GNU system does
--support job control, but if you are using the GNU library on some other
--system, that system may not support job control itself.
--
-- You can use the `_POSIX_JOB_CONTROL' macro to test at compile-time
--whether the system supports job control. *Note System Options::.
--
-- If job control is not supported, then there can be only one process
--group per session, which behaves as if it were always in the foreground.
--The functions for creating additional process groups simply fail with
--the error code `ENOSYS'.
--
-- The macros naming the various job control signals (*note Job Control
--Signals::.) are defined even if job control is not supported. However,
--the system never generates these signals, and attempts to send a job
--control signal or examine or specify their actions report errors or do
--nothing.
--
--
--File: libc.info, Node: Controlling Terminal, Next: Access to the Terminal, Prev: Job Control is Optional, Up: Job Control
--
--Controlling Terminal of a Process
--=================================
--
-- One of the attributes of a process is its controlling terminal.
--Child processes created with `fork' inherit the controlling terminal
--from their parent process. In this way, all the processes in a session
--inherit the controlling terminal from the session leader. A session
--leader that has control of a terminal is called the "controlling
--process" of that terminal.
--
-- You generally do not need to worry about the exact mechanism used to
--allocate a controlling terminal to a session, since it is done for you
--by the system when you log in.
--
-- An individual process disconnects from its controlling terminal when
--it calls `setsid' to become the leader of a new session. *Note Process
--Group Functions::.
--
--
--File: libc.info, Node: Access to the Terminal, Next: Orphaned Process Groups, Prev: Controlling Terminal, Up: Job Control
--
--Access to the Controlling Terminal
--==================================
--
-- Processes in the foreground job of a controlling terminal have
--unrestricted access to that terminal; background processes do not. This
--section describes in more detail what happens when a process in a
--background job tries to access its controlling terminal.
--
-- When a process in a background job tries to read from its controlling
--terminal, the process group is usually sent a `SIGTTIN' signal. This
--normally causes all of the processes in that group to stop (unless they
--handle the signal and don't stop themselves). However, if the reading
--process is ignoring or blocking this signal, then `read' fails with an
--`EIO' error instead.
--
-- Similarly, when a process in a background job tries to write to its
--controlling terminal, the default behavior is to send a `SIGTTOU'
--signal to the process group. However, the behavior is modified by the
--`TOSTOP' bit of the local modes flags (*note Local Modes::.). If this
--bit is not set (which is the default), then writing to the controlling
--terminal is always permitted without sending a signal. Writing is also
--permitted if the `SIGTTOU' signal is being ignored or blocked by the
--writing process.
--
-- Most other terminal operations that a program can do are treated as
--reading or as writing. (The description of each operation should say
--which.)
--
-- For more information about the primitive `read' and `write'
--functions, see *Note I/O Primitives::.
--
--
--File: libc.info, Node: Orphaned Process Groups, Next: Implementing a Shell, Prev: Access to the Terminal, Up: Job Control
--
--Orphaned Process Groups
--=======================
--
-- When a controlling process terminates, its terminal becomes free and
--a new session can be established on it. (In fact, another user could
--log in on the terminal.) This could cause a problem if any processes
--from the old session are still trying to use that terminal.
--
-- To prevent problems, process groups that continue running even after
--the session leader has terminated are marked as "orphaned process
--groups".
--
-- When a process group becomes an orphan, its processes are sent a
--`SIGHUP' signal. Ordinarily, this causes the processes to terminate.
--However, if a program ignores this signal or establishes a handler for
--it (*note Signal Handling::.), it can continue running as in the orphan
--process group even after its controlling process terminates; but it
--still cannot access the terminal any more.
--
--
--File: libc.info, Node: Implementing a Shell, Next: Functions for Job Control, Prev: Orphaned Process Groups, Up: Job Control
--
--Implementing a Job Control Shell
--================================
--
-- This section describes what a shell must do to implement job
--control, by presenting an extensive sample program to illustrate the
--concepts involved.
--
--* Menu:
--
--* Data Structures:: Introduction to the sample shell.
--* Initializing the Shell:: What the shell must do to take
-- responsibility for job control.
--* Launching Jobs:: Creating jobs to execute commands.
--* Foreground and Background:: Putting a job in foreground of background.
--* Stopped and Terminated Jobs:: Reporting job status.
--* Continuing Stopped Jobs:: How to continue a stopped job in
-- the foreground or background.
--* Missing Pieces:: Other parts of the shell.
--
--
--File: libc.info, Node: Data Structures, Next: Initializing the Shell, Up: Implementing a Shell
--
--Data Structures for the Shell
-------------------------------
--
-- All of the program examples included in this chapter are part of a
--simple shell program. This section presents data structures and
--utility functions which are used throughout the example.
--
-- The sample shell deals mainly with two data structures. The `job'
--type contains information about a job, which is a set of subprocesses
--linked together with pipes. The `process' type holds information about
--a single subprocess. Here are the relevant data structure declarations:
--
-- /* A process is a single process. */
-- typedef struct process
-- {
-- struct process *next; /* next process in pipeline */
-- char **argv; /* for exec */
-- pid_t pid; /* process ID */
-- char completed; /* true if process has completed */
-- char stopped; /* true if process has stopped */
-- int status; /* reported status value */
-- } process;
--
-- /* A job is a pipeline of processes. */
-- typedef struct job
-- {
-- struct job *next; /* next active job */
-- char *command; /* command line, used for messages */
-- process *first_process; /* list of processes in this job */
-- pid_t pgid; /* process group ID */
-- char notified; /* true if user told about stopped job */
-- struct termios tmodes; /* saved terminal modes */
-- int stdin, stdout, stderr; /* standard i/o channels */
-- } job;
--
-- /* The active jobs are linked into a list. This is its head. */
-- job *first_job = NULL;
--
-- Here are some utility functions that are used for operating on `job'
--objects.
--
-- /* Find the active job with the indicated PGID. */
-- job *
-- find_job (pid_t pgid)
-- {
-- job *j;
--
-- for (j = first_job; j; j = j->next)
-- if (j->pgid == pgid)
-- return j;
-- return NULL;
-- }
--
-- /* Return true if all processes in the job have stopped or completed. */
-- int
-- job_is_stopped (job *j)
-- {
-- process *p;
--
-- for (p = j->first_process; p; p = p->next)
-- if (!p->completed && !p->stopped)
-- return 0;
-- return 1;
-- }
--
-- /* Return true if all processes in the job have completed. */
-- int
-- job_is_completed (job *j)
-- {
-- process *p;
--
-- for (p = j->first_process; p; p = p->next)
-- if (!p->completed)
-- return 0;
-- return 1;
-- }
--
--
--File: libc.info, Node: Initializing the Shell, Next: Launching Jobs, Prev: Data Structures, Up: Implementing a Shell
--
--Initializing the Shell
------------------------
--
-- When a shell program that normally performs job control is started,
--it has to be careful in case it has been invoked from another shell
--that is already doing its own job control.
--
-- A subshell that runs interactively has to ensure that it has been
--placed in the foreground by its parent shell before it can enable job
--control itself. It does this by getting its initial process group ID
--with the `getpgrp' function, and comparing it to the process group ID
--of the current foreground job associated with its controlling terminal
--(which can be retrieved using the `tcgetpgrp' function).
--
-- If the subshell is not running as a foreground job, it must stop
--itself by sending a `SIGTTIN' signal to its own process group. It may
--not arbitrarily put itself into the foreground; it must wait for the
--user to tell the parent shell to do this. If the subshell is continued
--again, it should repeat the check and stop itself again if it is still
--not in the foreground.
--
-- Once the subshell has been placed into the foreground by its parent
--shell, it can enable its own job control. It does this by calling
--`setpgid' to put itself into its own process group, and then calling
--`tcsetpgrp' to place this process group into the foreground.
--
-- When a shell enables job control, it should set itself to ignore all
--the job control stop signals so that it doesn't accidentally stop
--itself. You can do this by setting the action for all the stop signals
--to `SIG_IGN'.
--
-- A subshell that runs non-interactively cannot and should not support
--job control. It must leave all processes it creates in the same process
--group as the shell itself; this allows the non-interactive shell and its
--child processes to be treated as a single job by the parent shell. This
--is easy to do--just don't use any of the job control primitives--but
--you must remember to make the shell do it.
--
-- Here is the initialization code for the sample shell that shows how
--to do all of this.
--
-- /* Keep track of attributes of the shell. */
--
-- #include <sys/types.h>
-- #include <termios.h>
-- #include <unistd.h>
--
-- pid_t shell_pgid;
-- struct termios shell_tmodes;
-- int shell_terminal;
-- int shell_is_interactive;
--
--
-- /* Make sure the shell is running interactively as the foreground job
-- before proceeding. */
--
-- void
-- init_shell ()
-- {
--
-- /* See if we are running interactively. */
-- shell_terminal = STDIN_FILENO;
-- shell_is_interactive = isatty (shell_terminal);
--
-- if (shell_is_interactive)
-- {
-- /* Loop until we are in the foreground. */
-- while (tcgetpgrp (shell_terminal) != (shell_pgid = getpgrp ()))
-- kill (- shell_pgid, SIGTTIN);
--
-- /* Ignore interactive and job-control signals. */
-- signal (SIGINT, SIG_IGN);
-- signal (SIGQUIT, SIG_IGN);
-- signal (SIGTSTP, SIG_IGN);
-- signal (SIGTTIN, SIG_IGN);
-- signal (SIGTTOU, SIG_IGN);
-- signal (SIGCHLD, SIG_IGN);
--
-- /* Put ourselves in our own process group. */
-- shell_pgid = getpid ();
-- if (setpgid (shell_pgid, shell_pgid) < 0)
-- {
-- perror ("Couldn't put the shell in its own process group");
-- exit (1);
-- }
--
-- /* Grab control of the terminal. */
-- tcsetpgrp (shell_terminal, shell_pgid);
--
-- /* Save default terminal attributes for shell. */
-- tcgetattr (shell_terminal, &shell_tmodes);
-- }
-- }
--
--
--File: libc.info, Node: Launching Jobs, Next: Foreground and Background, Prev: Initializing the Shell, Up: Implementing a Shell
--
--Launching Jobs
----------------
--
-- Once the shell has taken responsibility for performing job control on
--its controlling terminal, it can launch jobs in response to commands
--typed by the user.
--
-- To create the processes in a process group, you use the same `fork'
--and `exec' functions described in *Note Process Creation Concepts::.
--Since there are multiple child processes involved, though, things are a
--little more complicated and you must be careful to do things in the
--right order. Otherwise, nasty race conditions can result.
--
-- You have two choices for how to structure the tree of parent-child
--relationships among the processes. You can either make all the
--processes in the process group be children of the shell process, or you
--can make one process in group be the ancestor of all the other processes
--in that group. The sample shell program presented in this chapter uses
--the first approach because it makes bookkeeping somewhat simpler.
--
-- As each process is forked, it should put itself in the new process
--group by calling `setpgid'; see *Note Process Group Functions::. The
--first process in the new group becomes its "process group leader", and
--its process ID becomes the "process group ID" for the group.
--
-- The shell should also call `setpgid' to put each of its child
--processes into the new process group. This is because there is a
--potential timing problem: each child process must be put in the process
--group before it begins executing a new program, and the shell depends on
--having all the child processes in the group before it continues
--executing. If both the child processes and the shell call `setpgid',
--this ensures that the right things happen no matter which process gets
--to it first.
--
-- If the job is being launched as a foreground job, the new process
--group also needs to be put into the foreground on the controlling
--terminal using `tcsetpgrp'. Again, this should be done by the shell as
--well as by each of its child processes, to avoid race conditions.
--
-- The next thing each child process should do is to reset its signal
--actions.
--
-- During initialization, the shell process set itself to ignore job
--control signals; see *Note Initializing the Shell::. As a result, any
--child processes it creates also ignore these signals by inheritance.
--This is definitely undesirable, so each child process should explicitly
--set the actions for these signals back to `SIG_DFL' just after it is
--forked.
--
-- Since shells follow this convention, applications can assume that
--they inherit the correct handling of these signals from the parent
--process. But every application has a responsibility not to mess up the
--handling of stop signals. Applications that disable the normal
--interpretation of the SUSP character should provide some other
--mechanism for the user to stop the job. When the user invokes this
--mechanism, the program should send a `SIGTSTP' signal to the process
--group of the process, not just to the process itself. *Note Signaling
--Another Process::.
--
-- Finally, each child process should call `exec' in the normal way.
--This is also the point at which redirection of the standard input and
--output channels should be handled. *Note Duplicating Descriptors::,
--for an explanation of how to do this.
--
-- Here is the function from the sample shell program that is
--responsible for launching a program. The function is executed by each
--child process immediately after it has been forked by the shell, and
--never returns.
--
-- void
-- launch_process (process *p, pid_t pgid,
-- int infile, int outfile, int errfile,
-- int foreground)
-- {
-- pid_t pid;
--
-- if (shell_is_interactive)
-- {
-- /* Put the process into the process group and give the process group
-- the terminal, if appropriate.
-- This has to be done both by the shell and in the individual
-- child processes because of potential race conditions. */
-- pid = getpid ();
-- if (pgid == 0) pgid = pid;
-- setpgid (pid, pgid);
-- if (foreground)
-- tcsetpgrp (shell_terminal, pgid);
--
-- /* Set the handling for job control signals back to the default. */
-- signal (SIGINT, SIG_DFL);
-- signal (SIGQUIT, SIG_DFL);
-- signal (SIGTSTP, SIG_DFL);
-- signal (SIGTTIN, SIG_DFL);
-- signal (SIGTTOU, SIG_DFL);
-- signal (SIGCHLD, SIG_DFL);
-- }
--
-- /* Set the standard input/output channels of the new process. */
-- if (infile != STDIN_FILENO)
-- {
-- dup2 (infile, STDIN_FILENO);
-- close (infile);
-- }
-- if (outfile != STDOUT_FILENO)
-- {
-- dup2 (outfile, STDOUT_FILENO);
-- close (outfile);
-- }
-- if (errfile != STDERR_FILENO)
-- {
-- dup2 (errfile, STDERR_FILENO);
-- close (errfile);
-- }
--
-- /* Exec the new process. Make sure we exit. */
-- execvp (p->argv[0], p->argv);
-- perror ("execvp");
-- exit (1);
-- }
--
-- If the shell is not running interactively, this function does not do
--anything with process groups or signals. Remember that a shell not
--performing job control must keep all of its subprocesses in the same
--process group as the shell itself.
--
-- Next, here is the function that actually launches a complete job.
--After creating the child processes, this function calls some other
--functions to put the newly created job into the foreground or
--background; these are discussed in *Note Foreground and Background::.
--
-- void
-- launch_job (job *j, int foreground)
-- {
-- process *p;
-- pid_t pid;
-- int mypipe[2], infile, outfile;
--
-- infile = j->stdin;
-- for (p = j->first_process; p; p = p->next)
-- {
-- /* Set up pipes, if necessary. */
-- if (p->next)
-- {
-- if (pipe (mypipe) < 0)
-- {
-- perror ("pipe");
-- exit (1);
-- }
-- outfile = mypipe[1];
-- }
-- else
-- outfile = j->stdout;
--
-- /* Fork the child processes. */
-- pid = fork ();
-- if (pid == 0)
-- /* This is the child process. */
-- launch_process (p, j->pgid, infile,
-- outfile, j->stderr, foreground);
-- else if (pid < 0)
-- {
-- /* The fork failed. */
-- perror ("fork");
-- exit (1);
-- }
-- else
-- {
-- /* This is the parent process. */
-- p->pid = pid;
-- if (shell_is_interactive)
-- {
-- if (!j->pgid)
-- j->pgid = pid;
-- setpgid (pid, j->pgid);
-- }
-- }
--
-- /* Clean up after pipes. */
-- if (infile != j->stdin)
-- close (infile);
-- if (outfile != j->stdout)
-- close (outfile);
-- infile = mypipe[0];
-- }
--
-- format_job_info (j, "launched");
--
-- if (!shell_is_interactive)
-- wait_for_job (j);
-- else if (foreground)
-- put_job_in_foreground (j, 0);
-- else
-- put_job_in_background (j, 0);
-- }
--
--
--File: libc.info, Node: Foreground and Background, Next: Stopped and Terminated Jobs, Prev: Launching Jobs, Up: Implementing a Shell
--
--Foreground and Background
---------------------------
--
-- Now let's consider what actions must be taken by the shell when it
--launches a job into the foreground, and how this differs from what must
--be done when a background job is launched.
--
-- When a foreground job is launched, the shell must first give it
--access to the controlling terminal by calling `tcsetpgrp'. Then, the
--shell should wait for processes in that process group to terminate or
--stop. This is discussed in more detail in *Note Stopped and Terminated
--Jobs::.
--
-- When all of the processes in the group have either completed or
--stopped, the shell should regain control of the terminal for its own
--process group by calling `tcsetpgrp' again. Since stop signals caused
--by I/O from a background process or a SUSP character typed by the user
--are sent to the process group, normally all the processes in the job
--stop together.
--
-- The foreground job may have left the terminal in a strange state, so
--the shell should restore its own saved terminal modes before
--continuing. In case the job is merely been stopped, the shell should
--first save the current terminal modes so that it can restore them later
--if the job is continued. The functions for dealing with terminal modes
--are `tcgetattr' and `tcsetattr'; these are described in *Note Terminal
--Modes::.
--
-- Here is the sample shell's function for doing all of this.
--
-- /* Put job J in the foreground. If CONT is nonzero,
-- restore the saved terminal modes and send the process group a
-- `SIGCONT' signal to wake it up before we block. */
--
-- void
-- put_job_in_foreground (job *j, int cont)
-- {
-- /* Put the job into the foreground. */
-- tcsetpgrp (shell_terminal, j->pgid);
--
-- /* Send the job a continue signal, if necessary. */
-- if (cont)
-- {
-- tcsetattr (shell_terminal, TCSADRAIN, &j->tmodes);
-- if (kill (- j->pgid, SIGCONT) < 0)
-- perror ("kill (SIGCONT)");
-- }
--
-- /* Wait for it to report. */
-- wait_for_job (j);
--
-- /* Put the shell back in the foreground. */
-- tcsetpgrp (shell_terminal, shell_pgid);
-- /* Restore the shell's terminal modes. */
-- tcgetattr (shell_terminal, &j->tmodes);
-- tcsetattr (shell_terminal, TCSADRAIN, &shell_tmodes);
-- }
--
-- If the process group is launched as a background job, the shell
--should remain in the foreground itself and continue to read commands
--from the terminal.
--
-- In the sample shell, there is not much that needs to be done to put
--a job into the background. Here is the function it uses:
--
-- /* Put a job in the background. If the cont argument is true, send
-- the process group a `SIGCONT' signal to wake it up. */
--
-- void
-- put_job_in_background (job *j, int cont)
-- {
-- /* Send the job a continue signal, if necessary. */
-- if (cont)
-- if (kill (-j->pgid, SIGCONT) < 0)
-- perror ("kill (SIGCONT)");
-- }
--
--
--File: libc.info, Node: Stopped and Terminated Jobs, Next: Continuing Stopped Jobs, Prev: Foreground and Background, Up: Implementing a Shell
--
--Stopped and Terminated Jobs
-----------------------------
--
-- When a foreground process is launched, the shell must block until
--all of the processes in that job have either terminated or stopped. It
--can do this by calling the `waitpid' function; see *Note Process
--Completion::. Use the `WUNTRACED' option so that status is reported
--for processes that stop as well as processes that terminate.
--
-- The shell must also check on the status of background jobs so that it
--can report terminated and stopped jobs to the user; this can be done by
--calling `waitpid' with the `WNOHANG' option. A good place to put a
--such a check for terminated and stopped jobs is just before prompting
--for a new command.
--
-- The shell can also receive asynchronous notification that there is
--status information available for a child process by establishing a
--handler for `SIGCHLD' signals. *Note Signal Handling::.
--
-- In the sample shell program, the `SIGCHLD' signal is normally
--ignored. This is to avoid reentrancy problems involving the global data
--structures the shell manipulates. But at specific times when the shell
--is not using these data structures--such as when it is waiting for
--input on the terminal--it makes sense to enable a handler for
--`SIGCHLD'. The same function that is used to do the synchronous status
--checks (`do_job_notification', in this case) can also be called from
--within this handler.
--
-- Here are the parts of the sample shell program that deal with
--checking the status of jobs and reporting the information to the user.
--
-- /* Store the status of the process PID that was returned by waitpid.
-- Return 0 if all went well, nonzero otherwise. */
--
-- int
-- mark_process_status (pid_t pid, int status)
-- {
-- job *j;
-- process *p;
--
-- if (pid > 0)
-- {
-- /* Update the record for the process. */
-- for (j = first_job; j; j = j->next)
-- for (p = j->first_process; p; p = p->next)
-- if (p->pid == pid)
-- {
-- p->status = status;
-- if (WIFSTOPPED (status))
-- p->stopped = 1;
-- else
-- {
-- p->completed = 1;
-- if (WIFSIGNALED (status))
-- fprintf (stderr, "%d: Terminated by signal %d.\n",
-- (int) pid, WTERMSIG (p->status));
-- }
-- return 0;
-- }
-- fprintf (stderr, "No child process %d.\n", pid);
-- return -1;
-- }
--
-- else if (pid == 0 || errno == ECHILD)
-- /* No processes ready to report. */
-- return -1;
-- else {
-- /* Other weird errors. */
-- perror ("waitpid");
-- return -1;
-- }
-- }
--
-- /* Check for processes that have status information available,
-- without blocking. */
--
-- void
-- update_status (void)
-- {
-- int status;
-- pid_t pid;
--
-- do
-- pid = waitpid (WAIT_ANY, &status, WUNTRACED|WNOHANG);
-- while (!mark_process_status (pid, status));
-- }
--
-- /* Check for processes that have status information available,
-- blocking until all processes in the given job have reported. */
--
-- void
-- wait_for_job (job *j)
-- {
-- int status;
-- pid_t pid;
--
-- do
-- pid = waitpid (WAIT_ANY, &status, WUNTRACED);
-- while (!mark_process_status (pid, status)
-- && !job_is_stopped (j)
-- && !job_is_completed (j));
-- }
--
-- /* Format information about job status for the user to look at. */
--
-- void
-- format_job_info (job *j, const char *status)
-- {
-- fprintf (stderr, "%ld (%s): %s\n", (long)j->pgid, status, j->command);
-- }
--
-- /* Notify the user about stopped or terminated jobs.
-- Delete terminated jobs from the active job list. */
--
-- void
-- do_job_notification (void)
-- {
-- job *j, *jlast, *jnext;
-- process *p;
--
-- /* Update status information for child processes. */
-- update_status ();
--
-- jlast = NULL;
-- for (j = first_job; j; j = jnext)
-- {
-- jnext = j->next;
--
-- /* If all processes have completed, tell the user the job has
-- completed and delete it from the list of active jobs. */
-- if (job_is_completed (j)) {
-- format_job_info (j, "completed");
-- if (jlast)
-- jlast->next = jnext;
-- else
-- first_job = jnext;
-- free_job (j);
-- }
--
-- /* Notify the user about stopped jobs,
-- marking them so that we won't do this more than once. */
-- else if (job_is_stopped (j) && !j->notified) {
-- format_job_info (j, "stopped");
-- j->notified = 1;
-- jlast = j;
-- }
--
-- /* Don't say anything about jobs that are still running. */
-- else
-- jlast = j;
-- }
-- }
--
--
--File: libc.info, Node: Continuing Stopped Jobs, Next: Missing Pieces, Prev: Stopped and Terminated Jobs, Up: Implementing a Shell
--
--Continuing Stopped Jobs
-------------------------
--
-- The shell can continue a stopped job by sending a `SIGCONT' signal
--to its process group. If the job is being continued in the foreground,
--the shell should first invoke `tcsetpgrp' to give the job access to the
--terminal, and restore the saved terminal settings. After continuing a
--job in the foreground, the shell should wait for the job to stop or
--complete, as if the job had just been launched in the foreground.
--
-- The sample shell program handles both newly created and continued
--jobs with the same pair of functions, `put_job_in_foreground' and
--`put_job_in_background'. The definitions of these functions were given
--in *Note Foreground and Background::. When continuing a stopped job, a
--nonzero value is passed as the CONT argument to ensure that the
--`SIGCONT' signal is sent and the terminal modes reset, as appropriate.
--
-- This leaves only a function for updating the shell's internal
--bookkeeping about the job being continued:
--
-- /* Mark a stopped job J as being running again. */
--
-- void
-- mark_job_as_running (job *j)
-- {
-- Process *p;
--
-- for (p = j->first_process; p; p = p->next)
-- p->stopped = 0;
-- j->notified = 0;
-- }
--
-- /* Continue the job J. */
--
-- void
-- continue_job (job *j, int foreground)
-- {
-- mark_job_as_running (j);
-- if (foreground)
-- put_job_in_foreground (j, 1);
-- else
-- put_job_in_background (j, 1);
-- }
--
--
--File: libc.info, Node: Missing Pieces, Prev: Continuing Stopped Jobs, Up: Implementing a Shell
--
--The Missing Pieces
--------------------
--
-- The code extracts for the sample shell included in this chapter are
--only a part of the entire shell program. In particular, nothing at all
--has been said about how `job' and `program' data structures are
--allocated and initialized.
--
-- Most real shells provide a complex user interface that has support
--for a command language; variables; abbreviations, substitutions, and
--pattern matching on file names; and the like. All of this is far too
--complicated to explain here! Instead, we have concentrated on showing
--how to implement the core process creation and job control functions
--that can be called from such a shell.
--
-- Here is a table summarizing the major entry points we have presented:
--
--`void init_shell (void)'
-- Initialize the shell's internal state. *Note Initializing the
-- Shell::.
--
--`void launch_job (job *J, int FOREGROUND)'
-- Launch the job J as either a foreground or background job. *Note
-- Launching Jobs::.
--
--`void do_job_notification (void)'
-- Check for and report any jobs that have terminated or stopped.
-- Can be called synchronously or within a handler for `SIGCHLD'
-- signals. *Note Stopped and Terminated Jobs::.
--
--`void continue_job (job *J, int FOREGROUND)'
-- Continue the job J. *Note Continuing Stopped Jobs::.
--
-- Of course, a real shell would also want to provide other functions
--for managing jobs. For example, it would be useful to have commands to
--list all active jobs or to send a signal (such as `SIGKILL') to a job.
--
--
--File: libc.info, Node: Functions for Job Control, Prev: Implementing a Shell, Up: Job Control
--
--Functions for Job Control
--=========================
--
-- This section contains detailed descriptions of the functions relating
--to job control.
--
--* Menu:
--
--* Identifying the Terminal:: Determining the controlling terminal's name.
--* Process Group Functions:: Functions for manipulating process groups.
--* Terminal Access Functions:: Functions for controlling terminal access.
--
--
--File: libc.info, Node: Identifying the Terminal, Next: Process Group Functions, Up: Functions for Job Control
--
--Identifying the Controlling Terminal
--------------------------------------
--
-- You can use the `ctermid' function to get a file name that you can
--use to open the controlling terminal. In the GNU library, it returns
--the same string all the time: `"/dev/tty"'. That is a special "magic"
--file name that refers to the controlling terminal of the current
--process (if it has one). To find the name of the specific terminal
--device, use `ttyname'; *note Is It a Terminal::..
--
-- The function `ctermid' is declared in the header file `stdio.h'.
--
-- - Function: char * ctermid (char *STRING)
-- The `ctermid' function returns a string containing the file name of
-- the controlling terminal for the current process. If STRING is
-- not a null pointer, it should be an array that can hold at least
-- `L_ctermid' characters; the string is returned in this array.
-- Otherwise, a pointer to a string in a static area is returned,
-- which might get overwritten on subsequent calls to this function.
--
-- An empty string is returned if the file name cannot be determined
-- for any reason. Even if a file name is returned, access to the
-- file it represents is not guaranteed.
--
-- - Macro: int L_ctermid
-- The value of this macro is an integer constant expression that
-- represents the size of a string large enough to hold the file name
-- returned by `ctermid'.
--
-- See also the `isatty' and `ttyname' functions, in *Note Is It a
--Terminal::.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-38 glibc-2.1.3/manual/libc.info-38
---- ../glibc-2.1.3/manual/libc.info-38 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-38 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1195 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Process Group Functions, Next: Terminal Access Functions, Prev: Identifying the Terminal, Up: Functions for Job Control
--
--Process Group Functions
-------------------------
--
-- Here are descriptions of the functions for manipulating process
--groups. Your program should include the header files `sys/types.h' and
--`unistd.h' to use these functions.
--
-- - Function: pid_t setsid (void)
-- The `setsid' function creates a new session. The calling process
-- becomes the session leader, and is put in a new process group whose
-- process group ID is the same as the process ID of that process.
-- There are initially no other processes in the new process group,
-- and no other process groups in the new session.
--
-- This function also makes the calling process have no controlling
-- terminal.
--
-- The `setsid' function returns the new process group ID of the
-- calling process if successful. A return value of `-1' indicates an
-- error. The following `errno' error conditions are defined for this
-- function:
--
-- `EPERM'
-- The calling process is already a process group leader, or
-- there is already another process group around that has the
-- same process group ID.
--
-- - Function: pid_t getsid (pid_t PID)
-- The `getsid' function returns the process group ID of the session
-- leader of the specified process. If a PID is `0', the process
-- group ID of the session leader of the current process is returned.
--
-- In case of error `-1' is returned and `errno' is set. The
-- following `errno' error conditions are defined for this function:
--
-- `ESRCH'
-- There is no process with the given process ID PID.
--
-- `EPERM'
-- The calling process and the process specified by PID are in
-- different sessions, and the implementation doesn't allow to
-- access the process group ID of the session leader of the
-- process with ID PID from the calling process.
--
-- The `getpgrp' function has two definitions: one derived from BSD
--Unix, and one from the POSIX.1 standard. The feature test macros you
--have selected (*note Feature Test Macros::.) determine which definition
--you get. Specifically, you get the BSD version if you define
--`_BSD_SOURCE'; otherwise, you get the POSIX version if you define
--`_POSIX_SOURCE' or `_GNU_SOURCE'. Programs written for old BSD systems
--will not include `unistd.h', which defines `getpgrp' specially under
--`_BSD_SOURCE'. You must link such programs with the `-lbsd-compat'
--option to get the BSD definition.
--
-- - POSIX.1 Function: pid_t getpgrp (void)
-- The POSIX.1 definition of `getpgrp' returns the process group ID of
-- the calling process.
--
-- - BSD Function: pid_t getpgrp (pid_t PID)
-- The BSD definition of `getpgrp' returns the process group ID of the
-- process PID. You can supply a value of `0' for the PID argument
-- to get information about the calling process.
--
-- - System V Function: int getpgid (pid_t PID)
-- `getpgid' is the same as the BSD function `getpgrp'. It returns
-- the process group ID of the process PID. You can supply a value
-- of `0' for the PID argument to get information about the calling
-- process.
--
-- In case of error `-1' is returned and `errno' is set. The
-- following `errno' error conditions are defined for this function:
--
-- `ESRCH'
-- There is no process with the given process ID PID. The
-- calling process and the process specified by PID are in
-- different sessions, and the implementation doesn't allow to
-- access the process group ID of the process with ID PID from
-- the calling process.
--
-- - Function: int setpgid (pid_t PID, pid_t PGID)
-- The `setpgid' function puts the process PID into the process group
-- PGID. As a special case, either PID or PGID can be zero to
-- indicate the process ID of the calling process.
--
-- This function fails on a system that does not support job control.
-- *Note Job Control is Optional::, for more information.
--
-- If the operation is successful, `setpgid' returns zero. Otherwise
-- it returns `-1'. The following `errno' error conditions are
-- defined for this function:
--
-- `EACCES'
-- The child process named by PID has executed an `exec'
-- function since it was forked.
--
-- `EINVAL'
-- The value of the PGID is not valid.
--
-- `ENOSYS'
-- The system doesn't support job control.
--
-- `EPERM'
-- The process indicated by the PID argument is a session leader,
-- or is not in the same session as the calling process, or the
-- value of the PGID argument doesn't match a process group ID
-- in the same session as the calling process.
--
-- `ESRCH'
-- The process indicated by the PID argument is not the calling
-- process or a child of the calling process.
--
-- - Function: int setpgrp (pid_t PID, pid_t PGID)
-- This is the BSD Unix name for `setpgid'. Both functions do exactly
-- the same thing.
--
--
--File: libc.info, Node: Terminal Access Functions, Prev: Process Group Functions, Up: Functions for Job Control
--
--Functions for Controlling Terminal Access
-------------------------------------------
--
-- These are the functions for reading or setting the foreground
--process group of a terminal. You should include the header files
--`sys/types.h' and `unistd.h' in your application to use these functions.
--
-- Although these functions take a file descriptor argument to specify
--the terminal device, the foreground job is associated with the terminal
--file itself and not a particular open file descriptor.
--
-- - Function: pid_t tcgetpgrp (int FILEDES)
-- This function returns the process group ID of the foreground
-- process group associated with the terminal open on descriptor
-- FILEDES.
--
-- If there is no foreground process group, the return value is a
-- number greater than `1' that does not match the process group ID
-- of any existing process group. This can happen if all of the
-- processes in the job that was formerly the foreground job have
-- terminated, and no other job has yet been moved into the
-- foreground.
--
-- In case of an error, a value of `-1' is returned. The following
-- `errno' error conditions are defined for this function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `ENOSYS'
-- The system doesn't support job control.
--
-- `ENOTTY'
-- The terminal file associated with the FILEDES argument isn't
-- the controlling terminal of the calling process.
--
-- - Function: int tcsetpgrp (int FILEDES, pid_t PGID)
-- This function is used to set a terminal's foreground process group
-- ID. The argument FILEDES is a descriptor which specifies the
-- terminal; PGID specifies the process group. The calling process
-- must be a member of the same session as PGID and must have the same
-- controlling terminal.
--
-- For terminal access purposes, this function is treated as output.
-- If it is called from a background process on its controlling
-- terminal, normally all processes in the process group are sent a
-- `SIGTTOU' signal. The exception is if the calling process itself
-- is ignoring or blocking `SIGTTOU' signals, in which case the
-- operation is performed and no signal is sent.
--
-- If successful, `tcsetpgrp' returns `0'. A return value of `-1'
-- indicates an error. The following `errno' error conditions are
-- defined for this function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `EINVAL'
-- The PGID argument is not valid.
--
-- `ENOSYS'
-- The system doesn't support job control.
--
-- `ENOTTY'
-- The FILEDES isn't the controlling terminal of the calling
-- process.
--
-- `EPERM'
-- The PGID isn't a process group in the same session as the
-- calling process.
--
-- - Function: pid_t tcgetsid (int FILDES)
-- This function is used to obtain the process group ID of the session
-- for which terminal specified by FILDES is the controlling terminal.
-- If the call is successful the group ID is returned. Otherwise the
-- return value is `(pid_t) -1' and the global variable ERRNO is set
-- to the following value:
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `ENOTTY'
-- The calling process does not have a controlling terminal, or
-- the file ins not the controlling terminal.
--
--
--File: libc.info, Node: Name Service Switch, Next: Users and Groups, Prev: Job Control, Up: Top
--
--System Databases and Name Service Switch
--****************************************
--
-- Various functions in the C Library need to be configured to work
--correctly in the local environment. Traditionally, this was done by
--using files (e.g., `/etc/passwd'), but other nameservices (like the
--Network Information Service (NIS) and the Domain Name Service (DNS))
--became popular, and were hacked into the C library, usually with a fixed
--search order (*note frobnicate: (jargon)frobnicate.).
--
-- The GNU C Library contains a cleaner solution of this problem. It is
--designed after a method used by Sun Microsystems in the C library of
--Solaris 2. GNU C Library follows their name and calls this scheme
--"Name Service Switch" (NSS).
--
-- Though the interface might be similar to Sun's version there is no
--common code. We never saw any source code of Sun's implementation and
--so the internal interface is incompatible. This also manifests in the
--file names we use as we will see later.
--
--* Menu:
--
--* NSS Basics:: What is this NSS good for.
--* NSS Configuration File:: Configuring NSS.
--* NSS Module Internals:: How does it work internally.
--* Extending NSS:: What to do to add services or databases.
--
--
--File: libc.info, Node: NSS Basics, Next: NSS Configuration File, Prev: Name Service Switch, Up: Name Service Switch
--
--NSS Basics
--==========
--
-- The basic idea is to put the implementation of the different services
--offered to access the databases in separate modules. This has some
--advantages:
--
-- 1. Contributors can add new services without adding them to GNU C
-- Library.
--
-- 2. The modules can be updated separately.
--
-- 3. The C library image is smaller.
--
-- To fulfill the first goal above the ABI of the modules will be
--described below. For getting the implementation of a new service right
--it is important to understand how the functions in the modules get
--called. They are in no way designed to be used by the programmer
--directly. Instead the programmer should only use the documented and
--standardized functions to access the databases.
--
--The databases available in the NSS are
--
--`aliases'
-- Mail aliases
--
--`ethers'
-- Ethernet numbers,
--
--`group'
-- Groups of users, *note Group Database::..
--
--`hosts'
-- Host names and numbers, *note Host Names::..
--
--`netgroup'
-- Network wide list of host and users, *note Netgroup Database::..
--
--`networks'
-- Network names and numbers, *note Networks Database::..
--
--`protocols'
-- Network protocols, *note Protocols Database::..
--
--`passwd'
-- User passwords, *note User Database::..
--
--`rpc'
-- Remote procedure call names and numbers,
--
--`services'
-- Network services, *note Services Database::..
--
--`shadow'
-- Shadow user passwords,
--
--There will be some more added later (`automount', `bootparams',
--`netmasks', and `publickey').
--
--
--File: libc.info, Node: NSS Configuration File, Next: NSS Module Internals, Prev: NSS Basics, Up: Name Service Switch
--
--The NSS Configuration File
--==========================
--
-- Somehow the NSS code must be told about the wishes of the user. For
--this reason there is the file `/etc/nsswitch.conf'. For each database
--this file contain a specification how the lookup process should work.
--The file could look like this:
--
-- # /etc/nsswitch.conf
-- #
-- # Name Service Switch configuration file.
-- #
--
-- passwd: db files nis
-- shadow: files
-- group: db files nis
--
-- hosts: files nisplus nis dns
-- networks: nisplus [NOTFOUND=return] files
--
-- ethers: nisplus [NOTFOUND=return] db files
-- protocols: nisplus [NOTFOUND=return] db files
-- rpc: nisplus [NOTFOUND=return] db files
-- services: nisplus [NOTFOUND=return] db files
--
-- The first column is the database as you can guess from the table
--above. The rest of the line specifies how the lookup process works.
--Please note that you specify the way it works for each database
--individually. This cannot be done with the old way of a monolithic
--implementation.
--
-- The configuration specification for each database can contain two
--different items:
--
-- * the service specification like `files', `db', or `nis'.
--
-- * the reaction on lookup result like `[NOTFOUND=return]'.
--
--* Menu:
--
--* Services in the NSS configuration:: Service names in the NSS configuration.
--* Actions in the NSS configuration:: React appropriately to the lookup result.
--* Notes on NSS Configuration File:: Things to take care about while
-- configuring NSS.
--
--
--File: libc.info, Node: Services in the NSS configuration, Next: Actions in the NSS configuration, Prev: NSS Configuration File, Up: NSS Configuration File
--
--Services in the NSS configuration File
----------------------------------------
--
-- The above example file mentions four different services: `files',
--`db', `nis', and `nisplus'. This does not mean these services are
--available on all sites and it does also not mean these are all the
--services which will ever be available.
--
-- In fact, these names are simply strings which the NSS code uses to
--find the implicitly addressed functions. The internal interface will be
--described later. Visible to the user are the modules which implement an
--individual service.
--
-- Assume the service NAME shall be used for a lookup. The code for
--this service is implemented in a module called `libnss_NAME'. On a
--system supporting shared libraries this is in fact a shared library
--with the name (for example) `libnss_NAME.so.2'. The number at the end
--is the currently used version of the interface which will not change
--frequently. Normally the user should not have to be cognizant of these
--files since they should be placed in a directory where they are found
--automatically. Only the names of all available services are important.
--
--
--File: libc.info, Node: Actions in the NSS configuration, Next: Notes on NSS Configuration File, Prev: Services in the NSS configuration, Up: NSS Configuration File
--
--Actions in the NSS configuration
----------------------------------
--
-- The second item in the specification gives the user much finer
--control on the lookup process. Action items are placed between two
--service names and are written within brackets. The general form is
--
-- `[' ( `!'? STATUS `=' ACTION )+ `]'
--
--where
--
-- STATUS => success | notfound | unavail | tryagain
-- ACTION => return | continue
--
-- The case of the keywords is insignificant. The STATUS values are
--the results of a call to a lookup function of a specific service. They
--mean
--
--`success'
-- No error occurred and the wanted entry is returned. The default
-- action for this is `return'.
--
--`notfound'
-- The lookup process works ok but the needed value was not found.
-- The default action is `continue'.
--
--`unavail'
-- The service is permanently unavailable. This can either mean the
-- needed file is not available, or, for DNS, the server is not
-- available or does not allow queries. The default action is
-- `continue'.
--
--`tryagain'
-- The service is temporarily unavailable. This could mean a file is
-- locked or a server currently cannot accept more connections. The
-- default action is `continue'.
--
--If we have a line like
--
-- ethers: nisplus [NOTFOUND=return] db files
--
--this is equivalent to
--
-- ethers: nisplus [SUCCESS=return NOTFOUND=return UNAVAIL=continue
-- TRYAGAIN=continue]
-- db [SUCCESS=return NOTFOUND=continue UNAVAIL=continue
-- TRYAGAIN=continue]
-- files
--
--(except that it would have to be written on one line). The default
--value for the actions are normally what you want, and only need to be
--changed in exceptional cases.
--
-- If the optional `!' is placed before the STATUS this means the
--following action is used for all statuses but STATUS itself. I.e., `!'
--is negation as in the C language (and others).
--
-- Before we explain the exception which makes this action item
--necessary one more remark: obviously it makes no sense to add another
--action item after the `files' service. Since there is no other service
--following the action *always* is `return'.
--
-- Now, why is this `[NOTFOUND=return]' action useful? To understand
--this we should know that the `nisplus' service is often complete; i.e.,
--if an entry is not available in the NIS+ tables it is not available
--anywhere else. This is what is expressed by this action item: it is
--useless to examine further services since they will not give us a
--result.
--
-- The situation would be different if the NIS+ service is not available
--because the machine is booting. In this case the return value of the
--lookup function is not `notfound' but instead `unavail'. And as you
--can see in the complete form above: in this situation the `db' and
--`files' services are used. Neat, isn't it? The system administrator
--need not pay special care for the time the system is not completely
--ready to work (while booting or shutdown or network problems).
--
--
--File: libc.info, Node: Notes on NSS Configuration File, Prev: Actions in the NSS configuration, Up: NSS Configuration File
--
--Notes on the NSS Configuration File
-------------------------------------
--
-- Finally a few more hints. The NSS implementation is not completely
--helpless if `/etc/nsswitch.conf' does not exist. For all supported
--databases there is a default value so it should normally be possible to
--get the system running even if the file is corrupted or missing.
--
-- For the `hosts' and `networks' databases the default value is `dns
--[!UNAVAIL=return] files'. I.e., the system is prepared for the DNS
--service not to be available but if it is available the answer it
--returns is ultimative.
--
-- The `passwd', `group', and `shadow' databases are traditionally
--handled in a special way. The appropriate files in the `/etc'
--directory are read but if an entry with a name starting with a `+'
--character is found NIS is used. This kind of lookup remains possible
--by using the special lookup service `compat' and the default value for
--the three databases above is `compat [NOTFOUND=return] files'.
--
-- For all other databases the default value is `nis [NOTFOUND=return]
--files'. This solution give the best chance to be correct since NIS and
--file based lookup is used.
--
-- A second point is that the user should try to optimize the lookup
--process. The different service have different response times. A
--simple file look up on a local file could be fast, but if the file is
--long and the needed entry is near the end of the file this may take
--quite some time. In this case it might be better to use the `db'
--service which allows fast local access to large data sets.
--
-- Often the situation is that some global information like NIS must be
--used. So it is unavoidable to use service entries like `nis' etc. But
--one should avoid slow services like this if possible.
--
--
--File: libc.info, Node: NSS Module Internals, Next: Extending NSS, Prev: NSS Configuration File, Up: Name Service Switch
--
--NSS Module Internals
--====================
--
-- Now it is time to described how the modules look like. The functions
--contained in a module are identified by their names. I.e., there is no
--jump table or the like. How this is done is of no interest here; those
--interested in this topic should read about Dynamic Linking.
--
--* Menu:
--
--* NSS Module Names:: Construction of the interface function of
-- the NSS modules.
--* NSS Modules Interface:: Programming interface in the NSS module
-- functions.
--
--
--File: libc.info, Node: NSS Module Names, Next: NSS Modules Interface, Prev: NSS Module Internals, Up: NSS Module Internals
--
--The Naming Scheme of the NSS Modules
--------------------------------------
--
--The name of each function consist of various parts:
--
-- _nss_SERVICE_FUNCTION
--
-- SERVICE of course corresponds to the name of the module this
--function is found in.(1) The FUNCTION part is derived from the
--interface function in the C library itself. If the user calls the
--function `gethostbyname' and the service used is `files' the function
--
-- _nss_files_gethostbyname_r
--
--in the module
--
-- libnss_files.so.2
--
--is used. You see, what is explained above in not the whole truth. In
--fact the NSS modules only contain reentrant versions of the lookup
--functions. I.e., if the user would call the `gethostbyname_r' function
--this also would end in the above function. For all user interface
--functions the C library maps this call to a call to the reentrant
--function. For reentrant functions this is trivial since the interface
--is (nearly) the same. For the non-reentrant version The library keeps
--internal buffers which are used to replace the user supplied buffer.
--
-- I.e., the reentrant functions *can* have counterparts. No service
--module is forced to have functions for all databases and all kinds to
--access them. If a function is not available it is simply treated as if
--the function would return `unavail' (*note Actions in the NSS
--configuration::.).
--
-- The file name `libnss_files.so.2' would be on a Solaris 2 system
--`nss_files.so.2'. This is the difference mentioned above. Sun's NSS
--modules are usable as modules which get indirectly loaded only.
--
-- The NSS modules in the GNU C Library are prepared to be used as
--normal libraries itself. This is *not* true in the moment, though.
--But the different organization of the name space in the modules does
--not make it impossible like it is for Solaris. Now you can see why the
--modules are still libraries.(2)
--
-- ---------- Footnotes ----------
--
-- (1) Now you might ask why to duplicate this information. The answer
--is that we want to keep the possibility to link directly with these
--shared objects.
--
-- (2) There is a second explanation: we were too lazy to change the
--Makefiles to allow the generation of shared objects not starting with
--`lib' but do not tell this anybody.
--
--
--File: libc.info, Node: NSS Modules Interface, Prev: NSS Module Names, Up: NSS Module Internals
--
--The Interface of the Function in NSS Modules
----------------------------------------------
--
-- Now we know about the functions contained in the modules. It is now
--time to describe the types. When we mentioned the reentrant versions of
--the functions above, this means there are some additional arguments
--(compared with the standard, non-reentrant version). The prototypes for
--the non-reentrant and reentrant versions of our function above are:
--
-- struct hostent *gethostbyname (const char *name)
--
-- int gethostbyname_r (const char *name, struct hostent *result_buf,
-- char *buf, size_t buflen, struct hostent **result,
-- int *h_errnop)
--
--The actual prototype of the function in the NSS modules in this case is
--
-- enum nss_status _nss_files_gethostbyname_r (const char *name,
-- struct hostent *result_buf,
-- char *buf, size_t buflen,
-- int *errnop, int *h_errnop)
--
-- I.e., the interface function is in fact the reentrant function with
--the change of the return value and the omission of the RESULT
--parameter. While the user-level function returns a pointer to the
--result the reentrant function return an `enum nss_status' value:
--
--`NSS_STATUS_TRYAGAIN'
-- numeric value `-2'
--
--`NSS_STATUS_UNAVAIL'
-- numeric value `-1'
--
--`NSS_STATUS_NOTFOUND'
-- numeric value `0'
--
--`NSS_STATUS_SUCCESS'
-- numeric value `1'
--
--Now you see where the action items of the `/etc/nsswitch.conf' file are
--used.
--
-- If you study the source code you will find there is a fifth value:
--`NSS_STATUS_RETURN'. This is an internal use only value, used by a few
--functions in places where none of the above value can be used. If
--necessary the source code should be examined to learn about the details.
--
-- In case the interface function has to return an error it is important
--that the correct error code is stored in `*ERRNOP'. Some return status
--value have only one associated error code, others have more.
--
--`NSS_STATUS_TRYAGAIN' `EAGAIN' One functions used ran temporarily
-- out of resources or a service is
-- currently not available.
-- `ERANGE' The provided buffer is not large
-- enough. The function should be
-- called again with a larger buffer.
--`NSS_STATUS_UNAVAIL' `ENOENT' A necessary input file cannot be
-- found.
--`NSS_STATUS_NOTFOUND' `ENOENT' The requested entry is not
-- available.
--
-- These are proposed values. There can be other error codes and the
--described error codes can have different meaning. *With one
--exception:* when returning `NSS_STATUS_TRYAGAIN' the error code
--`ERANGE' *must* mean that the user provided buffer is too small.
--Everything is non-critical.
--
-- The above function has something special which is missing for almost
--all the other module functions. There is an argument H_ERRNOP. This
--points to a variable which will be filled with the error code in case
--the execution of the function fails for some reason. The reentrant
--function cannot use the global variable H_ERRNO; `gethostbyname' calls
--`gethostbyname_r' with the last argument set to `&h_errno'.
--
-- The `getXXXbyYYY' functions are the most important functions in the
--NSS modules. But there are others which implement the other ways to
--access system databases (say for the password database, there are
--`setpwent', `getpwent', and `endpwent'). These will be described in
--more detail later. Here we give a general way to determine the
--signature of the module function:
--
-- * the return value is `int';
--
-- * the name is as explain in *note NSS Module Names::.;
--
-- * the first arguments are identical to the arguments of the
-- non-reentrant function;
--
-- * the next three arguments are:
--
-- `STRUCT_TYPE *result_buf'
-- pointer to buffer where the result is stored. `STRUCT_TYPE'
-- is normally a struct which corresponds to the database.
--
-- `char *buffer'
-- pointer to a buffer where the function can store additional
-- adata for the result etc.
--
-- `size_t buflen'
-- length of the buffer pointed to by BUFFER.
--
-- * possibly a last argument H_ERRNOP, for the host name and network
-- name lookup functions.
--
--This table is correct for all functions but the `set...ent' and
--`end...ent' functions.
--
--
--File: libc.info, Node: Extending NSS, Prev: NSS Module Internals, Up: Name Service Switch
--
--Extending NSS
--=============
--
-- One of the advantages of NSS mentioned above is that it can be
--extended quite easily. There are two ways in which the extension can
--happen: adding another database or adding another service. The former
--is normally done only by the C library developers. It is here only
--important to remember that adding another database is independent from
--adding another service because a service need not support all databases
--or lookup functions.
--
-- A designer/implementor of a new service is therefore free to choose
--the databases s/he is interested in and leave the rest for later (or
--completely aside).
--
--* Menu:
--
--* Adding another Service to NSS:: What is to do to add a new service.
--* NSS Module Function Internals:: Guidelines for writing new NSS
-- service functions.
--
--
--File: libc.info, Node: Adding another Service to NSS, Next: NSS Module Function Internals, Prev: Extending NSS, Up: Extending NSS
--
--Adding another Service to NSS
-------------------------------
--
-- The sources for a new service need not (and should not) be part of
--the GNU C Library itself. The developer retains complete control over
--the sources and its development. The links between the C library and
--the new service module consists solely of the interface functions.
--
-- Each module is designed following a specific interface specification.
--For now the version is 2 (the interface in version 1 was not adequate)
--and this manifests in the version number of the shared library object of
--the NSS modules: they have the extension `.2'. If the interface
--changes again in an incompatible way, this number will be increased.
--Modules using the old interface will still be usable.
--
-- Developers of a new service will have to make sure that their module
--is created using the correct interface number. This means the file
--itself must have the correct name and on ElF systems the "soname"
--(Shared Object Name) must also have this number. Building a module
--from a bunch of object files on an ELF system using GNU CC could be
--done like this:
--
-- gcc -shared -o libnss_NAME.so.2 -Wl,-soname,libnss_NAME.so.2 OBJECTS
--
--*Note Options for Linking: (gcc)Link Options, to learn more about this
--command line.
--
-- To use the new module the library must be able to find it. This can
--be achieved by using options for the dynamic linker so that it will
--search directory where the binary is placed. For an ELF system this
--could be done by adding the wanted directory to the value of
--`LD_LIBRARY_PATH'.
--
-- But this is not always possible since some program (those which run
--under IDs which do not belong to the user) ignore this variable.
--Therefore the stable version of the module should be placed into a
--directory which is searched by the dynamic linker. Normally this should
--be the directory `$prefix/lib', where `$prefix' corresponds to the
--value given to configure using the `--prefix' option. But be careful:
--this should only be done if it is clear the module does not cause any
--harm. System administrators should be careful.
--
--
--File: libc.info, Node: NSS Module Function Internals, Prev: Adding another Service to NSS, Up: Extending NSS
--
--Internals of the NSS Module Functions
---------------------------------------
--
-- Until now we only provided the syntactic interface for the functions
--in the NSS module. In fact there is not more much we can tell since the
--implementation obviously is different for each function. But a few
--general rules must be followed by all functions.
--
-- In fact there are four kinds of different functions which may appear
--in the interface. All derive from the traditional ones for system
--databases. DB in the following table is normally an abbreviation for
--the database (e.g., it is `pw' for the password database).
--
--`enum nss_status _nss_DATABASE_setDBent (void)'
-- This function prepares the service for following operations. For a
-- simple file based lookup this means files could be opened, for
-- other services this function simply is a noop.
--
-- One special case for this function is that it takes an additional
-- argument for some DATABASEs (i.e., the interface is `int setDBent
-- (int)'). *Note Host Names::, which describes the `sethostent'
-- function.
--
-- The return value should be NSS_STATUS_SUCCESS or according to the
-- table above in case of an error (*note NSS Modules Interface::.).
--
--`enum nss_status _nss_DATABASE_endDBent (void)'
-- This function simply closes all files which are still open or
-- removes buffer caches. If there are no files or buffers to remove
-- this is again a simple noop.
--
-- There normally is no return value different to NSS_STATUS_SUCCESS.
--
--`enum nss_status _nss_DATABASE_getDBent_r (STRUCTURE *result, char *buffer, size_t buflen, int *errnop)'
-- Since this function will be called several times in a row to
-- retrieve one entry after the other it must keep some kind of
-- state. But this also means the functions are not really
-- reentrant. They are reentrant only in that simultaneous calls to
-- this function will not try to write the retrieved data in the same
-- place (as it would be the case for the non-reentrant functions);
-- instead, it writes to the structure pointed to by the RESULT
-- parameter. But the calls share a common state and in the case of
-- a file access this means they return neighboring entries in the
-- file.
--
-- The buffer of length BUFLEN pointed to by BUFFER can be used for
-- storing some additional data for the result. It is *not*
-- guaranteed that the same buffer will be passed for the next call
-- of this function. Therefore one must not misuse this buffer to
-- save some state information from one call to another.
--
-- Before the function returns the implementation should store the
-- value of the local ERRNO variable in the variable pointed to be
-- ERRNOP. This is important to guarantee the module working in
-- statically linked programs.
--
-- As explained above this function could also have an additional last
-- argument. This depends on the database used; it happens only for
-- `host' and `networks'.
--
-- The function shall return `NSS_STATUS_SUCCESS' as long as their are
-- more entries. When the last entry was read it should return
-- `NSS_STATUS_NOTFOUND'. When the buffer given as an argument is too
-- small for the data to be returned `NSS_STATUS_TRYAGAIN' should be
-- returned. When the service was not formerly initialized by a call
-- to `_nss_DATABASE_setDBent' all return value allowed for this
-- function can also be returned here.
--
--`enum nss_status _nss_DATABASE_getDBbyXX_r (PARAMS, STRUCTURE *result, char *buffer, size_t buflen, int *errnop)'
-- This function shall return the entry from the database which is
-- addressed by the PARAMS. The type and number of these arguments
-- vary. It must be individually determined by looking to the
-- user-level interface functions. All arguments given to the
-- non-reentrant version are here described by PARAMS.
--
-- The result must be stored in the structure pointed to by RESULT.
-- If there is additional data to return (say strings, where the
-- RESULT structure only contains pointers) the function must use the
-- BUFFER or length BUFLEN. There must not be any references to
-- non-constant global data.
--
-- The implementation of this function should honour the STAYOPEN
-- flag set by the `setDBent' function whenever this makes sense.
--
-- Before the function returns the implementation should store the
-- value of the local ERRNO variable in the variable pointed to be
-- ERRNOP. This is important to guarantee the module working in
-- statically linked programs.
--
-- Again, this function takes an additional last argument for the
-- `host' and `networks' database.
--
-- The return value should as always follow the rules given above
-- (*note NSS Modules Interface::.).
--
--
--File: libc.info, Node: Users and Groups, Next: System Information, Prev: Name Service Switch, Up: Top
--
--Users and Groups
--****************
--
-- Every user who can log in on the system is identified by a unique
--number called the "user ID". Each process has an effective user ID
--which says which user's access permissions it has.
--
-- Users are classified into "groups" for access control purposes. Each
--process has one or more "group ID values" which say which groups the
--process can use for access to files.
--
-- The effective user and group IDs of a process collectively form its
--"persona". This determines which files the process can access.
--Normally, a process inherits its persona from the parent process, but
--under special circumstances a process can change its persona and thus
--change its access permissions.
--
-- Each file in the system also has a user ID and a group ID. Access
--control works by comparing the user and group IDs of the file with those
--of the running process.
--
-- The system keeps a database of all the registered users, and another
--database of all the defined groups. There are library functions you
--can use to examine these databases.
--
--* Menu:
--
--* User and Group IDs:: Each user has a unique numeric ID;
-- likewise for groups.
--* Process Persona:: The user IDs and group IDs of a process.
--* Why Change Persona:: Why a program might need to change
-- its user and/or group IDs.
--* How Change Persona:: Changing the user and group IDs.
--* Reading Persona:: How to examine the user and group IDs.
--
--* Setting User ID:: Functions for setting the user ID.
--* Setting Groups:: Functions for setting the group IDs.
--
--* Enable/Disable Setuid:: Turning setuid access on and off.
--* Setuid Program Example:: The pertinent parts of one sample program.
--* Tips for Setuid:: How to avoid granting unlimited access.
--
--* Who Logged In:: Getting the name of the user who logged in,
-- or of the real user ID of the current process.
--
--* User Accounting Database:: Keeping information about users and various
-- actions in databases.
--
--* User Database:: Functions and data structures for
-- accessing the user database.
--* Group Database:: Functions and data structures for
-- accessing the group database.
--* Database Example:: Example program showing the use of database
-- inquiry functions.
--* Netgroup Database:: Functions for accessing the netgroup database.
--
--
--File: libc.info, Node: User and Group IDs, Next: Process Persona, Up: Users and Groups
--
--User and Group IDs
--==================
--
-- Each user account on a computer system is identified by a "user
--name" (or "login name") and "user ID". Normally, each user name has a
--unique user ID, but it is possible for several login names to have the
--same user ID. The user names and corresponding user IDs are stored in
--a data base which you can access as described in *Note User Database::.
--
-- Users are classified in "groups". Each user name belongs to one
--"default group" and may also belong to any number of "supplementary
--groups". Users who are members of the same group can share resources
--(such as files) that are not accessible to users who are not a member
--of that group. Each group has a "group name" and "group ID". *Note
--Group Database::, for how to find information about a group ID or group
--name.
--
--
--File: libc.info, Node: Process Persona, Next: Why Change Persona, Prev: User and Group IDs, Up: Users and Groups
--
--The Persona of a Process
--========================
--
-- At any time, each process has an "effective user ID", a "effective
--group ID", and a set of "supplementary group IDs". These IDs determine
--the privileges of the process. They are collectively called the
--"persona" of the process, because they determine "who it is" for
--purposes of access control.
--
-- Your login shell starts out with a persona which consists of your
--user ID, your default group ID, and your supplementary group IDs (if
--you are in more than one group). In normal circumstances, all your
--other processes inherit these values.
--
-- A process also has a "real user ID" which identifies the user who
--created the process, and a "real group ID" which identifies that user's
--default group. These values do not play a role in access control, so
--we do not consider them part of the persona. But they are also
--important.
--
-- Both the real and effective user ID can be changed during the
--lifetime of a process. *Note Why Change Persona::.
--
-- For details on how a process's effective user ID and group IDs affect
--its permission to access files, see *Note Access Permission::.
--
-- The effective user ID of a process also controls permissions for
--sending signals using the `kill' function. *Note Signaling Another
--Process::.
--
-- Finally, there are many operations which can only be performed by a
--process whose effective user ID is zero. A process with this user ID is
--a "privileged process". Commonly the user name `root' is associated
--with user ID 0, but there may be other user names with this ID.
--
--
--File: libc.info, Node: Why Change Persona, Next: How Change Persona, Prev: Process Persona, Up: Users and Groups
--
--Why Change the Persona of a Process?
--====================================
--
-- The most obvious situation where it is necessary for a process to
--change its user and/or group IDs is the `login' program. When `login'
--starts running, its user ID is `root'. Its job is to start a shell
--whose user and group IDs are those of the user who is logging in. (To
--accomplish this fully, `login' must set the real user and group IDs as
--well as its persona. But this is a special case.)
--
-- The more common case of changing persona is when an ordinary user
--program needs access to a resource that wouldn't ordinarily be
--accessible to the user actually running it.
--
-- For example, you may have a file that is controlled by your program
--but that shouldn't be read or modified directly by other users, either
--because it implements some kind of locking protocol, or because you want
--to preserve the integrity or privacy of the information it contains.
--This kind of restricted access can be implemented by having the program
--change its effective user or group ID to match that of the resource.
--
-- Thus, imagine a game program that saves scores in a file. The game
--program itself needs to be able to update this file no matter who is
--running it, but if users can write the file without going through the
--game, they can give themselves any scores they like. Some people
--consider this undesirable, or even reprehensible. It can be prevented
--by creating a new user ID and login name (say, `games') to own the
--scores file, and make the file writable only by this user. Then, when
--the game program wants to update this file, it can change its effective
--user ID to be that for `games'. In effect, the program must adopt the
--persona of `games' so it can write the scores file.
--
--
--File: libc.info, Node: How Change Persona, Next: Reading Persona, Prev: Why Change Persona, Up: Users and Groups
--
--How an Application Can Change Persona
--=====================================
--
-- The ability to change the persona of a process can be a source of
--unintentional privacy violations, or even intentional abuse. Because of
--the potential for problems, changing persona is restricted to special
--circumstances.
--
-- You can't arbitrarily set your user ID or group ID to anything you
--want; only privileged processes can do that. Instead, the normal way
--for a program to change its persona is that it has been set up in
--advance to change to a particular user or group. This is the function
--of the setuid and setgid bits of a file's access mode. *Note
--Permission Bits::.
--
-- When the setuid bit of an executable file is on, executing that file
--gives the process a third user ID: the "file user ID". This ID is set
--to the owner ID of the file. The system then changes the effective
--user ID to the file user ID. The real user ID remains as it was.
--Likewise, if the setgid bit is on, the process is given a "file group
--ID" equal to the group ID of the file, and its effective group ID is
--changed to the file group ID.
--
-- If a process has a file ID (user or group), then it can at any time
--change its effective ID to its real ID and back to its file ID.
--Programs use this feature to relinquish their special privileges except
--when they actually need them. This makes it less likely that they can
--be tricked into doing something inappropriate with their privileges.
--
-- *Portability Note:* Older systems do not have file IDs. To
--determine if a system has this feature, you can test the compiler
--define `_POSIX_SAVED_IDS'. (In the POSIX standard, file IDs are known
--as saved IDs.)
--
-- *Note File Attributes::, for a more general discussion of file modes
--and accessibility.
--
--
--File: libc.info, Node: Reading Persona, Next: Setting User ID, Prev: How Change Persona, Up: Users and Groups
--
--Reading the Persona of a Process
--================================
--
-- Here are detailed descriptions of the functions for reading the user
--and group IDs of a process, both real and effective. To use these
--facilities, you must include the header files `sys/types.h' and
--`unistd.h'.
--
-- - Data Type: uid_t
-- This is an integer data type used to represent user IDs. In the
-- GNU library, this is an alias for `unsigned int'.
--
-- - Data Type: gid_t
-- This is an integer data type used to represent group IDs. In the
-- GNU library, this is an alias for `unsigned int'.
--
-- - Function: uid_t getuid (void)
-- The `getuid' function returns the real user ID of the process.
--
-- - Function: gid_t getgid (void)
-- The `getgid' function returns the real group ID of the process.
--
-- - Function: uid_t geteuid (void)
-- The `geteuid' function returns the effective user ID of the
-- process.
--
-- - Function: gid_t getegid (void)
-- The `getegid' function returns the effective group ID of the
-- process.
--
-- - Function: int getgroups (int COUNT, gid_t *GROUPS)
-- The `getgroups' function is used to inquire about the supplementary
-- group IDs of the process. Up to COUNT of these group IDs are
-- stored in the array GROUPS; the return value from the function is
-- the number of group IDs actually stored. If COUNT is smaller than
-- the total number of supplementary group IDs, then `getgroups'
-- returns a value of `-1' and `errno' is set to `EINVAL'.
--
-- If COUNT is zero, then `getgroups' just returns the total number
-- of supplementary group IDs. On systems that do not support
-- supplementary groups, this will always be zero.
--
-- Here's how to use `getgroups' to read all the supplementary group
-- IDs:
--
-- gid_t *
-- read_all_groups (void)
-- {
-- int ngroups = getgroups (0, NULL);
-- gid_t *groups
-- = (gid_t *) xmalloc (ngroups * sizeof (gid_t));
-- int val = getgroups (ngroups, groups);
-- if (val < 0)
-- {
-- free (groups);
-- return NULL;
-- }
-- return groups;
-- }
--
--
--File: libc.info, Node: Setting User ID, Next: Setting Groups, Prev: Reading Persona, Up: Users and Groups
--
--Setting the User ID
--===================
--
-- This section describes the functions for altering the user ID (real
--and/or effective) of a process. To use these facilities, you must
--include the header files `sys/types.h' and `unistd.h'.
--
-- - Function: int seteuid (uid_t NEWEUID)
-- This function sets the effective user ID of a process to NEWUID,
-- provided that the process is allowed to change its effective user
-- ID. A privileged process (effective user ID zero) can change its
-- effective user ID to any legal value. An unprivileged process
-- with a file user ID can change its effective user ID to its real
-- user ID or to its file user ID. Otherwise, a process may not
-- change its effective user ID at all.
--
-- The `seteuid' function returns a value of `0' to indicate
-- successful completion, and a value of `-1' to indicate an error.
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EINVAL'
-- The value of the NEWUID argument is invalid.
--
-- `EPERM'
-- The process may not change to the specified ID.
--
-- Older systems (those without the `_POSIX_SAVED_IDS' feature) do not
-- have this function.
--
-- - Function: int setuid (uid_t NEWUID)
-- If the calling process is privileged, this function sets both the
-- real and effective user ID of the process to NEWUID. It also
-- deletes the file user ID of the process, if any. NEWUID may be any
-- legal value. (Once this has been done, there is no way to recover
-- the old effective user ID.)
--
-- If the process is not privileged, and the system supports the
-- `_POSIX_SAVED_IDS' feature, then this function behaves like
-- `seteuid'.
--
-- The return values and error conditions are the same as for
-- `seteuid'.
--
-- - Function: int setreuid (uid_t RUID, uid_t EUID)
-- This function sets the real user ID of the process to RUID and the
-- effective user ID to EUID. If RUID is `-1', it means not to
-- change the real user ID; likewise if EUID is `-1', it means not to
-- change the effective user ID.
--
-- The `setreuid' function exists for compatibility with 4.3 BSD Unix,
-- which does not support file IDs. You can use this function to
-- swap the effective and real user IDs of the process. (Privileged
-- processes are not limited to this particular usage.) If file IDs
-- are supported, you should use that feature instead of this
-- function. *Note Enable/Disable Setuid::.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error conditions are defined for this function:
--
-- `EPERM'
-- The process does not have the appropriate privileges; you do
-- not have permission to change to the specified ID.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-39 glibc-2.1.3/manual/libc.info-39
---- ../glibc-2.1.3/manual/libc.info-39 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-39 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1245 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Setting Groups, Next: Enable/Disable Setuid, Prev: Setting User ID, Up: Users and Groups
--
--Setting the Group IDs
--=====================
--
-- This section describes the functions for altering the group IDs (real
--and effective) of a process. To use these facilities, you must include
--the header files `sys/types.h' and `unistd.h'.
--
-- - Function: int setegid (gid_t NEWGID)
-- This function sets the effective group ID of the process to
-- NEWGID, provided that the process is allowed to change its group
-- ID. Just as with `seteuid', if the process is privileged it may
-- change its effective group ID to any value; if it isn't, but it
-- has a file group ID, then it may change to its real group ID or
-- file group ID; otherwise it may not change its effective group ID.
--
-- Note that a process is only privileged if its effective *user* ID
-- is zero. The effective group ID only affects access permissions.
--
-- The return values and error conditions for `setegid' are the same
-- as those for `seteuid'.
--
-- This function is only present if `_POSIX_SAVED_IDS' is defined.
--
-- - Function: int setgid (gid_t NEWGID)
-- This function sets both the real and effective group ID of the
-- process to NEWGID, provided that the process is privileged. It
-- also deletes the file group ID, if any.
--
-- If the process is not privileged, then `setgid' behaves like
-- `setegid'.
--
-- The return values and error conditions for `setgid' are the same
-- as those for `seteuid'.
--
-- - Function: int setregid (gid_t RGID, gid_t EGID)
-- This function sets the real group ID of the process to RGID and
-- the effective group ID to EGID. If RGID is `-1', it means not to
-- change the real group ID; likewise if EGID is `-1', it means not
-- to change the effective group ID.
--
-- The `setregid' function is provided for compatibility with 4.3 BSD
-- Unix, which does not support file IDs. You can use this function
-- to swap the effective and real group IDs of the process.
-- (Privileged processes are not limited to this usage.) If file IDs
-- are supported, you should use that feature instead of using this
-- function. *Note Enable/Disable Setuid::.
--
-- The return values and error conditions for `setregid' are the same
-- as those for `setreuid'.
--
-- `setuid' and `setgid' behave differently depending on whether the
--effective user ID at the time is zero. If it is not zero, they behave
--like `seteuid' and `setegid'. If it is, they change both effective and
--real IDs and delete the file ID. To avoid confusion, we recommend you
--always use `seteuid' and `setegid' except when you know the effective
--user ID is zero and your intent is to change the persona permanently.
--This case is rare--most of the programs that need it, such as `login'
--and `su', have already been written.
--
-- Note that if your program is setuid to some user other than `root',
--there is no way to drop privileges permanently.
--
-- The system also lets privileged processes change their supplementary
--group IDs. To use `setgroups' or `initgroups', your programs should
--include the header file `grp.h'.
--
-- - Function: int setgroups (size_t COUNT, gid_t *GROUPS)
-- This function sets the process's supplementary group IDs. It can
-- only be called from privileged processes. The COUNT argument
-- specifies the number of group IDs in the array GROUPS.
--
-- This function returns `0' if successful and `-1' on error. The
-- following `errno' error conditions are defined for this function:
--
-- `EPERM'
-- The calling process is not privileged.
--
-- - Function: int initgroups (const char *USER, gid_t GID)
-- The `initgroups' function sets the process's supplementary group
-- IDs to be the normal default for the user name USER. If GID is not
-- -1, it includes that group also.
--
-- This function works by scanning the group database for all the
-- groups USER belongs to. It then calls `setgroups' with the list it
-- has constructed.
--
-- The return values and error conditions are the same as for
-- `setgroups'.
--
--
--File: libc.info, Node: Enable/Disable Setuid, Next: Setuid Program Example, Prev: Setting Groups, Up: Users and Groups
--
--Enabling and Disabling Setuid Access
--====================================
--
-- A typical setuid program does not need its special access all of the
--time. It's a good idea to turn off this access when it isn't needed,
--so it can't possibly give unintended access.
--
-- If the system supports the `_POSIX_SAVED_IDS' feature, you can
--accomplish this with `seteuid'. When the game program starts, its real
--user ID is `jdoe', its effective user ID is `games', and its saved user
--ID is also `games'. The program should record both user ID values once
--at the beginning, like this:
--
-- user_user_id = getuid ();
-- game_user_id = geteuid ();
--
-- Then it can turn off game file access with
--
-- seteuid (user_user_id);
--
--and turn it on with
--
-- seteuid (game_user_id);
--
--Throughout this process, the real user ID remains `jdoe' and the file
--user ID remains `games', so the program can always set its effective
--user ID to either one.
--
-- On other systems that don't support file user IDs, you can turn
--setuid access on and off by using `setreuid' to swap the real and
--effective user IDs of the process, as follows:
--
-- setreuid (geteuid (), getuid ());
--
--This special case is always allowed--it cannot fail.
--
-- Why does this have the effect of toggling the setuid access?
--Suppose a game program has just started, and its real user ID is `jdoe'
--while its effective user ID is `games'. In this state, the game can
--write the scores file. If it swaps the two uids, the real becomes
--`games' and the effective becomes `jdoe'; now the program has only
--`jdoe' access. Another swap brings `games' back to the effective user
--ID and restores access to the scores file.
--
-- In order to handle both kinds of systems, test for the saved user ID
--feature with a preprocessor conditional, like this:
--
-- #ifdef _POSIX_SAVED_IDS
-- setuid (user_user_id);
-- #else
-- setreuid (geteuid (), getuid ());
-- #endif
--
--
--File: libc.info, Node: Setuid Program Example, Next: Tips for Setuid, Prev: Enable/Disable Setuid, Up: Users and Groups
--
--Setuid Program Example
--======================
--
-- Here's an example showing how to set up a program that changes its
--effective user ID.
--
-- This is part of a game program called `caber-toss' that manipulates
--a file `scores' that should be writable only by the game program
--itself. The program assumes that its executable file will be installed
--with the setuid bit set and owned by the same user as the `scores'
--file. Typically, a system administrator will set up an account like
--`games' for this purpose.
--
-- The executable file is given mode `4755', so that doing an `ls -l'
--on it produces output like:
--
-- -rwsr-xr-x 1 games 184422 Jul 30 15:17 caber-toss
--
--The setuid bit shows up in the file modes as the `s'.
--
-- The scores file is given mode `644', and doing an `ls -l' on it
--shows:
--
-- -rw-r--r-- 1 games 0 Jul 31 15:33 scores
--
-- Here are the parts of the program that show how to set up the changed
--user ID. This program is conditionalized so that it makes use of the
--file IDs feature if it is supported, and otherwise uses `setreuid' to
--swap the effective and real user IDs.
--
-- #include <stdio.h>
-- #include <sys/types.h>
-- #include <unistd.h>
-- #include <stdlib.h>
--
--
-- /* Remember the effective and real UIDs. */
--
-- static uid_t euid, ruid;
--
--
-- /* Restore the effective UID to its original value. */
--
-- void
-- do_setuid (void)
-- {
-- int status;
--
-- #ifdef _POSIX_SAVED_IDS
-- status = seteuid (euid);
-- #else
-- status = setreuid (ruid, euid);
-- #endif
-- if (status < 0) {
-- fprintf (stderr, "Couldn't set uid.\n");
-- exit (status);
-- }
-- }
-- /* Set the effective UID to the real UID. */
--
-- void
-- undo_setuid (void)
-- {
-- int status;
--
-- #ifdef _POSIX_SAVED_IDS
-- status = seteuid (ruid);
-- #else
-- status = setreuid (euid, ruid);
-- #endif
-- if (status < 0) {
-- fprintf (stderr, "Couldn't set uid.\n");
-- exit (status);
-- }
-- }
--
-- /* Main program. */
--
-- int
-- main (void)
-- {
-- /* Remember the real and effective user IDs. */
-- ruid = getuid ();
-- euid = geteuid ();
-- undo_setuid ();
--
-- /* Do the game and record the score. */
-- ...
-- }
--
-- Notice how the first thing the `main' function does is to set the
--effective user ID back to the real user ID. This is so that any other
--file accesses that are performed while the user is playing the game use
--the real user ID for determining permissions. Only when the program
--needs to open the scores file does it switch back to the file user ID,
--like this:
--
-- /* Record the score. */
--
-- int
-- record_score (int score)
-- {
-- FILE *stream;
-- char *myname;
--
-- /* Open the scores file. */
-- do_setuid ();
-- stream = fopen (SCORES_FILE, "a");
-- undo_setuid ();
-- /* Write the score to the file. */
-- if (stream)
-- {
-- myname = cuserid (NULL);
-- if (score < 0)
-- fprintf (stream, "%10s: Couldn't lift the caber.\n", myname);
-- else
-- fprintf (stream, "%10s: %d feet.\n", myname, score);
-- fclose (stream);
-- return 0;
-- }
-- else
-- return -1;
-- }
--
--
--File: libc.info, Node: Tips for Setuid, Next: Who Logged In, Prev: Setuid Program Example, Up: Users and Groups
--
--Tips for Writing Setuid Programs
--================================
--
-- It is easy for setuid programs to give the user access that isn't
--intended--in fact, if you want to avoid this, you need to be careful.
--Here are some guidelines for preventing unintended access and
--minimizing its consequences when it does occur:
--
-- * Don't have `setuid' programs with privileged user IDs such as
-- `root' unless it is absolutely necessary. If the resource is
-- specific to your particular program, it's better to define a new,
-- nonprivileged user ID or group ID just to manage that resource.
-- It's better if you can write your program to use a special group
-- than a special user.
--
-- * Be cautious about using the `exec' functions in combination with
-- changing the effective user ID. Don't let users of your program
-- execute arbitrary programs under a changed user ID. Executing a
-- shell is especially bad news. Less obviously, the `execlp' and
-- `execvp' functions are a potential risk (since the program they
-- execute depends on the user's `PATH' environment variable).
--
-- If you must `exec' another program under a changed ID, specify an
-- absolute file name (*note File Name Resolution::.) for the
-- executable, and make sure that the protections on that executable
-- and *all* containing directories are such that ordinary users
-- cannot replace it with some other program.
--
-- You should also check the arguments passed to the program to make
-- sure they do not have unexpected effects. Likewise, you should
-- examine the environment variables. Decide which arguments and
-- variables are safe, and reject all others.
--
-- You should never use `system' in a privileged program, because it
-- invokes a shell.
--
-- * Only use the user ID controlling the resource in the part of the
-- program that actually uses that resource. When you're finished
-- with it, restore the effective user ID back to the actual user's
-- user ID. *Note Enable/Disable Setuid::.
--
-- * If the `setuid' part of your program needs to access other files
-- besides the controlled resource, it should verify that the real
-- user would ordinarily have permission to access those files. You
-- can use the `access' function (*note Access Permission::.) to
-- check this; it uses the real user and group IDs, rather than the
-- effective IDs.
--
--
--File: libc.info, Node: Who Logged In, Next: User Accounting Database, Prev: Tips for Setuid, Up: Users and Groups
--
--Identifying Who Logged In
--=========================
--
-- You can use the functions listed in this section to determine the
--login name of the user who is running a process, and the name of the
--user who logged in the current session. See also the function `getuid'
--and friends (*note Reading Persona::.). How this information is
--collected by the system and how to control/add/remove information from
--the background storage is described in *Note User Accounting Database::.
--
-- The `getlogin' function is declared in `unistd.h', while `cuserid'
--and `L_cuserid' are declared in `stdio.h'.
--
-- - Function: char * getlogin (void)
-- The `getlogin' function returns a pointer to a string containing
-- the name of the user logged in on the controlling terminal of the
-- process, or a null pointer if this information cannot be
-- determined. The string is statically allocated and might be
-- overwritten on subsequent calls to this function or to `cuserid'.
--
-- - Function: char * cuserid (char *STRING)
-- The `cuserid' function returns a pointer to a string containing a
-- user name associated with the effective ID of the process. If
-- STRING is not a null pointer, it should be an array that can hold
-- at least `L_cuserid' characters; the string is returned in this
-- array. Otherwise, a pointer to a string in a static area is
-- returned. This string is statically allocated and might be
-- overwritten on subsequent calls to this function or to `getlogin'.
--
-- The use of this function is deprecated since it is marked to be
-- withdrawn in XPG4.2 and has already been removed from newer
-- revisions of POSIX.1.
--
-- - Macro: int L_cuserid
-- An integer constant that indicates how long an array you might
-- need to store a user name.
--
-- These functions let your program identify positively the user who is
--running or the user who logged in this session. (These can differ when
--setuid programs are involved; see *Note Process Persona::.) The user
--cannot do anything to fool these functions.
--
-- For most purposes, it is more useful to use the environment variable
--`LOGNAME' to find out who the user is. This is more flexible precisely
--because the user can set `LOGNAME' arbitrarily. *Note Standard
--Environment::.
--
--
--File: libc.info, Node: User Accounting Database, Next: User Database, Prev: Who Logged In, Up: Users and Groups
--
--The User Accounting Database
--============================
--
-- Most Unix-like operating systems keep track of logged in users by
--maintaining a user accounting database. This user accounting database
--stores for each terminal, who has logged on, at what time, the process
--ID of the user's login shell, etc., etc., but also stores information
--about the run level of the system, the time of the last system reboot,
--and possibly more.
--
-- The user accounting database typically lives in `/etc/utmp',
--`/var/adm/utmp' or `/var/run/utmp'. However, these files should
--*never* be accessed directly. For reading information from and writing
--information to the user accounting database, the functions described in
--this section should be used.
--
--* Menu:
--
--* Manipulating the Database:: Scanning and modifying the user
-- accounting database.
--* XPG Functions:: A standardized way for doing the same thing.
--* Logging In and Out:: Functions from BSD that modify the user
-- accounting database.
--
--
--File: libc.info, Node: Manipulating the Database, Next: XPG Functions, Up: User Accounting Database
--
--Manipulating the User Accounting Database
-------------------------------------------
--
-- These functions and the corresponding data structures are declared in
--the header file `utmp.h'.
--
-- - Data Type: struct exit_status
-- The `exit_status' data structure is used to hold information about
-- the exit status of processes marked as `DEAD_PROCESS' in the user
-- accounting database.
--
-- `short int e_termination'
-- The exit status of the process.
--
-- `short int e_exit'
-- The exit status of the process.
--
-- - Data Type: struct utmp
-- The `utmp' data structure is used to hold information about entries
-- in the user accounting database. On the GNU system it has the
-- following members:
--
-- `short int ut_type'
-- Specifies the type of login; one of `EMPTY', `RUN_LVL',
-- `BOOT_TIME', `OLD_TIME', `NEW_TIME', `INIT_PROCESS',
-- `LOGIN_PROCESS', `USER_PROCESS', `DEAD_PROCESS' or
-- `ACCOUNTING'.
--
-- `pid_t ut_pid'
-- The process ID number of the login process.
--
-- `char ut_line[]'
-- The device name of the tty (without `/dev/').
--
-- `char ut_id[]'
-- The inittab ID of the process.
--
-- `char ut_user[]'
-- The user's login name.
--
-- `char ut_host[]'
-- The name of the host from which the user logged in.
--
-- `struct exit_status ut_exit'
-- The exit status of a process marked as `DEAD_PROCESS'.
--
-- `long ut_session'
-- The Session ID, used for windowing.
--
-- `struct timeval ut_tv'
-- Time the entry was made. For entries of type `OLD_TIME' this
-- is the time when the system clock changed, and for entries of
-- type `NEW_TIME' this is the time the system clock was set to.
--
-- `int32_t ut_addr_v6[4]'
-- The Internet address of a remote host.
--
-- The `ut_type', `ut_pid', `ut_id', `ut_tv', and `ut_host' fields are
--not available on all systems. Portable applications therefore should
--be prepared for these situations. To help doing this the `utmp.h'
--header provides macros `_HAVE_UT_TYPE', `_HAVE_UT_PID', `_HAVE_UT_ID',
--`_HAVE_UT_TV', and `_HAVE_UT_HOST' if the respective field is
--available. The programmer can handle the situations by using `#ifdef'
--in the program code.
--
-- The following macros are defined for use as values for the `ut_type'
--member of the `utmp' structure. The values are integer constants.
--
--`EMPTY'
-- This macro is used to indicate that the entry contains no valid
-- user accounting information.
--
--`RUN_LVL'
-- This macro is used to identify the systems runlevel.
--
--`BOOT_TIME'
-- This macro is used to identify the time of system boot.
--
--`OLD_TIME'
-- This macro is used to identify the time when the system clock
-- changed.
--
--`NEW_TIME'
-- This macro is used to identify the time after the system changed.
--
--`INIT_PROCESS'
-- This macro is used to identify a process spawned by the init
-- process.
--
--`LOGIN_PROCESS'
-- This macro is used to identify the session leader of a logged in
-- user.
--
--`USER_PROCESS'
-- This macro is used to identify a user process.
--
--`DEAD_PROCESS'
-- This macro is used to identify a terminated process.
--
--`ACCOUNTING'
-- ???
--
-- The size of the `ut_line', `ut_id', `ut_user' and `ut_host' arrays
--can be found using the `sizeof' operator.
--
-- Many older systems have, instead of an `ut_tv' member, an `ut_time'
--member, usually of type `time_t', for representing the time associated
--with the entry. Therefore, for backwards compatibility only, `utmp.h'
--defines `ut_time' as an alias for `ut_tv.tv_sec'.
--
-- - Function: void setutent (void)
-- This function opens the user accounting database to begin scanning
-- it. You can then call `getutent', `getutid' or `getutline' to
-- read entries and `pututline' to write entries.
--
-- If the database is already open, it resets the input to the
-- beginning of the database.
--
-- - Function: struct utmp * getutent (void)
-- The `getutent' function reads the next entry from the user
-- accounting database. It returns a pointer to the entry, which is
-- statically allocated and may be overwritten by subsequent calls to
-- `getutent'. You must copy the contents of the structure if you
-- wish to save the information or you can use the `getutent_r'
-- function which stores the data in a user-provided buffer.
--
-- A null pointer is returned in case no further entry is available.
--
-- - Function: void endutent (void)
-- This function closes the user accounting database.
--
-- - Function: struct utmp * getutid (const struct utmp *ID)
-- This function searches forward from the current point in the
-- database for an entry that matches ID. If the `ut_type' member of
-- the ID structure is one of `RUN_LVL', `BOOT_TIME', `OLD_TIME' or
-- `NEW_TIME' the entries match if the `ut_type' members are
-- identical. If the `ut_type' member of the ID structure is
-- `INIT_PROCESS', `LOGIN_PROCESS', `USER_PROCESS' or `DEAD_PROCESS',
-- the entries match if the `ut_type' member of the entry read from
-- the database is one of these four, and the `ut_id' members match.
-- However if the `ut_id' member of either the ID structure or the
-- entry read from the database is empty it checks if the `ut_line'
-- members match instead. If a matching entry is found, `getutid'
-- returns a pointer to the entry, which is statically allocated, and
-- may be overwritten by a subsequent call to `getutent', `getutid'
-- or `getutline'. You must copy the contents of the structure if
-- you wish to save the information.
--
-- A null pointer is returned in case the end of the database is
-- reached without a match.
--
-- The `getutid' function may cache the last read entry. Therefore,
-- if you are using `getutid' to search for multiple occurrences, it
-- is necessary to zero out the static data after each call.
-- Otherwise `getutid' could just return a pointer to the same entry
-- over and over again.
--
-- - Function: struct utmp * getutline (const struct utmp *LINE)
-- This function searches forward from the current point in the
-- database until it finds an entry whose `ut_type' value is
-- `LOGIN_PROCESS' or `USER_PROCESS', and whose `ut_line' member
-- matches the `ut_line' member of the LINE structure. If it finds
-- such an entry, it returns a pointer to the entry which is
-- statically allocated, and may be overwritten by a subsequent call
-- to `getutent', `getutid' or `getutline'. You must copy the
-- contents of the structure if you wish to save the information.
--
-- A null pointer is returned in case the end of the database is
-- reached without a match.
--
-- The `getutline' function may cache the last read entry. Therefore
-- if you are using `getutline' to search for multiple occurrences, it
-- is necessary to zero out the static data after each call.
-- Otherwise `getutline' could just return a pointer to the same
-- entry over and over again.
--
-- - Function: struct utmp * pututline (const struct utmp *UTMP)
-- The `pututline' function inserts the entry `*UTMP' at the
-- appropriate place in the user accounting database. If it finds
-- that it is not already at the correct place in the database, it
-- uses `getutid' to search for the position to insert the entry,
-- however this will not modify the static structure returned by
-- `getutent', `getutid' and `getutline'. If this search fails, the
-- entry is appended to the database.
--
-- The `pututline' function returns a pointer to a copy of the entry
-- inserted in the user accounting database, or a null pointer if the
-- entry could not be added. The following `errno' error conditions
-- are defined for this function:
--
-- `EPERM'
-- The process does not have the appropriate privileges; you
-- cannot modify the user accounting database.
--
-- All the `get*' functions mentioned before store the information they
--return in a static buffer. This can be a problem in multi-threaded
--programs since the data return for the request is overwritten be the
--return value data in another thread. Therefore the GNU C Library
--provides as extensions three more functions which return the data in a
--user-provided buffer.
--
-- - Function: int getutent_r (struct utmp *BUFFER, struct utmp **RESULT)
-- The `getutent_r' is equivalent to the `getutent' function. It
-- returns the next entry from the database. But instead of storing
-- the information in a static buffer it stores it in the buffer
-- pointed to by the parameter BUFFER.
--
-- If the call was successful, the function returns `0' and the
-- pointer variable pointed to by the parameter RESULT contains a
-- pointer to the buffer which contains the result (this is most
-- probably the same value as BUFFER). If something went wrong
-- during the execution of `getutent_r' the function returns `-1'.
--
-- This function is a GNU extension.
--
-- - Function: int getutid_r (const struct utmp *ID, struct utmp *BUFFER,
-- struct utmp **RESULT)
-- This function retrieves just like `getutid' the next entry matching
-- the information stored in ID. But the result is stored in the
-- buffer pointed to by the parameter BUFFER.
--
-- If successful the function returns `0' and the pointer variable
-- pointed to by the parameter RESULT contains a pointer to the
-- buffer with the result (probably the same as RESULT. If not
-- successful the function return `-1'.
--
-- This function is a GNU extension.
--
-- - Function: int getutline_r (const struct utmp *LINE, struct utmp
-- *BUFFER, struct utmp **RESULT)
-- This function retrieves just like `getutline' the next entry
-- matching the information stored in LINE. But the result is stored
-- in the buffer pointed to by the parameter BUFFER.
--
-- If successful the function returns `0' and the pointer variable
-- pointed to by the parameter RESULT contains a pointer to the
-- buffer with the result (probably the same as RESULT. If not
-- successful the function return `-1'.
--
-- This function is a GNU extension.
--
-- In addition to the user accounting database, most systems keep a
--number of similar databases. For example most systems keep a log file
--with all previous logins (usually in `/etc/wtmp' or `/var/log/wtmp').
--
-- For specifying which database to examine, the following function
--should be used.
--
-- - Function: int utmpname (const char *FILE)
-- The `utmpname' function changes the name of the database to be
-- examined to FILE, and closes any previously opened database. By
-- default `getutent', `getutid', `getutline' and `pututline' read
-- from and write to the user accounting database.
--
-- The following macros are defined for use as the FILE argument:
--
-- - Macro: char * _PATH_UTMP
-- This macro is used to specify the user accounting database.
--
-- - Macro: char * _PATH_WTMP
-- This macro is used to specify the user accounting log file.
--
-- The `utmpname' function returns a value of `0' if the new name was
-- successfully stored, and a value of `-1' to indicate an error.
-- Note that `utmpname' does not try to open the database, and that
-- therefore the return value does not say anything about whether the
-- database can be successfully opened.
--
-- Specially for maintaining log-like databases the GNU C Library
--provides the following function:
--
-- - Function: void updwtmp (const char *WTMP_FILE, const struct utmp
-- *UTMP)
-- The `updwtmp' function appends the entry *UTMP to the database
-- specified by WTMP_FILE. For possible values for the WTMP_FILE
-- argument see the `utmpname' function.
--
-- *Portability Note:* Although many operating systems provide a subset
--of these functions, they are not standardized. There are often subtle
--differences in the return types, and there are considerable differences
--between the various definitions of `struct utmp'. When programming for
--the GNU system, it is probably best to stick with the functions
--described in this section. If however, you want your program to be
--portable, consider using the XPG functions described in *Note XPG
--Functions::, or take a look at the BSD compatible functions in *Note
--Logging In and Out::.
--
--
--File: libc.info, Node: XPG Functions, Next: Logging In and Out, Prev: Manipulating the Database, Up: User Accounting Database
--
--XPG User Accounting Database Functions
----------------------------------------
--
-- These functions, described in the X/Open Portability Guide, are
--declared in the header file `utmpx.h'.
--
-- - Data Type: struct utmpx
-- The `utmpx' data structure contains at least the following members:
--
-- `short int ut_type'
-- Specifies the type of login; one of `EMPTY', `RUN_LVL',
-- `BOOT_TIME', `OLD_TIME', `NEW_TIME', `INIT_PROCESS',
-- `LOGIN_PROCESS', `USER_PROCESS' or `DEAD_PROCESS'.
--
-- `pid_t ut_pid'
-- The process ID number of the login process.
--
-- `char ut_line[]'
-- The device name of the tty (without `/dev/').
--
-- `char ut_id[]'
-- The inittab ID of the process.
--
-- `char ut_user[]'
-- The user's login name.
--
-- `struct timeval ut_tv'
-- Time the entry was made. For entries of type `OLD_TIME' this
-- is the time when the system clock changed, and for entries of
-- type `NEW_TIME' this is the time the system clock was set to.
-- On the GNU system, `struct utmpx' is identical to `struct utmp'
-- except for the fact that including `utmpx.h' does not make visible
-- the declaration of `struct exit_status'.
--
-- The following macros are defined for use as values for the `ut_type'
--member of the `utmpx' structure. The values are integer constants and
--are, on the GNU system, identical to the definitions in `utmp.h'.
--
--`EMPTY'
-- This macro is used to indicate that the entry contains no valid
-- user accounting information.
--
--`RUN_LVL'
-- This macro is used to identify the systems runlevel.
--
--`BOOT_TIME'
-- This macro is used to identify the time of system boot.
--
--`OLD_TIME'
-- This macro is used to identify the time when the system clock
-- changed.
--
--`NEW_TIME'
-- This macro is used to identify the time after the system changed.
--
--`INIT_PROCESS'
-- This macro is used to identify a process spawned by the init
-- process.
--
--`LOGIN_PROCESS'
-- This macro is used to identify the session leader of a logged in
-- user.
--
--`USER_PROCESS'
-- This macro is used to identify a user process.
--
--`DEAD_PROCESS'
-- This macro is used to identify a terminated process.
--
-- The size of the `ut_line', `ut_id' and `ut_user' arrays can be found
--using the `sizeof' operator.
--
-- - Function: void setutxent (void)
-- This function is similar to `setutent'. On the GNU system it is
-- simply an alias for `setutent'.
--
-- - Function: struct utmpx * getutxent (void)
-- The `getutxent' function is similar to `getutent', but returns a
-- pointer to a `struct utmpx' instead of `struct utmp'. On the GNU
-- system it simply is an alias for `getutent'.
--
-- - Function: void endutxent (void)
-- This function is similar to `endutent'. On the GNU system it is
-- simply an alias for `endutent'.
--
-- - Function: struct utmpx * getutxid (const struct utmpx *ID)
-- This function is similar to `getutid', but uses `struct utmpx'
-- instead of `struct utmp'. On the GNU system it is simply an alias
-- for `getutid'.
--
-- - Function: struct utmpx * getutxline (const struct utmpx *LINE)
-- This function is similar to `getutid', but uses `struct utmpx'
-- instead of `struct utmp'. On the GNU system it is simply an alias
-- for `getutline'.
--
-- - Function: struct utmpx * pututxline (const struct utmpx *UTMP)
-- The `pututxline' function provides functionality identical to
-- `pututline', but uses `struct utmpx' instead of `struct utmp'. On
-- the GNU system `pututxline' is simply an alias for `pututline'.
--
--
--File: libc.info, Node: Logging In and Out, Prev: XPG Functions, Up: User Accounting Database
--
--Logging In and Out
--------------------
--
-- These functions, derived from BSD, are available in the separate
--`libutil' library, and declared in `utmp.h'.
--
-- Note that the `ut_user' member of `struct utmp' is called `ut_name'
--in BSD. Therefore, `ut_name' is defined as an alias for `ut_user' in
--`utmp.h'.
--
-- - Function: int login_tty (int FILEDES)
-- This function makes FILEDES the controlling terminal of the
-- current process, redirects standard input, standard output and
-- standard error output to this terminal, and closes FILEDES.
--
-- This function returns `0' on successful completion, and `-1' on
-- error.
--
-- - Function: void login (const struct utmp *ENTRY)
-- The `login' functions inserts an entry into the user accounting
-- database. The `ut_line' member is set to the name of the terminal
-- on standard input. If standard input is not a terminal `login'
-- uses standard output or standard error output to determine the
-- name of the terminal. If `struct utmp' has a `ut_type' member,
-- `login' sets it to `USER_PROCESS', and if there is an `ut_pid'
-- member, it will be set to the process ID of the current process.
-- The remaining entries are copied from ENTRY.
--
-- A copy of the entry is written to the user accounting log file.
--
-- - Function: int logout (const char *UT_LINE)
-- This function modifies the user accounting database to indicate
-- that the user on UT_LINE has logged out.
--
-- The `logout' function returns `1' if the entry was successfully
-- written to the database, or `0' on error.
--
-- - Function: void logwtmp (const char *UT_LINE, const char *UT_NAME,
-- const char *UT_HOST)
-- The `logwtmp' function appends an entry to the user accounting log
-- file, for the current time and the information provided in the
-- UT_LINE, UT_NAME and UT_HOST arguments.
--
-- *Portability Note:* The BSD `struct utmp' only has the `ut_line',
--`ut_name', `ut_host' and `ut_time' members. Older systems do not even
--have the `ut_host' member.
--
--
--File: libc.info, Node: User Database, Next: Group Database, Prev: User Accounting Database, Up: Users and Groups
--
--User Database
--=============
--
-- This section describes how to search and scan the database of
--registered users. The database itself is kept in the file
--`/etc/passwd' on most systems, but on some systems a special network
--server gives access to it.
--
--* Menu:
--
--* User Data Structure:: What each user record contains.
--* Lookup User:: How to look for a particular user.
--* Scanning All Users:: Scanning the list of all users, one by one.
--* Writing a User Entry:: How a program can rewrite a user's record.
--
--
--File: libc.info, Node: User Data Structure, Next: Lookup User, Up: User Database
--
--The Data Structure that Describes a User
------------------------------------------
--
-- The functions and data structures for accessing the system user
--database are declared in the header file `pwd.h'.
--
-- - Data Type: struct passwd
-- The `passwd' data structure is used to hold information about
-- entries in the system user data base. It has at least the
-- following members:
--
-- `char *pw_name'
-- The user's login name.
--
-- `char *pw_passwd.'
-- The encrypted password string.
--
-- `uid_t pw_uid'
-- The user ID number.
--
-- `gid_t pw_gid'
-- The user's default group ID number.
--
-- `char *pw_gecos'
-- A string typically containing the user's real name, and
-- possibly other information such as a phone number.
--
-- `char *pw_dir'
-- The user's home directory, or initial working directory.
-- This might be a null pointer, in which case the
-- interpretation is system-dependent.
--
-- `char *pw_shell'
-- The user's default shell, or the initial program run when the
-- user logs in. This might be a null pointer, indicating that
-- the system default should be used.
--
--
--File: libc.info, Node: Lookup User, Next: Scanning All Users, Prev: User Data Structure, Up: User Database
--
--Looking Up One User
---------------------
--
-- You can search the system user database for information about a
--specific user using `getpwuid' or `getpwnam'. These functions are
--declared in `pwd.h'.
--
-- - Function: struct passwd * getpwuid (uid_t UID)
-- This function returns a pointer to a statically-allocated structure
-- containing information about the user whose user ID is UID. This
-- structure may be overwritten on subsequent calls to `getpwuid'.
--
-- A null pointer value indicates there is no user in the data base
-- with user ID UID.
--
-- - Function: int getpwuid_r (uid_t UID, struct passwd *RESULT_BUF, char
-- *BUFFER, size_t BUFLEN, struct passwd **RESULT)
-- This function is similar to `getpwuid' in that it returns
-- information about the user whose user ID is UID. However, it
-- fills the user supplied structure pointed to by RESULT_BUF with
-- the information instead of using a static buffer. The first
-- BUFLEN bytes of the additional buffer pointed to by BUFFER are
-- used to contain additional information, normally strings which are
-- pointed to by the elements of the result structure.
--
-- If a user with ID UID is found, the pointer returned in RESULT
-- points to the record which contains the wanted data (i.e., RESULT
-- contains the value RESULT_BUF). If no user is found or if an
-- error occured, the pointer returned in RESULT is a null pointer.
-- The function returns zero or an error code. If the buffer BUFFER
-- is too small to contain all the needed information, the error code
-- `ERANGE' is returned and ERRNO is set to `ERANGE'.
--
-- - Function: struct passwd * getpwnam (const char *NAME)
-- This function returns a pointer to a statically-allocated structure
-- containing information about the user whose user name is NAME.
-- This structure may be overwritten on subsequent calls to
-- `getpwnam'.
--
-- A null pointer return indicates there is no user named NAME.
--
-- - Function: int getpwnam_r (const char *NAME, struct passwd
-- *RESULT_BUF, char *BUFFER, size_t BUFLEN, struct passwd
-- **RESULT)
-- This function is similar to `getpwnam' in that is returns
-- information about the user whose user name is NAME. However, like
-- `getpwuid_r', it fills the user supplied buffers in RESULT_BUF and
-- BUFFER with the information instead of using a static buffer.
--
-- The return values are the same as for `getpwuid_r'.
--
--
--File: libc.info, Node: Scanning All Users, Next: Writing a User Entry, Prev: Lookup User, Up: User Database
--
--Scanning the List of All Users
--------------------------------
--
-- This section explains how a program can read the list of all users in
--the system, one user at a time. The functions described here are
--declared in `pwd.h'.
--
-- You can use the `fgetpwent' function to read user entries from a
--particular file.
--
-- - Function: struct passwd * fgetpwent (FILE *STREAM)
-- This function reads the next user entry from STREAM and returns a
-- pointer to the entry. The structure is statically allocated and is
-- rewritten on subsequent calls to `fgetpwent'. You must copy the
-- contents of the structure if you wish to save the information.
--
-- The stream must correspond to a file in the same format as the
-- standard password database file.
--
-- - Function: int fgetpwent_r (FILE *STREAM, struct passwd *RESULT_BUF,
-- char *BUFFER, size_t BUFLEN, struct passwd **RESULT)
-- This function is similar to `fgetpwent' in that it reads the next
-- user entry from STREAM. But the result is returned in the
-- structure pointed to by RESULT_BUF. The first BUFLEN bytes of the
-- additional buffer pointed to by BUFFER are used to contain
-- additional information, normally strings which are pointed to by
-- the elements of the result structure.
--
-- The stream must correspond to a file in the same format as the
-- standard password database file.
--
-- If the function returns zero RESULT points to the structure with
-- the wanted data (normally this is in RESULT_BUF). If errors
-- occurred the return value is nonzero and RESULT contains a null
-- pointer.
--
-- The way to scan all the entries in the user database is with
--`setpwent', `getpwent', and `endpwent'.
--
-- - Function: void setpwent (void)
-- This function initializes a stream which `getpwent' and
-- `getpwent_r' use to read the user database.
--
-- - Function: struct passwd * getpwent (void)
-- The `getpwent' function reads the next entry from the stream
-- initialized by `setpwent'. It returns a pointer to the entry. The
-- structure is statically allocated and is rewritten on subsequent
-- calls to `getpwent'. You must copy the contents of the structure
-- if you wish to save the information.
--
-- A null pointer is returned when no more entries are available.
--
-- - Function: int getpwent_r (struct passwd *RESULT_BUF, char *BUFFER,
-- int BUFLEN, struct passwd **RESULT)
-- This function is similar to `getpwent' in that it returns the next
-- entry from the stream initialized by `setpwent'. Like
-- `fgetpwent_r', it uses the user-supplied buffers in RESULT_BUF and
-- BUFFER to return the information requested.
--
-- The return values are the same as for `fgetpwent_r'.
--
--
-- - Function: void endpwent (void)
-- This function closes the internal stream used by `getpwent' or
-- `getpwent_r'.
--
--
--File: libc.info, Node: Writing a User Entry, Prev: Scanning All Users, Up: User Database
--
--Writing a User Entry
----------------------
--
-- - Function: int putpwent (const struct passwd *P, FILE *STREAM)
-- This function writes the user entry `*P' to the stream STREAM, in
-- the format used for the standard user database file. The return
-- value is zero on success and nonzero on failure.
--
-- This function exists for compatibility with SVID. We recommend
-- that you avoid using it, because it makes sense only on the
-- assumption that the `struct passwd' structure has no members
-- except the standard ones; on a system which merges the traditional
-- Unix data base with other extended information about users, adding
-- an entry using this function would inevitably leave out much of
-- the important information.
--
-- The function `putpwent' is declared in `pwd.h'.
--
--
--File: libc.info, Node: Group Database, Next: Database Example, Prev: User Database, Up: Users and Groups
--
--Group Database
--==============
--
-- This section describes how to search and scan the database of
--registered groups. The database itself is kept in the file
--`/etc/group' on most systems, but on some systems a special network
--service provides access to it.
--
--* Menu:
--
--* Group Data Structure:: What each group record contains.
--* Lookup Group:: How to look for a particular group.
--* Scanning All Groups:: Scanning the list of all groups.
--
--
--File: libc.info, Node: Group Data Structure, Next: Lookup Group, Up: Group Database
--
--The Data Structure for a Group
--------------------------------
--
-- The functions and data structures for accessing the system group
--database are declared in the header file `grp.h'.
--
-- - Data Type: struct group
-- The `group' structure is used to hold information about an entry in
-- the system group database. It has at least the following members:
--
-- `char *gr_name'
-- The name of the group.
--
-- `gid_t gr_gid'
-- The group ID of the group.
--
-- `char **gr_mem'
-- A vector of pointers to the names of users in the group.
-- Each user name is a null-terminated string, and the vector
-- itself is terminated by a null pointer.
--
--
--File: libc.info, Node: Lookup Group, Next: Scanning All Groups, Prev: Group Data Structure, Up: Group Database
--
--Looking Up One Group
----------------------
--
-- You can search the group database for information about a specific
--group using `getgrgid' or `getgrnam'. These functions are declared in
--`grp.h'.
--
-- - Function: struct group * getgrgid (gid_t GID)
-- This function returns a pointer to a statically-allocated structure
-- containing information about the group whose group ID is GID.
-- This structure may be overwritten by subsequent calls to
-- `getgrgid'.
--
-- A null pointer indicates there is no group with ID GID.
--
-- - Function: int getgrgid_r (gid_t GID, struct group *RESULT_BUF, char
-- *BUFFER, size_t BUFLEN, struct group **RESULT)
-- This function is similar to `getgrgid' in that it returns
-- information about the group whose group ID is GID. However, it
-- fills the user supplied structure pointed to by RESULT_BUF with
-- the information instead of using a static buffer. The first
-- BUFLEN bytes of the additional buffer pointed to by BUFFER are
-- used to contain additional information, normally strings which are
-- pointed to by the elements of the result structure.
--
-- If a group with ID GID is found, the pointer returned in RESULT
-- points to the record which contains the wanted data (i.e., RESULT
-- contains the value RESULT_BUF). If no group is found or if an
-- error occured, the pointer returned in RESULT is a null pointer.
-- The function returns zero or an error code. If the buffer BUFFER
-- is too small to contain all the needed information, the error code
-- `ERANGE' is returned and ERRNO is set to `ERANGE'.
--
-- - Function: struct group * getgrnam (const char *NAME)
-- This function returns a pointer to a statically-allocated structure
-- containing information about the group whose group name is NAME.
-- This structure may be overwritten by subsequent calls to
-- `getgrnam'.
--
-- A null pointer indicates there is no group named NAME.
--
-- - Function: int getgrnam_r (const char *NAME, struct group
-- *RESULT_BUF, char *BUFFER, size_t BUFLEN, struct group
-- **RESULT)
-- This function is similar to `getgrnam' in that is returns
-- information about the group whose group name is NAME. Like
-- `getgrgid_r', it uses the user supplied buffers in RESULT_BUF and
-- BUFFER, not a static buffer.
--
-- The return values are the same as for `getgrgid_r' `ERANGE'.
--
--
--File: libc.info, Node: Scanning All Groups, Prev: Lookup Group, Up: Group Database
--
--Scanning the List of All Groups
---------------------------------
--
-- This section explains how a program can read the list of all groups
--in the system, one group at a time. The functions described here are
--declared in `grp.h'.
--
-- You can use the `fgetgrent' function to read group entries from a
--particular file.
--
-- - Function: struct group * fgetgrent (FILE *STREAM)
-- The `fgetgrent' function reads the next entry from STREAM. It
-- returns a pointer to the entry. The structure is statically
-- allocated and is overwritten on subsequent calls to `fgetgrent'.
-- You must copy the contents of the structure if you wish to save the
-- information.
--
-- The stream must correspond to a file in the same format as the
-- standard group database file.
--
-- - Function: int fgetgrent_r (FILE *STREAM, struct group *RESULT_BUF,
-- char *BUFFER, size_t BUFLEN, struct group **RESULT)
-- This function is similar to `fgetgrent' in that it reads the next
-- user entry from STREAM. But the result is returned in the
-- structure pointed to by RESULT_BUF. The first BUFLEN bytes of the
-- additional buffer pointed to by BUFFER are used to contain
-- additional information, normally strings which are pointed to by
-- the elements of the result structure.
--
-- This stream must correspond to a file in the same format as the
-- standard group database file.
--
-- If the function returns zero RESULT points to the structure with
-- the wanted data (normally this is in RESULT_BUF). If errors
-- occurred the return value is non-zero and RESULT contains a null
-- pointer.
--
-- The way to scan all the entries in the group database is with
--`setgrent', `getgrent', and `endgrent'.
--
-- - Function: void setgrent (void)
-- This function initializes a stream for reading from the group data
-- base. You use this stream by calling `getgrent' or `getgrent_r'.
--
-- - Function: struct group * getgrent (void)
-- The `getgrent' function reads the next entry from the stream
-- initialized by `setgrent'. It returns a pointer to the entry. The
-- structure is statically allocated and is overwritten on subsequent
-- calls to `getgrent'. You must copy the contents of the structure
-- if you wish to save the information.
--
-- - Function: int getgrent_r (struct group *RESULT_BUF, char *BUFFER,
-- size_t BUFLEN, struct group **RESULT)
-- This function is similar to `getgrent' in that it returns the next
-- entry from the stream initialized by `setgrent'. Like
-- `fgetgrent_r', it places the result in user-supplied buffers
-- pointed to RESULT_BUF and BUFFER.
--
-- If the function returns zero RESULT contains a pointer to the data
-- (normally equal to RESULT_BUF). If errors occurred the return
-- value is non-zero and RESULT contains a null pointer.
--
-- - Function: void endgrent (void)
-- This function closes the internal stream used by `getgrent' or
-- `getgrent_r'.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-4 glibc-2.1.3/manual/libc.info-4
---- ../glibc-2.1.3/manual/libc.info-4 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-4 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1233 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Hooks for Malloc, Next: Statistics of Malloc, Prev: Heap Consistency Checking, Up: Unconstrained Allocation
--
--Storage Allocation Hooks
--------------------------
--
-- The GNU C library lets you modify the behavior of `malloc',
--`realloc', and `free' by specifying appropriate hook functions. You
--can use these hooks to help you debug programs that use dynamic storage
--allocation, for example.
--
-- The hook variables are declared in `malloc.h'.
--
-- - Variable: __malloc_hook
-- The value of this variable is a pointer to function that `malloc'
-- uses whenever it is called. You should define this function to
-- look like `malloc'; that is, like:
--
-- void *FUNCTION (size_t SIZE, void *CALLER)
--
-- The value of CALLER is the return address found on the stack when
-- the `malloc' function was called. This value allows to trace the
-- memory consumption of the program.
--
-- - Variable: __realloc_hook
-- The value of this variable is a pointer to function that `realloc'
-- uses whenever it is called. You should define this function to
-- look like `realloc'; that is, like:
--
-- void *FUNCTION (void *PTR, size_t SIZE, void *CALLER)
--
-- The value of CALLER is the return address found on the stack when
-- the `realloc' function was called. This value allows to trace the
-- memory consumption of the program.
--
-- - Variable: __free_hook
-- The value of this variable is a pointer to function that `free'
-- uses whenever it is called. You should define this function to
-- look like `free'; that is, like:
--
-- void FUNCTION (void *PTR, void *CALLER)
--
-- The value of CALLER is the return address found on the stack when
-- the `free' function was called. This value allows to trace the
-- memory consumption of the program.
--
-- - Variable: __memalign_hook
-- The value of this variable is a pointer to function that `memalign'
-- uses whenever it is called. You should define this function to
-- look like `memalign'; that is, like:
--
-- void *FUNCTION (size_t SIZE, size_t ALIGNMENT)
--
-- You must make sure that the function you install as a hook for one of
--these functions does not call that function recursively without
--restoring the old value of the hook first! Otherwise, your program
--will get stuck in an infinite recursion. Before calling the function
--recursively, one should make sure to restore all the hooks to their
--previous value. When coming back from the recursive call, all the
--hooks should be resaved since a hook might modify itself.
--
-- Here is an example showing how to use `__malloc_hook' and
--`__free_hook' properly. It installs a function that prints out
--information every time `malloc' or `free' is called. We just assume
--here that `realloc' and `memalign' are not used in our program.
--
-- /* Global variables used to hold underlaying hook values. */
-- static void *(*old_malloc_hook) (size_t);
-- static void (*old_free_hook) (void*);
--
-- /* Prototypes for our hooks. */
-- static void *my_malloc_hook (size_t);
-- static void my_free_hook(void*);
--
-- static void *
-- my_malloc_hook (size_t size)
-- {
-- void *result;
-- /* Restore all old hooks */
-- __malloc_hook = old_malloc_hook;
-- __free_hook = old_free_hook;
-- /* Call recursively */
-- result = malloc (size);
-- /* Save underlaying hooks */
-- old_malloc_hook = __malloc_hook;
-- old_free_hook = __free_hook;
-- /* `printf' might call `malloc', so protect it too. */
-- printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
-- /* Restore our own hooks */
-- __malloc_hook = my_malloc_hook;
-- __free_hook = my_free_hook;
-- return result;
-- }
--
-- static void *
-- my_free_hook (void *ptr)
-- {
-- /* Restore all old hooks */
-- __malloc_hook = old_malloc_hook;
-- __free_hook = old_free_hook;
-- /* Call recursively */
-- free (ptr);
-- /* Save underlaying hooks */
-- old_malloc_hook = __malloc_hook;
-- old_free_hook = __free_hook;
-- /* `printf' might call `free', so protect it too. */
-- printf ("freed pointer %p\n", ptr);
-- /* Restore our own hooks */
-- __malloc_hook = my_malloc_hook;
-- __free_hook = my_free_hook;
-- }
--
-- main ()
-- {
-- ...
-- old_malloc_hook = __malloc_hook;
-- old_free_hook = __free_hook;
-- __malloc_hook = my_malloc_hook;
-- __free_hook = my_free_hook;
-- ...
-- }
--
-- The `mcheck' function (*note Heap Consistency Checking::.) works by
--installing such hooks.
--
--
--File: libc.info, Node: Statistics of Malloc, Next: Summary of Malloc, Prev: Hooks for Malloc, Up: Unconstrained Allocation
--
--Statistics for Storage Allocation with `malloc'
-------------------------------------------------
--
-- You can get information about dynamic storage allocation by calling
--the `mallinfo' function. This function and its associated data type
--are declared in `malloc.h'; they are an extension of the standard
--SVID/XPG version.
--
-- - Data Type: struct mallinfo
-- This structure type is used to return information about the dynamic
-- storage allocator. It contains the following members:
--
-- `int arena'
-- This is the total size of memory allocated with `sbrk' by
-- `malloc', in bytes.
--
-- `int ordblks'
-- This is the number of chunks not in use. (The storage
-- allocator internally gets chunks of memory from the operating
-- system, and then carves them up to satisfy individual
-- `malloc' requests; see *Note Efficiency and Malloc::.)
--
-- `int smblks'
-- This field is unused.
--
-- `int hblks'
-- This is the total number of chunks allocated with `mmap'.
--
-- `int hblkhd'
-- This is the total size of memory allocated with `mmap', in
-- bytes.
--
-- `int usmblks'
-- This field is unused.
--
-- `int fsmblks'
-- This field is unused.
--
-- `int uordblks'
-- This is the total size of memory occupied by chunks handed
-- out by `malloc'.
--
-- `int fordblks'
-- This is the total size of memory occupied by free (not in
-- use) chunks.
--
-- `int keepcost'
-- This is the size of the top-most, releaseable chunk that
-- normally borders the end of the heap (i.e. the "brk" of the
-- process).
--
--
-- - Function: struct mallinfo mallinfo (void)
-- This function returns information about the current dynamic memory
-- usage in a structure of type `struct mallinfo'.
--
--
--File: libc.info, Node: Summary of Malloc, Prev: Statistics of Malloc, Up: Unconstrained Allocation
--
--Summary of `malloc'-Related Functions
---------------------------------------
--
-- Here is a summary of the functions that work with `malloc':
--
--`void *malloc (size_t SIZE)'
-- Allocate a block of SIZE bytes. *Note Basic Allocation::.
--
--`void free (void *ADDR)'
-- Free a block previously allocated by `malloc'. *Note Freeing
-- after Malloc::.
--
--`void *realloc (void *ADDR, size_t SIZE)'
-- Make a block previously allocated by `malloc' larger or smaller,
-- possibly by copying it to a new location. *Note Changing Block
-- Size::.
--
--`void *calloc (size_t COUNT, size_t ELTSIZE)'
-- Allocate a block of COUNT * ELTSIZE bytes using `malloc', and set
-- its contents to zero. *Note Allocating Cleared Space::.
--
--`void *valloc (size_t SIZE)'
-- Allocate a block of SIZE bytes, starting on a page boundary.
-- *Note Aligned Memory Blocks::.
--
--`void *memalign (size_t SIZE, size_t BOUNDARY)'
-- Allocate a block of SIZE bytes, starting on an address that is a
-- multiple of BOUNDARY. *Note Aligned Memory Blocks::.
--
--`int mallopt (int PARAM, int VALUE)'
-- Adjust a tunable parameter. *Note Malloc Tunable Parameters::.
--
--`int mcheck (void (*ABORTFN) (void))'
-- Tell `malloc' to perform occasional consistency checks on
-- dynamically allocated memory, and to call ABORTFN when an
-- inconsistency is found. *Note Heap Consistency Checking::.
--
--`void *(*__malloc_hook) (size_t SIZE, void *CALLER)'
-- A pointer to a function that `malloc' uses whenever it is called.
--
--`void *(*__realloc_hook) (void *PTR, size_t SIZE, void *CALLER)'
-- A pointer to a function that `realloc' uses whenever it is called.
--
--`void (*__free_hook) (void *PTR, void *CALLER)'
-- A pointer to a function that `free' uses whenever it is called.
--
--`void (*__memalign_hook) (size_t SIZE, size_t ALIGNMENT)'
-- A pointer to a function that `memalign' uses whenever it is called.
--
--`struct mallinfo mallinfo (void)'
-- Return information about the current dynamic memory usage. *Note
-- Statistics of Malloc::.
--
--
--File: libc.info, Node: Allocation Debugging, Next: Obstacks, Prev: Unconstrained Allocation, Up: Memory Allocation
--
--Allocation Debugging
--====================
--
-- An complicated task when programming with languages which do not use
--garbage collected dynamic memory allocation is to find memory leaks.
--Long running programs must assure that dynamically allocated objects are
--freed at the end of their lifetime. If this does not happen the system
--runs out of memory, sooner or later.
--
-- The `malloc' implementation in the GNU C library provides some
--simple means to detect sich leaks and provide some information to find
--the location. To do this the application must be started in a special
--mode which is enabled by an environment variable. There are no speed
--penalties if the program is compiled in preparation of the debugging if
--the debug mode is not enabled.
--
--* Menu:
--
--* Tracing malloc:: How to install the tracing functionality.
--* Using the Memory Debugger:: Example programs excerpts.
--* Tips for the Memory Debugger:: Some more or less clever ideas.
--* Interpreting the traces:: What do all these lines mean?
--
--
--File: libc.info, Node: Tracing malloc, Next: Using the Memory Debugger, Up: Allocation Debugging
--
--How to install the tracing functionality
------------------------------------------
--
-- - Function: void mtrace (void)
-- When the `mtrace' function is called it looks for an environment
-- variable named `MALLOC_TRACE'. This variable is supposed to
-- contain a valid file name. The user must have write access. If
-- the file already exists it is truncated. If the environment
-- variable is not set or it does not name a valid file which can be
-- opened for writing nothing is done. The behaviour of `malloc'
-- etc. is not changed. For obvious reasons this also happens if the
-- application is install SUID or SGID.
--
-- If the named file is successfully opened `mtrace' installs special
-- handlers for the functions `malloc', `realloc', and `free' (*note
-- Hooks for Malloc::.). From now on all uses of these functions are
-- traced and protocolled into the file. There is now of course a
-- speed penalty for all calls to the traced functions so that the
-- tracing should not be enabled during their normal use.
--
-- This function is a GNU extension and generally not available on
-- other systems. The prototype can be found in `mcheck.h'.
--
-- - Function: void muntrace (void)
-- The `muntrace' function can be called after `mtrace' was used to
-- enable tracing the `malloc' calls. If no (succesful) call of
-- `mtrace' was made `muntrace' does nothing.
--
-- Otherwise it deinstalls the handlers for `malloc', `realloc', and
-- `free' and then closes the protocol file. No calls are
-- protocolled anymore and the programs runs again with the full
-- speed.
--
-- This function is a GNU extension and generally not available on
-- other systems. The prototype can be found in `mcheck.h'.
--
--
--File: libc.info, Node: Using the Memory Debugger, Next: Tips for the Memory Debugger, Prev: Tracing malloc, Up: Allocation Debugging
--
--Example programs excerpts
---------------------------
--
-- Even though the tracing functionality does not influence the runtime
--behaviour of the program it is no wise idea to call `mtrace' in all
--programs. Just imagine you debug a program using `mtrace' and all
--other programs used in the debug sessions also trace their `malloc'
--calls. The output file would be the same for all programs and so is
--unusable. Therefore one should call `mtrace' only if compiled for
--debugging. A program could therefore start like this:
--
-- #include <mcheck.h>
--
-- int
-- main (int argc, char *argv[])
-- {
-- #ifdef DEBUGGING
-- mtrace ();
-- #endif
-- ...
-- }
--
-- This is all what is needed if you want to trace the calls during the
--whole runtime of the program. Alternatively you can stop the tracing at
--any time with a call to `muntrace'. It is even possible to restart the
--tracing again with a new call to `mtrace'. But this can course
--unreliable results since there are possibly calls of the functions which
--are not called. Please note that not only the application uses the
--traced functions, also libraries (including the C library itself) use
--this function.
--
-- This last point is also why it is no good idea to call `muntrace'
--before the program terminated. The libraries are informed about the
--termination of the program only after the program returns from `main'
--or calls `exit' and so cannot free the memory they use before this time.
--
-- So the best thing one can do is to call `mtrace' as the very first
--function in the program and never call `muntrace'. So the program
--traces almost all uses of the `malloc' functions (except those calls
--which are executed by constructors of the program or used libraries).
--
--
--File: libc.info, Node: Tips for the Memory Debugger, Next: Interpreting the traces, Prev: Using the Memory Debugger, Up: Allocation Debugging
--
--Some more or less clever ideas
--------------------------------
--
-- You know the situation. The program is prepared for debugging and in
--all debugging sessions it runs well. But once it is started without
--debugging the error shows up. In our situation here: the memory leaks
--becomes visible only when we just turned off the debugging. If you
--foresee such situations you can still win. Simply use something
--equivalent to the following little program:
--
-- #include <mcheck.h>
-- #include <signal.h>
--
-- static void
-- enable (int sig)
-- {
-- mtrace ();
-- signal (SIGUSR1, enable);
-- }
--
-- static void
-- disable (int sig)
-- {
-- muntrace ();
-- signal (SIGUSR2, disable);
-- }
--
-- int
-- main (int argc, char *argv[])
-- {
-- ...
--
-- signal (SIGUSR1, enable);
-- signal (SIGUSR2, disable);
--
-- ...
-- }
--
-- I.e., the user can start the memory debugger any time s/he wants if
--the program was started with `MALLOC_TRACE' set in the environment.
--The output will of course not show the allocations which happened before
--the first signal but if there is a memory leak this will show up
--nevertheless.
--
--
--File: libc.info, Node: Interpreting the traces, Prev: Tips for the Memory Debugger, Up: Allocation Debugging
--
--Interpreting the traces
-------------------------
--
-- If you take a look at the output it will look similar to this:
--
-- = Start
-- [0x8048209] - 0x8064cc8
-- [0x8048209] - 0x8064ce0
-- [0x8048209] - 0x8064cf8
-- [0x80481eb] + 0x8064c48 0x14
-- [0x80481eb] + 0x8064c60 0x14
-- [0x80481eb] + 0x8064c78 0x14
-- [0x80481eb] + 0x8064c90 0x14
-- = End
--
-- What this all means is not really important since the trace file is
--not meant to be read by a human. Therefore no attention is payed to
--good readability. Instead there is a program which comes with the GNU C
--library which interprets the traces and outputs a summary in on
--user-friendly way. The program is called `mtrace' (it is in fact a
--Perl script) and it takes one or two arguments. In any case the name of
--the file with the trace output must be specified. If an optional
--argument precedes the name of the trace file this must be the name of
--the program which generated the trace.
--
-- drepper$ mtrace tst-mtrace log
-- No memory leaks.
--
-- In this case the program `tst-mtrace' was run and it produced a
--trace file `log'. The message printed by `mtrace' shows there are no
--problems with the code, all allocated memory was freed afterwards.
--
-- If we call `mtrace' on the example trace given above we would get a
--different outout:
--
-- drepper$ mtrace errlog
-- - 0x08064cc8 Free 2 was never alloc'd 0x8048209
-- - 0x08064ce0 Free 3 was never alloc'd 0x8048209
-- - 0x08064cf8 Free 4 was never alloc'd 0x8048209
--
-- Memory not freed:
-- -----------------
-- Address Size Caller
-- 0x08064c48 0x14 at 0x80481eb
-- 0x08064c60 0x14 at 0x80481eb
-- 0x08064c78 0x14 at 0x80481eb
-- 0x08064c90 0x14 at 0x80481eb
--
-- We have called `mtrace' with only one argument and so the script has
--no chance to find out what is meant with the addresses given in the
--trace. We can do better:
--
-- drepper$ mtrace tst-mtrace errlog
-- - 0x08064cc8 Free 2 was never alloc'd /home/drepper/tst-mtrace.c:39
-- - 0x08064ce0 Free 3 was never alloc'd /home/drepper/tst-mtrace.c:39
-- - 0x08064cf8 Free 4 was never alloc'd /home/drepper/tst-mtrace.c:39
--
-- Memory not freed:
-- -----------------
-- Address Size Caller
-- 0x08064c48 0x14 at /home/drepper/tst-mtrace.c:33
-- 0x08064c60 0x14 at /home/drepper/tst-mtrace.c:33
-- 0x08064c78 0x14 at /home/drepper/tst-mtrace.c:33
-- 0x08064c90 0x14 at /home/drepper/tst-mtrace.c:33
--
-- Suddenly the output makes much more sense and the user can see
--immediately where the function calls causing the trouble can be found.
--
-- Interpreting this output is not complicated. There are at most two
--different situations being detected. First, `free' was called for
--pointers which were never returned by one of the allocation functions.
--This is usually a very bad problem and how this looks like is shown in
--the first three lines of the output. Situations like this are quite
--rare and if they appear they show up very drastically: the program
--normally crashes.
--
-- The other situation which is much harder to detect are memory leaks.
--As you can see in the output the `mtrace' function collects all this
--information and so can say that the program calls an allocation function
--from line 33 in the source file `/home/drepper/tst-mtrace.c' four times
--without freeing this memory before the program terminates. Whether
--this is a real problem keeps to be investigated.
--
--
--File: libc.info, Node: Obstacks, Next: Variable Size Automatic, Prev: Allocation Debugging, Up: Memory Allocation
--
--Obstacks
--========
--
-- An "obstack" is a pool of memory containing a stack of objects. You
--can create any number of separate obstacks, and then allocate objects in
--specified obstacks. Within each obstack, the last object allocated must
--always be the first one freed, but distinct obstacks are independent of
--each other.
--
-- Aside from this one constraint of order of freeing, obstacks are
--totally general: an obstack can contain any number of objects of any
--size. They are implemented with macros, so allocation is usually very
--fast as long as the objects are usually small. And the only space
--overhead per object is the padding needed to start each object on a
--suitable boundary.
--
--* Menu:
--
--* Creating Obstacks:: How to declare an obstack in your program.
--* Preparing for Obstacks:: Preparations needed before you can
-- use obstacks.
--* Allocation in an Obstack:: Allocating objects in an obstack.
--* Freeing Obstack Objects:: Freeing objects in an obstack.
--* Obstack Functions:: The obstack functions are both
-- functions and macros.
--* Growing Objects:: Making an object bigger by stages.
--* Extra Fast Growing:: Extra-high-efficiency (though more
-- complicated) growing objects.
--* Status of an Obstack:: Inquiries about the status of an obstack.
--* Obstacks Data Alignment:: Controlling alignment of objects in obstacks.
--* Obstack Chunks:: How obstacks obtain and release chunks;
-- efficiency considerations.
--* Summary of Obstacks::
--
--
--File: libc.info, Node: Creating Obstacks, Next: Preparing for Obstacks, Up: Obstacks
--
--Creating Obstacks
-------------------
--
-- The utilities for manipulating obstacks are declared in the header
--file `obstack.h'.
--
-- - Data Type: struct obstack
-- An obstack is represented by a data structure of type `struct
-- obstack'. This structure has a small fixed size; it records the
-- status of the obstack and how to find the space in which objects
-- are allocated. It does not contain any of the objects themselves.
-- You should not try to access the contents of the structure
-- directly; use only the functions described in this chapter.
--
-- You can declare variables of type `struct obstack' and use them as
--obstacks, or you can allocate obstacks dynamically like any other kind
--of object. Dynamic allocation of obstacks allows your program to have a
--variable number of different stacks. (You can even allocate an obstack
--structure in another obstack, but this is rarely useful.)
--
-- All the functions that work with obstacks require you to specify
--which obstack to use. You do this with a pointer of type `struct
--obstack *'. In the following, we often say "an obstack" when strictly
--speaking the object at hand is such a pointer.
--
-- The objects in the obstack are packed into large blocks called
--"chunks". The `struct obstack' structure points to a chain of the
--chunks currently in use.
--
-- The obstack library obtains a new chunk whenever you allocate an
--object that won't fit in the previous chunk. Since the obstack library
--manages chunks automatically, you don't need to pay much attention to
--them, but you do need to supply a function which the obstack library
--should use to get a chunk. Usually you supply a function which uses
--`malloc' directly or indirectly. You must also supply a function to
--free a chunk. These matters are described in the following section.
--
--
--File: libc.info, Node: Preparing for Obstacks, Next: Allocation in an Obstack, Prev: Creating Obstacks, Up: Obstacks
--
--Preparing for Using Obstacks
------------------------------
--
-- Each source file in which you plan to use the obstack functions must
--include the header file `obstack.h', like this:
--
-- #include <obstack.h>
--
-- Also, if the source file uses the macro `obstack_init', it must
--declare or define two functions or macros that will be called by the
--obstack library. One, `obstack_chunk_alloc', is used to allocate the
--chunks of memory into which objects are packed. The other,
--`obstack_chunk_free', is used to return chunks when the objects in them
--are freed. These macros should appear before any use of obstacks in
--the source file.
--
-- Usually these are defined to use `malloc' via the intermediary
--`xmalloc' (*note Unconstrained Allocation::.). This is done with the
--following pair of macro definitions:
--
-- #define obstack_chunk_alloc xmalloc
-- #define obstack_chunk_free free
--
--Though the storage you get using obstacks really comes from `malloc',
--using obstacks is faster because `malloc' is called less often, for
--larger blocks of memory. *Note Obstack Chunks::, for full details.
--
-- At run time, before the program can use a `struct obstack' object as
--an obstack, it must initialize the obstack by calling `obstack_init'.
--
-- - Function: int obstack_init (struct obstack *OBSTACK-PTR)
-- Initialize obstack OBSTACK-PTR for allocation of objects. This
-- function calls the obstack's `obstack_chunk_alloc' function. If
-- allocation of memory fails, the function pointed to by
-- `obstack_alloc_failed_handler' is called. The `obstack_init'
-- function always returns 1 (Compatibility notice: Former versions of
-- obstack returned 0 if allocation failed).
--
-- Here are two examples of how to allocate the space for an obstack and
--initialize it. First, an obstack that is a static variable:
--
-- static struct obstack myobstack;
-- ...
-- obstack_init (&myobstack);
--
--Second, an obstack that is itself dynamically allocated:
--
-- struct obstack *myobstack_ptr
-- = (struct obstack *) xmalloc (sizeof (struct obstack));
--
-- obstack_init (myobstack_ptr);
--
-- - Variable: obstack_alloc_failed_handler
-- The value of this variable is a pointer to a function that
-- `obstack' uses when `obstack_chunk_alloc' fails to allocate
-- memory. The default action is to print a message and abort. You
-- should supply a function that either calls `exit' (*note Program
-- Termination::.) or `longjmp' (*note Non-Local Exits::.) and
-- doesn't return.
--
-- void my_obstack_alloc_failed (void)
-- ...
-- obstack_alloc_failed_handler = &my_obstack_alloc_failed;
--
--
--
--File: libc.info, Node: Allocation in an Obstack, Next: Freeing Obstack Objects, Prev: Preparing for Obstacks, Up: Obstacks
--
--Allocation in an Obstack
--------------------------
--
-- The most direct way to allocate an object in an obstack is with
--`obstack_alloc', which is invoked almost like `malloc'.
--
-- - Function: void * obstack_alloc (struct obstack *OBSTACK-PTR, int
-- SIZE)
-- This allocates an uninitialized block of SIZE bytes in an obstack
-- and returns its address. Here OBSTACK-PTR specifies which obstack
-- to allocate the block in; it is the address of the `struct obstack'
-- object which represents the obstack. Each obstack function or
-- macro requires you to specify an OBSTACK-PTR as the first argument.
--
-- This function calls the obstack's `obstack_chunk_alloc' function if
-- it needs to allocate a new chunk of memory; it calls
-- `obstack_alloc_failed_handler' if allocation of memory by
-- `obstack_chunk_alloc' failed.
--
-- For example, here is a function that allocates a copy of a string STR
--in a specific obstack, which is in the variable `string_obstack':
--
-- struct obstack string_obstack;
--
-- char *
-- copystring (char *string)
-- {
-- size_t len = strlen (string) + 1;
-- char *s = (char *) obstack_alloc (&string_obstack, len);
-- memcpy (s, string, len);
-- return s;
-- }
--
-- To allocate a block with specified contents, use the function
--`obstack_copy', declared like this:
--
-- - Function: void * obstack_copy (struct obstack *OBSTACK-PTR, void
-- *ADDRESS, int SIZE)
-- This allocates a block and initializes it by copying SIZE bytes of
-- data starting at ADDRESS. It calls `obstack_alloc_failed_handler'
-- if allocation of memory by `obstack_chunk_alloc' failed.
--
-- - Function: void * obstack_copy0 (struct obstack *OBSTACK-PTR, void
-- *ADDRESS, int SIZE)
-- Like `obstack_copy', but appends an extra byte containing a null
-- character. This extra byte is not counted in the argument SIZE.
--
-- The `obstack_copy0' function is convenient for copying a sequence of
--characters into an obstack as a null-terminated string. Here is an
--example of its use:
--
-- char *
-- obstack_savestring (char *addr, int size)
-- {
-- return obstack_copy0 (&myobstack, addr, size);
-- }
--
--Contrast this with the previous example of `savestring' using `malloc'
--(*note Basic Allocation::.).
--
--
--File: libc.info, Node: Freeing Obstack Objects, Next: Obstack Functions, Prev: Allocation in an Obstack, Up: Obstacks
--
--Freeing Objects in an Obstack
-------------------------------
--
-- To free an object allocated in an obstack, use the function
--`obstack_free'. Since the obstack is a stack of objects, freeing one
--object automatically frees all other objects allocated more recently in
--the same obstack.
--
-- - Function: void obstack_free (struct obstack *OBSTACK-PTR, void
-- *OBJECT)
-- If OBJECT is a null pointer, everything allocated in the obstack
-- is freed. Otherwise, OBJECT must be the address of an object
-- allocated in the obstack. Then OBJECT is freed, along with
-- everything allocated in OBSTACK since OBJECT.
--
-- Note that if OBJECT is a null pointer, the result is an
--uninitialized obstack. To free all storage in an obstack but leave it
--valid for further allocation, call `obstack_free' with the address of
--the first object allocated on the obstack:
--
-- obstack_free (obstack_ptr, first_object_allocated_ptr);
--
-- Recall that the objects in an obstack are grouped into chunks. When
--all the objects in a chunk become free, the obstack library
--automatically frees the chunk (*note Preparing for Obstacks::.). Then
--other obstacks, or non-obstack allocation, can reuse the space of the
--chunk.
--
--
--File: libc.info, Node: Obstack Functions, Next: Growing Objects, Prev: Freeing Obstack Objects, Up: Obstacks
--
--Obstack Functions and Macros
------------------------------
--
-- The interfaces for using obstacks may be defined either as functions
--or as macros, depending on the compiler. The obstack facility works
--with all C compilers, including both ISO C and traditional C, but there
--are precautions you must take if you plan to use compilers other than
--GNU C.
--
-- If you are using an old-fashioned non-ISO C compiler, all the obstack
--"functions" are actually defined only as macros. You can call these
--macros like functions, but you cannot use them in any other way (for
--example, you cannot take their address).
--
-- Calling the macros requires a special precaution: namely, the first
--operand (the obstack pointer) may not contain any side effects, because
--it may be computed more than once. For example, if you write this:
--
-- obstack_alloc (get_obstack (), 4);
--
--you will find that `get_obstack' may be called several times. If you
--use `*obstack_list_ptr++' as the obstack pointer argument, you will get
--very strange results since the incrementation may occur several times.
--
-- In ISO C, each function has both a macro definition and a function
--definition. The function definition is used if you take the address of
--the function without calling it. An ordinary call uses the macro
--definition by default, but you can request the function definition
--instead by writing the function name in parentheses, as shown here:
--
-- char *x;
-- void *(*funcp) ();
-- /* Use the macro. */
-- x = (char *) obstack_alloc (obptr, size);
-- /* Call the function. */
-- x = (char *) (obstack_alloc) (obptr, size);
-- /* Take the address of the function. */
-- funcp = obstack_alloc;
--
--This is the same situation that exists in ISO C for the standard library
--functions. *Note Macro Definitions::.
--
-- *Warning:* When you do use the macros, you must observe the
--precaution of avoiding side effects in the first operand, even in ISO C.
--
-- If you use the GNU C compiler, this precaution is not necessary,
--because various language extensions in GNU C permit defining the macros
--so as to compute each argument only once.
--
--
--File: libc.info, Node: Growing Objects, Next: Extra Fast Growing, Prev: Obstack Functions, Up: Obstacks
--
--Growing Objects
-----------------
--
-- Because storage in obstack chunks is used sequentially, it is
--possible to build up an object step by step, adding one or more bytes
--at a time to the end of the object. With this technique, you do not
--need to know how much data you will put in the object until you come to
--the end of it. We call this the technique of "growing objects". The
--special functions for adding data to the growing object are described
--in this section.
--
-- You don't need to do anything special when you start to grow an
--object. Using one of the functions to add data to the object
--automatically starts it. However, it is necessary to say explicitly
--when the object is finished. This is done with the function
--`obstack_finish'.
--
-- The actual address of the object thus built up is not known until the
--object is finished. Until then, it always remains possible that you
--will add so much data that the object must be copied into a new chunk.
--
-- While the obstack is in use for a growing object, you cannot use it
--for ordinary allocation of another object. If you try to do so, the
--space already added to the growing object will become part of the other
--object.
--
-- - Function: void obstack_blank (struct obstack *OBSTACK-PTR, int SIZE)
-- The most basic function for adding to a growing object is
-- `obstack_blank', which adds space without initializing it.
--
-- - Function: void obstack_grow (struct obstack *OBSTACK-PTR, void
-- *DATA, int SIZE)
-- To add a block of initialized space, use `obstack_grow', which is
-- the growing-object analogue of `obstack_copy'. It adds SIZE bytes
-- of data to the growing object, copying the contents from DATA.
--
-- - Function: void obstack_grow0 (struct obstack *OBSTACK-PTR, void
-- *DATA, int SIZE)
-- This is the growing-object analogue of `obstack_copy0'. It adds
-- SIZE bytes copied from DATA, followed by an additional null
-- character.
--
-- - Function: void obstack_1grow (struct obstack *OBSTACK-PTR, char C)
-- To add one character at a time, use the function `obstack_1grow'.
-- It adds a single byte containing C to the growing object.
--
-- - Function: void obstack_ptr_grow (struct obstack *OBSTACK-PTR, void
-- *DATA)
-- Adding the value of a pointer one can use the function
-- `obstack_ptr_grow'. It adds `sizeof (void *)' bytes containing
-- the value of DATA.
--
-- - Function: void obstack_int_grow (struct obstack *OBSTACK-PTR, int
-- DATA)
-- A single value of type `int' can be added by using the
-- `obstack_int_grow' function. It adds `sizeof (int)' bytes to the
-- growing object and initializes them with the value of DATA.
--
-- - Function: void * obstack_finish (struct obstack *OBSTACK-PTR)
-- When you are finished growing the object, use the function
-- `obstack_finish' to close it off and return its final address.
--
-- Once you have finished the object, the obstack is available for
-- ordinary allocation or for growing another object.
--
-- This function can return a null pointer under the same conditions
-- as `obstack_alloc' (*note Allocation in an Obstack::.).
--
-- When you build an object by growing it, you will probably need to
--know afterward how long it became. You need not keep track of this as
--you grow the object, because you can find out the length from the
--obstack just before finishing the object with the function
--`obstack_object_size', declared as follows:
--
-- - Function: int obstack_object_size (struct obstack *OBSTACK-PTR)
-- This function returns the current size of the growing object, in
-- bytes. Remember to call this function *before* finishing the
-- object. After it is finished, `obstack_object_size' will return
-- zero.
--
-- If you have started growing an object and wish to cancel it, you
--should finish it and then free it, like this:
--
-- obstack_free (obstack_ptr, obstack_finish (obstack_ptr));
--
--This has no effect if no object was growing.
--
-- You can use `obstack_blank' with a negative size argument to make
--the current object smaller. Just don't try to shrink it beyond zero
--length--there's no telling what will happen if you do that.
--
--
--File: libc.info, Node: Extra Fast Growing, Next: Status of an Obstack, Prev: Growing Objects, Up: Obstacks
--
--Extra Fast Growing Objects
----------------------------
--
-- The usual functions for growing objects incur overhead for checking
--whether there is room for the new growth in the current chunk. If you
--are frequently constructing objects in small steps of growth, this
--overhead can be significant.
--
-- You can reduce the overhead by using special "fast growth" functions
--that grow the object without checking. In order to have a robust
--program, you must do the checking yourself. If you do this checking in
--the simplest way each time you are about to add data to the object, you
--have not saved anything, because that is what the ordinary growth
--functions do. But if you can arrange to check less often, or check
--more efficiently, then you make the program faster.
--
-- The function `obstack_room' returns the amount of room available in
--the current chunk. It is declared as follows:
--
-- - Function: int obstack_room (struct obstack *OBSTACK-PTR)
-- This returns the number of bytes that can be added safely to the
-- current growing object (or to an object about to be started) in
-- obstack OBSTACK using the fast growth functions.
--
-- While you know there is room, you can use these fast growth functions
--for adding data to a growing object:
--
-- - Function: void obstack_1grow_fast (struct obstack *OBSTACK-PTR, char
-- C)
-- The function `obstack_1grow_fast' adds one byte containing the
-- character C to the growing object in obstack OBSTACK-PTR.
--
-- - Function: void obstack_ptr_grow_fast (struct obstack *OBSTACK-PTR,
-- void *DATA)
-- The function `obstack_ptr_grow_fast' adds `sizeof (void *)' bytes
-- containing the value of DATA to the growing object in obstack
-- OBSTACK-PTR.
--
-- - Function: void obstack_int_grow_fast (struct obstack *OBSTACK-PTR,
-- int DATA)
-- The function `obstack_int_grow_fast' adds `sizeof (int)' bytes
-- containing the value of DATA to the growing object in obstack
-- OBSTACK-PTR.
--
-- - Function: void obstack_blank_fast (struct obstack *OBSTACK-PTR, int
-- SIZE)
-- The function `obstack_blank_fast' adds SIZE bytes to the growing
-- object in obstack OBSTACK-PTR without initializing them.
--
-- When you check for space using `obstack_room' and there is not
--enough room for what you want to add, the fast growth functions are not
--safe. In this case, simply use the corresponding ordinary growth
--function instead. Very soon this will copy the object to a new chunk;
--then there will be lots of room available again.
--
-- So, each time you use an ordinary growth function, check afterward
--for sufficient space using `obstack_room'. Once the object is copied
--to a new chunk, there will be plenty of space again, so the program will
--start using the fast growth functions again.
--
-- Here is an example:
--
-- void
-- add_string (struct obstack *obstack, const char *ptr, int len)
-- {
-- while (len > 0)
-- {
-- int room = obstack_room (obstack);
-- if (room == 0)
-- {
-- /* Not enough room. Add one character slowly,
-- which may copy to a new chunk and make room. */
-- obstack_1grow (obstack, *ptr++);
-- len--;
-- }
-- else
-- {
-- if (room > len)
-- room = len;
-- /* Add fast as much as we have room for. */
-- len -= room;
-- while (room-- > 0)
-- obstack_1grow_fast (obstack, *ptr++);
-- }
-- }
-- }
--
--
--File: libc.info, Node: Status of an Obstack, Next: Obstacks Data Alignment, Prev: Extra Fast Growing, Up: Obstacks
--
--Status of an Obstack
----------------------
--
-- Here are functions that provide information on the current status of
--allocation in an obstack. You can use them to learn about an object
--while still growing it.
--
-- - Function: void * obstack_base (struct obstack *OBSTACK-PTR)
-- This function returns the tentative address of the beginning of the
-- currently growing object in OBSTACK-PTR. If you finish the object
-- immediately, it will have that address. If you make it larger
-- first, it may outgrow the current chunk--then its address will
-- change!
--
-- If no object is growing, this value says where the next object you
-- allocate will start (once again assuming it fits in the current
-- chunk).
--
-- - Function: void * obstack_next_free (struct obstack *OBSTACK-PTR)
-- This function returns the address of the first free byte in the
-- current chunk of obstack OBSTACK-PTR. This is the end of the
-- currently growing object. If no object is growing,
-- `obstack_next_free' returns the same value as `obstack_base'.
--
-- - Function: int obstack_object_size (struct obstack *OBSTACK-PTR)
-- This function returns the size in bytes of the currently growing
-- object. This is equivalent to
--
-- obstack_next_free (OBSTACK-PTR) - obstack_base (OBSTACK-PTR)
--
--
--File: libc.info, Node: Obstacks Data Alignment, Next: Obstack Chunks, Prev: Status of an Obstack, Up: Obstacks
--
--Alignment of Data in Obstacks
-------------------------------
--
-- Each obstack has an "alignment boundary"; each object allocated in
--the obstack automatically starts on an address that is a multiple of the
--specified boundary. By default, this boundary is 4 bytes.
--
-- To access an obstack's alignment boundary, use the macro
--`obstack_alignment_mask', whose function prototype looks like this:
--
-- - Macro: int obstack_alignment_mask (struct obstack *OBSTACK-PTR)
-- The value is a bit mask; a bit that is 1 indicates that the
-- corresponding bit in the address of an object should be 0. The
-- mask value should be one less than a power of 2; the effect is
-- that all object addresses are multiples of that power of 2. The
-- default value of the mask is 3, so that addresses are multiples of
-- 4. A mask value of 0 means an object can start on any multiple of
-- 1 (that is, no alignment is required).
--
-- The expansion of the macro `obstack_alignment_mask' is an lvalue,
-- so you can alter the mask by assignment. For example, this
-- statement:
--
-- obstack_alignment_mask (obstack_ptr) = 0;
--
-- has the effect of turning off alignment processing in the
-- specified obstack.
--
-- Note that a change in alignment mask does not take effect until
--*after* the next time an object is allocated or finished in the
--obstack. If you are not growing an object, you can make the new
--alignment mask take effect immediately by calling `obstack_finish'.
--This will finish a zero-length object and then do proper alignment for
--the next object.
--
--
--File: libc.info, Node: Obstack Chunks, Next: Summary of Obstacks, Prev: Obstacks Data Alignment, Up: Obstacks
--
--Obstack Chunks
----------------
--
-- Obstacks work by allocating space for themselves in large chunks, and
--then parceling out space in the chunks to satisfy your requests. Chunks
--are normally 4096 bytes long unless you specify a different chunk size.
--The chunk size includes 8 bytes of overhead that are not actually used
--for storing objects. Regardless of the specified size, longer chunks
--will be allocated when necessary for long objects.
--
-- The obstack library allocates chunks by calling the function
--`obstack_chunk_alloc', which you must define. When a chunk is no
--longer needed because you have freed all the objects in it, the obstack
--library frees the chunk by calling `obstack_chunk_free', which you must
--also define.
--
-- These two must be defined (as macros) or declared (as functions) in
--each source file that uses `obstack_init' (*note Creating Obstacks::.).
--Most often they are defined as macros like this:
--
-- #define obstack_chunk_alloc malloc
-- #define obstack_chunk_free free
--
-- Note that these are simple macros (no arguments). Macro definitions
--with arguments will not work! It is necessary that
--`obstack_chunk_alloc' or `obstack_chunk_free', alone, expand into a
--function name if it is not itself a function name.
--
-- If you allocate chunks with `malloc', the chunk size should be a
--power of 2. The default chunk size, 4096, was chosen because it is long
--enough to satisfy many typical requests on the obstack yet short enough
--not to waste too much memory in the portion of the last chunk not yet
--used.
--
-- - Macro: int obstack_chunk_size (struct obstack *OBSTACK-PTR)
-- This returns the chunk size of the given obstack.
--
-- Since this macro expands to an lvalue, you can specify a new chunk
--size by assigning it a new value. Doing so does not affect the chunks
--already allocated, but will change the size of chunks allocated for
--that particular obstack in the future. It is unlikely to be useful to
--make the chunk size smaller, but making it larger might improve
--efficiency if you are allocating many objects whose size is comparable
--to the chunk size. Here is how to do so cleanly:
--
-- if (obstack_chunk_size (obstack_ptr) < NEW-CHUNK-SIZE)
-- obstack_chunk_size (obstack_ptr) = NEW-CHUNK-SIZE;
--
--
--File: libc.info, Node: Summary of Obstacks, Prev: Obstack Chunks, Up: Obstacks
--
--Summary of Obstack Functions
------------------------------
--
-- Here is a summary of all the functions associated with obstacks.
--Each takes the address of an obstack (`struct obstack *') as its first
--argument.
--
--`void obstack_init (struct obstack *OBSTACK-PTR)'
-- Initialize use of an obstack. *Note Creating Obstacks::.
--
--`void *obstack_alloc (struct obstack *OBSTACK-PTR, int SIZE)'
-- Allocate an object of SIZE uninitialized bytes. *Note Allocation
-- in an Obstack::.
--
--`void *obstack_copy (struct obstack *OBSTACK-PTR, void *ADDRESS, int SIZE)'
-- Allocate an object of SIZE bytes, with contents copied from
-- ADDRESS. *Note Allocation in an Obstack::.
--
--`void *obstack_copy0 (struct obstack *OBSTACK-PTR, void *ADDRESS, int SIZE)'
-- Allocate an object of SIZE+1 bytes, with SIZE of them copied from
-- ADDRESS, followed by a null character at the end. *Note
-- Allocation in an Obstack::.
--
--`void obstack_free (struct obstack *OBSTACK-PTR, void *OBJECT)'
-- Free OBJECT (and everything allocated in the specified obstack
-- more recently than OBJECT). *Note Freeing Obstack Objects::.
--
--`void obstack_blank (struct obstack *OBSTACK-PTR, int SIZE)'
-- Add SIZE uninitialized bytes to a growing object. *Note Growing
-- Objects::.
--
--`void obstack_grow (struct obstack *OBSTACK-PTR, void *ADDRESS, int SIZE)'
-- Add SIZE bytes, copied from ADDRESS, to a growing object. *Note
-- Growing Objects::.
--
--`void obstack_grow0 (struct obstack *OBSTACK-PTR, void *ADDRESS, int SIZE)'
-- Add SIZE bytes, copied from ADDRESS, to a growing object, and then
-- add another byte containing a null character. *Note Growing
-- Objects::.
--
--`void obstack_1grow (struct obstack *OBSTACK-PTR, char DATA-CHAR)'
-- Add one byte containing DATA-CHAR to a growing object. *Note
-- Growing Objects::.
--
--`void *obstack_finish (struct obstack *OBSTACK-PTR)'
-- Finalize the object that is growing and return its permanent
-- address. *Note Growing Objects::.
--
--`int obstack_object_size (struct obstack *OBSTACK-PTR)'
-- Get the current size of the currently growing object. *Note
-- Growing Objects::.
--
--`void obstack_blank_fast (struct obstack *OBSTACK-PTR, int SIZE)'
-- Add SIZE uninitialized bytes to a growing object without checking
-- that there is enough room. *Note Extra Fast Growing::.
--
--`void obstack_1grow_fast (struct obstack *OBSTACK-PTR, char DATA-CHAR)'
-- Add one byte containing DATA-CHAR to a growing object without
-- checking that there is enough room. *Note Extra Fast Growing::.
--
--`int obstack_room (struct obstack *OBSTACK-PTR)'
-- Get the amount of room now available for growing the current
-- object. *Note Extra Fast Growing::.
--
--`int obstack_alignment_mask (struct obstack *OBSTACK-PTR)'
-- The mask used for aligning the beginning of an object. This is an
-- lvalue. *Note Obstacks Data Alignment::.
--
--`int obstack_chunk_size (struct obstack *OBSTACK-PTR)'
-- The size for allocating chunks. This is an lvalue. *Note Obstack
-- Chunks::.
--
--`void *obstack_base (struct obstack *OBSTACK-PTR)'
-- Tentative starting address of the currently growing object. *Note
-- Status of an Obstack::.
--
--`void *obstack_next_free (struct obstack *OBSTACK-PTR)'
-- Address just after the end of the currently growing object. *Note
-- Status of an Obstack::.
--
--
--File: libc.info, Node: Variable Size Automatic, Prev: Obstacks, Up: Memory Allocation
--
--Automatic Storage with Variable Size
--====================================
--
-- The function `alloca' supports a kind of half-dynamic allocation in
--which blocks are allocated dynamically but freed automatically.
--
-- Allocating a block with `alloca' is an explicit action; you can
--allocate as many blocks as you wish, and compute the size at run time.
--But all the blocks are freed when you exit the function that `alloca'
--was called from, just as if they were automatic variables declared in
--that function. There is no way to free the space explicitly.
--
-- The prototype for `alloca' is in `stdlib.h'. This function is a BSD
--extension.
--
-- - Function: void * alloca (size_t SIZE);
-- The return value of `alloca' is the address of a block of SIZE
-- bytes of storage, allocated in the stack frame of the calling
-- function.
--
-- Do not use `alloca' inside the arguments of a function call--you
--will get unpredictable results, because the stack space for the
--`alloca' would appear on the stack in the middle of the space for the
--function arguments. An example of what to avoid is `foo (x, alloca
--(4), y)'.
--
--* Menu:
--
--* Alloca Example:: Example of using `alloca'.
--* Advantages of Alloca:: Reasons to use `alloca'.
--* Disadvantages of Alloca:: Reasons to avoid `alloca'.
--* GNU C Variable-Size Arrays:: Only in GNU C, here is an alternative
-- method of allocating dynamically and
-- freeing automatically.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-40 glibc-2.1.3/manual/libc.info-40
---- ../glibc-2.1.3/manual/libc.info-40 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-40 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1028 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Database Example, Next: Netgroup Database, Prev: Group Database, Up: Users and Groups
--
--User and Group Database Example
--===============================
--
-- Here is an example program showing the use of the system database
--inquiry functions. The program prints some information about the user
--running the program.
--
-- #include <grp.h>
-- #include <pwd.h>
-- #include <sys/types.h>
-- #include <unistd.h>
-- #include <stdlib.h>
--
-- int
-- main (void)
-- {
-- uid_t me;
-- struct passwd *my_passwd;
-- struct group *my_group;
-- char **members;
--
-- /* Get information about the user ID. */
-- me = getuid ();
-- my_passwd = getpwuid (me);
-- if (!my_passwd)
-- {
-- printf ("Couldn't find out about user %d.\n", (int) me);
-- exit (EXIT_FAILURE);
-- }
--
-- /* Print the information. */
-- printf ("I am %s.\n", my_passwd->pw_gecos);
-- printf ("My login name is %s.\n", my_passwd->pw_name);
-- printf ("My uid is %d.\n", (int) (my_passwd->pw_uid));
-- printf ("My home directory is %s.\n", my_passwd->pw_dir);
-- printf ("My default shell is %s.\n", my_passwd->pw_shell);
--
-- /* Get information about the default group ID. */
-- my_group = getgrgid (my_passwd->pw_gid);
-- if (!my_group)
-- {
-- printf ("Couldn't find out about group %d.\n",
-- (int) my_passwd->pw_gid);
-- exit (EXIT_FAILURE);
-- }
--
-- /* Print the information. */
-- printf ("My default group is %s (%d).\n",
-- my_group->gr_name, (int) (my_passwd->pw_gid));
-- printf ("The members of this group are:\n");
-- members = my_group->gr_mem;
-- while (*members)
-- {
-- printf (" %s\n", *(members));
-- members++;
-- }
--
-- return EXIT_SUCCESS;
-- }
--
-- Here is some output from this program:
--
-- I am Throckmorton Snurd.
-- My login name is snurd.
-- My uid is 31093.
-- My home directory is /home/fsg/snurd.
-- My default shell is /bin/sh.
-- My default group is guest (12).
-- The members of this group are:
-- friedman
-- tami
--
--
--File: libc.info, Node: Netgroup Database, Prev: Database Example, Up: Users and Groups
--
--Netgroup Database
--=================
--
--* Menu:
--
--* Netgroup Data:: Data in the Netgroup database and where
-- it comes from.
--* Lookup Netgroup:: How to look for a particular netgroup.
--* Netgroup Membership:: How to test for netgroup membership.
--
--
--File: libc.info, Node: Netgroup Data, Next: Lookup Netgroup, Up: Netgroup Database
--
--Netgroup Data
---------------
--
-- Sometimes it is useful to group users according to other criteria
--(*note Group Database::.). E.g., it is useful to associate a certain
--group of users with a certain machine. On the other hand grouping of
--host names is not supported so far.
--
-- In Sun Microsystems SunOS appeared a new kind of database, the
--netgroup database. It allows to group hosts, users, and domain freely,
--giving them individual names. More concrete: a netgroup is a list of
--triples consisting of a host name, a user name, and a domain name,
--where any of the entries can be a wildcard entry, matching all inputs.
--A last possibility is that names of other netgroups can also be given
--in the list specifying a netgroup. So one can construct arbitrary
--hierarchies without loops.
--
-- Sun's implementation allows netgroups only for the `nis' or
--`nisplus' service *note Services in the NSS configuration::.. The
--implementation in the GNU C library has no such restriction. An entry
--in either of the input services must have the following form:
--
-- GROUPNAME ( GROUPNAME | `('HOSTNAME`,'USERNAME`,'`domainname'`)' )+
--
-- Any of the fields in the triple can be empty which means anything
--matches. While describing the functions we will see that the opposite
--case is useful as well. I.e., there may be entries which will not
--match any input. For entries like a name consisting of the single
--character `-' shall be used.
--
--
--File: libc.info, Node: Lookup Netgroup, Next: Netgroup Membership, Prev: Netgroup Data, Up: Netgroup Database
--
--Looking up one Netgroup
-------------------------
--
-- The lookup functions for netgroups are a bit different to all other
--system database handling functions. Since a single netgroup can contain
--many entries a two-step process is needed. First a single netgroup is
--selected and then one can iterate over all entries in this netgroup.
--These functions are declared in `netdb.h'.
--
-- - Function: int setnetgrent (const char *NETGROUP)
-- A call to this function initializes the internal state of the
-- library to allow following calls of the `getnetgrent' iterate over
-- all entries in the netgroup with name NETGROUP.
--
-- When the call is successful (i.e., when a netgroup with this name
-- exist) the return value is `1'. When the return value is `0' no
-- netgroup of this name is known or some other error occurred.
--
-- It is important to remember that there is only one single state for
--iterating the netgroups. Even if the programmer uses the
--`getnetgrent_r' function the result is not really reentrant since
--always only one single netgroup at a time can be processed. If the
--program needs to process more than one netgroup simultaneously she must
--protect this by using external locking. This problem was introduced in
--the original netgroups implementation in SunOS and since we must stay
--compatible it is not possible to change this.
--
-- Some other functions also use the netgroups state. Currently these
--are the `innetgr' function and parts of the implementation of the
--`compat' service part of the NSS implementation.
--
-- - Function: int getnetgrent (char **HOSTP, char **USERP, char
-- **DOMAINP)
-- This function returns the next unprocessed entry of the currently
-- selected netgroup. The string pointers, which addresses are
-- passed in the arguments HOSTP, USERP, and DOMAINP, will contain
-- after a successful call pointers to appropriate strings. If the
-- string in the next entry is empty the pointer has the value `NULL'.
-- The returned string pointers are only valid unless no of the
-- netgroup related functions are called.
--
-- The return value is `1' if the next entry was successfully read. A
-- value of `0' means no further entries exist or internal errors
-- occurred.
--
-- - Function: int getnetgrent_r (char **HOSTP, char **USERP, char
-- **DOMAINP, char *BUFFER, int BUFLEN)
-- This function is similar to `getnetgrent' with only one exception:
-- the strings the three string pointers HOSTP, USERP, and DOMAINP
-- point to, are placed in the buffer of BUFLEN bytes starting at
-- BUFFER. This means the returned values are valid even after other
-- netgroup related functions are called.
--
-- The return value is `1' if the next entry was successfully read and
-- the buffer contains enough room to place the strings in it. `0' is
-- returned in case no more entries are found, the buffer is too
-- small, or internal errors occurred.
--
-- This function is a GNU extension. The original implementation in
-- the SunOS libc does not provide this function.
--
-- - Function: void endnetgrent (void)
-- This function free all buffers which were allocated to process the
-- last selected netgroup. As a result all string pointers returned
-- by calls to `getnetgrent' are invalid afterwards.
--
--
--File: libc.info, Node: Netgroup Membership, Prev: Lookup Netgroup, Up: Netgroup Database
--
--Testing for Netgroup Membership
---------------------------------
--
-- It is often not necessary to scan the whole netgroup since often the
--only interesting question is whether a given entry is part of the
--selected netgroup.
--
-- - Function: int innetgr (const char *NETGROUP, const char *HOST, const
-- char *USER, const char *DOMAIN)
-- This function tests whether the triple specified by the parameters
-- HOSTP, USERP, and DOMAINP is part of the netgroup NETGROUP. Using
-- this function has the advantage that
--
-- 1. no other netgroup function can use the global netgroup state
-- since internal locking is used and
--
-- 2. the function is implemented more efficiently than successive
-- calls to the other `set'/`get'/`endnetgrent' functions.
--
-- Any of the pointers HOSTP, USERP, and DOMAINP can be `NULL' which
-- means any value is excepted in this position. This is also true
-- for the name `-' which should not match any other string otherwise.
--
-- The return value is `1' if an entry matching the given triple is
-- found in the netgroup. The return value is `0' if the netgroup
-- itself is not found, the netgroup does not contain the triple or
-- internal errors occurred.
--
--
--File: libc.info, Node: System Information, Next: System Configuration, Prev: Users and Groups, Up: Top
--
--System Information
--******************
--
-- This chapter describes functions that return information about the
--particular machine that is in use--the type of hardware, the type of
--software, and the individual machine's name.
--
--* Menu:
--
--* Host Identification:: Determining the name of the machine.
--* Hardware/Software Type ID:: Determining the hardware type of the
-- machine and what operating system it is
-- running.
--* Filesystem handling:: Which is mounted and/or available?
--
--
--File: libc.info, Node: Host Identification, Next: Hardware/Software Type ID, Up: System Information
--
--Host Identification
--===================
--
-- This section explains how to identify the particular machine that
--your program is running on. The identification of a machine consists
--of its Internet host name and Internet address; see *Note Internet
--Namespace::. The host name should always be a fully qualified domain
--name, like `crispy-wheats-n-chicken.ai.mit.edu', not a simple name like
--just `crispy-wheats-n-chicken'.
--
-- Prototypes for these functions appear in `unistd.h'. The shell
--commands `hostname' and `hostid' work by calling them.
--
-- - Function: int gethostname (char *NAME, size_t SIZE)
-- This function returns the name of the host machine in the array
-- NAME. The SIZE argument specifies the size of this array, in
-- bytes.
--
-- The return value is `0' on success and `-1' on failure. In the
-- GNU C library, `gethostname' fails if SIZE is not large enough;
-- then you can try again with a larger array. The following `errno'
-- error condition is defined for this function:
--
-- `ENAMETOOLONG'
-- The SIZE argument is less than the size of the host name plus
-- one.
--
-- On some systems, there is a symbol for the maximum possible host
-- name length: `MAXHOSTNAMELEN'. It is defined in `sys/param.h'.
-- But you can't count on this to exist, so it is cleaner to handle
-- failure and try again.
--
-- `gethostname' stores the beginning of the host name in NAME even
-- if the host name won't entirely fit. For some purposes, a
-- truncated host name is good enough. If it is, you can ignore the
-- error code.
--
-- - Function: int sethostname (const char *NAME, size_t LENGTH)
-- The `sethostname' function sets the name of the host machine to
-- NAME, a string with length LENGTH. Only privileged processes are
-- allowed to do this. Usually it happens just once, at system boot
-- time.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error condition is defined for this function:
--
-- `EPERM'
-- This process cannot set the host name because it is not
-- privileged.
--
-- - Function: long int gethostid (void)
-- This function returns the "host ID" of the machine the program is
-- running on. By convention, this is usually the primary Internet
-- address of that machine, converted to a `long int'. However, some
-- systems it is a meaningless but unique number which is hard-coded
-- for each machine.
--
-- - Function: int sethostid (long int ID)
-- The `sethostid' function sets the "host ID" of the host machine to
-- ID. Only privileged processes are allowed to do this. Usually it
-- happens just once, at system boot time.
--
-- The return value is `0' on success and `-1' on failure. The
-- following `errno' error condition is defined for this function:
--
-- `EPERM'
-- This process cannot set the host name because it is not
-- privileged.
--
-- `ENOSYS'
-- The operating system does not support setting the host ID.
-- On some systems, the host ID is a meaningless but unique
-- number hard-coded for each machine.
--
--
--File: libc.info, Node: Hardware/Software Type ID, Next: Filesystem handling, Prev: Host Identification, Up: System Information
--
--Hardware/Software Type Identification
--=====================================
--
-- You can use the `uname' function to find out some information about
--the type of computer your program is running on. This function and the
--associated data type are declared in the header file `sys/utsname.h'.
--
-- - Data Type: struct utsname
-- The `utsname' structure is used to hold information returned by
-- the `uname' function. It has the following members:
--
-- `char sysname[]'
-- This is the name of the operating system in use.
--
-- `char nodename[]'
-- This is the network name of this particular computer. In the
-- GNU library, the value is the same as that returned by
-- `gethostname'; see *Note Host Identification::.
--
-- `char release[]'
-- This is the current release level of the operating system
-- implementation.
--
-- `char version[]'
-- This is the current version level within the release of the
-- operating system.
--
-- `char machine[]'
-- This is a description of the type of hardware that is in use.
--
-- Some systems provide a mechanism to interrogate the kernel
-- directly for this information. On systems without such a
-- mechanism, the GNU C library fills in this field based on the
-- configuration name that was specified when building and
-- installing the library.
--
-- GNU uses a three-part name to describe a system
-- configuration; the three parts are CPU, MANUFACTURER and
-- SYSTEM-TYPE, and they are separated with dashes. Any
-- possible combination of three names is potentially
-- meaningful, but most such combinations are meaningless in
-- practice and even the meaningful ones are not necessarily
-- supported by any particular GNU program.
--
-- Since the value in `machine' is supposed to describe just the
-- hardware, it consists of the first two parts of the
-- configuration name: `CPU-MANUFACTURER'. For example, it
-- might be one of these:
--
-- `"sparc-sun"', `"i386-ANYTHING"', `"m68k-hp"',
-- `"m68k-sony"', `"m68k-sun"', `"mips-dec"'
--
-- - Function: int uname (struct utsname *INFO)
-- The `uname' function fills in the structure pointed to by INFO
-- with information about the operating system and host machine. A
-- non-negative value indicates that the data was successfully stored.
--
-- `-1' as the value indicates an error. The only error possible is
-- `EFAULT', which we normally don't mention as it is always a
-- possibility.
--
--
--File: libc.info, Node: Filesystem handling, Prev: Hardware/Software Type ID, Up: System Information
--
--Which filesystems are mounted and/or available?
--===============================================
--
-- The Unix concept of *Everything is a file* is based on the
--possibility to "mount" filesystems or other things into the filesystem.
--For some programs it is desirable and necessary to access the
--information whether and, if yes, where a certain filesystem is mounted
--or simply to get lists of all the available filesystems. The GNU libc
--provides some functions to retrieve this information portably.
--
-- Traditionally Unix systems have a file named `/etc/fstab' which
--describes all possibly mounted filesystems. The `mount' program uses
--this file to mount at startup time of the system all the necessary
--filesystems. The information about all the filesystems actually mounted
--is normally kept in a file named `/etc/mtab'. Both files share the
--same syntax and it is crucial that this syntax is followed all the
--time. Therefore it is best to never directly write the files. The
--functions described in this section can do this and they also provide
--the functionality to convert the external textual representation to the
--internal representation.
--
-- The filenames given above should never be used directly. The
--portable way to handle these file is to use the macros `_PATH_FSTAB',
--defined in `fstab.h' and `_PATH_MNTTAB', defined in `mntent.h',
--respectively. There are also two alternate macro names `FSTAB' and
--`_PATH_MOUNTED' defined but both names are deprecated and kept only for
--backward compatibility. The two former names should always be used.
--
-- The internal representation for entries of the file is
--`struct fstab', defined in `fstab.h'.
--
-- - Data Type: struct fstab
-- This structure is used with the `getfsent', `getfsspec', and
-- `getfsfile' functions.
--
-- `char *fs_spec'
-- This element describes the device from which the filesystem
-- is mounted. Normally this is the name of a special device,
-- such as a hard disk partition, but it could also be a more or
-- less generic string. For "NFS" it would be a hostname and
-- directory name combination.
--
-- Even though the element is not declared `const' it shouldn't
-- be modified. The missing `const' has historic reasons, since
-- this function predates ISO C. The same is true for the other
-- string elements of this structure.
--
-- `char *fs_file'
-- This describes the mount point on the local system. I.e.,
-- accessing any file in this filesystem has implicitly or
-- explicitly this string as a prefix.
--
-- `char *fs_vfstype'
-- This is the type of the filesystem. Depending on what the
-- underlying kernel understands it can be any string.
--
-- `char *fs_mntops'
-- This is a string containing options passed to the kernel with
-- the `mount' call. Again, this can be almost anything. There
-- can be more than one option, separated from the others by a
-- comma. Each option consists of a name and an optional value
-- part, introduced by an `=' character.
--
-- If the value of this element must be processed it should best
-- happen using the `getsubopt' function; see *Note Suboptions::.
--
-- `const char *fs_type'
-- This name is poorly chosen. This element points to a string
-- (possibly in the `fs_mntops' string) which describes the
-- modes with which the filesystem is mounted. `fstab' defines
-- five macros to describe the possible values:
--
-- `FSTAB_RW'
-- The filesystems gets mounted with read and write enabled.
--
-- `FSTAB_RQ'
-- The filesystems gets mounted with read and write
-- enabled. Write access is restricted by quotas.
--
-- `FSTAB_RO'
-- The filesystem gets mounted read-only.
--
-- `FSTAB_SW'
-- This is not a real filesystem, it is a swap device.
--
-- `FSTAB_XX'
-- This entry from the `fstab' file is totally ignored.
--
-- Testing for equality with these value must happen using
-- `strcmp' since these are all strings. Comparing the pointer
-- will probably always fail.
--
-- `int fs_freq'
-- This element describes the dump frequency in days.
--
-- `int fs_passno'
-- This element describes the pass number on parallel dumps. It
-- is closely related to the `dump' utility used on Unix systems.
--
-- To read the entire content of the of the `fstab' file the GNU libc
--contains a set of three functions which are designed in the usual way.
--
-- - Function: int setfsent (void)
-- This function makes sure that the internal read pointer for the
-- `fstab' file is at the beginning of the file. This is done by
-- either opening the file or resetting the read pointer.
--
-- Since the file handle is internal to the libc this function is not
-- thread-safe.
--
-- This function returns a non-zero value if the operation was
-- successful and the `getfs*' functions can be used to read the
-- entries of the file.
--
-- - Function: void endfsent (void)
-- This function makes sure that all resources acquired by a prior
-- call to `setfsent' (explicitly or implicitly by calling
-- `getfsent') are freed.
--
-- - Function: struct fstab * getfsent (void)
-- This function returns the next entry of the `fstab' file. If this
-- is the first call to any of the functions handling `fstab' since
-- program start or the last call of `endfsent', the file will be
-- opened.
--
-- The function returns a pointer to an variable of type `struct
-- fstab'. This variable is shared by all threads and therefore this
-- function is not thread-safe. If an error occurred `getfsent'
-- returns a `NULL' pointer.
--
-- - Function: struct fstab * getfsspec (const char *NAME)
-- This function returns the next entry of the `fstab' file which has
-- a string equal to NAME pointed to by the `fs_spec' element. Since
-- there is normally exactly one entry for each special device it
-- makes no sense to call this function more than once for the same
-- argument. If this is the first call to any of the functions
-- handling `fstab' since program start or the last call of
-- `endfsent', the file will be opened.
--
-- The function returns a pointer to an variable of type `struct
-- fstab'. This variable is shared by all threads and therefore this
-- function is not thread-safe. If an error occurred `getfsent'
-- returns a `NULL' pointer.
--
-- - Function: struct fstab * getfsfile (const char *NAME)
-- This function returns the next entry of the `fstab' file which has
-- a string equal to NAME pointed to by the `fs_file' element. Since
-- there is normally exactly one entry for each mount point it makes
-- no sense to call this function more than once for the same
-- argument. If this is the first call to any of the functions
-- handling `fstab' since program start or the last call of
-- `endfsent', the file will be opened.
--
-- The function returns a pointer to an variable of type `struct
-- fstab'. This variable is shared by all threads and therefore this
-- function is not thread-safe. If an error occurred `getfsent'
-- returns a `NULL' pointer.
--
-- To access the `mtab' file there is a different set of functions and
--also a different structure to describe the results.
--
-- - Data Type: struct mntent
-- This structure is used with the `getmntent', `getmntent_t',
-- `addmntent', and `hasmntopt' functions.
--
-- `char *mnt_fsname'
-- This element contains a pointer to a string describing the
-- name of the special device from which the filesystem is
-- mounted. It corresponds to the `fs_spec' element in `struct
-- fstab'.
--
-- `char *mnt_dir'
-- This element points to a string describing the mount point of
-- the filesystem. It corresponds to the `fs_file' element in
-- `struct fstab'.
--
-- `char *mnt_type'
-- `mnt_type' describes the filesystem type and is therefore
-- equivalent to `fs_vfstype' in `struct fstab'. `mntent.h'
-- defines a few symbolic names for some of the value this
-- string can have. But since the kernel can support an
-- arbitrary filesystems it does not make much sense to give
-- them symbolic names. If one knows the symbol name one also
-- knows the filesystem name. Nevertheless here follows the
-- list of the symbol provided in `mntent.h'.
--
-- `MNTTYPE_IGNORE'
-- This symbol expands to `"ignore"'. The value is
-- sometime used in `fstab' files to make sure entries are
-- not used without removing them.
--
-- `MNTTYPE_NFS'
-- Expands to `"nfs"'. Using this macro sometimes could
-- make sense since it names the default NFS
-- implementation, in case both version 2 and 3 are
-- supported.
--
-- `MNTTYPE_SWAP'
-- This symbol expands to `"swap"'. It names the special
-- `fstab' entry which names one of the possibly multiple
-- swap partitions.
--
-- `char *mnt_opts'
-- The element contains a string describing the options used
-- while mounting the filesystem. As for the equivalent element
-- `fs_mntops' of `struct fstab' it is best to use the function
-- `getsubopt' (*note Suboptions::.) to access the parts of this
-- string.
--
-- The `mntent.h' file defines a number of macros with string
-- values which correspond to some of the options understood by
-- the kernel. There might be many more options which are
-- possible so it makes not much sense to rely on these macros
-- but to be consistent here is the list:
--
-- `MNTOPT_DEFAULTS'
-- Expands to `"defaults"'. This option should be used
-- alone since it indicates all values for the custumizable
-- values are chosen to be the default.
--
-- `MNTOPT_RO'
-- Expands to `"ro"'. See the `FSTAB_RO' value, it means
-- the filesystem is mounted read-only.
--
-- `MNTOPT_RW'
-- Expand to `"rw"'. See the `FSTAB_RW' value, it means the
-- filesystem is mounted with read and write permissions.
--
-- `MNTOPT_SUID'
-- Expands to `"suid"'. This means that the SUID bit
-- (*note How Change Persona::.) is respected when a
-- program from the filesystem is started.
--
-- `MNTOPT_NOSUID'
-- Expands to `"nosuid"'. This is the opposite of
-- `MNTOPT_SUID', the SUID bit for all files from the
-- filesystem is ignored.
--
-- `MNTOPT_NOAUTO'
-- Expands to `"noauto"'. At startup time the `mount'
-- program will ignore this entry if it is started with the
-- `-a' option to mount all filesystems mentioned in the
-- `fstab' file.
--
-- As for the `FSTAB_*' entries introduced above it is important
-- to use `strcmp' to check for equality.
--
-- `mnt_freq'
-- This elements corresponds to `fs_freq' and also specifies the
-- frequency in days in which dumps are made.
--
-- `mnt_passno'
-- This element is equivalent to `fs_passno' with the same
-- meaning which is uninteresting for all programs beside `dump'.
--
-- For accessing the `mtab' file there is again a set of three
--functions to access all entries in a row. Unlike the functions to
--handle `fstab' these functions do not access a fixed file and there is
--even a thread safe variant of the get function. Beside this the GNU
--libc contains functions to alter the file and test for specific options.
--
-- - Function: FILE * setmntent (const char *FILE, const char *MODE)
-- The `setmntent' function prepares the file named FILE which must
-- be in the format of a `fstab' and `mtab' file for the upcoming
-- processing through the other functions of the family. The MODE
-- parameter can be chosen in the way the OPENTYPE parameter for
-- `fopen' (*note Opening Streams::.) can be chosen. If the file is
-- opened for writing the file is also allowed to be empty.
--
-- If the file was successfully opened `setmntent' returns a file
-- descriptor for future use. Otherwise the return value is `NULL'
-- and `errno' is set accordingly.
--
-- - Function: int endmntent (FILE *STREAM)
-- This function takes for the STREAM parameter a file handle which
-- previously was returned from the `setmntent' call. `endmntent'
-- closes the stream and frees all resources.
--
-- The return value is 1 unless an error occurred in which case it is
-- 0.
--
-- - Function: struct mntent * getmntent (FILE *STREAM)
-- The `getmntent' function takes as the parameter a file handle
-- previously returned by successful call to `setmntent'. It returns
-- a pointer to a static variable of type `struct mntent' which is
-- filled with the information from the next entry from the file
-- currently read.
--
-- If there was an error or the end of the file is reached the return
-- value is `NULL'.
--
-- This function is not thread-safe since all calls to this function
-- return a pointer to the same static variable. `getmntent_r'
-- should be used in situations where multiple threads access the
-- file.
--
-- - Function: struct mntent * getmntent_r (FILE *STREAM, struct mentent
-- *RESULT, char *BUFFER, int BUFSIZE)
-- The `getmntent_r' function is the reentrant variant of
-- `getmntent'. It also returns the next entry from the file and
-- returns a pointer. The actual variable the values are stored in
-- is not static, though. Instead the function stores the values in
-- the variable pointed to by the RESULT parameter. Additional
-- information (e.g., the strings pointed to by the elements of the
-- result) are kept in the buffer of size BUFSIZE pointed to by
-- BUFFER.
--
-- The function returns a `NULL' pointer in error cases. Errors
-- could be:
-- * error while reading the file,
--
-- * end of file reached,
--
-- * BUFSIZE is too small for reading a complete new entry.
--
-- - Function: int addmntent (FILE *STREAM, const struct mntent *MNT)
-- The `addmntent' function allows to add a new entry to the file
-- previously opened with `setmntent'. The new entries are always
-- appended. I.e., even if the position of the file descriptor is
-- not at the end of the file this function does not overwrite an
-- existing entry following the current position.
--
-- The implication of this is that to remove an entry from a file one
-- has to create a new file while leaving out the entry to be removed
-- and after closing the file remove the old one and rename the new
-- file to the chosen name.
--
-- This function returns 0 in case the operation was successful.
-- Otherwise the return value is 1 and `errno' is set appropriately.
--
-- - Function: char * hasmntopt (const struct mntent *MNT, const char
-- *OPT)
-- This function can be used to check whether the string pointed to
-- by the `mnt_opts' element of the variable pointed to by MNT
-- contains the option OPT. If this is true a pointer to the
-- beginning of the option in the `mnt_opts' element is returned. If
-- no such option exists the function returns `NULL'.
--
-- This function is useful to test whether a specific option is
-- present but when all options have to be processed one is better
-- off with using the `getsubopt' function to iterate over all
-- options in the string.
--
--
--File: libc.info, Node: System Configuration, Next: Cryptographic Functions, Prev: System Information, Up: Top
--
--System Configuration Parameters
--*******************************
--
-- The functions and macros listed in this chapter give information
--about configuration parameters of the operating system--for example,
--capacity limits, presence of optional POSIX features, and the default
--path for executable files (*note String Parameters::.).
--
--* Menu:
--
--* General Limits:: Constants and functions that describe
-- various process-related limits that have
-- one uniform value for any given machine.
--* System Options:: Optional POSIX features.
--* Version Supported:: Version numbers of POSIX.1 and POSIX.2.
--* Sysconf:: Getting specific configuration values
-- of general limits and system options.
--* Minimums:: Minimum values for general limits.
--
--* Limits for Files:: Size limitations that pertain to individual files.
-- These can vary between file systems
-- or even from file to file.
--* Options for Files:: Optional features that some files may support.
--* File Minimums:: Minimum values for file limits.
--* Pathconf:: Getting the limit values for a particular file.
--
--* Utility Limits:: Capacity limits of some POSIX.2 utility programs.
--* Utility Minimums:: Minimum allowable values of those limits.
--
--* String Parameters:: Getting the default search path.
--
--
--File: libc.info, Node: General Limits, Next: System Options, Up: System Configuration
--
--General Capacity Limits
--=======================
--
-- The POSIX.1 and POSIX.2 standards specify a number of parameters that
--describe capacity limitations of the system. These limits can be fixed
--constants for a given operating system, or they can vary from machine to
--machine. For example, some limit values may be configurable by the
--system administrator, either at run time or by rebuilding the kernel,
--and this should not require recompiling application programs.
--
-- Each of the following limit parameters has a macro that is defined in
--`limits.h' only if the system has a fixed, uniform limit for the
--parameter in question. If the system allows different file systems or
--files to have different limits, then the macro is undefined; use
--`sysconf' to find out the limit that applies at a particular time on a
--particular machine. *Note Sysconf::.
--
-- Each of these parameters also has another macro, with a name starting
--with `_POSIX', which gives the lowest value that the limit is allowed
--to have on *any* POSIX system. *Note Minimums::.
--
-- - Macro: int ARG_MAX
-- If defined, the unvarying maximum combined length of the ARGV and
-- ENVIRON arguments that can be passed to the `exec' functions.
--
-- - Macro: int CHILD_MAX
-- If defined, the unvarying maximum number of processes that can
-- exist with the same real user ID at any one time. In BSD and GNU,
-- this is controlled by the `RLIMIT_NPROC' resource limit; *note
-- Limits on Resources::..
--
-- - Macro: int OPEN_MAX
-- If defined, the unvarying maximum number of files that a single
-- process can have open simultaneously. In BSD and GNU, this is
-- controlled by the `RLIMIT_NOFILE' resource limit; *note Limits on
-- Resources::..
--
-- - Macro: int STREAM_MAX
-- If defined, the unvarying maximum number of streams that a single
-- process can have open simultaneously. *Note Opening Streams::.
--
-- - Macro: int TZNAME_MAX
-- If defined, the unvarying maximum length of a time zone name.
-- *Note Time Zone Functions::.
--
-- These limit macros are always defined in `limits.h'.
--
-- - Macro: int NGROUPS_MAX
-- The maximum number of supplementary group IDs that one process can
-- have.
--
-- The value of this macro is actually a lower bound for the maximum.
-- That is, you can count on being able to have that many
-- supplementary group IDs, but a particular machine might let you
-- have even more. You can use `sysconf' to see whether a particular
-- machine will let you have more (*note Sysconf::.).
--
-- - Macro: int SSIZE_MAX
-- The largest value that can fit in an object of type `ssize_t'.
-- Effectively, this is the limit on the number of bytes that can be
-- read or written in a single operation.
--
-- This macro is defined in all POSIX systems because this limit is
-- never configurable.
--
-- - Macro: int RE_DUP_MAX
-- The largest number of repetitions you are guaranteed is allowed in
-- the construct `\{MIN,MAX\}' in a regular expression.
--
-- The value of this macro is actually a lower bound for the maximum.
-- That is, you can count on being able to have that many
-- repetitions, but a particular machine might let you have even
-- more. You can use `sysconf' to see whether a particular machine
-- will let you have more (*note Sysconf::.). And even the value
-- that `sysconf' tells you is just a lower bound--larger values
-- might work.
--
-- This macro is defined in all POSIX.2 systems, because POSIX.2 says
-- it should always be defined even if there is no specific imposed
-- limit.
--
--
--File: libc.info, Node: System Options, Next: Version Supported, Prev: General Limits, Up: System Configuration
--
--Overall System Options
--======================
--
-- POSIX defines certain system-specific options that not all POSIX
--systems support. Since these options are provided in the kernel, not
--in the library, simply using the GNU C library does not guarantee any
--of these features is supported; it depends on the system you are using.
--
-- You can test for the availability of a given option using the macros
--in this section, together with the function `sysconf'. The macros are
--defined only if you include `unistd.h'.
--
-- For the following macros, if the macro is defined in `unistd.h',
--then the option is supported. Otherwise, the option may or may not be
--supported; use `sysconf' to find out. *Note Sysconf::.
--
-- - Macro: int _POSIX_JOB_CONTROL
-- If this symbol is defined, it indicates that the system supports
-- job control. Otherwise, the implementation behaves as if all
-- processes within a session belong to a single process group.
-- *Note Job Control::.
--
-- - Macro: int _POSIX_SAVED_IDS
-- If this symbol is defined, it indicates that the system remembers
-- the effective user and group IDs of a process before it executes an
-- executable file with the set-user-ID or set-group-ID bits set, and
-- that explicitly changing the effective user or group IDs back to
-- these values is permitted. If this option is not defined, then if
-- a nonprivileged process changes its effective user or group ID to
-- the real user or group ID of the process, it can't change it back
-- again. *Note Enable/Disable Setuid::.
--
-- For the following macros, if the macro is defined in `unistd.h',
--then its value indicates whether the option is supported. A value of
--`-1' means no, and any other value means yes. If the macro is not
--defined, then the option may or may not be supported; use `sysconf' to
--find out. *Note Sysconf::.
--
-- - Macro: int _POSIX2_C_DEV
-- If this symbol is defined, it indicates that the system has the
-- POSIX.2 C compiler command, `c89'. The GNU C library always
-- defines this as `1', on the assumption that you would not have
-- installed it if you didn't have a C compiler.
--
-- - Macro: int _POSIX2_FORT_DEV
-- If this symbol is defined, it indicates that the system has the
-- POSIX.2 Fortran compiler command, `fort77'. The GNU C library
-- never defines this, because we don't know what the system has.
--
-- - Macro: int _POSIX2_FORT_RUN
-- If this symbol is defined, it indicates that the system has the
-- POSIX.2 `asa' command to interpret Fortran carriage control. The
-- GNU C library never defines this, because we don't know what the
-- system has.
--
-- - Macro: int _POSIX2_LOCALEDEF
-- If this symbol is defined, it indicates that the system has the
-- POSIX.2 `localedef' command. The GNU C library never defines
-- this, because we don't know what the system has.
--
-- - Macro: int _POSIX2_SW_DEV
-- If this symbol is defined, it indicates that the system has the
-- POSIX.2 commands `ar', `make', and `strip'. The GNU C library
-- always defines this as `1', on the assumption that you had to have
-- `ar' and `make' to install the library, and it's unlikely that
-- `strip' would be absent when those are present.
--
--
--File: libc.info, Node: Version Supported, Next: Sysconf, Prev: System Options, Up: System Configuration
--
--Which Version of POSIX is Supported
--===================================
--
-- - Macro: long int _POSIX_VERSION
-- This constant represents the version of the POSIX.1 standard to
-- which the implementation conforms. For an implementation
-- conforming to the 1995 POSIX.1 standard, the value is the integer
-- `199506L'.
--
-- `_POSIX_VERSION' is always defined (in `unistd.h') in any POSIX
-- system.
--
-- *Usage Note:* Don't try to test whether the system supports POSIX
-- by including `unistd.h' and then checking whether `_POSIX_VERSION'
-- is defined. On a non-POSIX system, this will probably fail
-- because there is no `unistd.h'. We do not know of *any* way you
-- can reliably test at compilation time whether your target system
-- supports POSIX or whether `unistd.h' exists.
--
-- The GNU C compiler predefines the symbol `__POSIX__' if the target
-- system is a POSIX system. Provided you do not use any other
-- compilers on POSIX systems, testing `defined (__POSIX__)' will
-- reliably detect such systems.
--
-- - Macro: long int _POSIX2_C_VERSION
-- This constant represents the version of the POSIX.2 standard which
-- the library and system kernel support. We don't know what value
-- this will be for the first version of the POSIX.2 standard,
-- because the value is based on the year and month in which the
-- standard is officially adopted.
--
-- The value of this symbol says nothing about the utilities
-- installed on the system.
--
-- *Usage Note:* You can use this macro to tell whether a POSIX.1
-- system library supports POSIX.2 as well. Any POSIX.1 system
-- contains `unistd.h', so include that file and then test `defined
-- (_POSIX2_C_VERSION)'.
--
--
--File: libc.info, Node: Sysconf, Next: Minimums, Prev: Version Supported, Up: System Configuration
--
--Using `sysconf'
--===============
--
-- When your system has configurable system limits, you can use the
--`sysconf' function to find out the value that applies to any particular
--machine. The function and the associated PARAMETER constants are
--declared in the header file `unistd.h'.
--
--* Menu:
--
--* Sysconf Definition:: Detailed specifications of `sysconf'.
--* Constants for Sysconf:: The list of parameters `sysconf' can read.
--* Examples of Sysconf:: How to use `sysconf' and the parameter
-- macros properly together.
--
--
--File: libc.info, Node: Sysconf Definition, Next: Constants for Sysconf, Up: Sysconf
--
--Definition of `sysconf'
-------------------------
--
-- - Function: long int sysconf (int PARAMETER)
-- This function is used to inquire about runtime system parameters.
-- The PARAMETER argument should be one of the `_SC_' symbols listed
-- below.
--
-- The normal return value from `sysconf' is the value you requested.
-- A value of `-1' is returned both if the implementation does not
-- impose a limit, and in case of an error.
--
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EINVAL'
-- The value of the PARAMETER is invalid.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-41 glibc-2.1.3/manual/libc.info-41
---- ../glibc-2.1.3/manual/libc.info-41 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-41 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1269 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Constants for Sysconf, Next: Examples of Sysconf, Prev: Sysconf Definition, Up: Sysconf
--
--Constants for `sysconf' Parameters
------------------------------------
--
-- Here are the symbolic constants for use as the PARAMETER argument to
--`sysconf'. The values are all integer constants (more specifically,
--enumeration type values).
--
--`_SC_ARG_MAX'
-- Inquire about the parameter corresponding to `ARG_MAX'.
--
--`_SC_CHILD_MAX'
-- Inquire about the parameter corresponding to `CHILD_MAX'.
--
--`_SC_OPEN_MAX'
-- Inquire about the parameter corresponding to `OPEN_MAX'.
--
--`_SC_STREAM_MAX'
-- Inquire about the parameter corresponding to `STREAM_MAX'.
--
--`_SC_TZNAME_MAX'
-- Inquire about the parameter corresponding to `TZNAME_MAX'.
--
--`_SC_NGROUPS_MAX'
-- Inquire about the parameter corresponding to `NGROUPS_MAX'.
--
--`_SC_JOB_CONTROL'
-- Inquire about the parameter corresponding to `_POSIX_JOB_CONTROL'.
--
--`_SC_SAVED_IDS'
-- Inquire about the parameter corresponding to `_POSIX_SAVED_IDS'.
--
--`_SC_VERSION'
-- Inquire about the parameter corresponding to `_POSIX_VERSION'.
--
--`_SC_CLK_TCK'
-- Inquire about the parameter corresponding to `CLOCKS_PER_SEC';
-- *note Basic CPU Time::..
--
--`_SC_CHARCLASS_NAME_MAX'
-- Inquire about the parameter corresponding to maximal length
-- allowed for a character class name in an extended locale
-- specification. These extensions are not yet standardized and so
-- this option is not standardized as well.
--
--`_SC_REALTIME_SIGNALS'
-- Inquire about the parameter corresponding to
-- `_POSIX_REALTIME_SIGNALS'.
--
--`_SC_PRIORITY_SCHEDULING'
-- Inquire about the parameter corresponding to
-- `_POSIX_PRIORITY_SCHEDULING'.
--
--`_SC_TIMERS'
-- Inquire about the parameter corresponding to `_POSIX_TIMERS'.
--
--`_SC_ASYNCHRONOUS_IO'
-- Inquire about the parameter corresponding to
-- `_POSIX_ASYNCHRONOUS_IO'.
--
--`_SC_PRIORITIZED_IO'
-- Inquire about the parameter corresponding to
-- `_POSIX_PRIORITIZED_IO'.
--
--`_SC_SYNCHRONIZED_IO'
-- Inquire about the parameter corresponding to
-- `_POSIX_SYNCHRONIZED_IO'.
--
--`_SC_FSYNC'
-- Inquire about the parameter corresponding to `_POSIX_FSYNC'.
--
--`_SC_MAPPED_FILES'
-- Inquire about the parameter corresponding to `_POSIX_MAPPED_FILES'.
--
--`_SC_MEMLOCK'
-- Inquire about the parameter corresponding to `_POSIX_MEMLOCK'.
--
--`_SC_MEMLOCK_RANGE'
-- Inquire about the parameter corresponding to
-- `_POSIX_MEMLOCK_RANGE'.
--
--`_SC_MEMORY_PROTECTION'
-- Inquire about the parameter corresponding to
-- `_POSIX_MEMORY_PROTECTION'.
--
--`_SC_MESSAGE_PASSING'
-- Inquire about the parameter corresponding to
-- `_POSIX_MESSAGE_PASSING'.
--
--`_SC_SEMAPHORES'
-- Inquire about the parameter corresponding to `_POSIX_SEMAPHORES'.
--
--`_SC_SHARED_MEMORY_OBJECTS'
-- Inquire about the parameter corresponding to
-- `_POSIX_SHARED_MEMORY_OBJECTS'.
--
--`_SC_AIO_LISTIO_MAX'
-- Inquire about the parameter corresponding to
-- `_POSIX_AIO_LISTIO_MAX'.
--
--`_SC_AIO_MAX'
-- Inquire about the parameter corresponding to `_POSIX_AIO_MAX'.
--
--`_SC_AIO_PRIO_DELTA_MAX'
-- Inquire the value by which a process can decrease its asynchronous
-- I/O priority level from its own scheduling priority. This
-- corresponds to the run-time invariant value `AIO_PRIO_DELTA_MAX'.
--
--`_SC_DELAYTIMER_MAX'
-- Inquire about the parameter corresponding to
-- `_POSIX_DELAYTIMER_MAX'.
--
--`_SC_MQ_OPEN_MAX'
-- Inquire about the parameter corresponding to `_POSIX_MQ_OPEN_MAX'.
--
--`_SC_MQ_PRIO_MAX'
-- Inquire about the parameter corresponding to `_POSIX_MQ_PRIO_MAX'.
--
--`_SC_RTSIG_MAX'
-- Inquire about the parameter corresponding to `_POSIX_RTSIG_MAX'.
--
--`_SC_SEM_NSEMS_MAX'
-- Inquire about the parameter corresponding to
-- `_POSIX_SEM_NSEMS_MAX'.
--
--`_SC_SEM_VALUE_MAX'
-- Inquire about the parameter corresponding to
-- `_POSIX_SEM_VALUE_MAX'.
--
--`_SC_SIGQUEUE_MAX'
-- Inquire about the parameter corresponding to `_POSIX_SIGQUEUE_MAX'.
--
--`_SC_TIMER_MAX'
-- Inquire about the parameter corresponding to `_POSIX_TIMER_MAX'.
--
--`_SC_PII'
-- Inquire about the parameter corresponding to `_POSIX_PII'.
--
--`_SC_PII_XTI'
-- Inquire about the parameter corresponding to `_POSIX_PII_XTI'.
--
--`_SC_PII_SOCKET'
-- Inquire about the parameter corresponding to `_POSIX_PII_SOCKET'.
--
--`_SC_PII_INTERNET'
-- Inquire about the parameter corresponding to `_POSIX_PII_INTERNET'.
--
--`_SC_PII_OSI'
-- Inquire about the parameter corresponding to `_POSIX_PII_OSI'.
--
--`_SC_SELECT'
-- Inquire about the parameter corresponding to `_POSIX_SELECT'.
--
--`_SC_UIO_MAXIOV'
-- Inquire about the parameter corresponding to `_POSIX_UIO_MAXIOV'.
--
--`_SC_PII_INTERNET_STREAM'
-- Inquire about the parameter corresponding to
-- `_POSIX_PII_INTERNET_STREAM'.
--
--`_SC_PII_INTERNET_DGRAM'
-- Inquire about the parameter corresponding to
-- `_POSIX_PII_INTERNET_DGRAM'.
--
--`_SC_PII_OSI_COTS'
-- Inquire about the parameter corresponding to `_POSIX_PII_OSI_COTS'.
--
--`_SC_PII_OSI_CLTS'
-- Inquire about the parameter corresponding to `_POSIX_PII_OSI_CLTS'.
--
--`_SC_PII_OSI_M'
-- Inquire about the parameter corresponding to `_POSIX_PII_OSI_M'.
--
--`_SC_T_IOV_MAX'
-- Inquire the value of the value associated with the `T_IOV_MAX'
-- variable.
--
--`_SC_THREADS'
-- Inquire about the parameter corresponding to `_POSIX_THREADS'.
--
--`_SC_THREAD_SAFE_FUNCTIONS'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_SAFE_FUNCTIONS'.
--
--`_SC_GETGR_R_SIZE_MAX'
-- Inquire about the parameter corresponding to
-- `_POSIX_GETGR_R_SIZE_MAX'.
--
--`_SC_GETPW_R_SIZE_MAX'
-- Inquire about the parameter corresponding to
-- `_POSIX_GETPW_R_SIZE_MAX'.
--
--`_SC_LOGIN_NAME_MAX'
-- Inquire about the parameter corresponding to
-- `_POSIX_LOGIN_NAME_MAX'.
--
--`_SC_TTY_NAME_MAX'
-- Inquire about the parameter corresponding to `_POSIX_TTY_NAME_MAX'.
--
--`_SC_THREAD_DESTRUCTOR_ITERATIONS'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_DESTRUCTOR_ITERATIONS'.
--
--`_SC_THREAD_KEYS_MAX'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_KEYS_MAX'.
--
--`_SC_THREAD_STACK_MIN'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_STACK_MIN'.
--
--`_SC_THREAD_THREADS_MAX'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_THREADS_MAX'.
--
--`_SC_THREAD_ATTR_STACKADDR'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_ATTR_STACKADDR'.
--
--`_SC_THREAD_ATTR_STACKSIZE'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_ATTR_STACKSIZE'.
--
--`_SC_THREAD_PRIORITY_SCHEDULING'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_PRIORITY_SCHEDULING'.
--
--`_SC_THREAD_PRIO_INHERIT'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_PRIO_INHERIT'.
--
--`_SC_THREAD_PRIO_PROTECT'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_PRIO_PROTECT'.
--
--`_SC_THREAD_PROCESS_SHARED'
-- Inquire about the parameter corresponding to
-- `_POSIX_THREAD_PROCESS_SHARED'.
--
--`_SC_2_C_DEV'
-- Inquire about whether the system has the POSIX.2 C compiler
-- command, `c89'.
--
--`_SC_2_FORT_DEV'
-- Inquire about whether the system has the POSIX.2 Fortran compiler
-- command, `fort77'.
--
--`_SC_2_FORT_RUN'
-- Inquire about whether the system has the POSIX.2 `asa' command to
-- interpret Fortran carriage control.
--
--`_SC_2_LOCALEDEF'
-- Inquire about whether the system has the POSIX.2 `localedef'
-- command.
--
--`_SC_2_SW_DEV'
-- Inquire about whether the system has the POSIX.2 commands `ar',
-- `make', and `strip'.
--
--`_SC_BC_BASE_MAX'
-- Inquire about the maximum value of `obase' in the `bc' utility.
--
--`_SC_BC_DIM_MAX'
-- Inquire about the maximum size of an array in the `bc' utility.
--
--`_SC_BC_SCALE_MAX'
-- Inquire about the maximum value of `scale' in the `bc' utility.
--
--`_SC_BC_STRING_MAX'
-- Inquire about the maximum size of a string constant in the `bc'
-- utility.
--
--`_SC_COLL_WEIGHTS_MAX'
-- Inquire about the maximum number of weights that can necessarily
-- be used in defining the collating sequence for a locale.
--
--`_SC_EXPR_NEST_MAX'
-- Inquire about the maximum number of expressions nested within
-- parentheses when using the `expr' utility.
--
--`_SC_LINE_MAX'
-- Inquire about the maximum size of a text line that the POSIX.2 text
-- utilities can handle.
--
--`_SC_EQUIV_CLASS_MAX'
-- Inquire about the maximum number of weights that can be assigned
-- to an entry of the `LC_COLLATE' category `order' keyword in a
-- locale definition. The GNU C library does not presently support
-- locale definitions.
--
--`_SC_VERSION'
-- Inquire about the version number of POSIX.1 that the library and
-- kernel support.
--
--`_SC_2_VERSION'
-- Inquire about the version number of POSIX.2 that the system
-- utilities support.
--
--`_SC_PAGESIZE'
-- Inquire about the virtual memory page size of the machine.
-- `getpagesize' returns the same value.
--
--`_SC_NPROCESSORS_CONF'
-- Inquire about number of configured processors.
--
--`_SC_NPROCESSORS_ONLN'
-- Inquire about number of processors online.
--
--`_SC_PHYS_PAGES'
-- Inquire about number of physical pages in the system.
--
--`_SC_AVPHYS_PAGES'
-- Inquire about number of available physical pages in the system.
--
--`_SC_ATEXIT_MAX'
-- Inquire about number of functions which can be registered as
-- termination functions for `atexit'; *note Cleanups on Exit::..
--
--`_SC_XOPEN_VERSION'
-- Inquire about the parameter corresponding to `_XOPEN_VERSION'.
--
--`_SC_XOPEN_XCU_VERSION'
-- Inquire about the parameter corresponding to `_XOPEN_XCU_VERSION'.
--
--`_SC_XOPEN_UNIX'
-- Inquire about the parameter corresponding to `_XOPEN_UNIX'.
--
--`_SC_XOPEN_CRYPT'
-- Inquire about the parameter corresponding to `_XOPEN_CRYPT'.
--
--`_SC_XOPEN_ENH_I18N'
-- Inquire about the parameter corresponding to `_XOPEN_ENH_I18N'.
--
--`_SC_XOPEN_SHM'
-- Inquire about the parameter corresponding to `_XOPEN_SHM'.
--
--`_SC_XOPEN_XPG2'
-- Inquire about the parameter corresponding to `_XOPEN_XPG2'.
--
--`_SC_XOPEN_XPG3'
-- Inquire about the parameter corresponding to `_XOPEN_XPG3'.
--
--`_SC_XOPEN_XPG4'
-- Inquire about the parameter corresponding to `_XOPEN_XPG4'.
--
--`_SC_CHAR_BIT'
-- Inquire about number of bits in a variable of type `char'.
--
--`_SC_CHAR_MAX'
-- Inquire about maximum value which can be stored in a variable of
-- type `char'.
--
--`_SC_CHAR_MIN'
-- Inquire about minimum value which can be stored in a variable of
-- type `char'.
--
--`_SC_INT_MAX'
-- Inquire about maximum value which can be stored in a variable of
-- type `int'.
--
--`_SC_INT_MIN'
-- Inquire about minimum value which can be stored in a variable of
-- type `int'.
--
--`_SC_LONG_BIT'
-- Inquire about number of bits in a variable of type `long int'.
--
--`_SC_WORD_BIT'
-- Inquire about number of bits in a variable of a register word.
--
--`_SC_MB_LEN_MAX'
-- Inquire the maximum length of a multi-byte representation of a wide
-- character value.
--
--`_SC_NZERO'
-- Inquire value used to internally represent the zero priority level
-- for the process execution.
--
--`SC_SSIZE_MAX'
-- Inquire about maximum value which can be stored in a variable of
-- type `ssize_t'.
--
--`_SC_SCHAR_MAX'
-- Inquire about maximum value which can be stored in a variable of
-- type `signed char'.
--
--`_SC_SCHAR_MIN'
-- Inquire about minimum value which can be stored in a variable of
-- type `signed char'.
--
--`_SC_SHRT_MAX'
-- Inquire about maximum value which can be stored in a variable of
-- type `short int'.
--
--`_SC_SHRT_MIN'
-- Inquire about minimum value which can be stored in a variable of
-- type `short int'.
--
--`_SC_UCHAR_MAX'
-- Inquire about maximum value which can be stored in a variable of
-- type `unsigned char'.
--
--`_SC_UINT_MAX'
-- Inquire about maximum value which can be stored in a variable of
-- type `unsigned int'.
--
--`_SC_ULONG_MAX'
-- Inquire about maximum value which can be stored in a variable of
-- type `unsigned long int'.
--
--`_SC_USHRT_MAX'
-- Inquire about maximum value which can be stored in a variable of
-- type `unsigned short int'.
--
--`_SC_NL_ARGMAX'
-- Inquire about the parameter corresponding to `NL_ARGMAX'.
--
--`_SC_NL_LANGMAX'
-- Inquire about the parameter corresponding to `NL_LANGMAX'.
--
--`_SC_NL_MSGMAX'
-- Inquire about the parameter corresponding to `NL_MSGMAX'.
--
--`_SC_NL_NMAX'
-- Inquire about the parameter corresponding to `NL_NMAX'.
--
--`_SC_NL_SETMAX'
-- Inquire about the parameter corresponding to `NL_SETMAX'.
--
--`_SC_NL_TEXTMAX'
-- Inquire about the parameter corresponding to `NL_TEXTMAX'.
--
--
--File: libc.info, Node: Examples of Sysconf, Prev: Constants for Sysconf, Up: Sysconf
--
--Examples of `sysconf'
-----------------------
--
-- We recommend that you first test for a macro definition for the
--parameter you are interested in, and call `sysconf' only if the macro
--is not defined. For example, here is how to test whether job control
--is supported:
--
-- int
-- have_job_control (void)
-- {
-- #ifdef _POSIX_JOB_CONTROL
-- return 1;
-- #else
-- int value = sysconf (_SC_JOB_CONTROL);
-- if (value < 0)
-- /* If the system is that badly wedged,
-- there's no use trying to go on. */
-- fatal (strerror (errno));
-- return value;
-- #endif
-- }
--
-- Here is how to get the value of a numeric limit:
--
-- int
-- get_child_max ()
-- {
-- #ifdef CHILD_MAX
-- return CHILD_MAX;
-- #else
-- int value = sysconf (_SC_CHILD_MAX);
-- if (value < 0)
-- fatal (strerror (errno));
-- return value;
-- #endif
-- }
--
--
--File: libc.info, Node: Minimums, Next: Limits for Files, Prev: Sysconf, Up: System Configuration
--
--Minimum Values for General Capacity Limits
--==========================================
--
-- Here are the names for the POSIX minimum upper bounds for the system
--limit parameters. The significance of these values is that you can
--safely push to these limits without checking whether the particular
--system you are using can go that far.
--
--`_POSIX_AIO_LISTIO_MAX'
-- The most restrictive limit permitted by POSIX for the maximum
-- number of I/O operations that can be specified in a list I/O call.
-- The value of this constant is `2'; thus you can add up to two new
-- entries of the list of outstandard operations.
--
--`_POSIX_AIO_MAX'
-- The most restrictive limit permitted by POSIX for the maximum
-- number of outstanding asynchronous I/O operations. The value of
-- this constant is `1'. So you cannot expect that you can issue
-- more than one operation and immediately continue with the normal
-- work, receiving the notifications asynchronously.
--
--`_POSIX_ARG_MAX'
-- The value of this macro is the most restrictive limit permitted by
-- POSIX for the maximum combined length of the ARGV and ENVIRON
-- arguments that can be passed to the `exec' functions. Its value
-- is `4096'.
--
--`_POSIX_CHILD_MAX'
-- The value of this macro is the most restrictive limit permitted by
-- POSIX for the maximum number of simultaneous processes per real
-- user ID. Its value is `6'.
--
--`_POSIX_NGROUPS_MAX'
-- The value of this macro is the most restrictive limit permitted by
-- POSIX for the maximum number of supplementary group IDs per
-- process. Its value is `0'.
--
--`_POSIX_OPEN_MAX'
-- The value of this macro is the most restrictive limit permitted by
-- POSIX for the maximum number of files that a single process can
-- have open simultaneously. Its value is `16'.
--
--`_POSIX_SSIZE_MAX'
-- The value of this macro is the most restrictive limit permitted by
-- POSIX for the maximum value that can be stored in an object of type
-- `ssize_t'. Its value is `32767'.
--
--`_POSIX_STREAM_MAX'
-- The value of this macro is the most restrictive limit permitted by
-- POSIX for the maximum number of streams that a single process can
-- have open simultaneously. Its value is `8'.
--
--`_POSIX_TZNAME_MAX'
-- The value of this macro is the most restrictive limit permitted by
-- POSIX for the maximum length of a time zone name. Its value is
-- `3'.
--
--`_POSIX2_RE_DUP_MAX'
-- The value of this macro is the most restrictive limit permitted by
-- POSIX for the numbers used in the `\{MIN,MAX\}' construct in a
-- regular expression. Its value is `255'.
--
--
--File: libc.info, Node: Limits for Files, Next: Options for Files, Prev: Minimums, Up: System Configuration
--
--Limits on File System Capacity
--==============================
--
-- The POSIX.1 standard specifies a number of parameters that describe
--the limitations of the file system. It's possible for the system to
--have a fixed, uniform limit for a parameter, but this isn't the usual
--case. On most systems, it's possible for different file systems (and,
--for some parameters, even different files) to have different maximum
--limits. For example, this is very likely if you use NFS to mount some
--of the file systems from other machines.
--
-- Each of the following macros is defined in `limits.h' only if the
--system has a fixed, uniform limit for the parameter in question. If the
--system allows different file systems or files to have different limits,
--then the macro is undefined; use `pathconf' or `fpathconf' to find out
--the limit that applies to a particular file. *Note Pathconf::.
--
-- Each parameter also has another macro, with a name starting with
--`_POSIX', which gives the lowest value that the limit is allowed to
--have on *any* POSIX system. *Note File Minimums::.
--
-- - Macro: int LINK_MAX
-- The uniform system limit (if any) for the number of names for a
-- given file. *Note Hard Links::.
--
-- - Macro: int MAX_CANON
-- The uniform system limit (if any) for the amount of text in a line
-- of input when input editing is enabled. *Note Canonical or Not::.
--
-- - Macro: int MAX_INPUT
-- The uniform system limit (if any) for the total number of
-- characters typed ahead as input. *Note I/O Queues::.
--
-- - Macro: int NAME_MAX
-- The uniform system limit (if any) for the length of a file name
-- component.
--
-- - Macro: int PATH_MAX
-- The uniform system limit (if any) for the length of an entire file
-- name (that is, the argument given to system calls such as `open').
--
-- - Macro: int PIPE_BUF
-- The uniform system limit (if any) for the number of bytes that can
-- be written atomically to a pipe. If multiple processes are
-- writing to the same pipe simultaneously, output from different
-- processes might be interleaved in chunks of this size. *Note
-- Pipes and FIFOs::.
--
-- These are alternative macro names for some of the same information.
--
-- - Macro: int MAXNAMLEN
-- This is the BSD name for `NAME_MAX'. It is defined in `dirent.h'.
--
-- - Macro: int FILENAME_MAX
-- The value of this macro is an integer constant expression that
-- represents the maximum length of a file name string. It is
-- defined in `stdio.h'.
--
-- Unlike `PATH_MAX', this macro is defined even if there is no actual
-- limit imposed. In such a case, its value is typically a very large
-- number. *This is always the case on the GNU system.*
--
-- *Usage Note:* Don't use `FILENAME_MAX' as the size of an array in
-- which to store a file name! You can't possibly make an array that
-- big! Use dynamic allocation (*note Memory Allocation::.) instead.
--
--
--File: libc.info, Node: Options for Files, Next: File Minimums, Prev: Limits for Files, Up: System Configuration
--
--Optional Features in File Support
--=================================
--
-- POSIX defines certain system-specific options in the system calls for
--operating on files. Some systems support these options and others do
--not. Since these options are provided in the kernel, not in the
--library, simply using the GNU C library does not guarantee any of these
--features is supported; it depends on the system you are using. They can
--also vary between file systems on a single machine.
--
-- This section describes the macros you can test to determine whether a
--particular option is supported on your machine. If a given macro is
--defined in `unistd.h', then its value says whether the corresponding
--feature is supported. (A value of `-1' indicates no; any other value
--indicates yes.) If the macro is undefined, it means particular files
--may or may not support the feature.
--
-- Since all the machines that support the GNU C library also support
--NFS, one can never make a general statement about whether all file
--systems support the `_POSIX_CHOWN_RESTRICTED' and `_POSIX_NO_TRUNC'
--features. So these names are never defined as macros in the GNU C
--library.
--
-- - Macro: int _POSIX_CHOWN_RESTRICTED
-- If this option is in effect, the `chown' function is restricted so
-- that the only changes permitted to nonprivileged processes is to
-- change the group owner of a file to either be the effective group
-- ID of the process, or one of its supplementary group IDs. *Note
-- File Owner::.
--
-- - Macro: int _POSIX_NO_TRUNC
-- If this option is in effect, file name components longer than
-- `NAME_MAX' generate an `ENAMETOOLONG' error. Otherwise, file name
-- components that are too long are silently truncated.
--
-- - Macro: unsigned char _POSIX_VDISABLE
-- This option is only meaningful for files that are terminal devices.
-- If it is enabled, then handling for special control characters can
-- be disabled individually. *Note Special Characters::.
--
-- If one of these macros is undefined, that means that the option
--might be in effect for some files and not for others. To inquire about
--a particular file, call `pathconf' or `fpathconf'. *Note Pathconf::.
--
--
--File: libc.info, Node: File Minimums, Next: Pathconf, Prev: Options for Files, Up: System Configuration
--
--Minimum Values for File System Limits
--=====================================
--
-- Here are the names for the POSIX minimum upper bounds for some of the
--above parameters. The significance of these values is that you can
--safely push to these limits without checking whether the particular
--system you are using can go that far. In most cases GNU systems do not
--have these strict limitations. The actual limit should be requested if
--necessary.
--
--`_POSIX_LINK_MAX'
-- The most restrictive limit permitted by POSIX for the maximum
-- value of a file's link count. The value of this constant is `8';
-- thus, you can always make up to eight names for a file without
-- running into a system limit.
--
--`_POSIX_MAX_CANON'
-- The most restrictive limit permitted by POSIX for the maximum
-- number of bytes in a canonical input line from a terminal device.
-- The value of this constant is `255'.
--
--`_POSIX_MAX_INPUT'
-- The most restrictive limit permitted by POSIX for the maximum
-- number of bytes in a terminal device input queue (or typeahead
-- buffer). *Note Input Modes::. The value of this constant is
-- `255'.
--
--`_POSIX_NAME_MAX'
-- The most restrictive limit permitted by POSIX for the maximum
-- number of bytes in a file name component. The value of this
-- constant is `14'.
--
--`_POSIX_PATH_MAX'
-- The most restrictive limit permitted by POSIX for the maximum
-- number of bytes in a file name. The value of this constant is
-- `255'.
--
--`_POSIX_PIPE_BUF'
-- The most restrictive limit permitted by POSIX for the maximum
-- number of bytes that can be written atomically to a pipe. The
-- value of this constant is `512'.
--
--
--File: libc.info, Node: Pathconf, Next: Utility Limits, Prev: File Minimums, Up: System Configuration
--
--Using `pathconf'
--================
--
-- When your machine allows different files to have different values
--for a file system parameter, you can use the functions in this section
--to find out the value that applies to any particular file.
--
-- These functions and the associated constants for the PARAMETER
--argument are declared in the header file `unistd.h'.
--
-- - Function: long int pathconf (const char *FILENAME, int PARAMETER)
-- This function is used to inquire about the limits that apply to
-- the file named FILENAME.
--
-- The PARAMETER argument should be one of the `_PC_' constants
-- listed below.
--
-- The normal return value from `pathconf' is the value you requested.
-- A value of `-1' is returned both if the implementation does not
-- impose a limit, and in case of an error. In the former case,
-- `errno' is not set, while in the latter case, `errno' is set to
-- indicate the cause of the problem. So the only way to use this
-- function robustly is to store `0' into `errno' just before calling
-- it.
--
-- Besides the usual file name errors (*note File Name Errors::.),
-- the following error condition is defined for this function:
--
-- `EINVAL'
-- The value of PARAMETER is invalid, or the implementation
-- doesn't support the PARAMETER for the specific file.
--
-- - Function: long int fpathconf (int FILEDES, int PARAMETER)
-- This is just like `pathconf' except that an open file descriptor
-- is used to specify the file for which information is requested,
-- instead of a file name.
--
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EBADF'
-- The FILEDES argument is not a valid file descriptor.
--
-- `EINVAL'
-- The value of PARAMETER is invalid, or the implementation
-- doesn't support the PARAMETER for the specific file.
--
-- Here are the symbolic constants that you can use as the PARAMETER
--argument to `pathconf' and `fpathconf'. The values are all integer
--constants.
--
--`_PC_LINK_MAX'
-- Inquire about the value of `LINK_MAX'.
--
--`_PC_MAX_CANON'
-- Inquire about the value of `MAX_CANON'.
--
--`_PC_MAX_INPUT'
-- Inquire about the value of `MAX_INPUT'.
--
--`_PC_NAME_MAX'
-- Inquire about the value of `NAME_MAX'.
--
--`_PC_PATH_MAX'
-- Inquire about the value of `PATH_MAX'.
--
--`_PC_PIPE_BUF'
-- Inquire about the value of `PIPE_BUF'.
--
--`_PC_CHOWN_RESTRICTED'
-- Inquire about the value of `_POSIX_CHOWN_RESTRICTED'.
--
--`_PC_NO_TRUNC'
-- Inquire about the value of `_POSIX_NO_TRUNC'.
--
--`_PC_VDISABLE'
-- Inquire about the value of `_POSIX_VDISABLE'.
--
--`_PC_SYNC_IO'
-- Inquire about the value of `_POSIX_SYNC_IO'.
--
--`_PC_ASYNC_IO'
-- Inquire about the value of `_POSIX_ASYNC_IO'.
--
--`_PC_PRIO_IO'
-- Inquire about the value of `_POSIX_PRIO_IO'.
--
--`_PC_SOCK_MAXBUF'
-- Inquire about the value of `_POSIX_PIPE_BUF'.
--
--
--File: libc.info, Node: Utility Limits, Next: Utility Minimums, Prev: Pathconf, Up: System Configuration
--
--Utility Program Capacity Limits
--===============================
--
-- The POSIX.2 standard specifies certain system limits that you can
--access through `sysconf' that apply to utility behavior rather than the
--behavior of the library or the operating system.
--
-- The GNU C library defines macros for these limits, and `sysconf'
--returns values for them if you ask; but these values convey no
--meaningful information. They are simply the smallest values that
--POSIX.2 permits.
--
-- - Macro: int BC_BASE_MAX
-- The largest value of `obase' that the `bc' utility is guaranteed
-- to support.
--
-- - Macro: int BC_DIM_MAX
-- The largest number of elements in one array that the `bc' utility
-- is guaranteed to support.
--
-- - Macro: int BC_SCALE_MAX
-- The largest value of `scale' that the `bc' utility is guaranteed
-- to support.
--
-- - Macro: int BC_STRING_MAX
-- The largest number of characters in one string constant that the
-- `bc' utility is guaranteed to support.
--
-- - Macro: int COLL_WEIGHTS_MAX
-- The largest number of weights that can necessarily be used in
-- defining the collating sequence for a locale.
--
-- - Macro: int EXPR_NEST_MAX
-- The maximum number of expressions that can be nested within
-- parenthesis by the `expr' utility.
--
-- - Macro: int LINE_MAX
-- The largest text line that the text-oriented POSIX.2 utilities can
-- support. (If you are using the GNU versions of these utilities,
-- then there is no actual limit except that imposed by the available
-- virtual memory, but there is no way that the library can tell you
-- this.)
--
-- - Macro: int EQUIV_CLASS_MAX
-- The maximum number of weights that can be assigned to an entry of
-- the `LC_COLLATE' category `order' keyword in a locale definition.
-- The GNU C library does not presently support locale definitions.
--
--
--File: libc.info, Node: Utility Minimums, Next: String Parameters, Prev: Utility Limits, Up: System Configuration
--
--Minimum Values for Utility Limits
--=================================
--
--`_POSIX2_BC_BASE_MAX'
-- The most restrictive limit permitted by POSIX.2 for the maximum
-- value of `obase' in the `bc' utility. Its value is `99'.
--
--`_POSIX2_BC_DIM_MAX'
-- The most restrictive limit permitted by POSIX.2 for the maximum
-- size of an array in the `bc' utility. Its value is `2048'.
--
--`_POSIX2_BC_SCALE_MAX'
-- The most restrictive limit permitted by POSIX.2 for the maximum
-- value of `scale' in the `bc' utility. Its value is `99'.
--
--`_POSIX2_BC_STRING_MAX'
-- The most restrictive limit permitted by POSIX.2 for the maximum
-- size of a string constant in the `bc' utility. Its value is
-- `1000'.
--
--`_POSIX2_COLL_WEIGHTS_MAX'
-- The most restrictive limit permitted by POSIX.2 for the maximum
-- number of weights that can necessarily be used in defining the
-- collating sequence for a locale. Its value is `2'.
--
--`_POSIX2_EXPR_NEST_MAX'
-- The most restrictive limit permitted by POSIX.2 for the maximum
-- number of expressions nested within parenthesis when using the
-- `expr' utility. Its value is `32'.
--
--`_POSIX2_LINE_MAX'
-- The most restrictive limit permitted by POSIX.2 for the maximum
-- size of a text line that the text utilities can handle. Its value
-- is `2048'.
--
--`_POSIX2_EQUIV_CLASS_MAX'
-- The most restrictive limit permitted by POSIX.2 for the maximum
-- number of weights that can be assigned to an entry of the
-- `LC_COLLATE' category `order' keyword in a locale definition. Its
-- value is `2'. The GNU C library does not presently support locale
-- definitions.
--
--
--File: libc.info, Node: String Parameters, Prev: Utility Minimums, Up: System Configuration
--
--String-Valued Parameters
--========================
--
-- POSIX.2 defines a way to get string-valued parameters from the
--operating system with the function `confstr':
--
-- - Function: size_t confstr (int PARAMETER, char *BUF, size_t LEN)
-- This function reads the value of a string-valued system parameter,
-- storing the string into LEN bytes of memory space starting at BUF.
-- The PARAMETER argument should be one of the `_CS_' symbols listed
-- below.
--
-- The normal return value from `confstr' is the length of the string
-- value that you asked for. If you supply a null pointer for BUF,
-- then `confstr' does not try to store the string; it just returns
-- its length. A value of `0' indicates an error.
--
-- If the string you asked for is too long for the buffer (that is,
-- longer than `LEN - 1'), then `confstr' stores just that much
-- (leaving room for the terminating null character). You can tell
-- that this has happened because `confstr' returns a value greater
-- than or equal to LEN.
--
-- The following `errno' error conditions are defined for this
-- function:
--
-- `EINVAL'
-- The value of the PARAMETER is invalid.
--
-- Currently there is just one parameter you can read with `confstr':
--
--`_CS_PATH'
-- This parameter's value is the recommended default path for
-- searching for executable files. This is the path that a user has
-- by default just after logging in.
--
--`_CS_LFS_CFLAGS'
-- The returned string specifies which additional flags must be given
-- to the C compiler if a source is compiled using the
-- `_LARGEFILE_SOURCE' feature select macro; *note Feature Test
-- Macros::..
--
--`_CS_LFS_LDFLAGS'
-- The returned string specifies which additional flags must be given
-- to the linker if a source is compiled using the
-- `_LARGEFILE_SOURCE' feature select macro; *note Feature Test
-- Macros::..
--
--`_CS_LFS_LIBS'
-- The returned string specifies which additional libraries must be
-- linked to the application if a source is compiled using the
-- `_LARGEFILE_SOURCE' feature select macro; *note Feature Test
-- Macros::..
--
--`_CS_LFS_LINTFLAGS'
-- The returned string specifies which additional flags must be given
-- to the lint tool if a source is compiled using the
-- `_LARGEFILE_SOURCE' feature select macro; *note Feature Test
-- Macros::..
--
--`_CS_LFS64_CFLAGS'
-- The returned string specifies which additional flags must be given
-- to the C compiler if a source is compiled using the
-- `_LARGEFILE64_SOURCE' feature select macro; *note Feature Test
-- Macros::..
--
--`_CS_LFS64_LDFLAGS'
-- The returned string specifies which additional flags must be given
-- to the linker if a source is compiled using the
-- `_LARGEFILE64_SOURCE' feature select macro; *note Feature Test
-- Macros::..
--
--`_CS_LFS64_LIBS'
-- The returned string specifies which additional libraries must be
-- linked to the application if a source is compiled using the
-- `_LARGEFILE64_SOURCE' feature select macro; *note Feature Test
-- Macros::..
--
--`_CS_LFS64_LINTFLAGS'
-- The returned string specifies which additional flags must be given
-- to the lint tool if a source is compiled using the
-- `_LARGEFILE64_SOURCE' feature select macro; *note Feature Test
-- Macros::..
--
-- The way to use `confstr' without any arbitrary limit on string size
--is to call it twice: first call it to get the length, allocate the
--buffer accordingly, and then call `confstr' again to fill the buffer,
--like this:
--
-- char *
-- get_default_path (void)
-- {
-- size_t len = confstr (_CS_PATH, NULL, 0);
-- char *buffer = (char *) xmalloc (len);
--
-- if (confstr (_CS_PATH, buf, len + 1) == 0)
-- {
-- free (buffer);
-- return NULL;
-- }
--
-- return buffer;
-- }
--
--
--File: libc.info, Node: Cryptographic Functions, Next: POSIX Threads, Prev: System Configuration, Up: Top
--
--DES Encryption and Password Handling
--************************************
--
-- On many systems, it is unnecessary to have any kind of user
--authentication; for instance, a workstation which is not connected to a
--network probably does not need any user authentication, because to use
--the machine an intruder must have physical access.
--
-- Sometimes, however, it is necessary to be sure that a user is
--authorised to use some service a machine provides--for instance, to log
--in as a particular user id (*note Users and Groups::.). One
--traditional way of doing this is for each user to choose a secret
--"password"; then, the system can ask someone claiming to be a user what
--the user's password is, and if the person gives the correct password
--then the system can grant the appropriate privileges.
--
-- If all the passwords are just stored in a file somewhere, then this
--file has to be very carefully protected. To avoid this, passwords are
--run through a "one-way function", a function which makes it difficult to
--work out what its input was by looking at its output, before storing in
--the file.
--
-- The GNU C library already provides a one-way function based on MD5.
--The `crypt' add-on provides additional compatibility with the standard
--UNIX one-way function based on the Data Encryption Standard.
--
-- It also provides support for Secure RPC, and some library functions
--that can be used to perform normal DES encryption.
--
-- The add-on is not included in the main distribution of the GNU C
--library because some governments, most notably those of France, Russia,
--and the US, have very restrictive rules governing the distribution and
--use of encryption software. The first section below tries to describe
--some of those rules.
--
--* Menu:
--
--* Legal Problems:: This software can get you locked up, or worse.
--* getpass:: Prompting the user for a password.
--* crypt:: A one-way function for UNIX passwords.
--* DES Encryption:: Routines for DES encryption.
--
--
--File: libc.info, Node: Legal Problems, Next: getpass, Up: Cryptographic Functions
--
--Legal Problems
--==============
--
-- Because of the continuously changing state of the law, it's not
--possible to provide a definitive survey of the laws affecting
--cryptography. Instead, this section warns you of some of the known
--trouble spots; this may help you when you try to find out what the laws
--of your country are.
--
-- Some countries require that you have a licence to use, posess, or
--import cryptography. These countries are believed to include
--Byelorussia, Burma, France, India, Indonesia, Israel, Kazakhstan,
--Pakistan, Russia, and Saudi Arabia.
--
-- Some countries restrict the transmission of encrypted messages by
--radio; some telecommunications carriers restrict the transmission of
--encrypted messages over their network.
--
-- Many countries have some form of export control for encryption
--software. The Wassenaar Arrangement is a multilateral agreement
--between 33 countries (Argentina, Australia, Austria, Belgium, Bulgaria,
--Canada, the Czech Republic, Denmark, Finland, France, Germany, Greece,
--Hungary, Ireland, Italy, Japan, Luxembourg, the Netherlands, New
--Zealand, Norway, Poland, Portugal, the Republic of Korea, Romania, the
--Russian Federation, the Slovak Republic, Spain, Sweden, Switzerland,
--Turkey, Ukraine, the United Kingdom and the United States) which
--restricts some kinds of encryption exports. Different countries apply
--the arrangement in different ways; some do not allow the exception for
--certain kinds of "public domain" software (which would include this
--library), some only restrict the export of software in tangible form,
--and others impose significant additional restrictions.
--
-- In particular, the US does not allow export of this software without
--a licence, including via the Internet. So please do not download it
--from the main FSF FTP site at `ftp.gnu.org' if you are outside the US.
--This software was completely developed outside the US.
--
-- The rules in this area are continuously changing. If any
--information in this manual is out-of-date, please report it using the
--`glibcbug' script. *Note Reporting Bugs::.
--
--
--File: libc.info, Node: getpass, Next: crypt, Prev: Legal Problems, Up: Cryptographic Functions
--
--Reading Passwords
--=================
--
-- When reading in a password, it is desirable to avoid displaying it on
--the screen, to help keep it secret. The following function handles this
--in a convenient way.
--
-- - Function: char * getpass (const char * PROMPT)
-- `getpass' outputs PROMPT, then reads a string in from the terminal
-- without echoing it. It tries to connect to the real terminal,
-- `/dev/tty', if possible, to encourage users not to put plaintext
-- passwords in files; otherwise, it uses `stdin' and `stderr'.
--
-- In other C libraries, `getpass' may only return the first
-- `PASS_MAX' bytes of a password. The GNU C library has no limit, so
-- `PASS_MAX' is undefined.
--
-- The prototype for this function is in `unistd.h'. PASS_MAX would
-- be defined in `limits.h'.
--
--
--File: libc.info, Node: crypt, Next: DES Encryption, Prev: getpass, Up: Cryptographic Functions
--
--Encrypting Passwords
--====================
--
-- - Function: char * crypt (const char * KEY, const char * SALT)
-- The `crypt' function takes a password, KEY, as a string, and a
-- SALT character array which is described below, and returns a
-- printable ASCII string which starts with another salt. It is
-- believed that, given the output of the function, the best way to
-- find a KEY that will produce that output is to guess values of KEY
-- until the original value of KEY is found.
--
-- The SALT parameter does two things. Firstly, it selects which
-- algorithm is used, the MD5-based one or the DES-based one.
-- Secondly, it makes life harder for someone trying to guess
-- passwords against a file containing many passwords; without a
-- SALT, an intruder can make a guess, run `crypt' on it once, and
-- compare the result with all the passwords. With a SALT, the
-- intruder must run `crypt' once for each different salt.
--
-- For the MD5-based algorithm, the SALT should consist of the string
-- `$1$', followed by up to 8 characters, terminated by either
-- another `$' or the end of the string. The result of `crypt' will
-- be the SALT, followed by a `$' if the salt didn't end with one,
-- followed by 22 characters from the alphabet `./0-9A-Za-z', up to
-- 34 characters total. Every character in the KEY is significant.
--
-- For the DES-based algorithm, the SALT should consist of two
-- characters from the alphabet `./0-9A-Za-z', and the result of
-- `crypt' will be those two characters followed by 11 more from the
-- same alphabet, 13 in total. Only the first 8 characters in the
-- KEY are significant. If the `crypt' add-on is not installed,
-- trying to use the DES-based algorithm will return an empty string
-- and set `errno' to `EOPNOTSUPP'.
--
-- The MD5-based algorithm is available in the GNU C library even if
-- the `crypt' add-on is not installed. It also has no limit on the
-- useful length of the password used, and is slightly more secure.
-- It is therefore preferred over the DES-based algorithm.
--
-- When the user enters their password for the first time, the SALT
-- should be set to a new string which is reasonably random. To
-- verify a password against the result of a previous call to
-- `crypt', pass the result of the previous call as the SALT.
--
-- The following short program is an example of how to use `crypt' the
--first time a password is entered. Note that the SALT generation is
--just barely acceptable; in particular, it is not unique between
--machines, and in many applications it would not be acceptable to let an
--attacker know what time the user's password was last set.
--
-- #include <stdio.h>
-- #include <time.h>
-- #include <unistd.h>
-- #include <crypt.h>
--
-- int
-- main(void)
-- {
-- unsigned long seed[2];
-- char salt[] = "$1$........";
-- const char *const seedchars =
-- "./0123456789ABCDEFGHIJKLMNOPQRST"
-- "UVWXYZabcdefghijklmnopqrstuvwxyz";
-- char *password;
-- int i;
--
-- /* Generate a (not very) random seed.
-- You should do it better than this... */
-- seed[0] = time(NULL);
-- seed[1] = getpid() ^ (seed[0] >> 14 & 0x30000);
--
-- /* Turn it into printable characters from `seedchars'. */
-- for (i = 0; i < 8; i++)
-- salt[3+i] = seedchars[(seed[i/5] >> (i%5)*6) & 0x3f];
--
-- /* Read in the user's password and encrypt it. */
-- password = crypt(getpass("Password:"), salt);
--
-- /* Print the results. */
-- puts(password);
-- return 0;
-- }
--
-- The next program shows how to verify a password. It prompts the user
--for a password and prints "Access granted." if the user types `GNU libc
--manual'.
--
-- #include <stdio.h>
-- #include <string.h>
-- #include <unistd.h>
-- #include <crypt.h>
--
-- int
-- main(void)
-- {
-- /* Hashed form of "GNU libc manual". */
-- const char *const pass = "$1$/iSaq7rB$EoUw5jJPPvAPECNaaWzMK/";
--
-- char *result;
-- int ok;
--
-- /* Read in the user's password and encrypt it,
-- passing the expected password in as the salt. */
-- result = crypt(getpass("Password:"), pass);
--
-- /* Test the result. */
-- ok = strcmp (result, pass) == 0;
--
-- puts(ok ? "Access granted." : "Access denied.");
-- return ok ? 0 : 1;
-- }
--
-- - Function: char * crypt_r (const char * KEY, const char * SALT,
-- struct crypt_data * DATA)
-- The `crypt_r' function does the same thing as `crypt', but takes
-- an extra parameter which includes space for its result (among
-- other things), so it can be reentrant. `data->initialized' must be
-- cleared to zero before the first time `crypt_r' is called.
--
-- The `crypt_r' function is a GNU extension.
--
-- The `crypt' and `crypt_r' functions are prototyped in the header
--`crypt.h'.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-42 glibc-2.1.3/manual/libc.info-42
---- ../glibc-2.1.3/manual/libc.info-42 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-42 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1068 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: DES Encryption, Prev: crypt, Up: Cryptographic Functions
--
--DES Encryption
--==============
--
-- The Data Encryption Standard is described in the US Government
--Federal Information Processing Standards (FIPS) 46-2 published by the
--National Institute of Standards and Technology. The DES has been very
--thoroughly analysed since it was developed in the late 1970s, and no new
--significant flaws have been found. However, the DES uses only a 56-bit
--key (plus 8 parity bits), and a machine has been built which can search
--through all possible keys in about 6 days, which cost about US$200000;
--faster searches would be possible with more money. This makes simple
--DES insecure for most practical purposes, and NIST is now evaluating
--improved encryption algorithms.
--
-- The DES is a reversible operation which takes a 64-bit block and a
--64-bit key, and produces another 64-bit block. Usually the bits are
--numbered so that the most-significant bit, the first bit, of each block
--is numbered 1.
--
-- Under that numbering, every 8th bit of the key (the 8th, 16th, and so
--on) is not used by the encryption algorithm itself. But the key must
--have odd parity; that is, out of bits 1 through 8, and 9 through 16, and
--so on, there must be an odd number of `1' bits, and this completely
--specifies the unused bits.
--
-- - Function: void setkey (const char * KEY)
-- The `setkey' function sets an internal data structure to be an
-- expanded form of KEY. KEY is specified as an array of 64 bits
-- each stored in a `char', the first bit is `key[0]' and the 64th
-- bit is `key[63]'. The KEY should have the correct parity.
--
-- - Function: void encrypt (char * BLOCK, int EDFLAG)
-- The `encrypt' function encrypts BLOCK if EDFLAG is 0, otherwise it
-- decrypts BLOCK, using a key previously set by `setkey'. The
-- result is placed in BLOCK.
--
-- Like `setkey', BLOCK is specified as an array of 64 bits each
-- stored in a `char', but there are no parity bits in BLOCK.
--
-- - Function: void setkey_r (const char * KEY, struct crypt_data * DATA)
-- - Function: void encrypt_r (char * BLOCK, int EDFLAG, struct
-- crypt_data * DATA)
-- These are reentrant versions of `setkey' and `encrypt'. The only
-- difference is the extra parameter, which stores the expanded
-- version of KEY. Before calling `setkey' the first time,
-- `data->initialised' must be cleared to zero.
--
-- The `setkey_r' and `encrypt_r' functions are GNU extensions.
--`setkey', `encrypt', `setkey_r', and `encrypt_r' are defined in
--`crypt.h'.
--
-- If the `crypt' add-on is not used to build the library, programs
--that use these four functions will crash when the functions are called.
--If this is a problem, the `ecb_crypt' function described below is
--recommended instead.
--
-- - Function: int ecb_crypt (char * KEY, char * BLOCKS, unsigned LEN,
-- unsigned MODE)
-- The function `ecb_crypt' encrypts or decrypts one or more blocks
-- using DES. Each block is encrypted independently.
--
-- The BLOCKS and the KEY are stored packed in 8-bit bytes, so that
-- the first bit of the key is the most-significant bit of `key[0]'
-- and the 63rd bit of the key is stored as the least-significant bit
-- of `key[7]'. The KEY should have the correct parity.
--
-- LEN is the number of bytes in BLOCKS. It should be a multiple of
-- 8 (so that there is a whole number of blocks to encrypt). LEN is
-- limited to a maximum of `DES_MAXDATA' bytes.
--
-- The result of the encryption replaces the input in BLOCKS.
--
-- The MODE parameter is the bitwise OR of two of the following:
--
-- `DES_ENCRYPT'
-- This constant, used in the MODE parameter, specifies that
-- BLOCKS is to be encrypted.
--
-- `DES_DECRYPT'
-- This constant, used in the MODE parameter, specifies that
-- BLOCKS is to be decrypted.
--
-- `DES_HW'
-- This constant, used in the MODE parameter, asks to use a
-- hardware device. If no hardware device is available,
-- encryption happens anyway, but in software.
--
-- `DES_SW'
-- This constant, used in the MODE parameter, specifies that no
-- hardware device is to be used.
--
-- The result of the function will be one of these values:
--
-- `DESERR_NONE'
-- The encryption succeeded.
--
-- `DESERR_NOHWDEVICE'
-- The encryption succeeded, but there was no hardware device
-- available.
--
-- `DESERR_HWERROR'
-- The encryption failed because of a hardware problem. In the
-- GNU library, this error code is also returned if the `crypt'
-- add-on was not used to build the library.
--
-- `DESERR_BADPARAM'
-- The encryption failed because of a bad parameter, for
-- instance LEN is not a multiple of 8 or LEN is larger than
-- `DES_MAXDATA'.
--
-- - Function: int DES_FAILED (int ERR)
-- This macro returns 1 if ERR is a `success' result code from
-- `ecb_crypt' or `cbc_crypt', and 0 otherwise.
--
-- - Function: int cbc_crypt (char * KEY, char * BLOCKS, unsigned LEN,
-- unsigned MODE, char * IVEC)
-- The function `cbc_crypt' encrypts or decrypts one or more blocks
-- using DES in Cipher Block Chaining mode.
--
-- For encryption in CBC mode, each block is exclusive-ored with IVEC
-- before being encrypted, then IVEC is replaced with the result of
-- the encryption, then the next block is processed. Decryption is
-- the reverse of this process.
--
-- This has the advantage that blocks which are the same before being
-- encrypted are very unlikely to be the same after being encrypted,
-- making it much harder to detect patterns in the data.
--
-- Usually, IVEC is set to 8 random bytes before encryption starts.
-- Then the 8 random bytes are transmitted along with the encrypted
-- data (without themselves being encrypted), and passed back in as
-- IVEC for decryption. Another possibility is to set IVEC to 8
-- zeroes initially, and have the first the block encrypted consist
-- of 8 random bytes.
--
-- Otherwise, all the parameters are similar to those for `ecb_crypt'.
--
-- - Function: void des_setparity (char * KEY)
-- The function `des_setparity' changes the 64-bit KEY, stored packed
-- in 8-bit bytes, to have odd parity by altering the low bits of
-- each byte.
--
-- The `ecb_crypt', `cbc_crypt', and `des_setparity' functions and
--their accompanying macros are all defined in the header
--`rpc/des_crypt.h'.
--
--
--File: libc.info, Node: POSIX Threads, Next: Language Features, Prev: Cryptographic Functions, Up: Top
--
--POSIX Threads
--*************
--
-- This chapter describes the pthreads (POSIX threads) library. This
--library provides support functions for multithreaded programs: thread
--primitives, synchronization objects, and so forth. It also implements
--POSIX 1003.1b semaphores (not to be confused with System V semaphores).
--
-- The threads operations (`pthread_*') do not use ERRNO. Instead they
--return an error code directly. The semaphore operations do use ERRNO.
--
--* Menu:
--
--* Basic Thread Operations:: Creating, terminating, and waiting for threads.
--* Thread Attributes:: Tuning thread scheduling.
--* Cancellation:: Stopping a thread before it's done.
--* Cleanup Handlers:: Deallocating resources when a thread is
-- cancelled.
--* Mutexes:: One way to synchronize threads.
--* Condition Variables:: Another way.
--* POSIX Semaphores:: And a third way.
--* Thread-Specific Data:: Variables with different values in
-- different threads.
--* Threads and Signal Handling:: Why you should avoid mixing the two, and
-- how to do it if you must.
--* Miscellaneous Thread Functions:: A grab bag of utility routines.
--
--
--File: libc.info, Node: Basic Thread Operations, Next: Thread Attributes, Up: POSIX Threads
--
--Basic Thread Operations
--=======================
--
-- These functions are the thread equivalents of `fork', `exit', and
--`wait'.
--
-- - Function: int pthread_create (pthread_t * THREAD, pthread_attr_t *
-- ATTR, void * (*START_ROUTINE)(void *), void * ARG)
-- `pthread_create' creates a new thread of control that executes
-- concurrently with the calling thread. The new thread calls the
-- function START_ROUTINE, passing it ARG as first argument. The new
-- thread terminates either explicitly, by calling `pthread_exit', or
-- implicitly, by returning from the START_ROUTINE function. The
-- latter case is equivalent to calling `pthread_exit' with the result
-- returned by START_ROUTINE as exit code.
--
-- The ATTR argument specifies thread attributes to be applied to the
-- new thread. *Note Thread Attributes::, for details. The ATTR
-- argument can also be `NULL', in which case default attributes are
-- used: the created thread is joinable (not detached) and has an
-- ordinary (not realtime) scheduling policy.
--
-- On success, the identifier of the newly created thread is stored
-- in the location pointed by the THREAD argument, and a 0 is
-- returned. On error, a non-zero error code is returned.
--
-- This function may return the following errors:
-- `EAGAIN'
-- Not enough system resources to create a process for the new
-- thread, or more than `PTHREAD_THREADS_MAX' threads are
-- already active.
--
-- - Function: void pthread_exit (void *RETVAL)
-- `pthread_exit' terminates the execution of the calling thread. All
-- cleanup handlers (*note Cleanup Handlers::.) that have been set
-- for the calling thread with `pthread_cleanup_push' are executed in
-- reverse order (the most recently pushed handler is executed
-- first). Finalization functions for thread-specific data are then
-- called for all keys that have non-`NULL' values associated with
-- them in the calling thread (*note Thread-Specific Data::.).
-- Finally, execution of the calling thread is stopped.
--
-- The RETVAL argument is the return value of the thread. It can be
-- retrieved from another thread using `pthread_join'.
--
-- The `pthread_exit' function never returns.
--
-- - Function: int pthread_cancel (pthread_t THREAD)
-- `pthread_cancel' sends a cancellation request to the thread denoted
-- by the THREAD argument. If there is no such thread,
-- `pthread_cancel' fails and returns `ESRCH'. Otherwise it returns
-- 0. *Note Cancellation::, for details.
--
-- - Function: int pthread_join (pthread_t TH, void **thread_RETURN)
-- `pthread_join' suspends the execution of the calling thread until
-- the thread identified by TH terminates, either by calling
-- `pthread_exit' or by being cancelled.
--
-- If THREAD_RETURN is not `NULL', the return value of TH is stored
-- in the location pointed to by THREAD_RETURN. The return value of
-- TH is either the argument it gave to `pthread_exit', or
-- `PTHREAD_CANCELED' if TH was cancelled.
--
-- The joined thread `th' must be in the joinable state: it must not
-- have been detached using `pthread_detach' or the
-- `PTHREAD_CREATE_DETACHED' attribute to `pthread_create'.
--
-- When a joinable thread terminates, its memory resources (thread
-- descriptor and stack) are not deallocated until another thread
-- performs `pthread_join' on it. Therefore, `pthread_join' must be
-- called once for each joinable thread created to avoid memory leaks.
--
-- At most one thread can wait for the termination of a given thread.
-- Calling `pthread_join' on a thread TH on which another thread is
-- already waiting for termination returns an error.
--
-- `pthread_join' is a cancellation point. If a thread is canceled
-- while suspended in `pthread_join', the thread execution resumes
-- immediately and the cancellation is executed without waiting for
-- the TH thread to terminate. If cancellation occurs during
-- `pthread_join', the TH thread remains not joined.
--
-- On success, the return value of TH is stored in the location
-- pointed to by THREAD_RETURN, and 0 is returned. On error, one of
-- the following values is returned:
-- `ESRCH'
-- No thread could be found corresponding to that specified by
-- TH.
--
-- `EINVAL'
-- The TH thread has been detached, or another thread is already
-- waiting on termination of TH.
--
-- `EDEADLK'
-- The TH argument refers to the calling thread.
--
--
--File: libc.info, Node: Thread Attributes, Next: Cancellation, Prev: Basic Thread Operations, Up: POSIX Threads
--
--Thread Attributes
--=================
--
-- Threads have a number of attributes that may be set at creation time.
--This is done by filling a thread attribute object ATTR of type
--`pthread_attr_t', then passing it as second argument to
--`pthread_create'. Passing `NULL' is equivalent to passing a thread
--attribute object with all attributes set to their default values.
--
-- Attribute objects are consulted only when creating a new thread. The
--same attribute object can be used for creating several threads.
--Modifying an attribute object after a call to `pthread_create' does not
--change the attributes of the thread previously created.
--
-- - Function: int pthread_attr_init (pthread_attr_t *ATTR)
-- `pthread_attr_init' initializes the thread attribute object ATTR
-- and fills it with default values for the attributes. (The default
-- values are listed below for each attribute.)
--
-- Each attribute ATTRNAME (see below for a list of all attributes)
-- can be individually set using the function
-- `pthread_attr_setATTRNAME' and retrieved using the function
-- `pthread_attr_getATTRNAME'.
--
-- - Function: int pthread_attr_destroy (pthread_attr_t *ATTR)
-- `pthread_attr_destroy' destroys the attribute object pointed to by
-- ATTR releasing any resources associated with it. ATTR is left in
-- an undefined state, and you must not use it again in a call to any
-- pthreads function until it has been reinitialized.
--
-- - Function: int pthread_attr_setATTR (pthread_attr_t *OBJ, int VALUE)
-- Set attribute ATTR to VALUE in the attribute object pointed to by
-- OBJ. See below for a list of possible attributes and the values
-- they can take.
--
-- On success, these functions return 0. If VALUE is not meaningful
-- for the ATTR being modified, they will return the error code
-- `EINVAL'. Some of the functions have other failure modes; see
-- below.
--
-- - Function: int pthread_attr_getATTR (const pthread_attr_t *OBJ, int
-- *VALUE)
-- Store the current setting of ATTR in OBJ into the variable pointed
-- to by VALUE.
--
-- These functions always return 0.
--
-- The following thread attributes are supported:
--`detachstate'
-- Choose whether the thread is created in the joinable state (value
-- `PTHREAD_CREATE_JOINABLE') or in the detached state
-- (`PTHREAD_CREATE_DETACHED'). The default is
-- `PTHREAD_CREATE_JOINABLE'.
--
-- In the joinable state, another thread can synchronize on the thread
-- termination and recover its termination code using `pthread_join',
-- but some of the thread resources are kept allocated after the
-- thread terminates, and reclaimed only when another thread performs
-- `pthread_join' on that thread.
--
-- In the detached state, the thread resources are immediately freed
-- when it terminates, but `pthread_join' cannot be used to
-- synchronize on the thread termination.
--
-- A thread created in the joinable state can later be put in the
-- detached thread using `pthread_detach'.
--
--`schedpolicy'
-- Select the scheduling policy for the thread: one of `SCHED_OTHER'
-- (regular, non-realtime scheduling), `SCHED_RR' (realtime,
-- round-robin) or `SCHED_FIFO' (realtime, first-in first-out). The
-- default is `SCHED_OTHER'.
--
-- The realtime scheduling policies `SCHED_RR' and `SCHED_FIFO' are
-- available only to processes with superuser privileges.
-- `pthread_attr_setschedparam' will fail and return `ENOTSUP' if you
-- try to set a realtime policy when you are unprivileged.
--
-- The scheduling policy of a thread can be changed after creation
-- with `pthread_setschedparam'.
--
--`schedparam'
-- Change the scheduling parameter (the scheduling priority) for the
-- thread. The default is 0.
--
-- This attribute is not significant if the scheduling policy is
-- `SCHED_OTHER'; it only matters for the realtime policies
-- `SCHED_RR' and `SCHED_FIFO'.
--
-- The scheduling priority of a thread can be changed after creation
-- with `pthread_setschedparam'.
--
--`inheritsched'
-- Choose whether the scheduling policy and scheduling parameter for
-- the newly created thread are determined by the values of the
-- SCHEDPOLICY and SCHEDPARAM attributes (value
-- `PTHREAD_EXPLICIT_SCHED') or are inherited from the parent thread
-- (value `PTHREAD_INHERIT_SCHED'). The default is
-- `PTHREAD_EXPLICIT_SCHED'.
--
--`scope'
-- Choose the scheduling contention scope for the created thread. The
-- default is `PTHREAD_SCOPE_SYSTEM', meaning that the threads contend
-- for CPU time with all processes running on the machine. In
-- particular, thread priorities are interpreted relative to the
-- priorities of all other processes on the machine. The other
-- possibility, `PTHREAD_SCOPE_PROCESS', means that scheduling
-- contention occurs only between the threads of the running process:
-- thread priorities are interpreted relative to the priorities of
-- the other threads of the process, regardless of the priorities of
-- other processes.
--
-- `PTHREAD_SCOPE_PROCESS' is not supported in LinuxThreads. If you
-- try to set the scope to this value `pthread_attr_setscope' will
-- fail and return `ENOTSUP'.
--
--
--File: libc.info, Node: Cancellation, Next: Cleanup Handlers, Prev: Thread Attributes, Up: POSIX Threads
--
--Cancellation
--============
--
-- Cancellation is the mechanism by which a thread can terminate the
--execution of another thread. More precisely, a thread can send a
--cancellation request to another thread. Depending on its settings, the
--target thread can then either ignore the request, honor it immediately,
--or defer it till it reaches a cancellation point. When threads are
--first created by `pthread_create', they always defer cancellation
--requests.
--
-- When a thread eventually honors a cancellation request, it behaves
--as if `pthread_exit(PTHREAD_CANCELED)' was called. All cleanup handlers
--are executed in reverse order, finalization functions for
--thread-specific data are called, and finally the thread stops executing.
--If the cancelled thread was joinable, the return value
--`PTHREAD_CANCELED' is provided to whichever thread calls PTHREAD_JOIN
--on it. See `pthread_exit' for more information.
--
-- Cancellation points are the points where the thread checks for
--pending cancellation requests and performs them. The POSIX threads
--functions `pthread_join', `pthread_cond_wait',
--`pthread_cond_timedwait', `pthread_testcancel', `sem_wait', and
--`sigwait' are cancellation points. In addition, these system calls are
--cancellation points:
--
--accept open sendmsg
--close pause sendto
--connect read system
--fcntl recv tcdrain
--fsync recvfrom wait
--lseek recvmsg waitpid
--msync send write
--nanosleep
--
--All library functions that call these functions (such as `printf') are
--also cancellation points.
--
-- - Function: int pthread_setcancelstate (int STATE, int *OLDSTATE)
-- `pthread_setcancelstate' changes the cancellation state for the
-- calling thread - that is, whether cancellation requests are
-- ignored or not. The STATE argument is the new cancellation state:
-- either `PTHREAD_CANCEL_ENABLE' to enable cancellation, or
-- `PTHREAD_CANCEL_DISABLE' to disable cancellation (cancellation
-- requests are ignored).
--
-- If OLDSTATE is not `NULL', the previous cancellation state is
-- stored in the location pointed to by OLDSTATE, and can thus be
-- restored later by another call to `pthread_setcancelstate'.
--
-- If the STATE argument is not `PTHREAD_CANCEL_ENABLE' or
-- `PTHREAD_CANCEL_DISABLE', `pthread_setcancelstate' fails and
-- returns `EINVAL'. Otherwise it returns 0.
--
-- - Function: int pthread_setcanceltype (int TYPE, int *OLDTYPE)
-- `pthread_setcanceltype' changes the type of responses to
-- cancellation requests for the calling thread: asynchronous
-- (immediate) or deferred. The TYPE argument is the new
-- cancellation type: either `PTHREAD_CANCEL_ASYNCHRONOUS' to cancel
-- the calling thread as soon as the cancellation request is
-- received, or `PTHREAD_CANCEL_DEFERRED' to keep the cancellation
-- request pending until the next cancellation point. If OLDTYPE is
-- not `NULL', the previous cancellation state is stored in the
-- location pointed to by OLDTYPE, and can thus be restored later by
-- another call to `pthread_setcanceltype'.
--
-- If the TYPE argument is not `PTHREAD_CANCEL_DEFERRED' or
-- `PTHREAD_CANCEL_ASYNCHRONOUS', `pthread_setcanceltype' fails and
-- returns `EINVAL'. Otherwise it returns 0.
--
-- - Function: void pthread_testcancel (VOID)
-- `pthread_testcancel' does nothing except testing for pending
-- cancellation and executing it. Its purpose is to introduce explicit
-- checks for cancellation in long sequences of code that do not call
-- cancellation point functions otherwise.
--
--
--File: libc.info, Node: Cleanup Handlers, Next: Mutexes, Prev: Cancellation, Up: POSIX Threads
--
--Cleanup Handlers
--================
--
-- Cleanup handlers are functions that get called when a thread
--terminates, either by calling `pthread_exit' or because of
--cancellation. Cleanup handlers are installed and removed following a
--stack-like discipline.
--
-- The purpose of cleanup handlers is to free the resources that a
--thread may hold at the time it terminates. In particular, if a thread
--exits or is cancelled while it owns a locked mutex, the mutex will
--remain locked forever and prevent other threads from executing
--normally. The best way to avoid this is, just before locking the mutex,
--to install a cleanup handler whose effect is to unlock the mutex.
--Cleanup handlers can be used similarly to free blocks allocated with
--`malloc' or close file descriptors on thread termination.
--
-- Here is how to lock a mutex MUT in such a way that it will be
--unlocked if the thread is canceled while MUT is locked:
--
-- pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
-- pthread_mutex_lock(&mut);
-- /* do some work */
-- pthread_mutex_unlock(&mut);
-- pthread_cleanup_pop(0);
--
-- Equivalently, the last two lines can be replaced by
--
-- pthread_cleanup_pop(1);
--
-- Notice that the code above is safe only in deferred cancellation mode
--(see `pthread_setcanceltype'). In asynchronous cancellation mode, a
--cancellation can occur between `pthread_cleanup_push' and
--`pthread_mutex_lock', or between `pthread_mutex_unlock' and
--`pthread_cleanup_pop', resulting in both cases in the thread trying to
--unlock a mutex not locked by the current thread. This is the main
--reason why asynchronous cancellation is difficult to use.
--
-- If the code above must also work in asynchronous cancellation mode,
--then it must switch to deferred mode for locking and unlocking the
--mutex:
--
-- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
-- pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
-- pthread_mutex_lock(&mut);
-- /* do some work */
-- pthread_cleanup_pop(1);
-- pthread_setcanceltype(oldtype, NULL);
--
-- The code above can be rewritten in a more compact and efficient way,
--using the non-portable functions `pthread_cleanup_push_defer_np' and
--`pthread_cleanup_pop_restore_np':
--
-- pthread_cleanup_push_defer_np(pthread_mutex_unlock, (void *) &mut);
-- pthread_mutex_lock(&mut);
-- /* do some work */
-- pthread_cleanup_pop_restore_np(1);
--
-- - Function: void pthread_cleanup_push (void (*ROUTINE) (void *), void
-- *ARG)
-- `pthread_cleanup_push' installs the ROUTINE function with argument
-- ARG as a cleanup handler. From this point on to the matching
-- `pthread_cleanup_pop', the function ROUTINE will be called with
-- arguments ARG when the thread terminates, either through
-- `pthread_exit' or by cancellation. If several cleanup handlers are
-- active at that point, they are called in LIFO order: the most
-- recently installed handler is called first.
--
-- - Function: void pthread_cleanup_pop (int EXECUTE)
-- `pthread_cleanup_pop' removes the most recently installed cleanup
-- handler. If the EXECUTE argument is not 0, it also executes the
-- handler, by calling the ROUTINE function with arguments ARG. If
-- the EXECUTE argument is 0, the handler is only removed but not
-- executed.
--
-- Matching pairs of `pthread_cleanup_push' and `pthread_cleanup_pop'
--must occur in the same function, at the same level of block nesting.
--Actually, `pthread_cleanup_push' and `pthread_cleanup_pop' are macros,
--and the expansion of `pthread_cleanup_push' introduces an open brace
--`{' with the matching closing brace `}' being introduced by the
--expansion of the matching `pthread_cleanup_pop'.
--
-- - Function: void pthread_cleanup_push_defer_np (void (*ROUTINE) (void
-- *), void *ARG)
-- `pthread_cleanup_push_defer_np' is a non-portable extension that
-- combines `pthread_cleanup_push' and `pthread_setcanceltype'. It
-- pushes a cleanup handler just as `pthread_cleanup_push' does, but
-- also saves the current cancellation type and sets it to deferred
-- cancellation. This ensures that the cleanup mechanism is effective
-- even if the thread was initially in asynchronous cancellation mode.
--
-- - Function: void pthread_cleanup_pop_restore_np (int EXECUTE)
-- `pthread_cleanup_pop_restore_np' pops a cleanup handler introduced
-- by `pthread_cleanup_push_defer_np', and restores the cancellation
-- type to its value at the time `pthread_cleanup_push_defer_np' was
-- called.
--
-- `pthread_cleanup_push_defer_np' and `pthread_cleanup_pop_restore_np'
--must occur in matching pairs, at the same level of block nesting.
--
-- The sequence
--
-- pthread_cleanup_push_defer_np(routine, arg);
-- ...
-- pthread_cleanup_pop_defer_np(execute);
--
--is functionally equivalent to (but more compact and efficient than)
--
-- {
-- int oldtype;
-- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
-- pthread_cleanup_push(routine, arg);
-- ...
-- pthread_cleanup_pop(execute);
-- pthread_setcanceltype(oldtype, NULL);
-- }
--
--
--File: libc.info, Node: Mutexes, Next: Condition Variables, Prev: Cleanup Handlers, Up: POSIX Threads
--
--Mutexes
--=======
--
-- A mutex is a MUTual EXclusion device, and is useful for protecting
--shared data structures from concurrent modifications, and implementing
--critical sections and monitors.
--
-- A mutex has two possible states: unlocked (not owned by any thread),
--and locked (owned by one thread). A mutex can never be owned by two
--different threads simultaneously. A thread attempting to lock a mutex
--that is already locked by another thread is suspended until the owning
--thread unlocks the mutex first.
--
-- None of the mutex functions is a cancellation point, not even
--`pthread_mutex_lock', in spite of the fact that it can suspend a thread
--for arbitrary durations. This way, the status of mutexes at
--cancellation points is predictable, allowing cancellation handlers to
--unlock precisely those mutexes that need to be unlocked before the
--thread stops executing. Consequently, threads using deferred
--cancellation should never hold a mutex for extended periods of time.
--
-- It is not safe to call mutex functions from a signal handler. In
--particular, calling `pthread_mutex_lock' or `pthread_mutex_unlock' from
--a signal handler may deadlock the calling thread.
--
-- - Function: int pthread_mutex_init (pthread_mutex_t *MUTEX, const
-- pthread_mutexattr_t *MUTEXATTR)
-- `pthread_mutex_init' initializes the mutex object pointed to by
-- MUTEX according to the mutex attributes specified in MUTEXATTR.
-- If MUTEXATTR is `NULL', default attributes are used instead.
--
-- The LinuxThreads implementation supports only one mutex attribute,
-- the MUTEX KIND, which is either "fast", "recursive", or "error
-- checking". The kind of a mutex determines whether it can be locked
-- again by a thread that already owns it. The default kind is
-- "fast".
--
-- Variables of type `pthread_mutex_t' can also be initialized
-- statically, using the constants `PTHREAD_MUTEX_INITIALIZER' (for
-- fast mutexes), `PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP' (for
-- recursive mutexes), and `PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP'
-- (for error checking mutexes).
--
-- `pthread_mutex_init' always returns 0.
--
-- - Function: int pthread_mutex_lock (pthread_mutex_t *mutex))
-- `pthread_mutex_lock' locks the given mutex. If the mutex is
-- currently unlocked, it becomes locked and owned by the calling
-- thread, and `pthread_mutex_lock' returns immediately. If the mutex
-- is already locked by another thread, `pthread_mutex_lock' suspends
-- the calling thread until the mutex is unlocked.
--
-- If the mutex is already locked by the calling thread, the behavior
-- of `pthread_mutex_lock' depends on the kind of the mutex. If the
-- mutex is of the "fast" kind, the calling thread is suspended. It
-- will remain suspended forever, because no other thread can unlock
-- the mutex. If the mutex is of the "error checking" kind,
-- `pthread_mutex_lock' returns immediately with the error code
-- `EDEADLK'. If the mutex is of the "recursive" kind,
-- `pthread_mutex_lock' succeeds and returns immediately, recording
-- the number of times the calling thread has locked the mutex. An
-- equal number of `pthread_mutex_unlock' operations must be
-- performed before the mutex returns to the unlocked state.
--
-- - Function: int pthread_mutex_trylock (pthread_mutex_t *MUTEX)
-- `pthread_mutex_trylock' behaves identically to
-- `pthread_mutex_lock', except that it does not block the calling
-- thread if the mutex is already locked by another thread (or by the
-- calling thread in the case of a "fast" mutex). Instead,
-- `pthread_mutex_trylock' returns immediately with the error code
-- `EBUSY'.
--
-- - Function: int pthread_mutex_unlock (pthread_mutex_t *MUTEX)
-- `pthread_mutex_unlock' unlocks the given mutex. The mutex is
-- assumed to be locked and owned by the calling thread on entrance to
-- `pthread_mutex_unlock'. If the mutex is of the "fast" kind,
-- `pthread_mutex_unlock' always returns it to the unlocked state. If
-- it is of the "recursive" kind, it decrements the locking count of
-- the mutex (number of `pthread_mutex_lock' operations performed on
-- it by the calling thread), and only when this count reaches zero
-- is the mutex actually unlocked.
--
-- On "error checking" mutexes, `pthread_mutex_unlock' actually
-- checks at run-time that the mutex is locked on entrance, and that
-- it was locked by the same thread that is now calling
-- `pthread_mutex_unlock'. If these conditions are not met,
-- `pthread_mutex_unlock' returns `EPERM', and the mutex remains
-- unchanged. "Fast" and "recursive" mutexes perform no such checks,
-- thus allowing a locked mutex to be unlocked by a thread other than
-- its owner. This is non-portable behavior and must not be relied
-- upon.
--
-- - Function: int pthread_mutex_destroy (pthread_mutex_t *MUTEX)
-- `pthread_mutex_destroy' destroys a mutex object, freeing the
-- resources it might hold. The mutex must be unlocked on entrance.
-- In the LinuxThreads implementation, no resources are associated
-- with mutex objects, thus `pthread_mutex_destroy' actually does
-- nothing except checking that the mutex is unlocked.
--
-- If the mutex is locked by some thread, `pthread_mutex_destroy'
-- returns `EBUSY'. Otherwise it returns 0.
--
-- If any of the above functions (except `pthread_mutex_init') is
--applied to an uninitialized mutex, they will simply return `EINVAL' and
--do nothing.
--
-- A shared global variable X can be protected by a mutex as follows:
--
-- int x;
-- pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
--
-- All accesses and modifications to X should be bracketed by calls to
--`pthread_mutex_lock' and `pthread_mutex_unlock' as follows:
--
-- pthread_mutex_lock(&mut);
-- /* operate on x */
-- pthread_mutex_unlock(&mut);
--
-- Mutex attributes can be specified at mutex creation time, by passing
--a mutex attribute object as second argument to `pthread_mutex_init'.
--Passing `NULL' is equivalent to passing a mutex attribute object with
--all attributes set to their default values.
--
-- - Function: int pthread_mutexattr_init (pthread_mutexattr_t *ATTR)
-- `pthread_mutexattr_init' initializes the mutex attribute object
-- ATTR and fills it with default values for the attributes.
--
-- This function always returns 0.
--
-- - Function: int pthread_mutexattr_destroy (pthread_mutexattr_t *ATTR)
-- `pthread_mutexattr_destroy' destroys a mutex attribute object,
-- which must not be reused until it is reinitialized.
-- `pthread_mutexattr_destroy' does nothing in the LinuxThreads
-- implementation.
--
-- This function always returns 0.
--
-- LinuxThreads supports only one mutex attribute: the mutex kind,
--which is either `PTHREAD_MUTEX_FAST_NP' for "fast" mutexes,
--`PTHREAD_MUTEX_RECURSIVE_NP' for "recursive" mutexes, or
--`PTHREAD_MUTEX_ERRORCHECK_NP' for "error checking" mutexes. As the
--`NP' suffix indicates, this is a non-portable extension to the POSIX
--standard and should not be employed in portable programs.
--
-- The mutex kind determines what happens if a thread attempts to lock a
--mutex it already owns with `pthread_mutex_lock'. If the mutex is of the
--"fast" kind, `pthread_mutex_lock' simply suspends the calling thread
--forever. If the mutex is of the "error checking" kind,
--`pthread_mutex_lock' returns immediately with the error code `EDEADLK'.
--If the mutex is of the "recursive" kind, the call to
--`pthread_mutex_lock' returns immediately with a success return code.
--The number of times the thread owning the mutex has locked it is
--recorded in the mutex. The owning thread must call
--`pthread_mutex_unlock' the same number of times before the mutex
--returns to the unlocked state.
--
-- The default mutex kind is "fast", that is, `PTHREAD_MUTEX_FAST_NP'.
--
-- - Function: int pthread_mutexattr_setkind_np (pthread_mutexattr_t
-- *ATTR, int KIND)
-- `pthread_mutexattr_setkind_np' sets the mutex kind attribute in
-- ATTR to the value specified by KIND.
--
-- If KIND is not `PTHREAD_MUTEX_FAST_NP',
-- `PTHREAD_MUTEX_RECURSIVE_NP', or `PTHREAD_MUTEX_ERRORCHECK_NP',
-- this function will return `EINVAL' and leave ATTR unchanged.
--
-- - Function: int pthread_mutexattr_getkind_np (const
-- pthread_mutexattr_t *ATTR, int *KIND)
-- `pthread_mutexattr_getkind_np' retrieves the current value of the
-- mutex kind attribute in ATTR and stores it in the location pointed
-- to by KIND.
--
-- This function always returns 0.
--
--
--File: libc.info, Node: Condition Variables, Next: POSIX Semaphores, Prev: Mutexes, Up: POSIX Threads
--
--Condition Variables
--===================
--
-- A condition (short for "condition variable") is a synchronization
--device that allows threads to suspend execution until some predicate on
--shared data is satisfied. The basic operations on conditions are: signal
--the condition (when the predicate becomes true), and wait for the
--condition, suspending the thread execution until another thread signals
--the condition.
--
-- A condition variable must always be associated with a mutex, to avoid
--the race condition where a thread prepares to wait on a condition
--variable and another thread signals the condition just before the first
--thread actually waits on it.
--
-- - Function: int pthread_cond_init (pthread_cond_t *COND,
-- pthread_condattr_t *cond_ATTR)
-- `pthread_cond_init' initializes the condition variable COND, using
-- the condition attributes specified in COND_ATTR, or default
-- attributes if COND_ATTR is `NULL'. The LinuxThreads implementation
-- supports no attributes for conditions, hence the COND_ATTR
-- parameter is actually ignored.
--
-- Variables of type `pthread_cond_t' can also be initialized
-- statically, using the constant `PTHREAD_COND_INITIALIZER'.
--
-- This function always returns 0.
--
-- - Function: int pthread_cond_signal (pthread_cond_t *COND)
-- `pthread_cond_signal' restarts one of the threads that are waiting
-- on the condition variable COND. If no threads are waiting on COND,
-- nothing happens. If several threads are waiting on COND, exactly
-- one is restarted, but it is not specified which.
--
-- This function always returns 0.
--
-- - Function: int pthread_cond_broadcast (pthread_cond_t *COND)
-- `pthread_cond_broadcast' restarts all the threads that are waiting
-- on the condition variable COND. Nothing happens if no threads are
-- waiting on COND.
--
-- This function always returns 0.
--
-- - Function: int pthread_cond_wait (pthread_cond_t *COND,
-- pthread_mutex_t *MUTEX)
-- `pthread_cond_wait' atomically unlocks the MUTEX (as per
-- `pthread_unlock_mutex') and waits for the condition variable COND
-- to be signaled. The thread execution is suspended and does not
-- consume any CPU time until the condition variable is signaled. The
-- MUTEX must be locked by the calling thread on entrance to
-- `pthread_cond_wait'. Before returning to the calling thread,
-- `pthread_cond_wait' re-acquires MUTEX (as per
-- `pthread_lock_mutex').
--
-- Unlocking the mutex and suspending on the condition variable is
-- done atomically. Thus, if all threads always acquire the mutex
-- before signaling the condition, this guarantees that the condition
-- cannot be signaled (and thus ignored) between the time a thread
-- locks the mutex and the time it waits on the condition variable.
--
-- This function always returns 0.
--
-- - Function: int pthread_cond_timedwait (pthread_cond_t *COND,
-- pthread_mutex_t *MUTEX, const struct timespec *ABSTIME)
-- `pthread_cond_timedwait' atomically unlocks MUTEX and waits on
-- COND, as `pthread_cond_wait' does, but it also bounds the duration
-- of the wait. If COND has not been signaled before time ABSTIME,
-- the mutex MUTEX is re-acquired and `pthread_cond_timedwait'
-- returns the error code `ETIMEDOUT'. The wait can also be
-- interrupted by a signal; in that case `pthread_cond_timedwait'
-- returns `EINTR'.
--
-- The ABSTIME parameter specifies an absolute time, with the same
-- origin as `time' and `gettimeofday': an ABSTIME of 0 corresponds
-- to 00:00:00 GMT, January 1, 1970.
--
-- - Function: int pthread_cond_destroy (pthread_cond_t *COND)
-- `pthread_cond_destroy' destroys the condition variable COND,
-- freeing the resources it might hold. If any threads are waiting
-- on the condition variable, `pthread_cond_destroy' leaves COND
-- untouched and returns `EBUSY'. Otherwise it returns 0, and COND
-- must not be used again until it is reinitialized.
--
-- In the LinuxThreads implementation, no resources are associated
-- with condition variables, so `pthread_cond_destroy' actually does
-- nothing.
--
-- `pthread_cond_wait' and `pthread_cond_timedwait' are cancellation
--points. If a thread is cancelled while suspended in one of these
--functions, the thread immediately resumes execution, relocks the mutex
--specified by MUTEX, and finally executes the cancellation.
--Consequently, cleanup handlers are assured that MUTEX is locked when
--they are called.
--
-- It is not safe to call the condition variable functions from a signal
--handler. In particular, calling `pthread_cond_signal' or
--`pthread_cond_broadcast' from a signal handler may deadlock the calling
--thread.
--
-- Consider two shared variables X and Y, protected by the mutex MUT,
--and a condition variable COND that is to be signaled whenever X becomes
--greater than Y.
--
-- int x,y;
-- pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
-- pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
--
-- Waiting until X is greater than Y is performed as follows:
--
-- pthread_mutex_lock(&mut);
-- while (x <= y) {
-- pthread_cond_wait(&cond, &mut);
-- }
-- /* operate on x and y */
-- pthread_mutex_unlock(&mut);
--
-- Modifications on X and Y that may cause X to become greater than Y
--should signal the condition if needed:
--
-- pthread_mutex_lock(&mut);
-- /* modify x and y */
-- if (x > y) pthread_cond_broadcast(&cond);
-- pthread_mutex_unlock(&mut);
--
-- If it can be proved that at most one waiting thread needs to be waken
--up (for instance, if there are only two threads communicating through X
--and Y), `pthread_cond_signal' can be used as a slightly more efficient
--alternative to `pthread_cond_broadcast'. In doubt, use
--`pthread_cond_broadcast'.
--
-- To wait for X to becomes greater than Y with a timeout of 5 seconds,
--do:
--
-- struct timeval now;
-- struct timespec timeout;
-- int retcode;
--
-- pthread_mutex_lock(&mut);
-- gettimeofday(&now);
-- timeout.tv_sec = now.tv_sec + 5;
-- timeout.tv_nsec = now.tv_usec * 1000;
-- retcode = 0;
-- while (x <= y && retcode != ETIMEDOUT) {
-- retcode = pthread_cond_timedwait(&cond, &mut, &timeout);
-- }
-- if (retcode == ETIMEDOUT) {
-- /* timeout occurred */
-- } else {
-- /* operate on x and y */
-- }
-- pthread_mutex_unlock(&mut);
--
-- Condition attributes can be specified at condition creation time, by
--passing a condition attribute object as second argument to
--`pthread_cond_init'. Passing `NULL' is equivalent to passing a
--condition attribute object with all attributes set to their default
--values.
--
-- The LinuxThreads implementation supports no attributes for
--conditions. The functions on condition attributes are included only for
--compliance with the POSIX standard.
--
-- - Function: int pthread_condattr_init (pthread_condattr_t *ATTR)
-- - Function: int pthread_condattr_destroy (pthread_condattr_t *ATTR)
-- `pthread_condattr_init' initializes the condition attribute object
-- ATTR and fills it with default values for the attributes.
-- `pthread_condattr_destroy' destroys the condition attribute object
-- ATTR.
--
-- Both functions do nothing in the LinuxThreads implementation.
--
-- `pthread_condattr_init' and `pthread_condattr_destroy' always
-- return 0.
--
--
--File: libc.info, Node: POSIX Semaphores, Next: Thread-Specific Data, Prev: Condition Variables, Up: POSIX Threads
--
--POSIX Semaphores
--================
--
-- Semaphores are counters for resources shared between threads. The
--basic operations on semaphores are: increment the counter atomically,
--and wait until the counter is non-null and decrement it atomically.
--
-- Semaphores have a maximum value past which they cannot be
--incremented. The macro `SEM_VALUE_MAX' is defined to be this maximum
--value. In the GNU C library, `SEM_VALUE_MAX' is equal to `INT_MAX'
--(*note Range of Type::.), but it may be much smaller on other systems.
--
-- The pthreads library implements POSIX 1003.1b semaphores. These
--should not be confused with System V semaphores (`ipc', `semctl' and
--`semop').
--
-- All the semaphore functions and macros are defined in `semaphore.h'.
--
-- - Function: int sem_init (sem_t *SEM, int PSHARED, unsigned int VALUE)
-- `sem_init' initializes the semaphore object pointed to by SEM. The
-- count associated with the semaphore is set initially to VALUE. The
-- PSHARED argument indicates whether the semaphore is local to the
-- current process (PSHARED is zero) or is to be shared between
-- several processes (PSHARED is not zero).
--
-- On success `sem_init' returns 0. On failure it returns -1 and sets
-- ERRNO to one of the following values:
--
-- `EINVAL'
-- VALUE exceeds the maximal counter value `SEM_VALUE_MAX'
--
-- `ENOSYS'
-- PSHARED is not zero. LinuxThreads currently does not support
-- process-shared semaphores. (This will eventually change.)
--
-- - Function: int sem_destroy (sem_t * SEM)
-- `sem_destroy' destroys a semaphore object, freeing the resources it
-- might hold. If any threads are waiting on the semaphore when
-- `sem_destroy' is called, it fails and sets ERRNO to `EBUSY'.
--
-- In the LinuxThreads implementation, no resources are associated
-- with semaphore objects, thus `sem_destroy' actually does nothing
-- except checking that no thread is waiting on the semaphore. This
-- will change when process-shared semaphores are implemented.
--
-- - Function: int sem_wait (sem_t * SEM)
-- `sem_wait' suspends the calling thread until the semaphore pointed
-- to by SEM has non-zero count. It then atomically decreases the
-- semaphore count.
--
-- `sem_wait' is a cancellation point. It always returns 0.
--
-- - Function: int sem_trywait (sem_t * SEM)
-- `sem_trywait' is a non-blocking variant of `sem_wait'. If the
-- semaphore pointed to by SEM has non-zero count, the count is
-- atomically decreased and `sem_trywait' immediately returns 0. If
-- the semaphore count is zero, `sem_trywait' immediately returns -1
-- and sets errno to `EAGAIN'.
--
-- - Function: int sem_post (sem_t * SEM)
-- `sem_post' atomically increases the count of the semaphore pointed
-- to by SEM. This function never blocks.
--
-- On processors supporting atomic compare-and-swap (Intel 486,
-- Pentium and later, Alpha, PowerPC, MIPS II, Motorola 68k,
-- Ultrasparc), the `sem_post' function is can safely be called from
-- signal handlers. This is the only thread synchronization function
-- provided by POSIX threads that is async-signal safe. On the Intel
-- 386 and earlier Sparc chips, the current LinuxThreads
-- implementation of `sem_post' is not async-signal safe, because the
-- hardware does not support the required atomic operations.
--
-- `sem_post' always succeeds and returns 0, unless the semaphore
-- count would exceed `SEM_VALUE_MAX' after being incremented. In
-- that case `sem_post' returns -1 and sets ERRNO to `EINVAL'. The
-- semaphore count is left unchanged.
--
-- - Function: int sem_getvalue (sem_t * SEM, int * SVAL)
-- `sem_getvalue' stores in the location pointed to by SVAL the
-- current count of the semaphore SEM. It always returns 0.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-43 glibc-2.1.3/manual/libc.info-43
---- ../glibc-2.1.3/manual/libc.info-43 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-43 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1182 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Thread-Specific Data, Next: Threads and Signal Handling, Prev: POSIX Semaphores, Up: POSIX Threads
--
--Thread-Specific Data
--====================
--
-- Programs often need global or static variables that have different
--values in different threads. Since threads share one memory space, this
--cannot be achieved with regular variables. Thread-specific data is the
--POSIX threads answer to this need.
--
-- Each thread possesses a private memory block, the thread-specific
--data area, or TSD area for short. This area is indexed by TSD keys. The
--TSD area associates values of type `void *' to TSD keys. TSD keys are
--common to all threads, but the value associated with a given TSD key can
--be different in each thread.
--
-- For concreteness, the TSD areas can be viewed as arrays of `void *'
--pointers, TSD keys as integer indices into these arrays, and the value
--of a TSD key as the value of the corresponding array element in the
--calling thread.
--
-- When a thread is created, its TSD area initially associates `NULL'
--with all keys.
--
-- - Function: int pthread_key_create (pthread_key_t *KEY, void
-- (*destr_function) (void *))
-- `pthread_key_create' allocates a new TSD key. The key is stored in
-- the location pointed to by KEY. There is a limit of
-- `PTHREAD_KEYS_MAX' on the number of keys allocated at a given
-- time. The value initially associated with the returned key is
-- `NULL' in all currently executing threads.
--
-- The DESTR_FUNCTION argument, if not `NULL', specifies a destructor
-- function associated with the key. When a thread terminates via
-- `pthread_exit' or by cancellation, DESTR_FUNCTION is called on the
-- value associated with the key in that thread. The DESTR_FUNCTION
-- is not called if a key is deleted with `pthread_key_delete' or a
-- value is changed with `pthread_setspecific'. The order in which
-- destructor functions are called at thread termination time is
-- unspecified.
--
-- Before the destructor function is called, the `NULL' value is
-- associated with the key in the current thread. A destructor
-- function might, however, re-associate non-`NULL' values to that
-- key or some other key. To deal with this, if after all the
-- destructors have been called for all non-`NULL' values, there are
-- still some non-`NULL' values with associated destructors, then the
-- process is repeated. The LinuxThreads implementation stops the
-- process after `PTHREAD_DESTRUCTOR_ITERATIONS' iterations, even if
-- some non-`NULL' values with associated descriptors remain. Other
-- implementations may loop indefinitely.
--
-- `pthread_key_create' returns 0 unless `PTHREAD_KEYS_MAX' keys have
-- already been allocated, in which case it fails and returns
-- `EAGAIN'.
--
-- - Function: int pthread_key_delete (pthread_key_t KEY)
-- `pthread_key_delete' deallocates a TSD key. It does not check
-- whether non-`NULL' values are associated with that key in the
-- currently executing threads, nor call the destructor function
-- associated with the key.
--
-- If there is no such key KEY, it returns `EINVAL'. Otherwise it
-- returns 0.
--
-- - Function: int pthread_setspecific (pthread_key_t KEY, const void
-- *POINTER)
-- `pthread_setspecific' changes the value associated with KEY in the
-- calling thread, storing the given POINTER instead.
--
-- If there is no such key KEY, it returns `EINVAL'. Otherwise it
-- returns 0.
--
-- - Function: void * pthread_getspecific (pthread_key_t KEY)
-- `pthread_getspecific' returns the value currently associated with
-- KEY in the calling thread.
--
-- If there is no such key KEY, it returns `NULL'.
--
-- The following code fragment allocates a thread-specific array of 100
--characters, with automatic reclaimation at thread exit:
--
-- /* Key for the thread-specific buffer */
-- static pthread_key_t buffer_key;
--
-- /* Once-only initialisation of the key */
-- static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
--
-- /* Allocate the thread-specific buffer */
-- void buffer_alloc(void)
-- {
-- pthread_once(&buffer_key_once, buffer_key_alloc);
-- pthread_setspecific(buffer_key, malloc(100));
-- }
--
-- /* Return the thread-specific buffer */
-- char * get_buffer(void)
-- {
-- return (char *) pthread_getspecific(buffer_key);
-- }
--
-- /* Allocate the key */
-- static void buffer_key_alloc()
-- {
-- pthread_key_create(&buffer_key, buffer_destroy);
-- }
--
-- /* Free the thread-specific buffer */
-- static void buffer_destroy(void * buf)
-- {
-- free(buf);
-- }
--
--
--File: libc.info, Node: Threads and Signal Handling, Next: Miscellaneous Thread Functions, Prev: Thread-Specific Data, Up: POSIX Threads
--
--Threads and Signal Handling
--===========================
--
-- - Function: int pthread_sigmask (int HOW, const sigset_t *NEWMASK,
-- sigset_t *OLDMASK)
-- `pthread_sigmask' changes the signal mask for the calling thread as
-- described by the HOW and NEWMASK arguments. If OLDMASK is not
-- `NULL', the previous signal mask is stored in the location pointed
-- to by OLDMASK.
--
-- The meaning of the HOW and NEWMASK arguments is the same as for
-- `sigprocmask'. If HOW is `SIG_SETMASK', the signal mask is set to
-- NEWMASK. If HOW is `SIG_BLOCK', the signals specified to NEWMASK
-- are added to the current signal mask. If HOW is `SIG_UNBLOCK',
-- the signals specified to NEWMASK are removed from the current
-- signal mask.
--
-- Recall that signal masks are set on a per-thread basis, but signal
-- actions and signal handlers, as set with `sigaction', are shared
-- between all threads.
--
-- The `pthread_sigmask' function returns 0 on success, and one of the
-- following error codes on error:
-- `EINVAL'
-- HOW is not one of `SIG_SETMASK', `SIG_BLOCK', or `SIG_UNBLOCK'
--
-- `EFAULT'
-- NEWMASK or OLDMASK point to invalid addresses
--
-- - Function: int pthread_kill (pthread_t THREAD, int SIGNO)
-- `pthread_kill' sends signal number SIGNO to the thread THREAD.
-- The signal is delivered and handled as described in *Note Signal
-- Handling::.
--
-- `pthread_kill' returns 0 on success, one of the following error
-- codes on error:
-- `EINVAL'
-- SIGNO is not a valid signal number
--
-- `ESRCH'
-- The thread THREAD does not exist (e.g. it has already
-- terminated)
--
-- - Function: int sigwait (const sigset_t *SET, int *SIG)
-- `sigwait' suspends the calling thread until one of the signals in
-- SET is delivered to the calling thread. It then stores the number
-- of the signal received in the location pointed to by SIG and
-- returns. The signals in SET must be blocked and not ignored on
-- entrance to `sigwait'. If the delivered signal has a signal handler
-- function attached, that function is *not* called.
--
-- `sigwait' is a cancellation point. It always returns 0.
--
-- For `sigwait' to work reliably, the signals being waited for must be
--blocked in all threads, not only in the calling thread, since otherwise
--the POSIX semantics for signal delivery do not guarantee that it's the
--thread doing the `sigwait' that will receive the signal. The best way
--to achieve this is block those signals before any threads are created,
--and never unblock them in the program other than by calling `sigwait'.
--
-- Signal handling in LinuxThreads departs significantly from the POSIX
--standard. According to the standard, "asynchronous" (external) signals
--are addressed to the whole process (the collection of all threads),
--which then delivers them to one particular thread. The thread that
--actually receives the signal is any thread that does not currently block
--the signal.
--
-- In LinuxThreads, each thread is actually a kernel process with its
--own PID, so external signals are always directed to one particular
--thread. If, for instance, another thread is blocked in `sigwait' on
--that signal, it will not be restarted.
--
-- The LinuxThreads implementation of `sigwait' installs dummy signal
--handlers for the signals in SET for the duration of the wait. Since
--signal handlers are shared between all threads, other threads must not
--attach their own signal handlers to these signals, or alternatively
--they should all block these signals (which is recommended anyway).
--
--
--File: libc.info, Node: Miscellaneous Thread Functions, Prev: Threads and Signal Handling, Up: POSIX Threads
--
--Miscellaneous Thread Functions
--==============================
--
-- - Function: pthread_t pthread_self (VOID)
-- `pthread_self' returns the thread identifier for the calling
-- thread.
--
-- - Function: int pthread_equal (pthread_t thread1, pthread_t thread2)
-- `pthread_equal' determines if two thread identifiers refer to the
-- same thread.
--
-- A non-zero value is returned if THREAD1 and THREAD2 refer to the
-- same thread. Otherwise, 0 is returned.
--
-- - Function: int pthread_detach (pthread_t TH)
-- `pthread_detach' puts the thread TH in the detached state. This
-- guarantees that the memory resources consumed by TH will be freed
-- immediately when TH terminates. However, this prevents other
-- threads from synchronizing on the termination of TH using
-- `pthread_join'.
--
-- A thread can be created initially in the detached state, using the
-- `detachstate' attribute to `pthread_create'. In contrast,
-- `pthread_detach' applies to threads created in the joinable state,
-- and which need to be put in the detached state later.
--
-- After `pthread_detach' completes, subsequent attempts to perform
-- `pthread_join' on TH will fail. If another thread is already
-- joining the thread TH at the time `pthread_detach' is called,
-- `pthread_detach' does nothing and leaves TH in the joinable state.
--
-- On success, 0 is returned. On error, one of the following codes is
-- returned:
-- `ESRCH'
-- No thread could be found corresponding to that specified by TH
--
-- `EINVAL'
-- The thread TH is already in the detached state
--
-- - Function: int pthread_atfork (void (*PREPARE)(void), void
-- (*PARENT)(void), void (*CHILD)(void))
-- `pthread_atfork' registers handler functions to be called just
-- before and just after a new process is created with `fork'. The
-- PREPARE handler will be called from the parent process, just
-- before the new process is created. The PARENT handler will be
-- called from the parent process, just before `fork' returns. The
-- CHILD handler will be called from the child process, just before
-- `fork' returns.
--
-- `pthread_atfork' returns 0 on success and a non-zero error code on
-- error.
--
-- One or more of the three handlers PREPARE, PARENT and CHILD can be
-- given as `NULL', meaning that no handler needs to be called at the
-- corresponding point.
--
-- `pthread_atfork' can be called several times to install several
-- sets of handlers. At `fork' time, the PREPARE handlers are called
-- in LIFO order (last added with `pthread_atfork', first called
-- before `fork'), while the PARENT and CHILD handlers are called in
-- FIFO order (first added, first called).
--
-- If there is insufficient memory available to register the handlers,
-- `pthread_atfork' fails and returns `ENOMEM'. Otherwise it returns
-- 0.
--
-- To understand the purpose of `pthread_atfork', recall that `fork'
--duplicates the whole memory space, including mutexes in their current
--locking state, but only the calling thread: other threads are not
--running in the child process. Thus, if a mutex is locked by a thread
--other than the thread calling `fork', that mutex will remain locked
--forever in the child process, possibly blocking the execution of the
--child process. To avoid this, install handlers with `pthread_atfork' as
--follows: the PREPARE handler locks the global mutexes (in locking
--order), and the PARENT and CHILD handlers unlock them (in reverse
--order). Alternatively, PREPARE and PARENT can be set to `NULL' and
--CHILD to a function that calls `pthread_mutex_init' on the global
--mutexes.
--
-- - Function: void pthread_kill_other_threads_np (VOID)
-- `pthread_kill_other_threads_np' is a non-portable LinuxThreads
-- extension. It causes all threads in the program to terminate
-- immediately, except the calling thread which proceeds normally. It
-- is intended to be called just before a thread calls one of the
-- `exec' functions, e.g. `execve'.
--
-- Termination of the other threads is not performed through
-- `pthread_cancel' and completely bypasses the cancellation
-- mechanism. Hence, the current settings for cancellation state and
-- cancellation type are ignored, and the cleanup handlers are not
-- executed in the terminated threads.
--
-- According to POSIX 1003.1c, a successful `exec*' in one of the
-- threads should automatically terminate all other threads in the
-- program. This behavior is not yet implemented in LinuxThreads.
-- Calling `pthread_kill_other_threads_np' before `exec*' achieves
-- much of the same behavior, except that if `exec*' ultimately
-- fails, then all other threads are already killed.
--
-- - Function: int pthread_once (pthread_once_t *once_CONTROL, void
-- (*INIT_ROUTINE) (void))
-- The purpose of `pthread_once' is to ensure that a piece of
-- initialization code is executed at most once. The ONCE_CONTROL
-- argument points to a static or extern variable statically
-- initialized to `PTHREAD_ONCE_INIT'.
--
-- The first time `pthread_once' is called with a given ONCE_CONTROL
-- argument, it calls INIT_ROUTINE with no argument and changes the
-- value of the ONCE_CONTROL variable to record that initialization
-- has been performed. Subsequent calls to `pthread_once' with the
-- same `once_control' argument do nothing.
--
-- `pthread_once' always returns 0.
--
-- - Function: int pthread_setschedparam (pthread_t target_THREAD, int
-- POLICY, const struct sched_param *PARAM)
-- `pthread_setschedparam' sets the scheduling parameters for the
-- thread TARGET_THREAD as indicated by POLICY and PARAM. POLICY can
-- be either `SCHED_OTHER' (regular, non-realtime scheduling),
-- `SCHED_RR' (realtime, round-robin) or `SCHED_FIFO' (realtime,
-- first-in first-out). PARAM specifies the scheduling priority for
-- the two realtime policies. See `sched_setpolicy' for more
-- information on scheduling policies.
--
-- The realtime scheduling policies `SCHED_RR' and `SCHED_FIFO' are
-- available only to processes with superuser privileges.
--
-- On success, `pthread_setschedparam' returns 0. On error it returns
-- one of the following codes:
-- `EINVAL'
-- POLICY is not one of `SCHED_OTHER', `SCHED_RR', `SCHED_FIFO',
-- or the priority value specified by PARAM is not valid for the
-- specified policy
--
-- `EPERM'
-- Realtime scheduling was requested but the calling process
-- does not have sufficient privileges.
--
-- `ESRCH'
-- The TARGET_THREAD is invalid or has already terminated
--
-- `EFAULT'
-- PARAM points outside the process memory space
--
-- - Function: int pthread_getschedparam (pthread_t target_THREAD, int
-- *POLICY, struct sched_param *PARAM)
-- `pthread_getschedparam' retrieves the scheduling policy and
-- scheduling parameters for the thread TARGET_THREAD and stores them
-- in the locations pointed to by POLICY and PARAM, respectively.
--
-- `pthread_getschedparam' returns 0 on success, or one of the
-- following error codes on failure:
-- `ESRCH'
-- The TARGET_THREAD is invalid or has already terminated.
--
-- `EFAULT'
-- POLICY or PARAM point outside the process memory space.
--
--
--
--File: libc.info, Node: Language Features, Next: Library Summary, Prev: POSIX Threads, Up: Top
--
--C Language Facilities in the Library
--************************************
--
-- Some of the facilities implemented by the C library really should be
--thought of as parts of the C language itself. These facilities ought to
--be documented in the C Language Manual, not in the library manual; but
--since we don't have the language manual yet, and documentation for these
--features has been written, we are publishing it here.
--
--* Menu:
--
--* Consistency Checking:: Using `assert' to abort if
-- something "impossible" happens.
--* Variadic Functions:: Defining functions with varying numbers
-- of args.
--* Null Pointer Constant:: The macro `NULL'.
--* Important Data Types:: Data types for object sizes.
--* Data Type Measurements:: Parameters of data type representations.
--
--
--File: libc.info, Node: Consistency Checking, Next: Variadic Functions, Up: Language Features
--
--Explicitly Checking Internal Consistency
--========================================
--
-- When you're writing a program, it's often a good idea to put in
--checks at strategic places for "impossible" errors or violations of
--basic assumptions. These kinds of checks are helpful in debugging
--problems with the interfaces between different parts of the program,
--for example.
--
-- The `assert' macro, defined in the header file `assert.h', provides
--a convenient way to abort the program while printing a message about
--where in the program the error was detected.
--
-- Once you think your program is debugged, you can disable the error
--checks performed by the `assert' macro by recompiling with the macro
--`NDEBUG' defined. This means you don't actually have to change the
--program source code to disable these checks.
--
-- But disabling these consistency checks is undesirable unless they
--make the program significantly slower. All else being equal, more error
--checking is good no matter who is running the program. A wise user
--would rather have a program crash, visibly, than have it return nonsense
--without indicating anything might be wrong.
--
-- - Macro: void assert (int EXPRESSION)
-- Verify the programmer's belief that EXPRESSION should be nonzero
-- at this point in the program.
--
-- If `NDEBUG' is not defined, `assert' tests the value of
-- EXPRESSION. If it is false (zero), `assert' aborts the program
-- (*note Aborting a Program::.) after printing a message of the form:
--
-- `FILE':LINENUM: FUNCTION: Assertion `EXPRESSION' failed.
--
-- on the standard error stream `stderr' (*note Standard Streams::.).
-- The filename and line number are taken from the C preprocessor
-- macros `__FILE__' and `__LINE__' and specify where the call to
-- `assert' was written. When using the GNU C compiler, the name of
-- the function which calls `assert' is taken from the built-in
-- variable `__PRETTY_FUNCTION__'; with older compilers, the function
-- name and following colon are omitted.
--
-- If the preprocessor macro `NDEBUG' is defined before `assert.h' is
-- included, the `assert' macro is defined to do absolutely nothing.
--
-- *Warning:* Even the argument expression EXPRESSION is not
-- evaluated if `NDEBUG' is in effect. So never use `assert' with
-- arguments that involve side effects. For example, `assert (++i >
-- 0);' is a bad idea, because `i' will not be incremented if
-- `NDEBUG' is defined.
--
-- Sometimes the "impossible" condition you want to check for is an
--error return from an operating system function. Then it is useful to
--display not only where the program crashes, but also what error was
--returned. The `assert_perror' macro makes this easy.
--
-- - Macro: void assert_perror (int ERRNUM)
-- Similar to `assert', but verifies that ERRNUM is zero.
--
-- If `NDEBUG' is defined, `assert_perror' tests the value of ERRNUM.
-- If it is nonzero, `assert_perror' aborts the program after a
-- printing a message of the form:
--
-- `FILE':LINENUM: FUNCTION: ERROR TEXT
--
-- on the standard error stream. The file name, line number, and
-- function name are as for `assert'. The error text is the result of
-- `strerror (ERRNUM)'. *Note Error Messages::.
--
-- Like `assert', if `NDEBUG' is defined before `assert.h' is
-- included, the `assert_perror' macro does absolutely nothing. It
-- does not evaluate the argument, so ERRNUM should not have any side
-- effects. It is best for ERRNUM to be a just simple variable
-- reference; often it will be `errno'.
--
-- This macro is a GNU extension.
--
-- *Usage note:* The `assert' facility is designed for detecting
--*internal inconsistency*; it is not suitable for reporting invalid
--input or improper usage by *the user* of the program.
--
-- The information in the diagnostic messages printed by the `assert'
--macro is intended to help you, the programmer, track down the cause of a
--bug, but is not really useful for telling a user of your program why his
--or her input was invalid or why a command could not be carried out. So
--you can't use `assert' or `assert_perror' to print the error messages
--for these eventualities.
--
-- What's more, your program should not abort when given invalid input,
--as `assert' would do--it should exit with nonzero status (*note Exit
--Status::.) after printing its error messages, or perhaps read another
--command or move on to the next input file.
--
-- *Note Error Messages::, for information on printing error messages
--for problems that *do not* represent bugs in the program.
--
--
--File: libc.info, Node: Variadic Functions, Next: Null Pointer Constant, Prev: Consistency Checking, Up: Language Features
--
--Variadic Functions
--==================
--
-- ISO C defines a syntax for declaring a function to take a variable
--number or type of arguments. (Such functions are referred to as
--"varargs functions" or "variadic functions".) However, the language
--itself provides no mechanism for such functions to access their
--non-required arguments; instead, you use the variable arguments macros
--defined in `stdarg.h'.
--
-- This section describes how to declare variadic functions, how to
--write them, and how to call them properly.
--
-- *Compatibility Note:* Many older C dialects provide a similar, but
--incompatible, mechanism for defining functions with variable numbers of
--arguments, using `varargs.h'.
--
--* Menu:
--
--* Why Variadic:: Reasons for making functions take
-- variable arguments.
--* How Variadic:: How to define and call variadic functions.
--* Variadic Example:: A complete example.
--
--
--File: libc.info, Node: Why Variadic, Next: How Variadic, Up: Variadic Functions
--
--Why Variadic Functions are Used
---------------------------------
--
-- Ordinary C functions take a fixed number of arguments. When you
--define a function, you specify the data type for each argument. Every
--call to the function should supply the expected number of arguments,
--with types that can be converted to the specified ones. Thus, if the
--function `foo' is declared with `int foo (int, char *);' then you must
--call it with two arguments, a number (any kind will do) and a string
--pointer.
--
-- But some functions perform operations that can meaningfully accept an
--unlimited number of arguments.
--
-- In some cases a function can handle any number of values by
--operating on all of them as a block. For example, consider a function
--that allocates a one-dimensional array with `malloc' to hold a
--specified set of values. This operation makes sense for any number of
--values, as long as the length of the array corresponds to that number.
--Without facilities for variable arguments, you would have to define a
--separate function for each possible array size.
--
-- The library function `printf' (*note Formatted Output::.) is an
--example of another class of function where variable arguments are
--useful. This function prints its arguments (which can vary in type as
--well as number) under the control of a format template string.
--
-- These are good reasons to define a "variadic" function which can
--handle as many arguments as the caller chooses to pass.
--
-- Some functions such as `open' take a fixed set of arguments, but
--occasionally ignore the last few. Strict adherence to ISO C requires
--these functions to be defined as variadic; in practice, however, the GNU
--C compiler and most other C compilers let you define such a function to
--take a fixed set of arguments--the most it can ever use--and then only
--*declare* the function as variadic (or not declare its arguments at
--all!).
--
--
--File: libc.info, Node: How Variadic, Next: Variadic Example, Prev: Why Variadic, Up: Variadic Functions
--
--How Variadic Functions are Defined and Used
---------------------------------------------
--
-- Defining and using a variadic function involves three steps:
--
-- * *Define* the function as variadic, using an ellipsis (`...') in
-- the argument list, and using special macros to access the variable
-- arguments. *Note Receiving Arguments::.
--
-- * *Declare* the function as variadic, using a prototype with an
-- ellipsis (`...'), in all the files which call it. *Note Variadic
-- Prototypes::.
--
-- * *Call* the function by writing the fixed arguments followed by the
-- additional variable arguments. *Note Calling Variadics::.
--
--* Menu:
--
--* Variadic Prototypes:: How to make a prototype for a function
-- with variable arguments.
--* Receiving Arguments:: Steps you must follow to access the
-- optional argument values.
--* How Many Arguments:: How to decide whether there are more arguments.
--* Calling Variadics:: Things you need to know about calling
-- variable arguments functions.
--* Argument Macros:: Detailed specification of the macros
-- for accessing variable arguments.
--* Old Varargs:: The pre-ISO way of defining variadic functions.
--
--
--File: libc.info, Node: Variadic Prototypes, Next: Receiving Arguments, Up: How Variadic
--
--Syntax for Variable Arguments
--.............................
--
-- A function that accepts a variable number of arguments must be
--declared with a prototype that says so. You write the fixed arguments
--as usual, and then tack on `...' to indicate the possibility of
--additional arguments. The syntax of ISO C requires at least one fixed
--argument before the `...'. For example,
--
-- int
-- func (const char *a, int b, ...)
-- {
-- ...
-- }
--
--outlines a definition of a function `func' which returns an `int' and
--takes two required arguments, a `const char *' and an `int'. These are
--followed by any number of anonymous arguments.
--
-- *Portability note:* For some C compilers, the last required argument
--must not be declared `register' in the function definition.
--Furthermore, this argument's type must be "self-promoting": that is,
--the default promotions must not change its type. This rules out array
--and function types, as well as `float', `char' (whether signed or not)
--and `short int' (whether signed or not). This is actually an ISO C
--requirement.
--
--
--File: libc.info, Node: Receiving Arguments, Next: How Many Arguments, Prev: Variadic Prototypes, Up: How Variadic
--
--Receiving the Argument Values
--.............................
--
-- Ordinary fixed arguments have individual names, and you can use these
--names to access their values. But optional arguments have no
--names--nothing but `...'. How can you access them?
--
-- The only way to access them is sequentially, in the order they were
--written, and you must use special macros from `stdarg.h' in the
--following three step process:
--
-- 1. You initialize an argument pointer variable of type `va_list' using
-- `va_start'. The argument pointer when initialized points to the
-- first optional argument.
--
-- 2. You access the optional arguments by successive calls to `va_arg'.
-- The first call to `va_arg' gives you the first optional argument,
-- the next call gives you the second, and so on.
--
-- You can stop at any time if you wish to ignore any remaining
-- optional arguments. It is perfectly all right for a function to
-- access fewer arguments than were supplied in the call, but you
-- will get garbage values if you try to access too many arguments.
--
-- 3. You indicate that you are finished with the argument pointer
-- variable by calling `va_end'.
--
-- (In practice, with most C compilers, calling `va_end' does nothing
-- and you do not really need to call it. This is always true in the
-- GNU C compiler. But you might as well call `va_end' just in case
-- your program is someday compiled with a peculiar compiler.)
--
-- *Note Argument Macros::, for the full definitions of `va_start',
--`va_arg' and `va_end'.
--
-- Steps 1 and 3 must be performed in the function that accepts the
--optional arguments. However, you can pass the `va_list' variable as an
--argument to another function and perform all or part of step 2 there.
--
-- You can perform the entire sequence of the three steps multiple times
--within a single function invocation. If you want to ignore the optional
--arguments, you can do these steps zero times.
--
-- You can have more than one argument pointer variable if you like.
--You can initialize each variable with `va_start' when you wish, and
--then you can fetch arguments with each argument pointer as you wish.
--Each argument pointer variable will sequence through the same set of
--argument values, but at its own pace.
--
-- *Portability note:* With some compilers, once you pass an argument
--pointer value to a subroutine, you must not keep using the same
--argument pointer value after that subroutine returns. For full
--portability, you should just pass it to `va_end'. This is actually an
--ISO C requirement, but most ANSI C compilers work happily regardless.
--
--
--File: libc.info, Node: How Many Arguments, Next: Calling Variadics, Prev: Receiving Arguments, Up: How Variadic
--
--How Many Arguments Were Supplied
--................................
--
-- There is no general way for a function to determine the number and
--type of the optional arguments it was called with. So whoever designs
--the function typically designs a convention for the caller to tell it
--how many arguments it has, and what kind. It is up to you to define an
--appropriate calling convention for each variadic function, and write all
--calls accordingly.
--
-- One kind of calling convention is to pass the number of optional
--arguments as one of the fixed arguments. This convention works provided
--all of the optional arguments are of the same type.
--
-- A similar alternative is to have one of the required arguments be a
--bit mask, with a bit for each possible purpose for which an optional
--argument might be supplied. You would test the bits in a predefined
--sequence; if the bit is set, fetch the value of the next argument,
--otherwise use a default value.
--
-- A required argument can be used as a pattern to specify both the
--number and types of the optional arguments. The format string argument
--to `printf' is one example of this (*note Formatted Output
--Functions::.).
--
-- Another possibility is to pass an "end marker" value as the last
--optional argument. For example, for a function that manipulates an
--arbitrary number of pointer arguments, a null pointer might indicate the
--end of the argument list. (This assumes that a null pointer isn't
--otherwise meaningful to the function.) The `execl' function works in
--just this way; see *Note Executing a File::.
--
--
--File: libc.info, Node: Calling Variadics, Next: Argument Macros, Prev: How Many Arguments, Up: How Variadic
--
--Calling Variadic Functions
--..........................
--
-- You don't have to write anything special when you call a variadic
--function. Just write the arguments (required arguments, followed by
--optional ones) inside parentheses, separated by commas, as usual. But
--you should prepare by declaring the function with a prototype, and you
--must know how the argument values are converted.
--
-- In principle, functions that are *defined* to be variadic must also
--be *declared* to be variadic using a function prototype whenever you
--call them. (*Note Variadic Prototypes::, for how.) This is because
--some C compilers use a different calling convention to pass the same set
--of argument values to a function depending on whether that function
--takes variable arguments or fixed arguments.
--
-- In practice, the GNU C compiler always passes a given set of argument
--types in the same way regardless of whether they are optional or
--required. So, as long as the argument types are self-promoting, you can
--safely omit declaring them. Usually it is a good idea to declare the
--argument types for variadic functions, and indeed for all functions.
--But there are a few functions which it is extremely convenient not to
--have to declare as variadic--for example, `open' and `printf'.
--
-- Since the prototype doesn't specify types for optional arguments, in
--a call to a variadic function the "default argument promotions" are
--performed on the optional argument values. This means the objects of
--type `char' or `short int' (whether signed or not) are promoted to
--either `int' or `unsigned int', as appropriate; and that objects of
--type `float' are promoted to type `double'. So, if the caller passes a
--`char' as an optional argument, it is promoted to an `int', and the
--function should get it with `va_arg (AP, int)'.
--
-- Conversion of the required arguments is controlled by the function
--prototype in the usual way: the argument expression is converted to the
--declared argument type as if it were being assigned to a variable of
--that type.
--
--
--File: libc.info, Node: Argument Macros, Next: Old Varargs, Prev: Calling Variadics, Up: How Variadic
--
--Argument Access Macros
--......................
--
-- Here are descriptions of the macros used to retrieve variable
--arguments. These macros are defined in the header file `stdarg.h'.
--
-- - Data Type: va_list
-- The type `va_list' is used for argument pointer variables.
--
-- - Macro: void va_start (va_list AP, LAST-REQUIRED)
-- This macro initializes the argument pointer variable AP to point
-- to the first of the optional arguments of the current function;
-- LAST-REQUIRED must be the last required argument to the function.
--
-- *Note Old Varargs::, for an alternate definition of `va_start'
-- found in the header file `varargs.h'.
--
-- - Macro: TYPE va_arg (va_list AP, TYPE)
-- The `va_arg' macro returns the value of the next optional argument,
-- and modifies the value of AP to point to the subsequent argument.
-- Thus, successive uses of `va_arg' return successive optional
-- arguments.
--
-- The type of the value returned by `va_arg' is TYPE as specified in
-- the call. TYPE must be a self-promoting type (not `char' or
-- `short int' or `float') that matches the type of the actual
-- argument.
--
-- - Macro: void va_end (va_list AP)
-- This ends the use of AP. After a `va_end' call, further `va_arg'
-- calls with the same AP may not work. You should invoke `va_end'
-- before returning from the function in which `va_start' was invoked
-- with the same AP argument.
--
-- In the GNU C library, `va_end' does nothing, and you need not ever
-- use it except for reasons of portability.
--
--
-- Sometimes it is necessary to parse the list of parameters more than
--once or one wants to remember a certain position in the parameter list.
--To do this one will have to make a copy of the current value of the
--argument. But `va_list' is an opaque type and it is not guaranteed
--that one can simply assign the value of a variable to another one of
--type `va_list'
--
-- - Macro: void __va_copy (va_list DEST, va_list SRC)
-- The `__va_copy' macro allows copying of objects of type `va_list'
-- even if this is no integral type. The argument pointer in DEST is
-- initialized to point to the same argument as the pointer in SRC.
--
-- This macro is a GNU extension but it will hopefully also be
-- available in the next update of the ISO C standard.
--
-- If you want to use `__va_copy' you should always be prepared that
--this macro is not available. On architectures where a simple assignment
--is invalid it hopefully is and so one should always write something like
--this:
--
-- {
-- va_list ap, save;
-- ...
-- #ifdef __va_copy
-- __va_copy (save, ap);
-- #else
-- save = ap;
-- #endif
-- ...
-- }
--
--
--File: libc.info, Node: Variadic Example, Prev: How Variadic, Up: Variadic Functions
--
--Example of a Variadic Function
--------------------------------
--
-- Here is a complete sample function that accepts a variable number of
--arguments. The first argument to the function is the count of remaining
--arguments, which are added up and the result returned. While trivial,
--this function is sufficient to illustrate how to use the variable
--arguments facility.
--
-- #include <stdarg.h>
-- #include <stdio.h>
--
-- int
-- add_em_up (int count,...)
-- {
-- va_list ap;
-- int i, sum;
--
-- va_start (ap, count); /* Initialize the argument list. */
--
-- sum = 0;
-- for (i = 0; i < count; i++)
-- sum += va_arg (ap, int); /* Get the next argument value. */
--
-- va_end (ap); /* Clean up. */
-- return sum;
-- }
--
-- int
-- main (void)
-- {
-- /* This call prints 16. */
-- printf ("%d\n", add_em_up (3, 5, 5, 6));
--
-- /* This call prints 55. */
-- printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
--
-- return 0;
-- }
--
--
--File: libc.info, Node: Old Varargs, Prev: Argument Macros, Up: How Variadic
--
--Old-Style Variadic Functions
--............................
--
-- Before ISO C, programmers used a slightly different facility for
--writing variadic functions. The GNU C compiler still supports it;
--currently, it is more portable than the ISO C facility, since support
--for ISO C is still not universal. The header file which defines the
--old-fashioned variadic facility is called `varargs.h'.
--
-- Using `varargs.h' is almost the same as using `stdarg.h'. There is
--no difference in how you call a variadic function; see *Note Calling
--Variadics::. The only difference is in how you define them. First of
--all, you must use old-style non-prototype syntax, like this:
--
-- tree
-- build (va_alist)
-- va_dcl
-- {
--
-- Secondly, you must give `va_start' just one argument, like this:
--
-- va_list p;
-- va_start (p);
--
-- These are the special macros used for defining old-style variadic
--functions:
--
-- - Macro: va_alist
-- This macro stands for the argument name list required in a variadic
-- function.
--
-- - Macro: va_dcl
-- This macro declares the implicit argument or arguments for a
-- variadic function.
--
-- - Macro: void va_start (va_list AP)
-- This macro, as defined in `varargs.h', initializes the argument
-- pointer variable AP to point to the first argument of the current
-- function.
--
-- The other argument macros, `va_arg' and `va_end', are the same in
--`varargs.h' as in `stdarg.h'; see *Note Argument Macros::, for details.
--
-- It does not work to include both `varargs.h' and `stdarg.h' in the
--same compilation; they define `va_start' in conflicting ways.
--
--
--File: libc.info, Node: Null Pointer Constant, Next: Important Data Types, Prev: Variadic Functions, Up: Language Features
--
--Null Pointer Constant
--=====================
--
-- The null pointer constant is guaranteed not to point to any real
--object. You can assign it to any pointer variable since it has type
--`void *'. The preferred way to write a null pointer constant is with
--`NULL'.
--
-- - Macro: void * NULL
-- This is a null pointer constant.
--
-- You can also use `0' or `(void *)0' as a null pointer constant, but
--using `NULL' is cleaner because it makes the purpose of the constant
--more evident.
--
-- If you use the null pointer constant as a function argument, then for
--complete portability you should make sure that the function has a
--prototype declaration. Otherwise, if the target machine has two
--different pointer representations, the compiler won't know which
--representation to use for that argument. You can avoid the problem by
--explicitly casting the constant to the proper pointer type, but we
--recommend instead adding a prototype for the function you are calling.
--
--
--File: libc.info, Node: Important Data Types, Next: Data Type Measurements, Prev: Null Pointer Constant, Up: Language Features
--
--Important Data Types
--====================
--
-- The result of subtracting two pointers in C is always an integer,
--but the precise data type varies from C compiler to C compiler.
--Likewise, the data type of the result of `sizeof' also varies between
--compilers. ISO defines standard aliases for these two types, so you
--can refer to them in a portable fashion. They are defined in the
--header file `stddef.h'.
--
-- - Data Type: ptrdiff_t
-- This is the signed integer type of the result of subtracting two
-- pointers. For example, with the declaration `char *p1, *p2;', the
-- expression `p2 - p1' is of type `ptrdiff_t'. This will probably
-- be one of the standard signed integer types (`short int', `int' or
-- `long int'), but might be a nonstandard type that exists only for
-- this purpose.
--
-- - Data Type: size_t
-- This is an unsigned integer type used to represent the sizes of
-- objects. The result of the `sizeof' operator is of this type, and
-- functions such as `malloc' (*note Unconstrained Allocation::.) and
-- `memcpy' (*note Copying and Concatenation::.) accept arguments of
-- this type to specify object sizes.
--
-- *Usage Note:* `size_t' is the preferred way to declare any
-- arguments or variables that hold the size of an object.
--
-- In the GNU system `size_t' is equivalent to either `unsigned int' or
--`unsigned long int'. These types have identical properties on the GNU
--system, and for most purposes, you can use them interchangeably.
--However, they are distinct as data types, which makes a difference in
--certain contexts.
--
-- For example, when you specify the type of a function argument in a
--function prototype, it makes a difference which one you use. If the
--system header files declare `malloc' with an argument of type `size_t'
--and you declare `malloc' with an argument of type `unsigned int', you
--will get a compilation error if `size_t' happens to be `unsigned long
--int' on your system. To avoid any possibility of error, when a
--function argument or value is supposed to have type `size_t', never
--declare its type in any other way.
--
-- *Compatibility Note:* Implementations of C before the advent of
--ISO C generally used `unsigned int' for representing object sizes and
--`int' for pointer subtraction results. They did not necessarily define
--either `size_t' or `ptrdiff_t'. Unix systems did define `size_t', in
--`sys/types.h', but the definition was usually a signed type.
--
--
--File: libc.info, Node: Data Type Measurements, Prev: Important Data Types, Up: Language Features
--
--Data Type Measurements
--======================
--
-- Most of the time, if you choose the proper C data type for each
--object in your program, you need not be concerned with just how it is
--represented or how many bits it uses. When you do need such
--information, the C language itself does not provide a way to get it.
--The header files `limits.h' and `float.h' contain macros which give you
--this information in full detail.
--
--* Menu:
--
--* Width of Type:: How many bits does an integer type hold?
--* Range of Type:: What are the largest and smallest values
-- that an integer type can hold?
--* Floating Type Macros:: Parameters that measure the floating point types.
--* Structure Measurement:: Getting measurements on structure types.
--
--
--File: libc.info, Node: Width of Type, Next: Range of Type, Up: Data Type Measurements
--
--Computing the Width of an Integer Data Type
---------------------------------------------
--
-- The most common reason that a program needs to know how many bits
--are in an integer type is for using an array of `long int' as a bit
--vector. You can access the bit at index N with
--
-- vector[N / LONGBITS] & (1 << (N % LONGBITS))
--
--provided you define `LONGBITS' as the number of bits in a `long int'.
--
-- There is no operator in the C language that can give you the number
--of bits in an integer data type. But you can compute it from the macro
--`CHAR_BIT', defined in the header file `limits.h'.
--
--`CHAR_BIT'
-- This is the number of bits in a `char'--eight, on most systems.
-- The value has type `int'.
--
-- You can compute the number of bits in any data type TYPE like this:
--
-- sizeof (TYPE) * CHAR_BIT
--
--
--File: libc.info, Node: Range of Type, Next: Floating Type Macros, Prev: Width of Type, Up: Data Type Measurements
--
--Range of an Integer Type
--------------------------
--
-- Suppose you need to store an integer value which can range from zero
--to one million. Which is the smallest type you can use? There is no
--general rule; it depends on the C compiler and target machine. You can
--use the `MIN' and `MAX' macros in `limits.h' to determine which type
--will work.
--
-- Each signed integer type has a pair of macros which give the smallest
--and largest values that it can hold. Each unsigned integer type has one
--such macro, for the maximum value; the minimum value is, of course,
--zero.
--
-- The values of these macros are all integer constant expressions. The
--`MAX' and `MIN' macros for `char' and `short int' types have values of
--type `int'. The `MAX' and `MIN' macros for the other types have values
--of the same type described by the macro--thus, `ULONG_MAX' has type
--`unsigned long int'.
--
--`SCHAR_MIN'
-- This is the minimum value that can be represented by a
-- `signed char'.
--
--`SCHAR_MAX'
--`UCHAR_MAX'
-- These are the maximum values that can be represented by a
-- `signed char' and `unsigned char', respectively.
--
--`CHAR_MIN'
-- This is the minimum value that can be represented by a `char'.
-- It's equal to `SCHAR_MIN' if `char' is signed, or zero otherwise.
--
--`CHAR_MAX'
-- This is the maximum value that can be represented by a `char'.
-- It's equal to `SCHAR_MAX' if `char' is signed, or `UCHAR_MAX'
-- otherwise.
--
--`SHRT_MIN'
-- This is the minimum value that can be represented by a
-- `signed short int'. On most machines that the GNU C library runs
-- on, `short' integers are 16-bit quantities.
--
--`SHRT_MAX'
--`USHRT_MAX'
-- These are the maximum values that can be represented by a
-- `signed short int' and `unsigned short int', respectively.
--
--`INT_MIN'
-- This is the minimum value that can be represented by a
-- `signed int'. On most machines that the GNU C system runs on, an
-- `int' is a 32-bit quantity.
--
--`INT_MAX'
--`UINT_MAX'
-- These are the maximum values that can be represented by,
-- respectively, the type `signed int' and the type `unsigned int'.
--
--`LONG_MIN'
-- This is the minimum value that can be represented by a
-- `signed long int'. On most machines that the GNU C system runs
-- on, `long' integers are 32-bit quantities, the same size as `int'.
--
--`LONG_MAX'
--`ULONG_MAX'
-- These are the maximum values that can be represented by a
-- `signed long int' and `unsigned long int', respectively.
--
--`LONG_LONG_MIN'
-- This is the minimum value that can be represented by a
-- `signed long long int'. On most machines that the GNU C system
-- runs on, `long long' integers are 64-bit quantities.
--
--`LONG_LONG_MAX'
--`ULONG_LONG_MAX'
-- These are the maximum values that can be represented by a `signed
-- long long int' and `unsigned long long int', respectively.
--
--`WCHAR_MAX'
-- This is the maximum value that can be represented by a `wchar_t'.
-- *Note Extended Char Intro::.
--
-- The header file `limits.h' also defines some additional constants
--that parameterize various operating system and file system limits.
--These constants are described in *Note System Configuration::.
--
--
--File: libc.info, Node: Floating Type Macros, Next: Structure Measurement, Prev: Range of Type, Up: Data Type Measurements
--
--Floating Type Macros
----------------------
--
-- The specific representation of floating point numbers varies from
--machine to machine. Because floating point numbers are represented
--internally as approximate quantities, algorithms for manipulating
--floating point data often need to take account of the precise details of
--the machine's floating point representation.
--
-- Some of the functions in the C library itself need this information;
--for example, the algorithms for printing and reading floating point
--numbers (*note I/O on Streams::.) and for calculating trigonometric and
--irrational functions (*note Mathematics::.) use it to avoid round-off
--error and loss of accuracy. User programs that implement numerical
--analysis techniques also often need this information in order to
--minimize or compute error bounds.
--
-- The header file `float.h' describes the format used by your machine.
--
--* Menu:
--
--* Floating Point Concepts:: Definitions of terminology.
--* Floating Point Parameters:: Details of specific macros.
--* IEEE Floating Point:: The measurements for one common
-- representation.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-44 glibc-2.1.3/manual/libc.info-44
---- ../glibc-2.1.3/manual/libc.info-44 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-44 1969-12-31 16:00:00.000000000 -0800
-@@ -1,355 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Floating Point Concepts, Next: Floating Point Parameters, Up: Floating Type Macros
--
--Floating Point Representation Concepts
--......................................
--
-- This section introduces the terminology for describing floating point
--representations.
--
-- You are probably already familiar with most of these concepts in
--terms of scientific or exponential notation for floating point numbers.
--For example, the number `123456.0' could be expressed in exponential
--notation as `1.23456e+05', a shorthand notation indicating that the
--mantissa `1.23456' is multiplied by the base `10' raised to power `5'.
--
-- More formally, the internal representation of a floating point number
--can be characterized in terms of the following parameters:
--
-- * The "sign" is either `-1' or `1'.
--
-- * The "base" or "radix" for exponentiation, an integer greater than
-- `1'. This is a constant for a particular representation.
--
-- * The "exponent" to which the base is raised. The upper and lower
-- bounds of the exponent value are constants for a particular
-- representation.
--
-- Sometimes, in the actual bits representing the floating point
-- number, the exponent is "biased" by adding a constant to it, to
-- make it always be represented as an unsigned quantity. This is
-- only important if you have some reason to pick apart the bit
-- fields making up the floating point number by hand, which is
-- something for which the GNU library provides no support. So this
-- is ignored in the discussion that follows.
--
-- * The "mantissa" or "significand", an unsigned integer which is a
-- part of each floating point number.
--
-- * The "precision" of the mantissa. If the base of the representation
-- is B, then the precision is the number of base-B digits in the
-- mantissa. This is a constant for a particular representation.
--
-- Many floating point representations have an implicit "hidden bit"
-- in the mantissa. This is a bit which is present virtually in the
-- mantissa, but not stored in memory because its value is always 1
-- in a normalized number. The precision figure (see above) includes
-- any hidden bits.
--
-- Again, the GNU library provides no facilities for dealing with such
-- low-level aspects of the representation.
--
-- The mantissa of a floating point number actually represents an
--implicit fraction whose denominator is the base raised to the power of
--the precision. Since the largest representable mantissa is one less
--than this denominator, the value of the fraction is always strictly
--less than `1'. The mathematical value of a floating point number is
--then the product of this fraction, the sign, and the base raised to the
--exponent.
--
-- We say that the floating point number is "normalized" if the
--fraction is at least `1/B', where B is the base. In other words, the
--mantissa would be too large to fit if it were multiplied by the base.
--Non-normalized numbers are sometimes called "denormal"; they contain
--less precision than the representation normally can hold.
--
-- If the number is not normalized, then you can subtract `1' from the
--exponent while multiplying the mantissa by the base, and get another
--floating point number with the same value. "Normalization" consists of
--doing this repeatedly until the number is normalized. Two distinct
--normalized floating point numbers cannot be equal in value.
--
-- (There is an exception to this rule: if the mantissa is zero, it is
--considered normalized. Another exception happens on certain machines
--where the exponent is as small as the representation can hold. Then it
--is impossible to subtract `1' from the exponent, so a number may be
--normalized even if its fraction is less than `1/B'.)
--
--
--File: libc.info, Node: Floating Point Parameters, Next: IEEE Floating Point, Prev: Floating Point Concepts, Up: Floating Type Macros
--
--Floating Point Parameters
--.........................
--
-- These macro definitions can be accessed by including the header file
--`float.h' in your program.
--
-- Macro names starting with `FLT_' refer to the `float' type, while
--names beginning with `DBL_' refer to the `double' type and names
--beginning with `LDBL_' refer to the `long double' type. (If GCC does
--not support `long double' as a distinct data type on a target machine
--then the values for the `LDBL_' constants are equal to the
--corresponding constants for the `double' type.)
--
-- Of these macros, only `FLT_RADIX' is guaranteed to be a constant
--expression. The other macros listed here cannot be reliably used in
--places that require constant expressions, such as `#if' preprocessing
--directives or in the dimensions of static arrays.
--
-- Although the ISO C standard specifies minimum and maximum values for
--most of these parameters, the GNU C implementation uses whatever values
--describe the floating point representation of the target machine. So in
--principle GNU C actually satisfies the ISO C requirements only if the
--target machine is suitable. In practice, all the machines currently
--supported are suitable.
--
--`FLT_ROUNDS'
-- This value characterizes the rounding mode for floating point
-- addition. The following values indicate standard rounding modes:
--
-- `-1'
-- The mode is indeterminable.
--
-- `0'
-- Rounding is towards zero.
--
-- `1'
-- Rounding is to the nearest number.
--
-- `2'
-- Rounding is towards positive infinity.
--
-- `3'
-- Rounding is towards negative infinity.
--
-- Any other value represents a machine-dependent nonstandard rounding
-- mode.
--
-- On most machines, the value is `1', in accordance with the IEEE
-- standard for floating point.
--
-- Here is a table showing how certain values round for each possible
-- value of `FLT_ROUNDS', if the other aspects of the representation
-- match the IEEE single-precision standard.
--
-- 0 1 2 3
-- 1.00000003 1.0 1.0 1.00000012 1.0
-- 1.00000007 1.0 1.00000012 1.00000012 1.0
-- -1.00000003 -1.0 -1.0 -1.0 -1.00000012
-- -1.00000007 -1.0 -1.00000012 -1.0 -1.00000012
--
--`FLT_RADIX'
-- This is the value of the base, or radix, of exponent
-- representation. This is guaranteed to be a constant expression,
-- unlike the other macros described in this section. The value is 2
-- on all machines we know of except the IBM 360 and derivatives.
--
--`FLT_MANT_DIG'
-- This is the number of base-`FLT_RADIX' digits in the floating point
-- mantissa for the `float' data type. The following expression
-- yields `1.0' (even though mathematically it should not) due to the
-- limited number of mantissa digits:
--
-- float radix = FLT_RADIX;
--
-- 1.0f + 1.0f / radix / radix / ... / radix
--
-- where `radix' appears `FLT_MANT_DIG' times.
--
--`DBL_MANT_DIG'
--`LDBL_MANT_DIG'
-- This is the number of base-`FLT_RADIX' digits in the floating point
-- mantissa for the data types `double' and `long double',
-- respectively.
--
--`FLT_DIG'
-- This is the number of decimal digits of precision for the `float'
-- data type. Technically, if P and B are the precision and base
-- (respectively) for the representation, then the decimal precision
-- Q is the maximum number of decimal digits such that any floating
-- point number with Q base 10 digits can be rounded to a floating
-- point number with P base B digits and back again, without change
-- to the Q decimal digits.
--
-- The value of this macro is supposed to be at least `6', to satisfy
-- ISO C.
--
--`DBL_DIG'
--`LDBL_DIG'
-- These are similar to `FLT_DIG', but for the data types `double'
-- and `long double', respectively. The values of these macros are
-- supposed to be at least `10'.
--
--`FLT_MIN_EXP'
-- This is the smallest possible exponent value for type `float'.
-- More precisely, is the minimum negative integer such that the value
-- `FLT_RADIX' raised to this power minus 1 can be represented as a
-- normalized floating point number of type `float'.
--
--`DBL_MIN_EXP'
--`LDBL_MIN_EXP'
-- These are similar to `FLT_MIN_EXP', but for the data types
-- `double' and `long double', respectively.
--
--`FLT_MIN_10_EXP'
-- This is the minimum negative integer such that `10' raised to this
-- power minus 1 can be represented as a normalized floating point
-- number of type `float'. This is supposed to be `-37' or even less.
--
--`DBL_MIN_10_EXP'
--`LDBL_MIN_10_EXP'
-- These are similar to `FLT_MIN_10_EXP', but for the data types
-- `double' and `long double', respectively.
--
--`FLT_MAX_EXP'
-- This is the largest possible exponent value for type `float'. More
-- precisely, this is the maximum positive integer such that value
-- `FLT_RADIX' raised to this power minus 1 can be represented as a
-- floating point number of type `float'.
--
--`DBL_MAX_EXP'
--`LDBL_MAX_EXP'
-- These are similar to `FLT_MAX_EXP', but for the data types
-- `double' and `long double', respectively.
--
--`FLT_MAX_10_EXP'
-- This is the maximum positive integer such that `10' raised to this
-- power minus 1 can be represented as a normalized floating point
-- number of type `float'. This is supposed to be at least `37'.
--
--`DBL_MAX_10_EXP'
--`LDBL_MAX_10_EXP'
-- These are similar to `FLT_MAX_10_EXP', but for the data types
-- `double' and `long double', respectively.
--
--`FLT_MAX'
-- The value of this macro is the maximum number representable in type
-- `float'. It is supposed to be at least `1E+37'. The value has
-- type `float'.
--
-- The smallest representable number is `- FLT_MAX'.
--
--`DBL_MAX'
--`LDBL_MAX'
-- These are similar to `FLT_MAX', but for the data types `double'
-- and `long double', respectively. The type of the macro's value is
-- the same as the type it describes.
--
--`FLT_MIN'
-- The value of this macro is the minimum normalized positive floating
-- point number that is representable in type `float'. It is supposed
-- to be no more than `1E-37'.
--
--`DBL_MIN'
--`LDBL_MIN'
-- These are similar to `FLT_MIN', but for the data types `double'
-- and `long double', respectively. The type of the macro's value is
-- the same as the type it describes.
--
--`FLT_EPSILON'
-- This is the minimum positive floating point number of type `float'
-- such that `1.0 + FLT_EPSILON != 1.0' is true. It's supposed to be
-- no greater than `1E-5'.
--
--`DBL_EPSILON'
--`LDBL_EPSILON'
-- These are similar to `FLT_EPSILON', but for the data types
-- `double' and `long double', respectively. The type of the macro's
-- value is the same as the type it describes. The values are not
-- supposed to be greater than `1E-9'.
--
--
--File: libc.info, Node: IEEE Floating Point, Prev: Floating Point Parameters, Up: Floating Type Macros
--
--IEEE Floating Point
--...................
--
-- Here is an example showing how the floating type measurements come
--out for the most common floating point representation, specified by the
--`IEEE Standard for Binary Floating Point Arithmetic (ANSI/IEEE Std
--754-1985)'. Nearly all computers designed since the 1980s use this
--format.
--
-- The IEEE single-precision float representation uses a base of 2.
--There is a sign bit, a mantissa with 23 bits plus one hidden bit (so
--the total precision is 24 base-2 digits), and an 8-bit exponent that
--can represent values in the range -125 to 128, inclusive.
--
-- So, for an implementation that uses this representation for the
--`float' data type, appropriate values for the corresponding parameters
--are:
--
-- FLT_RADIX 2
-- FLT_MANT_DIG 24
-- FLT_DIG 6
-- FLT_MIN_EXP -125
-- FLT_MIN_10_EXP -37
-- FLT_MAX_EXP 128
-- FLT_MAX_10_EXP +38
-- FLT_MIN 1.17549435E-38F
-- FLT_MAX 3.40282347E+38F
-- FLT_EPSILON 1.19209290E-07F
--
-- Here are the values for the `double' data type:
--
-- DBL_MANT_DIG 53
-- DBL_DIG 15
-- DBL_MIN_EXP -1021
-- DBL_MIN_10_EXP -307
-- DBL_MAX_EXP 1024
-- DBL_MAX_10_EXP 308
-- DBL_MAX 1.7976931348623157E+308
-- DBL_MIN 2.2250738585072014E-308
-- DBL_EPSILON 2.2204460492503131E-016
--
--
--File: libc.info, Node: Structure Measurement, Prev: Floating Type Macros, Up: Data Type Measurements
--
--Structure Field Offset Measurement
------------------------------------
--
-- You can use `offsetof' to measure the location within a structure
--type of a particular structure member.
--
-- - Macro: size_t offsetof (TYPE, MEMBER)
-- This expands to a integer constant expression that is the offset
-- of the structure member named MEMBER in a the structure type TYPE.
-- For example, `offsetof (struct s, elem)' is the offset, in bytes,
-- of the member `elem' in a `struct s'.
--
-- This macro won't work if MEMBER is a bit field; you get an error
-- from the C compiler in that case.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-45 glibc-2.1.3/manual/libc.info-45
---- ../glibc-2.1.3/manual/libc.info-45 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-45 1969-12-31 16:00:00.000000000 -0800
-@@ -1,6297 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Library Summary, Next: Installation, Prev: Language Features, Up: Top
--
--Summary of Library Facilities
--*****************************
--
-- This appendix is a complete list of the facilities declared within
--the header files supplied with the GNU C library. Each entry also
--lists the standard or other source from which each facility is derived,
--and tells you where in the manual you can find more information about
--how to use it.
--
--`long int a64l (const char *STRING)'
-- `stdlib.h' (XPG): *Note Encode Binary Data::.
--
--`void abort (void)'
-- `stdlib.h' (ISO): *Note Aborting a Program::.
--
--`int abs (int NUMBER)'
-- `stdlib.h' (ISO): *Note Absolute Value::.
--
--`int accept (int SOCKET, struct sockaddr *ADDR, socklen_t *LENGTH_PTR)'
-- `sys/socket.h' (BSD): *Note Accepting Connections::.
--
--`int access (const char *FILENAME, int HOW)'
-- `unistd.h' (POSIX.1): *Note Testing File Access::.
--
--`ACCOUNTING'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`double acos (double X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`float acosf (float X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`double acosh (double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`float acoshf (float X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double acoshl (long double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double acosl (long double X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`int addmntent (FILE *STREAM, const struct mntent *MNT)'
-- `mntent.h' (BSD): *Note Filesystem handling::.
--
--`int adjtime (const struct timeval *DELTA, struct timeval *OLDDELTA)'
-- `sys/time.h' (BSD): *Note High-Resolution Calendar::.
--
--`AF_FILE'
-- `sys/socket.h' (GNU): *Note Address Formats::.
--
--`AF_INET'
-- `sys/socket.h' (BSD): *Note Address Formats::.
--
--`AF_INET6'
-- `sys/socket.h' (IPv6 Basic API): *Note Address Formats::.
--
--`AF_LOCAL'
-- `sys/socket.h' (POSIX): *Note Address Formats::.
--
--`AF_UNIX'
-- `sys/socket.h' (BSD): *Note Address Formats::.
--
--`AF_UNSPEC'
-- `sys/socket.h' (BSD): *Note Address Formats::.
--
--`int aio_cancel (int FILDES, struct aiocb *AIOCBP)'
-- `aio.h' (POSIX.1b): *Note Cancel AIO Operations::.
--
--`int aio_cancel64 (int FILDES, struct aiocb *AIOCBP)'
-- `aio.h' (Unix98): *Note Cancel AIO Operations::.
--
--`int aio_error (const struct aiocb *AIOCBP)'
-- `aio.h' (POSIX.1b): *Note Status of AIO Operations::.
--
--`int aio_error64 (const struct aiocb64 *AIOCBP)'
-- `aio.h' (Unix98): *Note Status of AIO Operations::.
--
--`int aio_fsync (int OP, struct aiocb *AIOCBP)'
-- `aio.h' (POSIX.1b): *Note Synchronizing AIO Operations::.
--
--`int aio_fsync64 (int OP, struct aiocb64 *AIOCBP)'
-- `aio.h' (Unix98): *Note Synchronizing AIO Operations::.
--
--`void aio_init (const struct aioinit *INIT)'
-- `aio.h' (GNU): *Note Configuration of AIO::.
--
--`int aio_read (struct aiocb *AIOCBP)'
-- `aio.h' (POSIX.1b): *Note Asynchronous Reads/Writes::.
--
--`int aio_read64 (struct aiocb *AIOCBP)'
-- `aio.h' (Unix98): *Note Asynchronous Reads/Writes::.
--
--`ssize_t aio_return (const struct aiocb *AIOCBP)'
-- `aio.h' (POSIX.1b): *Note Status of AIO Operations::.
--
--`int aio_return64 (const struct aiocb64 *AIOCBP)'
-- `aio.h' (Unix98): *Note Status of AIO Operations::.
--
--`int aio_suspend (const struct aiocb *const LIST[], int NENT, const struct timespec *TIMEOUT)'
-- `aio.h' (POSIX.1b): *Note Synchronizing AIO Operations::.
--
--`int aio_suspend64 (const struct aiocb64 *const LIST[], int NENT, const struct timespec *TIMEOUT)'
-- `aio.h' (Unix98): *Note Synchronizing AIO Operations::.
--
--`int aio_write (struct aiocb *AIOCBP)'
-- `aio.h' (POSIX.1b): *Note Asynchronous Reads/Writes::.
--
--`int aio_write64 (struct aiocb *AIOCBP)'
-- `aio.h' (Unix98): *Note Asynchronous Reads/Writes::.
--
--`unsigned int alarm (unsigned int SECONDS)'
-- `unistd.h' (POSIX.1): *Note Setting an Alarm::.
--
--`void * alloca (size_t SIZE);'
-- `stdlib.h' (GNU, BSD): *Note Variable Size Automatic::.
--
--`int alphasort (const void *A, const void *B)'
-- `dirent.h' (BSD/SVID): *Note Scanning Directory Content::.
--
--`int alphasort64 (const void *A, const void *B)'
-- `dirent.h' (GNU): *Note Scanning Directory Content::.
--
--`tcflag_t ALTWERASE'
-- `termios.h' (BSD): *Note Local Modes::.
--
--`int ARG_MAX'
-- `limits.h' (POSIX.1): *Note General Limits::.
--
--`error_t argp_err_exit_status'
-- `argp.h' (GNU): *Note Argp Global Variables::.
--
--`void argp_error (const struct argp_state *STATE, const char *FMT, ...)'
-- `argp.h' (GNU): *Note Argp Helper Functions::.
--
--`int ARGP_ERR_UNKNOWN'
-- `argp.h' (GNU): *Note Argp Parser Functions::.
--
--`void argp_failure (const struct argp_state *STATE, int STATUS, int ERRNUM, const char *FMT, ...)'
-- `argp.h' (GNU): *Note Argp Helper Functions::.
--
--`void argp_help (const struct argp *ARGP, FILE *STREAM, unsigned FLAGS, char *NAME)'
-- `argp.h' (GNU): *Note Argp Help::.
--
--`ARGP_IN_ORDER'
-- `argp.h' (GNU): *Note Argp Flags::.
--
--`ARGP_KEY_ARG'
-- `argp.h' (GNU): *Note Argp Special Keys::.
--
--`ARGP_KEY_ARGS'
-- `argp.h' (GNU): *Note Argp Special Keys::.
--
--`ARGP_KEY_END'
-- `argp.h' (GNU): *Note Argp Special Keys::.
--
--`ARGP_KEY_ERROR'
-- `argp.h' (GNU): *Note Argp Special Keys::.
--
--`ARGP_KEY_FINI'
-- `argp.h' (GNU): *Note Argp Special Keys::.
--
--`ARGP_KEY_HELP_ARGS_DOC'
-- `argp.h' (GNU): *Note Argp Help Filter Keys::.
--
--`ARGP_KEY_HELP_DUP_ARGS_NOTE'
-- `argp.h' (GNU): *Note Argp Help Filter Keys::.
--
--`ARGP_KEY_HELP_EXTRA'
-- `argp.h' (GNU): *Note Argp Help Filter Keys::.
--
--`ARGP_KEY_HELP_HEADER'
-- `argp.h' (GNU): *Note Argp Help Filter Keys::.
--
--`ARGP_KEY_HELP_POST_DOC'
-- `argp.h' (GNU): *Note Argp Help Filter Keys::.
--
--`ARGP_KEY_HELP_PRE_DOC'
-- `argp.h' (GNU): *Note Argp Help Filter Keys::.
--
--`ARGP_KEY_INIT'
-- `argp.h' (GNU): *Note Argp Special Keys::.
--
--`ARGP_KEY_NO_ARGS'
-- `argp.h' (GNU): *Note Argp Special Keys::.
--
--`ARGP_KEY_SUCCESS'
-- `argp.h' (GNU): *Note Argp Special Keys::.
--
--`ARGP_LONG_ONLY'
-- `argp.h' (GNU): *Note Argp Flags::.
--
--`ARGP_NO_ARGS'
-- `argp.h' (GNU): *Note Argp Flags::.
--
--`ARGP_NO_ERRS'
-- `argp.h' (GNU): *Note Argp Flags::.
--
--`ARGP_NO_EXIT'
-- `argp.h' (GNU): *Note Argp Flags::.
--
--`ARGP_NO_HELP'
-- `argp.h' (GNU): *Note Argp Flags::.
--
--`error_t argp_parse (const struct argp *ARGP, int ARGC, char **ARGV, unsigned FLAGS, int *ARG_INDEX, void *INPUT)'
-- `argp.h' (GNU): *Note Suboptions: Argp.
--
--`ARGP_PARSE_ARGV0'
-- `argp.h' (GNU): *Note Argp Flags::.
--
--`const char * argp_program_bug_address'
-- `argp.h' (GNU): *Note Argp Global Variables::.
--
--`const char * argp_program_version'
-- `argp.h' (GNU): *Note Argp Global Variables::.
--
--`argp_program_version_hook'
-- `argp.h' (GNU): *Note Argp Global Variables::.
--
--`ARGP_SILENT'
-- `argp.h' (GNU): *Note Argp Flags::.
--
--`void argp_state_help (const struct argp_state *STATE, FILE *STREAM, unsigned FLAGS)'
-- `argp.h' (GNU): *Note Argp Helper Functions::.
--
--`void argp_usage (const struct argp_state *STATE)'
-- `argp.h' (GNU): *Note Argp Helper Functions::.
--
--`error_t argz_add (char **ARGZ, size_t *ARGZ_LEN, const char *STR)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`error_t argz_add_sep (char **ARGZ, size_t *ARGZ_LEN, const char *STR, int DELIM)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`error_t argz_append (char **ARGZ, size_t *ARGZ_LEN, const char *BUF, size_t BUF_LEN)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`size_t argz_count (const char *ARGZ, size_t ARG_LEN)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`error_t argz_create (char *const ARGV[], char **ARGZ, size_t *ARGZ_LEN)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`error_t argz_create_sep (const char *STRING, int SEP, char **ARGZ, size_t *ARGZ_LEN)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`error_t argz_delete (char **ARGZ, size_t *ARGZ_LEN, char *ENTRY)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`void argz_extract (char *ARGZ, size_t ARGZ_LEN, char **ARGV)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`error_t argz_insert (char **ARGZ, size_t *ARGZ_LEN, char *BEFORE, const char *ENTRY)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`char * argz_next (char *ARGZ, size_t ARGZ_LEN, const char *ENTRY)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`error_t argz_replace (char **ARGZ, size_t *ARGZ_LEN, const char *STR, const char *WITH, unsigned *REPLACE_COUNT)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`void argz_stringify (char *ARGZ, size_t LEN, int SEP)'
-- `argz.h' (GNU): *Note Argz Functions::.
--
--`char * asctime (const struct tm *BROKENTIME)'
-- `time.h' (ISO): *Note Formatting Date and Time::.
--
--`char * asctime_r (const struct tm *BROKENTIME, char *BUFFER)'
-- `time.h' (POSIX.1c): *Note Formatting Date and Time::.
--
--`double asin (double X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`float asinf (float X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`double asinh (double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`float asinhf (float X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double asinhl (long double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double asinl (long double X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`int asprintf (char **PTR, const char *TEMPLATE, ...)'
-- `stdio.h' (GNU): *Note Dynamic Output::.
--
--`void assert (int EXPRESSION)'
-- `assert.h' (ISO): *Note Consistency Checking::.
--
--`void assert_perror (int ERRNUM)'
-- `assert.h' (GNU): *Note Consistency Checking::.
--
--`double atan (double X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`double atan2 (double Y, double X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`float atan2f (float Y, float X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`long double atan2l (long double Y, long double X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`float atanf (float X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`double atanh (double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`float atanhf (float X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double atanhl (long double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double atanl (long double X)'
-- `math.h' (ISO): *Note Inverse Trig Functions::.
--
--`int atexit (void (*FUNCTION) (void))'
-- `stdlib.h' (ISO): *Note Cleanups on Exit::.
--
--`double atof (const char *STRING)'
-- `stdlib.h' (ISO): *Note Parsing of Floats::.
--
--`int atoi (const char *STRING)'
-- `stdlib.h' (ISO): *Note Parsing of Integers::.
--
--`long int atol (const char *STRING)'
-- `stdlib.h' (ISO): *Note Parsing of Integers::.
--
--`long long int atoll (const char *STRING)'
-- `stdlib.h' (ISO): *Note Parsing of Integers::.
--
--`B0'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B110'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B115200'
-- `termios.h' (GNU): *Note Line Speed::.
--
--`B1200'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B134'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B150'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B1800'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B19200'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B200'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B230400'
-- `termios.h' (GNU): *Note Line Speed::.
--
--`B2400'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B300'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B38400'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B460800'
-- `termios.h' (GNU): *Note Line Speed::.
--
--`B4800'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B50'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B57600'
-- `termios.h' (GNU): *Note Line Speed::.
--
--`B600'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B75'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`B9600'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`int BC_BASE_MAX'
-- `limits.h' (POSIX.2): *Note Utility Limits::.
--
--`int BC_DIM_MAX'
-- `limits.h' (POSIX.2): *Note Utility Limits::.
--
--`int bcmp (const void *A1, const void *A2, size_t SIZE)'
-- `string.h' (BSD): *Note String/Array Comparison::.
--
--`void bcopy (const void *FROM, void *TO, size_t SIZE)'
-- `string.h' (BSD): *Note Copying and Concatenation::.
--
--`int BC_SCALE_MAX'
-- `limits.h' (POSIX.2): *Note Utility Limits::.
--
--`int BC_STRING_MAX'
-- `limits.h' (POSIX.2): *Note Utility Limits::.
--
--`int bind (int SOCKET, struct sockaddr *ADDR, socklen_t LENGTH)'
-- `sys/socket.h' (BSD): *Note Setting Address::.
--
--`blkcnt64_t'
-- `sys/types.h' (Unix98): *Note Attribute Meanings::.
--
--`blkcnt_t'
-- `sys/types.h' (Unix98): *Note Attribute Meanings::.
--
--`BOOT_TIME'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`BOOT_TIME'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`tcflag_t BRKINT'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`_BSD_SOURCE'
-- (GNU): *Note Feature Test Macros::.
--
--`void * bsearch (const void *KEY, const void *ARRAY, size_t COUNT, size_t SIZE, comparison_fn_t COMPARE)'
-- `stdlib.h' (ISO): *Note Array Search Function::.
--
--`wint_t btowc (int C)'
-- `wchar.h' (ISO): *Note Converting a Character::.
--
--`int BUFSIZ'
-- `stdio.h' (ISO): *Note Controlling Buffering::.
--
--`void bzero (void *BLOCK, size_t SIZE)'
-- `string.h' (BSD): *Note Copying and Concatenation::.
--
--`double cabs (complex double Z)'
-- `complex.h' (ISO): *Note Absolute Value::.
--
--`float cabsf (complex float Z)'
-- `complex.h' (ISO): *Note Absolute Value::.
--
--`long double cabsl (complex long double Z)'
-- `complex.h' (ISO): *Note Absolute Value::.
--
--`complex double cacos (complex double Z)'
-- `complex.h' (ISO): *Note Inverse Trig Functions::.
--
--`complex float cacosf (complex float Z)'
-- `complex.h' (ISO): *Note Inverse Trig Functions::.
--
--`complex double cacosh (complex double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex float cacoshf (complex float Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double cacoshl (complex long double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double cacosl (complex long double Z)'
-- `complex.h' (ISO): *Note Inverse Trig Functions::.
--
--`void * calloc (size_t COUNT, size_t ELTSIZE)'
-- `malloc.h', `stdlib.h' (ISO): *Note Allocating Cleared Space::.
--
--`double carg (complex double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`float cargf (complex float Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`long double cargl (complex long double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`complex double casin (complex double Z)'
-- `complex.h' (ISO): *Note Inverse Trig Functions::.
--
--`complex float casinf (complex float Z)'
-- `complex.h' (ISO): *Note Inverse Trig Functions::.
--
--`complex double casinh (complex double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex float casinhf (complex float Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double casinhl (complex long double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double casinl (complex long double Z)'
-- `complex.h' (ISO): *Note Inverse Trig Functions::.
--
--`complex double catan (complex double Z)'
-- `complex.h' (ISO): *Note Inverse Trig Functions::.
--
--`complex float catanf (complex float Z)'
-- `complex.h' (ISO): *Note Inverse Trig Functions::.
--
--`complex double catanh (complex double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex float catanhf (complex float Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double catanhl (complex long double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double catanl (complex long double Z)'
-- `complex.h' (ISO): *Note Inverse Trig Functions::.
--
--`nl_catd catopen (const char *CAT_NAME, int FLAG)'
-- `nl_types.h' (X/Open): *Note The catgets Functions::.
--
--`int cbc_crypt (char * KEY, char * BLOCKS, unsigned LEN, unsigned MODE, char * IVEC)'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`double cbrt (double X)'
-- `math.h' (BSD): *Note Exponents and Logarithms::.
--
--`float cbrtf (float X)'
-- `math.h' (BSD): *Note Exponents and Logarithms::.
--
--`long double cbrtl (long double X)'
-- `math.h' (BSD): *Note Exponents and Logarithms::.
--
--`complex double ccos (complex double Z)'
-- `complex.h' (ISO): *Note Trig Functions::.
--
--`complex float ccosf (complex float Z)'
-- `complex.h' (ISO): *Note Trig Functions::.
--
--`complex double ccosh (complex double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex float ccoshf (complex float Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double ccoshl (complex long double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double ccosl (complex long double Z)'
-- `complex.h' (ISO): *Note Trig Functions::.
--
--`cc_t'
-- `termios.h' (POSIX.1): *Note Mode Data Types::.
--
--`tcflag_t CCTS_OFLOW'
-- `termios.h' (BSD): *Note Control Modes::.
--
--`double ceil (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`float ceilf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long double ceill (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`complex double cexp (complex double Z)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`complex float cexpf (complex float Z)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`complex long double cexpl (complex long double Z)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`speed_t cfgetispeed (const struct termios *TERMIOS-P)'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`speed_t cfgetospeed (const struct termios *TERMIOS-P)'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`int cfmakeraw (struct termios *TERMIOS-P)'
-- `termios.h' (BSD): *Note Noncanonical Input::.
--
--`void cfree (void *PTR)'
-- `stdlib.h' (Sun): *Note Freeing after Malloc::.
--
--`int cfsetispeed (struct termios *TERMIOS-P, speed_t SPEED)'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`int cfsetospeed (struct termios *TERMIOS-P, speed_t SPEED)'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`int cfsetspeed (struct termios *TERMIOS-P, speed_t SPEED)'
-- `termios.h' (BSD): *Note Line Speed::.
--
--`CHAR_BIT'
-- `limits.h' (ISO): *Note Width of Type::.
--
--`CHAR_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`CHAR_MIN'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`int chdir (const char *FILENAME)'
-- `unistd.h' (POSIX.1): *Note Working Directory::.
--
--`int CHILD_MAX'
-- `limits.h' (POSIX.1): *Note General Limits::.
--
--`int chmod (const char *FILENAME, mode_t MODE)'
-- `sys/stat.h' (POSIX.1): *Note Setting Permissions::.
--
--`int chown (const char *FILENAME, uid_t OWNER, gid_t GROUP)'
-- `unistd.h' (POSIX.1): *Note File Owner::.
--
--`tcflag_t CIGNORE'
-- `termios.h' (BSD): *Note Control Modes::.
--
--`double cimag (complex double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`float cimagf (complex float Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`long double cimagl (complex long double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`int clearenv (void)'
-- `stdlib.h' (GNU): *Note Environment Access::.
--
--`void clearerr (FILE *STREAM)'
-- `stdio.h' (ISO): *Note EOF and Errors::.
--
--`int CLK_TCK'
-- `time.h' (POSIX.1): *Note Basic CPU Time::.
--
--`tcflag_t CLOCAL'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`clock_t clock (void)'
-- `time.h' (ISO): *Note Basic CPU Time::.
--
--`int CLOCKS_PER_SEC'
-- `time.h' (ISO): *Note Basic CPU Time::.
--
--`clock_t'
-- `time.h' (ISO): *Note Basic CPU Time::.
--
--`complex double clog (complex double Z)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`complex double clog10 (complex double Z)'
-- `complex.h' (GNU): *Note Exponents and Logarithms::.
--
--`complex float clog10f (complex float Z)'
-- `complex.h' (GNU): *Note Exponents and Logarithms::.
--
--`complex long double clog10l (complex long double Z)'
-- `complex.h' (GNU): *Note Exponents and Logarithms::.
--
--`complex float clogf (complex float Z)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`complex long double clogl (complex long double Z)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`int close (int FILEDES)'
-- `unistd.h' (POSIX.1): *Note Opening and Closing Files::.
--
--`int closedir (DIR *DIRSTREAM)'
-- `dirent.h' (POSIX.1): *Note Reading/Closing Directory::.
--
--`int COLL_WEIGHTS_MAX'
-- `limits.h' (POSIX.2): *Note Utility Limits::.
--
--`size_t confstr (int PARAMETER, char *BUF, size_t LEN)'
-- `unistd.h' (POSIX.2): *Note String Parameters::.
--
--`complex double conj (complex double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`complex float conjf (complex float Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`complex long double conjl (complex long double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`int connect (int SOCKET, struct sockaddr *ADDR, socklen_t LENGTH)'
-- `sys/socket.h' (BSD): *Note Connecting::.
--
--`cookie_close_function'
-- `stdio.h' (GNU): *Note Hook Functions::.
--
--`cookie_io_functions_t'
-- `stdio.h' (GNU): *Note Streams and Cookies::.
--
--`cookie_read_function'
-- `stdio.h' (GNU): *Note Hook Functions::.
--
--`cookie_seek_function'
-- `stdio.h' (GNU): *Note Hook Functions::.
--
--`cookie_write_function'
-- `stdio.h' (GNU): *Note Hook Functions::.
--
--`double copysign (double X, double Y)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`float copysignf (float X, float Y)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`long double copysignl (long double X, long double Y)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`double cos (double X)'
-- `math.h' (ISO): *Note Trig Functions::.
--
--`float cosf (float X)'
-- `math.h' (ISO): *Note Trig Functions::.
--
--`double cosh (double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`float coshf (float X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double coshl (long double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double cosl (long double X)'
-- `math.h' (ISO): *Note Trig Functions::.
--
--`complex double cpow (complex double BASE, complex double POWER)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`complex float cpowf (complex float BASE, complex float POWER)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`complex long double cpowl (complex long double BASE, complex long double POWER)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`complex double cproj (complex double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`complex float cprojf (complex float Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`complex long double cprojl (complex long double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`tcflag_t CREAD'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`double creal (complex double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`float crealf (complex float Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`long double creall (complex long double Z)'
-- `complex.h' (ISO): *Note Operations on Complex::.
--
--`int creat (const char *FILENAME, mode_t MODE)'
-- `fcntl.h' (POSIX.1): *Note Opening and Closing Files::.
--
--`int creat64 (const char *FILENAME, mode_t MODE)'
-- `fcntl.h' (Unix98): *Note Opening and Closing Files::.
--
--`tcflag_t CRTS_IFLOW'
-- `termios.h' (BSD): *Note Control Modes::.
--
--`char * crypt (const char * KEY, const char * SALT)'
-- `crypt.h' (crypt.h): *Note crypt::.
--
--`char * crypt_r (const char * KEY, const char * SALT, struct crypt_data * DATA)'
-- `crypt.h' (GNU): *Note crypt::.
--
--`tcflag_t CS5'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`tcflag_t CS6'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`tcflag_t CS7'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`tcflag_t CS8'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`complex double csin (complex double Z)'
-- `complex.h' (ISO): *Note Trig Functions::.
--
--`complex float csinf (complex float Z)'
-- `complex.h' (ISO): *Note Trig Functions::.
--
--`complex double csinh (complex double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex float csinhf (complex float Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double csinhl (complex long double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double csinl (complex long double Z)'
-- `complex.h' (ISO): *Note Trig Functions::.
--
--`tcflag_t CSIZE'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`_CS_LFS64_CFLAGS'
-- `unistd.h' (Unix98): *Note String Parameters::.
--
--`_CS_LFS64_LDFLAGS'
-- `unistd.h' (Unix98): *Note String Parameters::.
--
--`_CS_LFS64_LIBS'
-- `unistd.h' (Unix98): *Note String Parameters::.
--
--`_CS_LFS64_LINTFLAGS'
-- `unistd.h' (Unix98): *Note String Parameters::.
--
--`_CS_LFS_CFLAGS'
-- `unistd.h' (Unix98): *Note String Parameters::.
--
--`_CS_LFS_LDFLAGS'
-- `unistd.h' (Unix98): *Note String Parameters::.
--
--`_CS_LFS_LIBS'
-- `unistd.h' (Unix98): *Note String Parameters::.
--
--`_CS_LFS_LINTFLAGS'
-- `unistd.h' (Unix98): *Note String Parameters::.
--
--`_CS_PATH'
-- `unistd.h' (POSIX.2): *Note String Parameters::.
--
--`complex double csqrt (complex double Z)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`complex float csqrtf (complex float Z)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`complex long double csqrtl (complex long double Z)'
-- `complex.h' (ISO): *Note Exponents and Logarithms::.
--
--`tcflag_t CSTOPB'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`complex double ctan (complex double Z)'
-- `complex.h' (ISO): *Note Trig Functions::.
--
--`complex float ctanf (complex float Z)'
-- `complex.h' (ISO): *Note Trig Functions::.
--
--`complex double ctanh (complex double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex float ctanhf (complex float Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double ctanhl (complex long double Z)'
-- `complex.h' (ISO): *Note Hyperbolic Functions::.
--
--`complex long double ctanl (complex long double Z)'
-- `complex.h' (ISO): *Note Trig Functions::.
--
--`char * ctermid (char *STRING)'
-- `stdio.h' (POSIX.1): *Note Identifying the Terminal::.
--
--`char * ctime (const time_t *TIME)'
-- `time.h' (ISO): *Note Formatting Date and Time::.
--
--`char * ctime_r (const time_t *TIME, char *BUFFER)'
-- `time.h' (POSIX.1c): *Note Formatting Date and Time::.
--
--`char * cuserid (char *STRING)'
-- `stdio.h' (POSIX.1): *Note Who Logged In::.
--
--`int daylight'
-- `time.h' (SVID): *Note Time Zone Functions::.
--
--`DBL_DIG'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`DBL_EPSILON'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`DBL_MANT_DIG'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`DBL_MAX'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`DBL_MAX_10_EXP'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`DBL_MAX_EXP'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`DBL_MIN'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`DBL_MIN_10_EXP'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`DBL_MIN_EXP'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`DEAD_PROCESS'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`DEAD_PROCESS'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`DES_DECRYPT'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`DES_ENCRYPT'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`DESERR_BADPARAM'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`DESERR_HWERROR'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`DESERR_NOHWDEVICE'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`DESERR_NONE'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`int DES_FAILED (int ERR)'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`DES_HW'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`void des_setparity (char * KEY)'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`DES_SW'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`dev_t'
-- `sys/types.h' (POSIX.1): *Note Attribute Meanings::.
--
--`double difftime (time_t TIME1, time_t TIME0)'
-- `time.h' (ISO): *Note Simple Calendar Time::.
--
--`DIR'
-- `dirent.h' (POSIX.1): *Note Opening a Directory::.
--
--`div_t div (int NUMERATOR, int DENOMINATOR)'
-- `stdlib.h' (ISO): *Note Integer Division::.
--
--`div_t'
-- `stdlib.h' (ISO): *Note Integer Division::.
--
--`double drand48 (void)'
-- `stdlib.h' (SVID): *Note SVID Random::.
--
--`int drand48_r (struct drand48_data *BUFFER, double *RESULT)'
-- `stdlib.h' (GNU): *Note SVID Random::.
--
--`double drem (double NUMERATOR, double DENOMINATOR)'
-- `math.h' (BSD): *Note Remainder Functions::.
--
--`float dremf (float NUMERATOR, float DENOMINATOR)'
-- `math.h' (BSD): *Note Remainder Functions::.
--
--`long double dreml (long double NUMERATOR, long double DENOMINATOR)'
-- `math.h' (BSD): *Note Remainder Functions::.
--
--`int dup (int OLD)'
-- `unistd.h' (POSIX.1): *Note Duplicating Descriptors::.
--
--`int dup2 (int OLD, int NEW)'
-- `unistd.h' (POSIX.1): *Note Duplicating Descriptors::.
--
--`int E2BIG'
-- `errno.h' (POSIX.1: Argument list too long): *Note Error Codes::.
--
--`int EACCES'
-- `errno.h' (POSIX.1: Permission denied): *Note Error Codes::.
--
--`int EADDRINUSE'
-- `errno.h' (BSD: Address already in use): *Note Error Codes::.
--
--`int EADDRNOTAVAIL'
-- `errno.h' (BSD: Cannot assign requested address): *Note Error
-- Codes::.
--
--`int EADV'
-- `errno.h' (Linux???: Advertise error): *Note Error Codes::.
--
--`int EAFNOSUPPORT'
-- `errno.h' (BSD: Address family not supported by protocol): *Note
-- Error Codes::.
--
--`int EAGAIN'
-- `errno.h' (POSIX.1: Resource temporarily unavailable): *Note
-- Error Codes::.
--
--`int EALREADY'
-- `errno.h' (BSD: Operation already in progress): *Note Error
-- Codes::.
--
--`int EAUTH'
-- `errno.h' (BSD: Authentication error): *Note Error Codes::.
--
--`int EBACKGROUND'
-- `errno.h' (GNU: Inappropriate operation for background process):
-- *Note Error Codes::.
--
--`int EBADE'
-- `errno.h' (Linux???: Invalid exchange): *Note Error Codes::.
--
--`int EBADF'
-- `errno.h' (POSIX.1: Bad file descriptor): *Note Error Codes::.
--
--`int EBADFD'
-- `errno.h' (Linux???: File descriptor in bad state): *Note Error
-- Codes::.
--
--`int EBADMSG'
-- `errno.h' (XOPEN: Bad message): *Note Error Codes::.
--
--`int EBADR'
-- `errno.h' (Linux???: Invalid request descriptor): *Note Error
-- Codes::.
--
--`int EBADRPC'
-- `errno.h' (BSD: RPC struct is bad): *Note Error Codes::.
--
--`int EBADRQC'
-- `errno.h' (Linux???: Invalid request code): *Note Error Codes::.
--
--`int EBADSLT'
-- `errno.h' (Linux???: Invalid slot): *Note Error Codes::.
--
--`int EBFONT'
-- `errno.h' (Linux???: Bad font file format): *Note Error Codes::.
--
--`int EBUSY'
-- `errno.h' (POSIX.1: Device or resource busy): *Note Error Codes::.
--
--`int ecb_crypt (char * KEY, char * BLOCKS, unsigned LEN, unsigned MODE)'
-- `rpc/des_crypt.h' (SUNRPC): *Note DES Encryption::.
--
--`int ECHILD'
-- `errno.h' (POSIX.1: No child processes): *Note Error Codes::.
--
--`tcflag_t ECHO'
-- `termios.h' (POSIX.1): *Note Local Modes::.
--
--`tcflag_t ECHOCTL'
-- `termios.h' (BSD): *Note Local Modes::.
--
--`tcflag_t ECHOE'
-- `termios.h' (POSIX.1): *Note Local Modes::.
--
--`tcflag_t ECHOK'
-- `termios.h' (POSIX.1): *Note Local Modes::.
--
--`tcflag_t ECHOKE'
-- `termios.h' (BSD): *Note Local Modes::.
--
--`tcflag_t ECHONL'
-- `termios.h' (POSIX.1): *Note Local Modes::.
--
--`tcflag_t ECHOPRT'
-- `termios.h' (BSD): *Note Local Modes::.
--
--`int ECHRNG'
-- `errno.h' (Linux???: Channel number out of range): *Note Error
-- Codes::.
--
--`int ECOMM'
-- `errno.h' (Linux???: Communication error on send): *Note Error
-- Codes::.
--
--`int ECONNABORTED'
-- `errno.h' (BSD: Software caused connection abort): *Note Error
-- Codes::.
--
--`int ECONNREFUSED'
-- `errno.h' (BSD: Connection refused): *Note Error Codes::.
--
--`int ECONNRESET'
-- `errno.h' (BSD: Connection reset by peer): *Note Error Codes::.
--
--`char * ecvt (double VALUE, int NDIGIT, int *DECPT, int *NEG)'
-- `stdlib.h' (SVID, Unix98): *Note System V Number Conversion::.
--
--`char * ecvt_r (double VALUE, int NDIGIT, int *DECPT, int *NEG, char *BUF, size_t LEN)'
-- `stdlib.h' (GNU): *Note System V Number Conversion::.
--
--`int ED'
-- `errno.h' (GNU: ?): *Note Error Codes::.
--
--`int EDEADLK'
-- `errno.h' (POSIX.1: Resource deadlock avoided): *Note Error
-- Codes::.
--
--`int EDEADLOCK'
-- `errno.h' (Linux???: File locking deadlock error): *Note Error
-- Codes::.
--
--`int EDESTADDRREQ'
-- `errno.h' (BSD: Destination address required): *Note Error
-- Codes::.
--
--`int EDIED'
-- `errno.h' (GNU: Translator died): *Note Error Codes::.
--
--`int EDOM'
-- `errno.h' (ISO: Numerical argument out of domain): *Note Error
-- Codes::.
--
--`int EDOTDOT'
-- `errno.h' (Linux???: RFS specific error): *Note Error Codes::.
--
--`int EDQUOT'
-- `errno.h' (BSD: Disk quota exceeded): *Note Error Codes::.
--
--`int EEXIST'
-- `errno.h' (POSIX.1: File exists): *Note Error Codes::.
--
--`int EFAULT'
-- `errno.h' (POSIX.1: Bad address): *Note Error Codes::.
--
--`int EFBIG'
-- `errno.h' (POSIX.1: File too large): *Note Error Codes::.
--
--`int EFTYPE'
-- `errno.h' (BSD: Inappropriate file type or format): *Note Error
-- Codes::.
--
--`int EGRATUITOUS'
-- `errno.h' (GNU: Gratuitous error): *Note Error Codes::.
--
--`int EGREGIOUS'
-- `errno.h' (GNU: You really blew it this time): *Note Error
-- Codes::.
--
--`int EHOSTDOWN'
-- `errno.h' (BSD: Host is down): *Note Error Codes::.
--
--`int EHOSTUNREACH'
-- `errno.h' (BSD: No route to host): *Note Error Codes::.
--
--`int EIDRM'
-- `errno.h' (XOPEN: Identifier removed): *Note Error Codes::.
--
--`int EIEIO'
-- `errno.h' (GNU: Computer bought the farm): *Note Error Codes::.
--
--`int EILSEQ'
-- `errno.h' (ISO: Invalid or incomplete multibyte or wide
-- character): *Note Error Codes::.
--
--`int EINPROGRESS'
-- `errno.h' (BSD: Operation now in progress): *Note Error Codes::.
--
--`int EINTR'
-- `errno.h' (POSIX.1: Interrupted system call): *Note Error Codes::.
--
--`int EINVAL'
-- `errno.h' (POSIX.1: Invalid argument): *Note Error Codes::.
--
--`int EIO'
-- `errno.h' (POSIX.1: Input/output error): *Note Error Codes::.
--
--`int EISCONN'
-- `errno.h' (BSD: Transport endpoint is already connected): *Note
-- Error Codes::.
--
--`int EISDIR'
-- `errno.h' (POSIX.1: Is a directory): *Note Error Codes::.
--
--`int EISNAM'
-- `errno.h' (Linux???: Is a named type file): *Note Error Codes::.
--
--`int EL2HLT'
-- `errno.h' (Obsolete: Level 2 halted): *Note Error Codes::.
--
--`int EL2NSYNC'
-- `errno.h' (Obsolete: Level 2 not synchronized): *Note Error
-- Codes::.
--
--`int EL3HLT'
-- `errno.h' (Obsolete: Level 3 halted): *Note Error Codes::.
--
--`int EL3RST'
-- `errno.h' (Obsolete: Level 3 reset): *Note Error Codes::.
--
--`int ELIBACC'
-- `errno.h' (Linux???: Can not access a needed shared library):
-- *Note Error Codes::.
--
--`int ELIBBAD'
-- `errno.h' (Linux???: Accessing a corrupted shared library): *Note
-- Error Codes::.
--
--`int ELIBEXEC'
-- `errno.h' (Linux???: Cannot exec a shared library directly):
-- *Note Error Codes::.
--
--`int ELIBMAX'
-- `errno.h' (Linux???: Attempting to link in too many shared
-- libraries): *Note Error Codes::.
--
--`int ELIBSCN'
-- `errno.h' (Linux???: .lib section in a.out corrupted): *Note
-- Error Codes::.
--
--`int ELNRNG'
-- `errno.h' (Linux???: Link number out of range): *Note Error
-- Codes::.
--
--`int ELOOP'
-- `errno.h' (BSD: Too many levels of symbolic links): *Note Error
-- Codes::.
--
--`int EMEDIUMTYPE'
-- `errno.h' (Linux???: Wrong medium type): *Note Error Codes::.
--
--`int EMFILE'
-- `errno.h' (POSIX.1: Too many open files): *Note Error Codes::.
--
--`int EMLINK'
-- `errno.h' (POSIX.1: Too many links): *Note Error Codes::.
--
--`EMPTY'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`EMPTY'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`int EMSGSIZE'
-- `errno.h' (BSD: Message too long): *Note Error Codes::.
--
--`int EMULTIHOP'
-- `errno.h' (XOPEN: Multihop attempted): *Note Error Codes::.
--
--`int ENAMETOOLONG'
-- `errno.h' (POSIX.1: File name too long): *Note Error Codes::.
--
--`int ENAVAIL'
-- `errno.h' (Linux???: No XENIX semaphores available): *Note Error
-- Codes::.
--
--`void encrypt (char * BLOCK, int EDFLAG)'
-- `crypt.h' (crypt.h): *Note DES Encryption::.
--
--`void encrypt_r (char * BLOCK, int EDFLAG, struct crypt_data * DATA)'
-- `crypt.h' (GNU): *Note DES Encryption::.
--
--`void endfsent (void)'
-- `fstab.h' (BSD): *Note Filesystem handling::.
--
--`void endgrent (void)'
-- `grp.h' (SVID, BSD): *Note Scanning All Groups::.
--
--`void endhostent (void)'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`int endmntent (FILE *STREAM)'
-- `mntent.h' (BSD): *Note Filesystem handling::.
--
--`void endnetent (void)'
-- `netdb.h' (BSD): *Note Networks Database::.
--
--`void endnetgrent (void)'
-- `netdb.h' (BSD): *Note Lookup Netgroup::.
--
--`void endprotoent (void)'
-- `netdb.h' (BSD): *Note Protocols Database::.
--
--`void endpwent (void)'
-- `pwd.h' (SVID, BSD): *Note Scanning All Users::.
--
--`void endservent (void)'
-- `netdb.h' (BSD): *Note Services Database::.
--
--`void endutent (void)'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`void endutxent (void)'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`int ENEEDAUTH'
-- `errno.h' (BSD: Need authenticator): *Note Error Codes::.
--
--`int ENETDOWN'
-- `errno.h' (BSD: Network is down): *Note Error Codes::.
--
--`int ENETRESET'
-- `errno.h' (BSD: Network dropped connection on reset): *Note Error
-- Codes::.
--
--`int ENETUNREACH'
-- `errno.h' (BSD: Network is unreachable): *Note Error Codes::.
--
--`int ENFILE'
-- `errno.h' (POSIX.1: Too many open files in system): *Note Error
-- Codes::.
--
--`int ENOANO'
-- `errno.h' (Linux???: No anode): *Note Error Codes::.
--
--`int ENOBUFS'
-- `errno.h' (BSD: No buffer space available): *Note Error Codes::.
--
--`int ENOCSI'
-- `errno.h' (Linux???: No CSI structure available): *Note Error
-- Codes::.
--
--`int ENODATA'
-- `errno.h' (XOPEN: No data available): *Note Error Codes::.
--
--`int ENODEV'
-- `errno.h' (POSIX.1: No such device): *Note Error Codes::.
--
--`int ENOENT'
-- `errno.h' (POSIX.1: No such file or directory): *Note Error
-- Codes::.
--
--`int ENOEXEC'
-- `errno.h' (POSIX.1: Exec format error): *Note Error Codes::.
--
--`int ENOLCK'
-- `errno.h' (POSIX.1: No locks available): *Note Error Codes::.
--
--`int ENOLINK'
-- `errno.h' (XOPEN: Link has been severed): *Note Error Codes::.
--
--`int ENOMEDIUM'
-- `errno.h' (Linux???: No medium found): *Note Error Codes::.
--
--`int ENOMEM'
-- `errno.h' (POSIX.1: Cannot allocate memory): *Note Error Codes::.
--
--`int ENOMSG'
-- `errno.h' (XOPEN: No message of desired type): *Note Error
-- Codes::.
--
--`int ENONET'
-- `errno.h' (Linux???: Machine is not on the network): *Note Error
-- Codes::.
--
--`int ENOPKG'
-- `errno.h' (Linux???: Package not installed): *Note Error Codes::.
--
--`int ENOPROTOOPT'
-- `errno.h' (BSD: Protocol not available): *Note Error Codes::.
--
--`int ENOSPC'
-- `errno.h' (POSIX.1: No space left on device): *Note Error Codes::.
--
--`int ENOSR'
-- `errno.h' (XOPEN: Out of streams resources): *Note Error Codes::.
--
--`int ENOSTR'
-- `errno.h' (XOPEN: Device not a stream): *Note Error Codes::.
--
--`int ENOSYS'
-- `errno.h' (POSIX.1: Function not implemented): *Note Error
-- Codes::.
--
--`int ENOTBLK'
-- `errno.h' (BSD: Block device required): *Note Error Codes::.
--
--`int ENOTCONN'
-- `errno.h' (BSD: Transport endpoint is not connected): *Note Error
-- Codes::.
--
--`int ENOTDIR'
-- `errno.h' (POSIX.1: Not a directory): *Note Error Codes::.
--
--`int ENOTEMPTY'
-- `errno.h' (POSIX.1: Directory not empty): *Note Error Codes::.
--
--`int ENOTNAM'
-- `errno.h' (Linux???: Not a XENIX named type file): *Note Error
-- Codes::.
--
--`int ENOTSOCK'
-- `errno.h' (BSD: Socket operation on non-socket): *Note Error
-- Codes::.
--
--`int ENOTSUP'
-- `errno.h' (POSIX.1: Not supported): *Note Error Codes::.
--
--`int ENOTTY'
-- `errno.h' (POSIX.1: Inappropriate ioctl for device): *Note Error
-- Codes::.
--
--`int ENOTUNIQ'
-- `errno.h' (Linux???: Name not unique on network): *Note Error
-- Codes::.
--
--`char ** environ'
-- `unistd.h' (POSIX.1): *Note Environment Access::.
--
--`error_t envz_add (char **ENVZ, size_t *ENVZ_LEN, const char *NAME, const char *VALUE)'
-- `envz.h' (GNU): *Note Envz Functions::.
--
--`char * envz_entry (const char *ENVZ, size_t ENVZ_LEN, const char *NAME)'
-- `envz.h' (GNU): *Note Envz Functions::.
--
--`char * envz_get (const char *ENVZ, size_t ENVZ_LEN, const char *NAME)'
-- `envz.h' (GNU): *Note Envz Functions::.
--
--`error_t envz_merge (char **ENVZ, size_t *ENVZ_LEN, const char *ENVZ2, size_t ENVZ2_LEN, int OVERRIDE)'
-- `envz.h' (GNU): *Note Envz Functions::.
--
--`void envz_strip (char **ENVZ, size_t *ENVZ_LEN)'
-- `envz.h' (GNU): *Note Envz Functions::.
--
--`int ENXIO'
-- `errno.h' (POSIX.1: Device not configured): *Note Error Codes::.
--
--`int EOF'
-- `stdio.h' (ISO): *Note EOF and Errors::.
--
--`int EOPNOTSUPP'
-- `errno.h' (BSD: Operation not supported): *Note Error Codes::.
--
--`int EOVERFLOW'
-- `errno.h' (XOPEN: Value too large for defined data type): *Note
-- Error Codes::.
--
--`int EPERM'
-- `errno.h' (POSIX.1: Operation not permitted): *Note Error Codes::.
--
--`int EPFNOSUPPORT'
-- `errno.h' (BSD: Protocol family not supported): *Note Error
-- Codes::.
--
--`int EPIPE'
-- `errno.h' (POSIX.1: Broken pipe): *Note Error Codes::.
--
--`int EPROCLIM'
-- `errno.h' (BSD: Too many processes): *Note Error Codes::.
--
--`int EPROCUNAVAIL'
-- `errno.h' (BSD: RPC bad procedure for program): *Note Error
-- Codes::.
--
--`int EPROGMISMATCH'
-- `errno.h' (BSD: RPC program version wrong): *Note Error Codes::.
--
--`int EPROGUNAVAIL'
-- `errno.h' (BSD: RPC program not available): *Note Error Codes::.
--
--`int EPROTO'
-- `errno.h' (XOPEN: Protocol error): *Note Error Codes::.
--
--`int EPROTONOSUPPORT'
-- `errno.h' (BSD: Protocol not supported): *Note Error Codes::.
--
--`int EPROTOTYPE'
-- `errno.h' (BSD: Protocol wrong type for socket): *Note Error
-- Codes::.
--
--`int EQUIV_CLASS_MAX'
-- `limits.h' (POSIX.2): *Note Utility Limits::.
--
--`double erand48 (unsigned short int XSUBI[3])'
-- `stdlib.h' (SVID): *Note SVID Random::.
--
--`int erand48_r (unsigned short int XSUBI[3], struct drand48_data *BUFFER, double *RESULT)'
-- `stdlib.h' (GNU): *Note SVID Random::.
--
--`int ERANGE'
-- `errno.h' (ISO: Numerical result out of range): *Note Error
-- Codes::.
--
--`int EREMCHG'
-- `errno.h' (Linux???: Remote address changed): *Note Error Codes::.
--
--`int EREMOTE'
-- `errno.h' (BSD: Object is remote): *Note Error Codes::.
--
--`int EREMOTEIO'
-- `errno.h' (Linux???: Remote I/O error): *Note Error Codes::.
--
--`int ERESTART'
-- `errno.h' (Linux???: Interrupted system call should be restarted):
-- *Note Error Codes::.
--
--`double erf (double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`double erfc (double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float erfcf (float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double erfcl (long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float erff (float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double erfl (long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`int EROFS'
-- `errno.h' (POSIX.1: Read-only file system): *Note Error Codes::.
--
--`int ERPCMISMATCH'
-- `errno.h' (BSD: RPC version wrong): *Note Error Codes::.
--
--`volatile int errno'
-- `errno.h' (ISO): *Note Checking for Errors::.
--
--`int ESHUTDOWN'
-- `errno.h' (BSD: Cannot send after transport endpoint shutdown):
-- *Note Error Codes::.
--
--`int ESOCKTNOSUPPORT'
-- `errno.h' (BSD: Socket type not supported): *Note Error Codes::.
--
--`int ESPIPE'
-- `errno.h' (POSIX.1: Illegal seek): *Note Error Codes::.
--
--`int ESRCH'
-- `errno.h' (POSIX.1: No such process): *Note Error Codes::.
--
--`int ESRMNT'
-- `errno.h' (Linux???: Srmount error): *Note Error Codes::.
--
--`int ESTALE'
-- `errno.h' (BSD: Stale NFS file handle): *Note Error Codes::.
--
--`int ESTRPIPE'
-- `errno.h' (Linux???: Streams pipe error): *Note Error Codes::.
--
--`int ETIME'
-- `errno.h' (XOPEN: Timer expired): *Note Error Codes::.
--
--`int ETIMEDOUT'
-- `errno.h' (BSD: Connection timed out): *Note Error Codes::.
--
--`int ETOOMANYREFS'
-- `errno.h' (BSD: Too many references: cannot splice): *Note Error
-- Codes::.
--
--`int ETXTBSY'
-- `errno.h' (BSD: Text file busy): *Note Error Codes::.
--
--`int EUCLEAN'
-- `errno.h' (Linux???: Structure needs cleaning): *Note Error
-- Codes::.
--
--`int EUNATCH'
-- `errno.h' (Linux???: Protocol driver not attached): *Note Error
-- Codes::.
--
--`int EUSERS'
-- `errno.h' (BSD: Too many users): *Note Error Codes::.
--
--`int EWOULDBLOCK'
-- `errno.h' (BSD: Operation would block): *Note Error Codes::.
--
--`int EXDEV'
-- `errno.h' (POSIX.1: Invalid cross-device link): *Note Error
-- Codes::.
--
--`int execl (const char *FILENAME, const char *ARG0, ...)'
-- `unistd.h' (POSIX.1): *Note Executing a File::.
--
--`int execle (const char *FILENAME, const char *ARG0, char *const ENV[], ...)'
-- `unistd.h' (POSIX.1): *Note Executing a File::.
--
--`int execlp (const char *FILENAME, const char *ARG0, ...)'
-- `unistd.h' (POSIX.1): *Note Executing a File::.
--
--`int execv (const char *FILENAME, char *const ARGV[])'
-- `unistd.h' (POSIX.1): *Note Executing a File::.
--
--`int execve (const char *FILENAME, char *const ARGV[], char *const ENV[])'
-- `unistd.h' (POSIX.1): *Note Executing a File::.
--
--`int execvp (const char *FILENAME, char *const ARGV[])'
-- `unistd.h' (POSIX.1): *Note Executing a File::.
--
--`int EXFULL'
-- `errno.h' (Linux???: Exchange full): *Note Error Codes::.
--
--`void _Exit (int STATUS)'
-- `stdlib.h' (ISO): *Note Termination Internals::.
--
--`void _exit (int STATUS)'
-- `unistd.h' (POSIX.1): *Note Termination Internals::.
--
--`void exit (int STATUS)'
-- `stdlib.h' (ISO): *Note Normal Termination::.
--
--`int EXIT_FAILURE'
-- `stdlib.h' (ISO): *Note Exit Status::.
--
--`int EXIT_SUCCESS'
-- `stdlib.h' (ISO): *Note Exit Status::.
--
--`double exp (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`double exp10 (double X)'
-- `math.h' (GNU): *Note Exponents and Logarithms::.
--
--`float exp10f (float X)'
-- `math.h' (GNU): *Note Exponents and Logarithms::.
--
--`long double exp10l (long double X)'
-- `math.h' (GNU): *Note Exponents and Logarithms::.
--
--`double exp2 (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float exp2f (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double exp2l (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float expf (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double expl (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`double expm1 (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float expm1f (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double expm1l (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`int EXPR_NEST_MAX'
-- `limits.h' (POSIX.2): *Note Utility Limits::.
--
--`double fabs (double NUMBER)'
-- `math.h' (ISO): *Note Absolute Value::.
--
--`float fabsf (float NUMBER)'
-- `math.h' (ISO): *Note Absolute Value::.
--
--`long double fabsl (long double NUMBER)'
-- `math.h' (ISO): *Note Absolute Value::.
--
--`int fchmod (int FILEDES, int MODE)'
-- `sys/stat.h' (BSD): *Note Setting Permissions::.
--
--`int fchown (int FILEDES, int OWNER, int GROUP)'
-- `unistd.h' (BSD): *Note File Owner::.
--
--`int fclean (FILE *STREAM)'
-- `stdio.h' (GNU): *Note Cleaning Streams::.
--
--`int fclose (FILE *STREAM)'
-- `stdio.h' (ISO): *Note Closing Streams::.
--
--`int fcloseall (void)'
-- `stdio.h' (GNU): *Note Closing Streams::.
--
--`int fcntl (int FILEDES, int COMMAND, ...)'
-- `fcntl.h' (POSIX.1): *Note Control Operations::.
--
--`char * fcvt (double VALUE, int NDIGIT, int *DECPT, int *NEG)'
-- `stdlib.h' (SVID, Unix98): *Note System V Number Conversion::.
--
--`char * fcvt_r (double VALUE, int NDIGIT, int *DECPT, int *NEG, char *BUF, size_t LEN)'
-- `stdlib.h' (SVID, Unix98): *Note System V Number Conversion::.
--
--`int fdatasync (int FILDES)'
-- `unistd.h' (POSIX): *Note Synchronizing I/O::.
--
--`int FD_CLOEXEC'
-- `fcntl.h' (POSIX.1): *Note Descriptor Flags::.
--
--`void FD_CLR (int FILEDES, fd_set *SET)'
-- `sys/types.h' (BSD): *Note Waiting for I/O::.
--
--`double fdim (double X, double Y)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`float fdimf (float X, float Y)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`long double fdiml (long double X, long double Y)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`int FD_ISSET (int FILEDES, fd_set *SET)'
-- `sys/types.h' (BSD): *Note Waiting for I/O::.
--
--`FILE * fdopen (int FILEDES, const char *OPENTYPE)'
-- `stdio.h' (POSIX.1): *Note Descriptors and Streams::.
--
--`void FD_SET (int FILEDES, fd_set *SET)'
-- `sys/types.h' (BSD): *Note Waiting for I/O::.
--
--`fd_set'
-- `sys/types.h' (BSD): *Note Waiting for I/O::.
--
--`int FD_SETSIZE'
-- `sys/types.h' (BSD): *Note Waiting for I/O::.
--
--`int F_DUPFD'
-- `fcntl.h' (POSIX.1): *Note Duplicating Descriptors::.
--
--`void FD_ZERO (fd_set *SET)'
-- `sys/types.h' (BSD): *Note Waiting for I/O::.
--
--`void feclearexcept (int EXCEPTS)'
-- `fenv.h' (ISO): *Note Status bit operations::.
--
--`FE_DIVBYZERO'
-- `fenv.h' (ISO): *Note Status bit operations::.
--
--`FE_DOWNWARD'
-- `fenv.h' (ISO): *Note Rounding::.
--
--`void fegetenv (fenv_t *ENVP)'
-- `fenv.h' (ISO): *Note Control Functions::.
--
--`void fegetexceptflag (fexcept_t *FLAGP, int EXCEPTS)'
-- `fenv.h' (ISO): *Note Status bit operations::.
--
--`int fegetround (void)'
-- `fenv.h' (ISO): *Note Rounding::.
--
--`int feholdexcept (fenv_t *ENVP)'
-- `fenv.h' (ISO): *Note Control Functions::.
--
--`FE_INEXACT'
-- `fenv.h' (ISO): *Note Status bit operations::.
--
--`FE_INVALID'
-- `fenv.h' (ISO): *Note Status bit operations::.
--
--`int feof (FILE *STREAM)'
-- `stdio.h' (ISO): *Note EOF and Errors::.
--
--`FE_OVERFLOW'
-- `fenv.h' (ISO): *Note Status bit operations::.
--
--`int ferror (FILE *STREAM)'
-- `stdio.h' (ISO): *Note EOF and Errors::.
--
--`void fesetenv (const fenv_t *ENVP)'
-- `fenv.h' (ISO): *Note Control Functions::.
--
--`void fesetexceptflag (const fexcept_t *FLAGP, int'
-- `fenv.h' (ISO): *Note Status bit operations::.
--
--`int fesetround (int ROUND)'
-- `fenv.h' (ISO): *Note Rounding::.
--
--`int fetestexcept (int EXCEPTS)'
-- `fenv.h' (ISO): *Note Status bit operations::.
--
--`FE_TONEAREST'
-- `fenv.h' (ISO): *Note Rounding::.
--
--`FE_TOWARDZERO'
-- `fenv.h' (ISO): *Note Rounding::.
--
--`FE_UNDERFLOW'
-- `fenv.h' (ISO): *Note Status bit operations::.
--
--`void feupdateenv (const fenv_t *ENVP)'
-- `fenv.h' (ISO): *Note Control Functions::.
--
--`FE_UPWARD'
-- `fenv.h' (ISO): *Note Rounding::.
--
--`int fflush (FILE *STREAM)'
-- `stdio.h' (ISO): *Note Flushing Buffers::.
--
--`int fgetc (FILE *STREAM)'
-- `stdio.h' (ISO): *Note Character Input::.
--
--`int F_GETFD'
-- `fcntl.h' (POSIX.1): *Note Descriptor Flags::.
--
--`int F_GETFL'
-- `fcntl.h' (POSIX.1): *Note Getting File Status Flags::.
--
--`struct group * fgetgrent (FILE *STREAM)'
-- `grp.h' (SVID): *Note Scanning All Groups::.
--
--`int fgetgrent_r (FILE *STREAM, struct group *RESULT_BUF, char *BUFFER, size_t BUFLEN, struct group **RESULT)'
-- `grp.h' (GNU): *Note Scanning All Groups::.
--
--`int F_GETLK'
-- `fcntl.h' (POSIX.1): *Note File Locks::.
--
--`int F_GETOWN'
-- `fcntl.h' (BSD): *Note Interrupt Input::.
--
--`int fgetpos (FILE *STREAM, fpos_t *POSITION)'
-- `stdio.h' (ISO): *Note Portable Positioning::.
--
--`int fgetpos64 (FILE *STREAM, fpos64_t *POSITION)'
-- `stdio.h' (Unix98): *Note Portable Positioning::.
--
--`struct passwd * fgetpwent (FILE *STREAM)'
-- `pwd.h' (SVID): *Note Scanning All Users::.
--
--`int fgetpwent_r (FILE *STREAM, struct passwd *RESULT_BUF, char *BUFFER, size_t BUFLEN, struct passwd **RESULT)'
-- `pwd.h' (GNU): *Note Scanning All Users::.
--
--`char * fgets (char *S, int COUNT, FILE *STREAM)'
-- `stdio.h' (ISO): *Note Line Input::.
--
--`FILE'
-- `stdio.h' (ISO): *Note Streams::.
--
--`int FILENAME_MAX'
-- `stdio.h' (ISO): *Note Limits for Files::.
--
--`int fileno (FILE *STREAM)'
-- `stdio.h' (POSIX.1): *Note Descriptors and Streams::.
--
--`int finite (double X)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`int finitef (float X)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`int finitel (long double X)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`double floor (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`float floorf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long double floorl (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`FLT_DIG'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_EPSILON'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_MANT_DIG'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_MAX'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_MAX_10_EXP'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_MAX_EXP'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_MIN'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_MIN_10_EXP'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_MIN_EXP'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_RADIX'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`FLT_ROUNDS'
-- `float.h' (ISO): *Note Floating Point Parameters::.
--
--`tcflag_t FLUSHO'
-- `termios.h' (BSD): *Note Local Modes::.
--
--`double fma (double X, double Y, double Z)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`float fmaf (float X, float Y, float Z)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`long double fmal (long double X, long double Y, long double Z)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`double fmax (double X, double Y)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`float fmaxf (float X, float Y)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`long double fmaxl (long double X, long double Y)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`FILE * fmemopen (void *BUF, size_t SIZE, const char *OPENTYPE)'
-- `stdio.h' (GNU): *Note String Streams::.
--
--`double fmin (double X, double Y)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`float fminf (float X, float Y)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`long double fminl (long double X, long double Y)'
-- `math.h' (ISO): *Note Misc FP Arithmetic::.
--
--`double fmod (double NUMERATOR, double DENOMINATOR)'
-- `math.h' (ISO): *Note Remainder Functions::.
--
--`float fmodf (float NUMERATOR, float DENOMINATOR)'
-- `math.h' (ISO): *Note Remainder Functions::.
--
--`long double fmodl (long double NUMERATOR, long double DENOMINATOR)'
-- `math.h' (ISO): *Note Remainder Functions::.
--
--`int fmtmsg (long int CLASSIFICATION, const char *LABEL, int SEVERITY, const char *TEXT, const char *ACTION, const char *TAG)'
-- `fmtmsg.h' (XPG): *Note Printing Formatted Messages::.
--
--`int fnmatch (const char *PATTERN, const char *STRING, int FLAGS)'
-- `fnmatch.h' (POSIX.2): *Note Wildcard Matching::.
--
--`FNM_CASEFOLD'
-- `fnmatch.h' (GNU): *Note Wildcard Matching::.
--
--`FNM_FILE_NAME'
-- `fnmatch.h' (GNU): *Note Wildcard Matching::.
--
--`FNM_LEADING_DIR'
-- `fnmatch.h' (GNU): *Note Wildcard Matching::.
--
--`FNM_NOESCAPE'
-- `fnmatch.h' (POSIX.2): *Note Wildcard Matching::.
--
--`FNM_PATHNAME'
-- `fnmatch.h' (POSIX.2): *Note Wildcard Matching::.
--
--`FNM_PERIOD'
-- `fnmatch.h' (POSIX.2): *Note Wildcard Matching::.
--
--`int F_OK'
-- `unistd.h' (POSIX.1): *Note Testing File Access::.
--
--`FILE * fopen (const char *FILENAME, const char *OPENTYPE)'
-- `stdio.h' (ISO): *Note Opening Streams::.
--
--`FILE * fopen64 (const char *FILENAME, const char *OPENTYPE)'
-- `stdio.h' (Unix98): *Note Opening Streams::.
--
--`FILE * fopencookie (void *COOKIE, const char *OPENTYPE, cookie_io_functions_t IO-FUNCTIONS)'
-- `stdio.h' (GNU): *Note Streams and Cookies::.
--
--`int FOPEN_MAX'
-- `stdio.h' (ISO): *Note Opening Streams::.
--
--`pid_t fork (void)'
-- `unistd.h' (POSIX.1): *Note Creating a Process::.
--
--`int forkpty (int *AMASTER, char *NAME, struct termios *TERMP, struct winsize *WINP)'
-- `pty.h' (BSD): *Note Pseudo-Terminal Pairs::.
--
--`long int fpathconf (int FILEDES, int PARAMETER)'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`int fpclassify (*float-type* X)'
-- `math.h' (ISO): *Note Floating Point Classes::.
--
--`FPE_DECOVF_TRAP'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`FPE_FLTDIV_FAULT'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`FPE_FLTDIV_TRAP'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`FPE_FLTOVF_FAULT'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`FPE_FLTOVF_TRAP'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`FPE_FLTUND_FAULT'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`FPE_FLTUND_TRAP'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`FPE_INTDIV_TRAP'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`FPE_INTOVF_TRAP'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`FPE_SUBRNG_TRAP'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`int FP_ILOGB0'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`int FP_ILOGBNAN'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`fpos64_t'
-- `stdio.h' (Unix98): *Note Portable Positioning::.
--
--`fpos_t'
-- `stdio.h' (ISO): *Note Portable Positioning::.
--
--`int fprintf (FILE *STREAM, const char *TEMPLATE, ...)'
-- `stdio.h' (ISO): *Note Formatted Output Functions::.
--
--`int fputc (int C, FILE *STREAM)'
-- `stdio.h' (ISO): *Note Simple Output::.
--
--`int fputs (const char *S, FILE *STREAM)'
-- `stdio.h' (ISO): *Note Simple Output::.
--
--`F_RDLCK'
-- `fcntl.h' (POSIX.1): *Note File Locks::.
--
--`size_t fread (void *DATA, size_t SIZE, size_t COUNT, FILE *STREAM)'
-- `stdio.h' (ISO): *Note Block Input/Output::.
--
--`void free (void *PTR)'
-- `malloc.h', `stdlib.h' (ISO): *Note Freeing after Malloc::.
--
--`__free_hook'
-- `malloc.h' (GNU): *Note Hooks for Malloc::.
--
--`FILE * freopen (const char *FILENAME, const char *OPENTYPE, FILE *STREAM)'
-- `stdio.h' (ISO): *Note Opening Streams::.
--
--`FILE * freopen64 (const char *FILENAME, const char *OPENTYPE, FILE *STREAM)'
-- `stdio.h' (Unix98): *Note Opening Streams::.
--
--`double frexp (double VALUE, int *EXPONENT)'
-- `math.h' (ISO): *Note Normalization Functions::.
--
--`float frexpf (float VALUE, int *EXPONENT)'
-- `math.h' (ISO): *Note Normalization Functions::.
--
--`long double frexpl (long double VALUE, int *EXPONENT)'
-- `math.h' (ISO): *Note Normalization Functions::.
--
--`int fscanf (FILE *STREAM, const char *TEMPLATE, ...)'
-- `stdio.h' (ISO): *Note Formatted Input Functions::.
--
--`int fseek (FILE *STREAM, long int OFFSET, int WHENCE)'
-- `stdio.h' (ISO): *Note File Positioning::.
--
--`int fseeko (FILE *STREAM, off_t OFFSET, int WHENCE)'
-- `stdio.h' (Unix98): *Note File Positioning::.
--
--`int fseeko64 (FILE *STREAM, off64_t OFFSET, int WHENCE)'
-- `stdio.h' (Unix98): *Note File Positioning::.
--
--`int F_SETFD'
-- `fcntl.h' (POSIX.1): *Note Descriptor Flags::.
--
--`int F_SETFL'
-- `fcntl.h' (POSIX.1): *Note Getting File Status Flags::.
--
--`int F_SETLK'
-- `fcntl.h' (POSIX.1): *Note File Locks::.
--
--`int F_SETLKW'
-- `fcntl.h' (POSIX.1): *Note File Locks::.
--
--`int F_SETOWN'
-- `fcntl.h' (BSD): *Note Interrupt Input::.
--
--`int fsetpos (FILE *STREAM, const fpos_t *POSITION)'
-- `stdio.h' (ISO): *Note Portable Positioning::.
--
--`int fsetpos64 (FILE *STREAM, const fpos64_t *POSITION)'
-- `stdio.h' (Unix98): *Note Portable Positioning::.
--
--`int fstat (int FILEDES, struct stat *BUF)'
-- `sys/stat.h' (POSIX.1): *Note Reading Attributes::.
--
--`int fstat64 (int FILEDES, struct stat64 *BUF)'
-- `sys/stat.h' (Unix98): *Note Reading Attributes::.
--
--`int fsync (int FILDES)'
-- `unistd.h' (POSIX): *Note Synchronizing I/O::.
--
--`long int ftell (FILE *STREAM)'
-- `stdio.h' (ISO): *Note File Positioning::.
--
--`off_t ftello (FILE *STREAM)'
-- `stdio.h' (Unix98): *Note File Positioning::.
--
--`off64_t ftello64 (FILE *STREAM)'
-- `stdio.h' (Unix98): *Note File Positioning::.
--
--`int ftruncate (int FD, off_t LENGTH)'
-- `unistd.h' (POSIX): *Note Truncating Files::.
--
--`int ftruncate64 (int ID, off64_t LENGTH)'
-- `unistd.h' (Unix98): *Note Truncating Files::.
--
--`int ftw (const char *FILENAME, __ftw_func_t FUNC, int DESCRIPTORS)'
-- `ftw.h' (SVID): *Note Working on Directory Trees::.
--
--`int ftw64 (const char *FILENAME, __ftw64_func_t FUNC, int DESCRIPTORS)'
-- `ftw.h' (Unix98): *Note Working on Directory Trees::.
--
--`__ftw64_func_t'
-- `ftw.h' (GNU): *Note Working on Directory Trees::.
--
--`__ftw_func_t'
-- `ftw.h' (GNU): *Note Working on Directory Trees::.
--
--`F_UNLCK'
-- `fcntl.h' (POSIX.1): *Note File Locks::.
--
--`size_t fwrite (const void *DATA, size_t SIZE, size_t COUNT, FILE *STREAM)'
-- `stdio.h' (ISO): *Note Block Input/Output::.
--
--`F_WRLCK'
-- `fcntl.h' (POSIX.1): *Note File Locks::.
--
--`double gamma (double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float gammaf (float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double gammal (long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`void (*gconv_end_fct) (struct gconv_step *)'
-- `gconv.h' (GNU): *Note glibc iconv Implementation::.
--
--`int (*gconv_fct) (struct gconv_step *, struct gconv_step_data *, const char **, const char *, size_t *, int)'
-- `gconv.h' (GNU): *Note glibc iconv Implementation::.
--
--`int (*gconv_init_fct) (struct gconv_step *)'
-- `gconv.h' (GNU): *Note glibc iconv Implementation::.
--
--`char * gcvt (double VALUE, int NDIGIT, char *BUF)'
-- `stdlib.h' (SVID, Unix98): *Note System V Number Conversion::.
--
--`int getc (FILE *STREAM)'
-- `stdio.h' (ISO): *Note Character Input::.
--
--`int getchar (void)'
-- `stdio.h' (ISO): *Note Character Input::.
--
--`char * getcwd (char *BUFFER, size_t SIZE)'
-- `unistd.h' (POSIX.1): *Note Working Directory::.
--
--`struct tm * getdate (const char *STRING)'
-- `time.h' (Unix98): *Note General Time String Parsing::.
--
--`getdate_err'
-- `time.h' (Unix98): *Note General Time String Parsing::.
--
--`int getdate_r (const char *STRING, struct tm *TP)'
-- `time.h' (GNU): *Note General Time String Parsing::.
--
--`ssize_t getdelim (char **LINEPTR, size_t *N, int DELIMITER, FILE *STREAM)'
-- `stdio.h' (GNU): *Note Line Input::.
--
--`gid_t getegid (void)'
-- `unistd.h' (POSIX.1): *Note Reading Persona::.
--
--`char * getenv (const char *NAME)'
-- `stdlib.h' (ISO): *Note Environment Access::.
--
--`uid_t geteuid (void)'
-- `unistd.h' (POSIX.1): *Note Reading Persona::.
--
--`struct fstab * getfsent (void)'
-- `fstab.h' (BSD): *Note Filesystem handling::.
--
--`struct fstab * getfsfile (const char *NAME)'
-- `fstab.h' (BSD): *Note Filesystem handling::.
--
--`struct fstab * getfsspec (const char *NAME)'
-- `fstab.h' (BSD): *Note Filesystem handling::.
--
--`gid_t getgid (void)'
-- `unistd.h' (POSIX.1): *Note Reading Persona::.
--
--`struct group * getgrent (void)'
-- `grp.h' (SVID, BSD): *Note Scanning All Groups::.
--
--`int getgrent_r (struct group *RESULT_BUF, char *BUFFER, size_t BUFLEN, struct group **RESULT)'
-- `grp.h' (GNU): *Note Scanning All Groups::.
--
--`struct group * getgrgid (gid_t GID)'
-- `grp.h' (POSIX.1): *Note Lookup Group::.
--
--`int getgrgid_r (gid_t GID, struct group *RESULT_BUF, char *BUFFER, size_t BUFLEN, struct group **RESULT)'
-- `grp.h' (POSIX.1c): *Note Lookup Group::.
--
--`struct group * getgrnam (const char *NAME)'
-- `grp.h' (SVID, BSD): *Note Lookup Group::.
--
--`int getgrnam_r (const char *NAME, struct group *RESULT_BUF, char *BUFFER, size_t BUFLEN, struct group **RESULT)'
-- `grp.h' (POSIX.1c): *Note Lookup Group::.
--
--`int getgroups (int COUNT, gid_t *GROUPS)'
-- `unistd.h' (POSIX.1): *Note Reading Persona::.
--
--`struct hostent * gethostbyaddr (const char *ADDR, int LENGTH, int FORMAT)'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`int gethostbyaddr_r (const char *ADDR, int LENGTH, int FORMAT, struct hostent *restrict RESULT_BUF, char *restrict BUF, size_t BUFLEN, struct hostent **restrict RESULT, int *restrict H_ERRNOP)'
-- `netdb.h' (GNU): *Note Host Names::.
--
--`struct hostent * gethostbyname (const char *NAME)'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`struct hostent * gethostbyname2 (const char *NAME, int AF)'
-- `netdb.h' (IPv6 Basic API): *Note Host Names::.
--
--`int gethostbyname2_r (const char *NAME, int AF, struct hostent *restrict RESULT_BUF, char *restrict BUF, size_t BUFLEN, struct hostent **restrict RESULT, int *restrict H_ERRNOP)'
-- `netdb.h' (GNU): *Note Host Names::.
--
--`int gethostbyname_r (const char *restrict NAME, struct hostent *restrict RESULT_BUF, char *restrict BUF, size_t BUFLEN, struct hostent **restrict RESULT, int *restrict H_ERRNOP)'
-- `netdb.h' (GNU): *Note Host Names::.
--
--`struct hostent * gethostent (void)'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`long int gethostid (void)'
-- `unistd.h' (BSD): *Note Host Identification::.
--
--`int gethostname (char *NAME, size_t SIZE)'
-- `unistd.h' (BSD): *Note Host Identification::.
--
--`int getitimer (int WHICH, struct itimerval *OLD)'
-- `sys/time.h' (BSD): *Note Setting an Alarm::.
--
--`ssize_t getline (char **LINEPTR, size_t *N, FILE *STREAM)'
-- `stdio.h' (GNU): *Note Line Input::.
--
--`char * getlogin (void)'
-- `unistd.h' (POSIX.1): *Note Who Logged In::.
--
--`struct mntent * getmntent (FILE *STREAM)'
-- `mntent.h' (BSD): *Note Filesystem handling::.
--
--`struct mntent * getmntent_r (FILE *STREAM, struct mentent *RESULT, char *BUFFER, int BUFSIZE)'
-- `mntent.h' (BSD): *Note Filesystem handling::.
--
--`struct netent * getnetbyaddr (unsigned long int NET, int TYPE)'
-- `netdb.h' (BSD): *Note Networks Database::.
--
--`struct netent * getnetbyname (const char *NAME)'
-- `netdb.h' (BSD): *Note Networks Database::.
--
--`struct netent * getnetent (void)'
-- `netdb.h' (BSD): *Note Networks Database::.
--
--`int getnetgrent (char **HOSTP, char **USERP, char **DOMAINP)'
-- `netdb.h' (BSD): *Note Lookup Netgroup::.
--
--`int getnetgrent_r (char **HOSTP, char **USERP, char **DOMAINP, char *BUFFER, int BUFLEN)'
-- `netdb.h' (GNU): *Note Lookup Netgroup::.
--
--`int getopt (int ARGC, char **ARGV, const char *OPTIONS)'
-- `unistd.h' (POSIX.2): *Note Using Getopt::.
--
--`int getopt_long (int ARGC, char **ARGV, const char *SHORTOPTS, struct option *LONGOPTS, int *INDEXPTR)'
-- `getopt.h' (GNU): *Note Getopt Long Options::.
--
--`char * getpass (const char * PROMPT)'
-- `unistd.h' (BSD): *Note getpass::.
--
--`int getpeername (int SOCKET, struct sockaddr *ADDR, socklen_t *LENGTH-PTR)'
-- `sys/socket.h' (BSD): *Note Who is Connected::.
--
--`int getpgid (pid_t PID)'
-- `unistd.h' (SVID): *Note Process Group Functions::.
--
--`pid_t getpgrp (pid_t PID)'
-- `unistd.h' (BSD): *Note Process Group Functions::.
--
--`pid_t getpgrp (void)'
-- `unistd.h' (POSIX.1): *Note Process Group Functions::.
--
--`pid_t getpid (void)'
-- `unistd.h' (POSIX.1): *Note Process Identification::.
--
--`pid_t getppid (void)'
-- `unistd.h' (POSIX.1): *Note Process Identification::.
--
--`int getpriority (int CLASS, int ID)'
-- `sys/resource.h' (BSD): *Note Priority::.
--
--`struct protoent * getprotobyname (const char *NAME)'
-- `netdb.h' (BSD): *Note Protocols Database::.
--
--`struct protoent * getprotobynumber (int PROTOCOL)'
-- `netdb.h' (BSD): *Note Protocols Database::.
--
--`struct protoent * getprotoent (void)'
-- `netdb.h' (BSD): *Note Protocols Database::.
--
--`int getpt (void)'
-- `stdlib.h' (GNU): *Note Allocation::.
--
--`struct passwd * getpwent (void)'
-- `pwd.h' (POSIX.1): *Note Scanning All Users::.
--
--`int getpwent_r (struct passwd *RESULT_BUF, char *BUFFER, int BUFLEN, struct passwd **RESULT)'
-- `pwd.h' (GNU): *Note Scanning All Users::.
--
--`struct passwd * getpwnam (const char *NAME)'
-- `pwd.h' (POSIX.1): *Note Lookup User::.
--
--`int getpwnam_r (const char *NAME, struct passwd *RESULT_BUF, char *BUFFER, size_t BUFLEN, struct passwd **RESULT)'
-- `pwd.h' (POSIX.1c): *Note Lookup User::.
--
--`struct passwd * getpwuid (uid_t UID)'
-- `pwd.h' (POSIX.1): *Note Lookup User::.
--
--`int getpwuid_r (uid_t UID, struct passwd *RESULT_BUF, char *BUFFER, size_t BUFLEN, struct passwd **RESULT)'
-- `pwd.h' (POSIX.1c): *Note Lookup User::.
--
--`int getrlimit (int RESOURCE, struct rlimit *RLP)'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`int getrlimit64 (int RESOURCE, struct rlimit64 *RLP)'
-- `sys/resource.h' (Unix98): *Note Limits on Resources::.
--
--`int getrusage (int PROCESSES, struct rusage *RUSAGE)'
-- `sys/resource.h' (BSD): *Note Resource Usage::.
--
--`char * gets (char *S)'
-- `stdio.h' (ISO): *Note Line Input::.
--
--`struct servent * getservbyname (const char *NAME, const char *PROTO)'
-- `netdb.h' (BSD): *Note Services Database::.
--
--`struct servent * getservbyport (int PORT, const char *PROTO)'
-- `netdb.h' (BSD): *Note Services Database::.
--
--`struct servent * getservent (void)'
-- `netdb.h' (BSD): *Note Services Database::.
--
--`pid_t getsid (pid_t PID)'
-- `unistd.h' (SVID): *Note Process Group Functions::.
--
--`int getsockname (int SOCKET, struct sockaddr *ADDR, socklen_t *LENGTH-PTR)'
-- `sys/socket.h' (BSD): *Note Reading Address::.
--
--`int getsockopt (int SOCKET, int LEVEL, int OPTNAME, void *OPTVAL, socklen_t *OPTLEN-PTR)'
-- `sys/socket.h' (BSD): *Note Socket Option Functions::.
--
--`int getsubopt (char **OPTIONP, const char* const *TOKENS, char **VALUEP)'
-- `stdlib.h' (stdlib.h): *Note Suboptions Example: Suboptions.
--
--`int gettimeofday (struct timeval *TP, struct timezone *TZP)'
-- `sys/time.h' (BSD): *Note High-Resolution Calendar::.
--
--`uid_t getuid (void)'
-- `unistd.h' (POSIX.1): *Note Reading Persona::.
--
--`mode_t getumask (void)'
-- `sys/stat.h' (GNU): *Note Setting Permissions::.
--
--`struct utmp * getutent (void)'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`int getutent_r (struct utmp *BUFFER, struct utmp **RESULT)'
-- `utmp.h' (GNU): *Note Manipulating the Database::.
--
--`struct utmp * getutid (const struct utmp *ID)'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`int getutid_r (const struct utmp *ID, struct utmp *BUFFER, struct utmp **RESULT)'
-- `utmp.h' (GNU): *Note Manipulating the Database::.
--
--`struct utmp * getutline (const struct utmp *LINE)'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`int getutline_r (const struct utmp *LINE, struct utmp *BUFFER, struct utmp **RESULT)'
-- `utmp.h' (GNU): *Note Manipulating the Database::.
--
--`struct utmpx * getutxent (void)'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`struct utmpx * getutxid (const struct utmpx *ID)'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`struct utmpx * getutxline (const struct utmpx *LINE)'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`int getw (FILE *STREAM)'
-- `stdio.h' (SVID): *Note Character Input::.
--
--`char * getwd (char *BUFFER)'
-- `unistd.h' (BSD): *Note Working Directory::.
--
--`gid_t'
-- `sys/types.h' (POSIX.1): *Note Reading Persona::.
--
--`int glob (const char *PATTERN, int FLAGS, int (*ERRFUNC) (const char *FILENAME, int ERROR-CODE), glob_t *VECTOR-PTR)'
-- `glob.h' (POSIX.2): *Note Calling Glob::.
--
--`GLOB_ABORTED'
-- `glob.h' (POSIX.2): *Note Calling Glob::.
--
--`GLOB_ALTDIRFUNC'
-- `glob.h' (GNU): *Note More Flags for Globbing::.
--
--`GLOB_APPEND'
-- `glob.h' (POSIX.2): *Note Flags for Globbing::.
--
--`GLOB_BRACE'
-- `glob.h' (GNU): *Note More Flags for Globbing::.
--
--`GLOB_DOOFFS'
-- `glob.h' (POSIX.2): *Note Flags for Globbing::.
--
--`GLOB_ERR'
-- `glob.h' (POSIX.2): *Note Flags for Globbing::.
--
--`void globfree (glob_t *PGLOB)'
-- `glob.h' (POSIX.2): *Note More Flags for Globbing::.
--
--`GLOB_MAGCHAR'
-- `glob.h' (GNU): *Note More Flags for Globbing::.
--
--`GLOB_MARK'
-- `glob.h' (POSIX.2): *Note Flags for Globbing::.
--
--`GLOB_NOCHECK'
-- `glob.h' (POSIX.2): *Note Flags for Globbing::.
--
--`GLOB_NOESCAPE'
-- `glob.h' (POSIX.2): *Note Flags for Globbing::.
--
--`GLOB_NOMAGIC'
-- `glob.h' (GNU): *Note More Flags for Globbing::.
--
--`GLOB_NOMATCH'
-- `glob.h' (POSIX.2): *Note Calling Glob::.
--
--`GLOB_NOSORT'
-- `glob.h' (POSIX.2): *Note Flags for Globbing::.
--
--`GLOB_NOSPACE'
-- `glob.h' (POSIX.2): *Note Calling Glob::.
--
--`GLOB_ONLYDIR'
-- `glob.h' (GNU): *Note More Flags for Globbing::.
--
--`GLOB_PERIOD'
-- `glob.h' (GNU): *Note More Flags for Globbing::.
--
--`glob_t'
-- `glob.h' (POSIX.2): *Note Calling Glob::.
--
--`GLOB_TILDE'
-- `glob.h' (GNU): *Note More Flags for Globbing::.
--
--`GLOB_TILDE_CHECK'
-- `glob.h' (GNU): *Note More Flags for Globbing::.
--
--`struct tm * gmtime (const time_t *TIME)'
-- `time.h' (ISO): *Note Broken-down Time::.
--
--`struct tm * gmtime_r (const time_t *TIME, struct tm *RESULTP)'
-- `time.h' (POSIX.1c): *Note Broken-down Time::.
--
--`_GNU_SOURCE'
-- (GNU): *Note Feature Test Macros::.
--
--`int grantpt (int FILEDES)'
-- `stdlib.h' (SVID, XPG4.2): *Note Allocation::.
--
--`int gsignal (int SIGNUM)'
-- `signal.h' (SVID): *Note Signaling Yourself::.
--
--`char * hasmntopt (const struct mntent *MNT, const char *OPT)'
-- `mntent.h' (BSD): *Note Filesystem handling::.
--
--`int hcreate (size_t NEL)'
-- `search.h' (SVID): *Note Hash Search Function::.
--
--`int hcreate_r (size_t NEL, struct hsearch_data *HTAB)'
-- `search.h' (GNU): *Note Hash Search Function::.
--
--`void hdestroy (void)'
-- `search.h' (SVID): *Note Hash Search Function::.
--
--`void hdestroy_r (struct hsearch_data *HTAB)'
-- `search.h' (GNU): *Note Hash Search Function::.
--
--`HOST_NOT_FOUND'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`ENTRY * hsearch (ENTRY ITEM, ACTION ACTION)'
-- `search.h' (SVID): *Note Hash Search Function::.
--
--`int hsearch_r (ENTRY ITEM, ACTION ACTION, ENTRY **RETVAL, struct hsearch_data *HTAB)'
-- `search.h' (GNU): *Note Hash Search Function::.
--
--`uint32_t htonl (uint32_t HOSTLONG)'
-- `netinet/in.h' (BSD): *Note Byte Order::.
--
--`uint16_t htons (uint16_t HOSTSHORT)'
-- `netinet/in.h' (BSD): *Note Byte Order::.
--
--`double HUGE_VAL'
-- `math.h' (ISO): *Note Math Error Reporting::.
--
--`float HUGE_VALF'
-- `math.h' (ISO): *Note Math Error Reporting::.
--
--`long double HUGE_VALL'
-- `math.h' (ISO): *Note Math Error Reporting::.
--
--`tcflag_t HUPCL'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`double hypot (double X, double Y)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float hypotf (float X, float Y)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double hypotl (long double X, long double Y)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`tcflag_t ICANON'
-- `termios.h' (POSIX.1): *Note Local Modes::.
--
--`size_t iconv (iconv_t CD, const char **INBUF, size_t *INBYTESLEFT, char **OUTBUF, size_t *OUTBYTESLEFT)'
-- `iconv.h' (XPG2): *Note Generic Conversion Interface::.
--
--`int iconv_close (iconv_t CD)'
-- `iconv.h' (XPG2): *Note Generic Conversion Interface::.
--
--`iconv_t iconv_open (const char *TOCODE, const char *FROMCODE)'
-- `iconv.h' (XPG2): *Note Generic Conversion Interface::.
--
--`iconv_t'
-- `iconv.h' (XPG2): *Note Generic Conversion Interface::.
--
--`tcflag_t ICRNL'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`tcflag_t IEXTEN'
-- `termios.h' (POSIX.1): *Note Local Modes::.
--
--`void if_freenameindex (struct if_nameindex *ptr)'
-- `net/if.h' (IPv6 basic API): *Note Interface Naming::.
--
--`char * if_indextoname (unsigned int ifindex, char *ifname)'
-- `net/if.h' (IPv6 basic API): *Note Interface Naming::.
--
--`struct if_nameindex * if_nameindex (void)'
-- `net/if.h' (IPv6 basic API): *Note Interface Naming::.
--
--`unsigned int if_nametoindex (const char *ifname)'
-- `net/if.h' (IPv6 basic API): *Note Interface Naming::.
--
--`size_t IFNAMSIZ'
-- `net/if.h' (net/if.h): *Note Interface Naming::.
--
--`tcflag_t IGNBRK'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`tcflag_t IGNCR'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`tcflag_t IGNPAR'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`int ilogb (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`int ilogbf (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`int ilogbl (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`intmax_t imaxabs (intmax_t NUMBER)'
-- `inttypes.h' (ISO): *Note Absolute Value::.
--
--`tcflag_t IMAXBEL'
-- `termios.h' (BSD): *Note Input Modes::.
--
--`imaxdiv_t imaxdiv (intmax_t NUMERATOR, intmax_t DENOMINATOR)'
-- `inttypes.h' (ISO): *Note Integer Division::.
--
--`imaxdiv_t'
-- `inttypes.h' (ISO): *Note Integer Division::.
--
--`struct in6_addr in6addr_any'
-- `netinet/in.h' (IPv6 basic API): *Note Host Address Data Type::.
--
--`struct in6_addr in6addr_loopback'
-- `netinet/in.h' (IPv6 basic API): *Note Host Address Data Type::.
--
--`uint32_t INADDR_ANY'
-- `netinet/in.h' (BSD): *Note Host Address Data Type::.
--
--`uint32_t INADDR_BROADCAST'
-- `netinet/in.h' (BSD): *Note Host Address Data Type::.
--
--`uint32_t INADDR_LOOPBACK'
-- `netinet/in.h' (BSD): *Note Host Address Data Type::.
--
--`uint32_t INADDR_NONE'
-- `netinet/in.h' (BSD): *Note Host Address Data Type::.
--
--`char * index (const char *STRING, int C)'
-- `string.h' (BSD): *Note Search Functions::.
--
--`uint32_t inet_addr (const char *NAME)'
-- `arpa/inet.h' (BSD): *Note Host Address Functions::.
--
--`int inet_aton (const char *NAME, struct in_addr *ADDR)'
-- `arpa/inet.h' (BSD): *Note Host Address Functions::.
--
--`uint32_t inet_lnaof (struct in_addr ADDR)'
-- `arpa/inet.h' (BSD): *Note Host Address Functions::.
--
--`struct in_addr inet_makeaddr (uint32_t NET, uint32_t LOCAL)'
-- `arpa/inet.h' (BSD): *Note Host Address Functions::.
--
--`uint32_t inet_netof (struct in_addr ADDR)'
-- `arpa/inet.h' (BSD): *Note Host Address Functions::.
--
--`uint32_t inet_network (const char *NAME)'
-- `arpa/inet.h' (BSD): *Note Host Address Functions::.
--
--`char * inet_ntoa (struct in_addr ADDR)'
-- `arpa/inet.h' (BSD): *Note Host Address Functions::.
--
--`const char * inet_ntop (int AF, const void *CP, char *BUF, size_t LEN)'
-- `arpa/inet.h' (IPv6 basic API): *Note Host Address Functions::.
--
--`int inet_pton (int AF, const char *CP, void *BUF)'
-- `arpa/inet.h' (IPv6 basic API): *Note Host Address Functions::.
--
--`float INFINITY'
-- `math.h' (ISO): *Note Infinity and NaN::.
--
--`double infnan (int ERROR)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`int initgroups (const char *USER, gid_t GID)'
-- `grp.h' (BSD): *Note Setting Groups::.
--
--`INIT_PROCESS'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`INIT_PROCESS'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`void * initstate (unsigned int SEED, void *STATE, size_t SIZE)'
-- `stdlib.h' (BSD): *Note BSD Random::.
--
--`tcflag_t INLCR'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`int innetgr (const char *NETGROUP, const char *HOST, const char *USER, const char *DOMAIN)'
-- `netdb.h' (BSD): *Note Netgroup Membership::.
--
--`ino64_t'
-- `sys/types.h' (Unix98): *Note Attribute Meanings::.
--
--`ino_t'
-- `sys/types.h' (POSIX.1): *Note Attribute Meanings::.
--
--`tcflag_t INPCK'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`INT_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`INT_MIN'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`int _IOFBF'
-- `stdio.h' (ISO): *Note Controlling Buffering::.
--
--`int _IOLBF'
-- `stdio.h' (ISO): *Note Controlling Buffering::.
--
--`int _IONBF'
-- `stdio.h' (ISO): *Note Controlling Buffering::.
--
--`int IPPORT_RESERVED'
-- `netinet/in.h' (BSD): *Note Ports::.
--
--`int IPPORT_USERRESERVED'
-- `netinet/in.h' (BSD): *Note Ports::.
--
--`int isalnum (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`int isalpha (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`int isascii (int C)'
-- `ctype.h' (SVID, BSD): *Note Classification of Characters::.
--
--`int isatty (int FILEDES)'
-- `unistd.h' (POSIX.1): *Note Is It a Terminal::.
--
--`int isblank (int C)'
-- `ctype.h' (GNU): *Note Classification of Characters::.
--
--`int iscntrl (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`int isdigit (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`int isfinite (*float-type* X)'
-- `math.h' (ISO): *Note Floating Point Classes::.
--
--`int isgraph (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`int isgreater (*real-floating* X, *real-floating* Y)'
-- `math.h' (ISO): *Note FP Comparison Functions::.
--
--`int isgreaterequal (*real-floating* X, *real-floating* Y)'
-- `math.h' (ISO): *Note FP Comparison Functions::.
--
--`tcflag_t ISIG'
-- `termios.h' (POSIX.1): *Note Local Modes::.
--
--`int isinf (double X)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`int isinff (float X)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`int isinfl (long double X)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`int isless (*real-floating* X, *real-floating* Y)'
-- `math.h' (ISO): *Note FP Comparison Functions::.
--
--`int islessequal (*real-floating* X, *real-floating* Y)'
-- `math.h' (ISO): *Note FP Comparison Functions::.
--
--`int islessgreater (*real-floating* X, *real-floating* Y)'
-- `math.h' (ISO): *Note FP Comparison Functions::.
--
--`int islower (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`int isnan (*float-type* X)'
-- `math.h' (ISO): *Note Floating Point Classes::.
--
--`int isnan (double X)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`int isnanf (float X)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`int isnanl (long double X)'
-- `math.h' (BSD): *Note Floating Point Classes::.
--
--`int isnormal (*float-type* X)'
-- `math.h' (ISO): *Note Floating Point Classes::.
--
--`int isprint (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`int ispunct (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`int isspace (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`tcflag_t ISTRIP'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`int isunordered (*real-floating* X, *real-floating* Y)'
-- `math.h' (ISO): *Note FP Comparison Functions::.
--
--`int isupper (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`int iswalnum (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswalpha (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswblank (wint_t WC)'
-- `wctype.h' (GNU): *Note Classification of Wide Characters::.
--
--`int iswcntrl (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswctype (wint_t WC, wctype_t DESC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswdigit (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswgraph (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswlower (wint_t WC)'
-- `ctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswprint (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswpunct (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswspace (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswupper (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int iswxdigit (wint_t WC)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`int isxdigit (int C)'
-- `ctype.h' (ISO): *Note Classification of Characters::.
--
--`ITIMER_PROF'
-- `sys/time.h' (BSD): *Note Setting an Alarm::.
--
--`ITIMER_REAL'
-- `sys/time.h' (BSD): *Note Setting an Alarm::.
--
--`ITIMER_VIRTUAL'
-- `sys/time.h' (BSD): *Note Setting an Alarm::.
--
--`tcflag_t IXANY'
-- `termios.h' (BSD): *Note Input Modes::.
--
--`tcflag_t IXOFF'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`tcflag_t IXON'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`double j0 (double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float j0f (float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double j0l (long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`double j1 (double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float j1f (float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double j1l (long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`jmp_buf'
-- `setjmp.h' (ISO): *Note Non-Local Details::.
--
--`double jn (int n, double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float jnf (int n, float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double jnl (int n, long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long int jrand48 (unsigned short int XSUBI[3])'
-- `stdlib.h' (SVID): *Note SVID Random::.
--
--`int jrand48_r (unsigned short int XSUBI[3], struct drand48_data *BUFFER, long int *RESULT)'
-- `stdlib.h' (GNU): *Note SVID Random::.
--
--`int kill (pid_t PID, int SIGNUM)'
-- `signal.h' (POSIX.1): *Note Signaling Another Process::.
--
--`int killpg (int PGID, int SIGNUM)'
-- `signal.h' (BSD): *Note Signaling Another Process::.
--
--`char * l64a (long int N)'
-- `stdlib.h' (XPG): *Note Encode Binary Data::.
--
--`long int labs (long int NUMBER)'
-- `stdlib.h' (ISO): *Note Absolute Value::.
--
--`LANG'
-- `locale.h' (ISO): *Note Locale Categories::.
--
--`LC_ALL'
-- `locale.h' (ISO): *Note Locale Categories::.
--
--`LC_COLLATE'
-- `locale.h' (ISO): *Note Locale Categories::.
--
--`LC_CTYPE'
-- `locale.h' (ISO): *Note Locale Categories::.
--
--`LC_MESSAGES'
-- `locale.h' (XOPEN): *Note Locale Categories::.
--
--`LC_MONETARY'
-- `locale.h' (ISO): *Note Locale Categories::.
--
--`LC_NUMERIC'
-- `locale.h' (ISO): *Note Locale Categories::.
--
--`void lcong48 (unsigned short int PARAM[7])'
-- `stdlib.h' (SVID): *Note SVID Random::.
--
--`int lcong48_r (unsigned short int PARAM[7], struct drand48_data *BUFFER)'
-- `stdlib.h' (GNU): *Note SVID Random::.
--
--`int L_ctermid'
-- `stdio.h' (POSIX.1): *Note Identifying the Terminal::.
--
--`LC_TIME'
-- `locale.h' (ISO): *Note Locale Categories::.
--
--`int L_cuserid'
-- `stdio.h' (POSIX.1): *Note Who Logged In::.
--
--`double ldexp (double VALUE, int EXPONENT)'
-- `math.h' (ISO): *Note Normalization Functions::.
--
--`float ldexpf (float VALUE, int EXPONENT)'
-- `math.h' (ISO): *Note Normalization Functions::.
--
--`long double ldexpl (long double VALUE, int EXPONENT)'
-- `math.h' (ISO): *Note Normalization Functions::.
--
--`ldiv_t ldiv (long int NUMERATOR, long int DENOMINATOR)'
-- `stdlib.h' (ISO): *Note Integer Division::.
--
--`ldiv_t'
-- `stdlib.h' (ISO): *Note Integer Division::.
--
--`void * lfind (const void *KEY, void *BASE, size_t *NMEMB, size_t SIZE, comparison_fn_t COMPAR)'
-- `search.h' (SVID): *Note Array Search Function::.
--
--`double lgamma (double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float lgammaf (float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float lgammaf_r (float X, int *SIGNP)'
-- `math.h' (XPG): *Note Special Functions::.
--
--`long double lgammal (long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double lgammal_r (long double X, int *SIGNP)'
-- `math.h' (XPG): *Note Special Functions::.
--
--`double lgamma_r (double X, int *SIGNP)'
-- `math.h' (XPG): *Note Special Functions::.
--
--`L_INCR'
-- `sys/file.h' (BSD): *Note File Positioning::.
--
--`int LINE_MAX'
-- `limits.h' (POSIX.2): *Note Utility Limits::.
--
--`int link (const char *OLDNAME, const char *NEWNAME)'
-- `unistd.h' (POSIX.1): *Note Hard Links::.
--
--`int LINK_MAX'
-- `limits.h' (POSIX.1): *Note Limits for Files::.
--
--`int lio_listio (int MODE, struct aiocb *const LIST[], int NENT, struct sigevent *SIG)'
-- `aio.h' (POSIX.1b): *Note Asynchronous Reads/Writes::.
--
--`int lio_listio64 (int MODE, struct aiocb *const LIST, int NENT, struct sigevent *SIG)'
-- `aio.h' (Unix98): *Note Asynchronous Reads/Writes::.
--
--`int listen (int SOCKET, unsigned int N)'
-- `sys/socket.h' (BSD): *Note Listening::.
--
--`long long int llabs (long long int NUMBER)'
-- `stdlib.h' (ISO): *Note Absolute Value::.
--
--`lldiv_t lldiv (long long int NUMERATOR, long long int DENOMINATOR)'
-- `stdlib.h' (ISO): *Note Integer Division::.
--
--`lldiv_t'
-- `stdlib.h' (ISO): *Note Integer Division::.
--
--`long long int llrint (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long long int llrintf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long long int llrintl (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long long int llround (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long long int llroundf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long long int llroundl (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`struct lconv * localeconv (void)'
-- `locale.h' (ISO): *Note The Lame Way to Locale Data::.
--
--`struct tm * localtime (const time_t *TIME)'
-- `time.h' (ISO): *Note Broken-down Time::.
--
--`struct tm * localtime_r (const time_t *TIME, struct tm *RESULTP)'
-- `time.h' (POSIX.1c): *Note Broken-down Time::.
--
--`double log (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`double log10 (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float log10f (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double log10l (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`double log1p (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float log1pf (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double log1pl (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`double log2 (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float log2f (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double log2l (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`double logb (double X)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`double logb (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float logbf (float X)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`float logbf (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double logbl (long double X)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long double logbl (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float logf (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`void login (const struct utmp *ENTRY)'
-- `utmp.h' (BSD): *Note Logging In and Out::.
--
--`LOGIN_PROCESS'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`LOGIN_PROCESS'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`int login_tty (int FILEDES)'
-- `utmp.h' (BSD): *Note Logging In and Out::.
--
--`long double logl (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`int logout (const char *UT_LINE)'
-- `utmp.h' (BSD): *Note Logging In and Out::.
--
--`void logwtmp (const char *UT_LINE, const char *UT_NAME, const char *UT_HOST)'
-- `utmp.h' (BSD): *Note Logging In and Out::.
--
--`void longjmp (jmp_buf STATE, int VALUE)'
-- `setjmp.h' (ISO): *Note Non-Local Details::.
--
--`LONG_LONG_MAX'
-- `limits.h' (GNU): *Note Range of Type::.
--
--`LONG_LONG_MIN'
-- `limits.h' (GNU): *Note Range of Type::.
--
--`LONG_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`LONG_MIN'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`long int lrand48 (void)'
-- `stdlib.h' (SVID): *Note SVID Random::.
--
--`int lrand48_r (struct drand48_data *BUFFER, double *RESULT)'
-- `stdlib.h' (GNU): *Note SVID Random::.
--
--`long int lrint (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long int lrintf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long int lrintl (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long int lround (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long int lroundf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long int lroundl (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`void * lsearch (const void *KEY, void *BASE, size_t *NMEMB, size_t SIZE, comparison_fn_t COMPAR)'
-- `search.h' (SVID): *Note Array Search Function::.
--
--`off_t lseek (int FILEDES, off_t OFFSET, int WHENCE)'
-- `unistd.h' (POSIX.1): *Note File Position Primitive::.
--
--`off64_t lseek64 (int FILEDES, off64_t OFFSET, int WHENCE)'
-- `unistd.h' (Unix98): *Note File Position Primitive::.
--
--`L_SET'
-- `sys/file.h' (BSD): *Note File Positioning::.
--
--`int lstat (const char *FILENAME, struct stat *BUF)'
-- `sys/stat.h' (BSD): *Note Reading Attributes::.
--
--`int lstat64 (const char *FILENAME, struct stat64 *BUF)'
-- `sys/stat.h' (Unix98): *Note Reading Attributes::.
--
--`int L_tmpnam'
-- `stdio.h' (ISO): *Note Temporary Files::.
--
--`L_XTND'
-- `sys/file.h' (BSD): *Note File Positioning::.
--
--`struct mallinfo mallinfo (void)'
-- `malloc.h' (SVID): *Note Statistics of Malloc::.
--
--`void * malloc (size_t SIZE)'
-- `malloc.h', `stdlib.h' (ISO): *Note Basic Allocation::.
--
--`__malloc_hook'
-- `malloc.h' (GNU): *Note Hooks for Malloc::.
--
--`int MAX_CANON'
-- `limits.h' (POSIX.1): *Note Limits for Files::.
--
--`int MAX_INPUT'
-- `limits.h' (POSIX.1): *Note Limits for Files::.
--
--`int MAXNAMLEN'
-- `dirent.h' (BSD): *Note Limits for Files::.
--
--`int MB_CUR_MAX'
-- `stdlib.h' (ISO): *Note Selecting the Conversion::.
--
--`int mblen (const char *STRING, size_t SIZE)'
-- `stdlib.h' (ISO): *Note Non-reentrant Character Conversion::.
--
--`int MB_LEN_MAX'
-- `limits.h' (ISO): *Note Selecting the Conversion::.
--
--`size_t mbrlen (const char *restrict S, size_t N, mbstate_t *PS)'
-- `wchar.h' (ISO): *Note Converting a Character::.
--
--`size_t mbrtowc (wchar_t *restrict PWC, const char *restrict S, size_t N, mbstate_t *restrict PS)'
-- `wchar.h' (ISO): *Note Converting a Character::.
--
--`int mbsinit (const mbstate_t *PS)'
-- `wchar.h' (ISO): *Note Keeping the state::.
--
--`size_t mbsnrtowcs (wchar_t *restrict DST, const char **restrict SRC, size_t NMC, size_t LEN, mbstate_t *restrict PS)'
-- `wchar.h' (GNU): *Note Converting Strings::.
--
--`size_t mbsrtowcs (wchar_t *restrict DST, const char **restrict SRC, size_t LEN, mbstate_t *restrict PS)'
-- `wchar.h' (ISO): *Note Converting Strings::.
--
--`mbstate_t'
-- `wchar.h' (ISO): *Note Keeping the state::.
--
--`size_t mbstowcs (wchar_t *WSTRING, const char *STRING, size_t SIZE)'
-- `stdlib.h' (ISO): *Note Non-reentrant String Conversion::.
--
--`int mbtowc (wchar_t *restrict RESULT, const char *restrict STRING, size_t SIZE)'
-- `stdlib.h' (ISO): *Note Non-reentrant Character Conversion::.
--
--`int mcheck (void (*ABORTFN) (enum mcheck_status STATUS))'
-- `mcheck.h' (GNU): *Note Heap Consistency Checking::.
--
--`tcflag_t MDMBUF'
-- `termios.h' (BSD): *Note Control Modes::.
--
--`void * memalign (size_t BOUNDARY, size_t SIZE)'
-- `malloc.h', `stdlib.h' (BSD): *Note Aligned Memory Blocks::.
--
--`__memalign_hook'
-- `malloc.h' (GNU): *Note Hooks for Malloc::.
--
--`void * memccpy (void *TO, const void *FROM, int C, size_t SIZE)'
-- `string.h' (SVID): *Note Copying and Concatenation::.
--
--`void * memchr (const void *BLOCK, int C, size_t SIZE)'
-- `string.h' (ISO): *Note Search Functions::.
--
--`int memcmp (const void *A1, const void *A2, size_t SIZE)'
-- `string.h' (ISO): *Note String/Array Comparison::.
--
--`void * memcpy (void *TO, const void *FROM, size_t SIZE)'
-- `string.h' (ISO): *Note Copying and Concatenation::.
--
--`void * memmem (const void *HAYSTACK, size_t HAYSTACK-LEN,
-- const void *NEEDLE, size_t NEEDLE-LEN)'
-- `string.h' (GNU): *Note Search Functions::.
--
--`void * memmove (void *TO, const void *FROM, size_t SIZE)'
-- `string.h' (ISO): *Note Copying and Concatenation::.
--
--`void * mempcpy (void *TO, const void *FROM, size_t SIZE)'
-- `string.h' (GNU): *Note Copying and Concatenation::.
--
--`void * memset (void *BLOCK, int C, size_t SIZE)'
-- `string.h' (ISO): *Note Copying and Concatenation::.
--
--`int mkdir (const char *FILENAME, mode_t MODE)'
-- `sys/stat.h' (POSIX.1): *Note Creating Directories::.
--
--`int mkfifo (const char *FILENAME, mode_t MODE)'
-- `sys/stat.h' (POSIX.1): *Note FIFO Special Files::.
--
--`int mknod (const char *FILENAME, int MODE, int DEV)'
-- `sys/stat.h' (BSD): *Note Making Special Files::.
--
--`int mkstemp (char *TEMPLATE)'
-- `stdlib.h' (BSD): *Note Temporary Files::.
--
--`char * mktemp (char *TEMPLATE)'
-- `stdlib.h' (Unix): *Note Temporary Files::.
--
--`time_t mktime (struct tm *BROKENTIME)'
-- `time.h' (ISO): *Note Broken-down Time::.
--
--`mode_t'
-- `sys/types.h' (POSIX.1): *Note Attribute Meanings::.
--
--`double modf (double VALUE, double *INTEGER-PART)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`float modff (float VALUE, float *INTEGER-PART)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long double modfl (long double VALUE, long double *INTEGER-PART)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long int mrand48 (void)'
-- `stdlib.h' (SVID): *Note SVID Random::.
--
--`int mrand48_r (struct drand48_data *BUFFER, double *RESULT)'
-- `stdlib.h' (GNU): *Note SVID Random::.
--
--`int MSG_DONTROUTE'
-- `sys/socket.h' (BSD): *Note Socket Data Options::.
--
--`int MSG_OOB'
-- `sys/socket.h' (BSD): *Note Socket Data Options::.
--
--`int MSG_PEEK'
-- `sys/socket.h' (BSD): *Note Socket Data Options::.
--
--`void mtrace (void)'
-- `mcheck.h' (GNU): *Note Tracing malloc::.
--
--`void muntrace (void)'
-- `mcheck.h' (GNU): *Note Tracing malloc::.
--
--`int NAME_MAX'
-- `limits.h' (POSIX.1): *Note Limits for Files::.
--
--`float NAN'
-- `math.h' (GNU): *Note Infinity and NaN::.
--
--`double nan (const char *TAGP)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`float nanf (const char *TAGP)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`long double nanl (const char *TAGP)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`int nanosleep (const struct timespec *REQUESTED_TIME, struct timespec *REMAINING)'
-- `time.h' (POSIX.1): *Note Sleeping::.
--
--`int NCCS'
-- `termios.h' (POSIX.1): *Note Mode Data Types::.
--
--`double nearbyint (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`float nearbyintf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long double nearbyintl (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`NEW_TIME'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`NEW_TIME'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`double nextafter (double X, double Y)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`float nextafterf (float X, float Y)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`long double nextafterl (long double X, long double Y)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`double nexttoward (double X, long double Y)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`float nexttowardf (float X, long double Y)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`long double nexttowardl (long double X, long double Y)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`int nftw (const char *FILENAME, __nftw_func_t FUNC, int DESCRIPTORS, int FLAG)'
-- `ftw.h' (XPG4.2): *Note Working on Directory Trees::.
--
--`int nftw64 (const char *FILENAME, __nftw64_func_t FUNC, int DESCRIPTORS, int FLAG)'
-- `ftw.h' (Unix98): *Note Working on Directory Trees::.
--
--`__nftw64_func_t'
-- `ftw.h' (GNU): *Note Working on Directory Trees::.
--
--`__nftw_func_t'
-- `ftw.h' (GNU): *Note Working on Directory Trees::.
--
--`int NGROUPS_MAX'
-- `limits.h' (POSIX.1): *Note General Limits::.
--
--`int nice (int INCREMENT)'
-- `dunno.h' (dunno.h): *Note Priority::.
--
--`nlink_t'
-- `sys/types.h' (POSIX.1): *Note Attribute Meanings::.
--
--`char * nl_langinfo (nl_item ITEM)'
-- `langinfo.h' (XOPEN): *Note The Elegant and Fast Way::.
--
--`NO_ADDRESS'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`tcflag_t NOFLSH'
-- `termios.h' (POSIX.1): *Note Local Modes::.
--
--`tcflag_t NOKERNINFO'
-- `termios.h' (BSD): *Note Local Modes::.
--
--`NO_RECOVERY'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`long int nrand48 (unsigned short int XSUBI[3])'
-- `stdlib.h' (SVID): *Note SVID Random::.
--
--`int nrand48_r (unsigned short int XSUBI[3], struct drand48_data *BUFFER, long int *RESULT)'
-- `stdlib.h' (GNU): *Note SVID Random::.
--
--`int NSIG'
-- `signal.h' (BSD): *Note Standard Signals::.
--
--`uint32_t ntohl (uint32_t NETLONG)'
-- `netinet/in.h' (BSD): *Note Byte Order::.
--
--`uint16_t ntohs (uint16_t NETSHORT)'
-- `netinet/in.h' (BSD): *Note Byte Order::.
--
--`int ntp_adjtime (struct timex *TPTR)'
-- `sys/timex.h' (GNU): *Note Precision Time::.
--
--`void * NULL'
-- `stddef.h' (ISO): *Note Null Pointer Constant::.
--
--`int O_ACCMODE'
-- `fcntl.h' (POSIX.1): *Note Access Modes::.
--
--`int O_APPEND'
-- `fcntl.h' (POSIX.1): *Note Operating Modes::.
--
--`int O_ASYNC'
-- `fcntl.h' (BSD): *Note Operating Modes::.
--
--`void obstack_1grow (struct obstack *OBSTACK-PTR, char C)'
-- `obstack.h' (GNU): *Note Growing Objects::.
--
--`void obstack_1grow_fast (struct obstack *OBSTACK-PTR, char C)'
-- `obstack.h' (GNU): *Note Extra Fast Growing::.
--
--`int obstack_alignment_mask (struct obstack *OBSTACK-PTR)'
-- `obstack.h' (GNU): *Note Obstacks Data Alignment::.
--
--`void * obstack_alloc (struct obstack *OBSTACK-PTR, int SIZE)'
-- `obstack.h' (GNU): *Note Allocation in an Obstack::.
--
--`obstack_alloc_failed_handler'
-- `obstack.h' (GNU): *Note Preparing for Obstacks::.
--
--`void * obstack_base (struct obstack *OBSTACK-PTR)'
-- `obstack.h' (GNU): *Note Status of an Obstack::.
--
--`void obstack_blank (struct obstack *OBSTACK-PTR, int SIZE)'
-- `obstack.h' (GNU): *Note Growing Objects::.
--
--`void obstack_blank_fast (struct obstack *OBSTACK-PTR, int SIZE)'
-- `obstack.h' (GNU): *Note Extra Fast Growing::.
--
--`int obstack_chunk_size (struct obstack *OBSTACK-PTR)'
-- `obstack.h' (GNU): *Note Obstack Chunks::.
--
--`void * obstack_copy (struct obstack *OBSTACK-PTR, void *ADDRESS, int SIZE)'
-- `obstack.h' (GNU): *Note Allocation in an Obstack::.
--
--`void * obstack_copy0 (struct obstack *OBSTACK-PTR, void *ADDRESS, int SIZE)'
-- `obstack.h' (GNU): *Note Allocation in an Obstack::.
--
--`void * obstack_finish (struct obstack *OBSTACK-PTR)'
-- `obstack.h' (GNU): *Note Growing Objects::.
--
--`void obstack_free (struct obstack *OBSTACK-PTR, void *OBJECT)'
-- `obstack.h' (GNU): *Note Freeing Obstack Objects::.
--
--`void obstack_grow (struct obstack *OBSTACK-PTR, void *DATA, int SIZE)'
-- `obstack.h' (GNU): *Note Growing Objects::.
--
--`void obstack_grow0 (struct obstack *OBSTACK-PTR, void *DATA, int SIZE)'
-- `obstack.h' (GNU): *Note Growing Objects::.
--
--`int obstack_init (struct obstack *OBSTACK-PTR)'
-- `obstack.h' (GNU): *Note Preparing for Obstacks::.
--
--`void obstack_int_grow (struct obstack *OBSTACK-PTR, int DATA)'
-- `obstack.h' (GNU): *Note Growing Objects::.
--
--`void obstack_int_grow_fast (struct obstack *OBSTACK-PTR, int DATA)'
-- `obstack.h' (GNU): *Note Extra Fast Growing::.
--
--`void * obstack_next_free (struct obstack *OBSTACK-PTR)'
-- `obstack.h' (GNU): *Note Status of an Obstack::.
--
--`int obstack_object_size (struct obstack *OBSTACK-PTR)'
-- `obstack.h' (GNU): *Note Growing Objects::.
--
--`int obstack_object_size (struct obstack *OBSTACK-PTR)'
-- `obstack.h' (GNU): *Note Status of an Obstack::.
--
--`int obstack_printf (struct obstack *OBSTACK, const char *TEMPLATE, ...)'
-- `stdio.h' (GNU): *Note Dynamic Output::.
--
--`void obstack_ptr_grow (struct obstack *OBSTACK-PTR, void *DATA)'
-- `obstack.h' (GNU): *Note Growing Objects::.
--
--`void obstack_ptr_grow_fast (struct obstack *OBSTACK-PTR, void *DATA)'
-- `obstack.h' (GNU): *Note Extra Fast Growing::.
--
--`int obstack_room (struct obstack *OBSTACK-PTR)'
-- `obstack.h' (GNU): *Note Extra Fast Growing::.
--
--`int obstack_vprintf (struct obstack *OBSTACK, const char *TEMPLATE, va_list AP)'
-- `stdio.h' (GNU): *Note Variable Arguments Output::.
--
--`int O_CREAT'
-- `fcntl.h' (POSIX.1): *Note Open-time Flags::.
--
--`int O_EXCL'
-- `fcntl.h' (POSIX.1): *Note Open-time Flags::.
--
--`int O_EXEC'
-- `fcntl.h' (GNU): *Note Access Modes::.
--
--`int O_EXLOCK'
-- `fcntl.h' (BSD): *Note Open-time Flags::.
--
--`off64_t'
-- `sys/types.h' (Unix98): *Note File Position Primitive::.
--
--`size_t offsetof (TYPE, MEMBER)'
-- `stddef.h' (ISO): *Note Structure Measurement::.
--
--`off_t'
-- `sys/types.h' (POSIX.1): *Note File Position Primitive::.
--
--`int O_FSYNC'
-- `fcntl.h' (BSD): *Note Operating Modes::.
--
--`int O_IGNORE_CTTY'
-- `fcntl.h' (GNU): *Note Open-time Flags::.
--
--`OLD_TIME'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`OLD_TIME'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`int O_NDELAY'
-- `fcntl.h' (BSD): *Note Operating Modes::.
--
--`int on_exit (void (*FUNCTION)(int STATUS, void *ARG), void *ARG)'
-- `stdlib.h' (SunOS): *Note Cleanups on Exit::.
--
--`tcflag_t ONLCR'
-- `termios.h' (BSD): *Note Output Modes::.
--
--`int O_NOATIME'
-- `fcntl.h' (GNU): *Note Operating Modes::.
--
--`int O_NOCTTY'
-- `fcntl.h' (POSIX.1): *Note Open-time Flags::.
--
--`tcflag_t ONOEOT'
-- `termios.h' (BSD): *Note Output Modes::.
--
--`int O_NOLINK'
-- `fcntl.h' (GNU): *Note Open-time Flags::.
--
--`int O_NONBLOCK'
-- `fcntl.h' (POSIX.1): *Note Open-time Flags::.
--
--`int O_NONBLOCK'
-- `fcntl.h' (POSIX.1): *Note Operating Modes::.
--
--`int O_NOTRANS'
-- `fcntl.h' (GNU): *Note Open-time Flags::.
--
--`int open (const char *FILENAME, int FLAGS[, mode_t MODE])'
-- `fcntl.h' (POSIX.1): *Note Opening and Closing Files::.
--
--`int open64 (const char *FILENAME, int FLAGS[, mode_t MODE])'
-- `fcntl.h' (Unix98): *Note Opening and Closing Files::.
--
--`DIR * opendir (const char *DIRNAME)'
-- `dirent.h' (POSIX.1): *Note Opening a Directory::.
--
--`int OPEN_MAX'
-- `limits.h' (POSIX.1): *Note General Limits::.
--
--`FILE * open_memstream (char **PTR, size_t *SIZELOC)'
-- `stdio.h' (GNU): *Note String Streams::.
--
--`FILE * open_obstack_stream (struct obstack *OBSTACK)'
-- `stdio.h' (GNU): *Note Obstack Streams::.
--
--`int openpty (int *AMASTER, int *ASLAVE, char *NAME, struct termios *TERMP, struct winsize *WINP)'
-- `pty.h' (BSD): *Note Pseudo-Terminal Pairs::.
--
--`tcflag_t OPOST'
-- `termios.h' (POSIX.1): *Note Output Modes::.
--
--`char * optarg'
-- `unistd.h' (POSIX.2): *Note Using Getopt::.
--
--`int opterr'
-- `unistd.h' (POSIX.2): *Note Using Getopt::.
--
--`int optind'
-- `unistd.h' (POSIX.2): *Note Using Getopt::.
--
--`OPTION_ALIAS'
-- `argp.h' (GNU): *Note Argp Option Flags::.
--
--`OPTION_ARG_OPTIONAL'
-- `argp.h' (GNU): *Note Argp Option Flags::.
--
--`OPTION_DOC'
-- `argp.h' (GNU): *Note Argp Option Flags::.
--
--`OPTION_HIDDEN'
-- `argp.h' (GNU): *Note Argp Option Flags::.
--
--`OPTION_NO_USAGE'
-- `argp.h' (GNU): *Note Argp Option Flags::.
--
--`int optopt'
-- `unistd.h' (POSIX.2): *Note Using Getopt::.
--
--`int O_RDONLY'
-- `fcntl.h' (POSIX.1): *Note Access Modes::.
--
--`int O_RDWR'
-- `fcntl.h' (POSIX.1): *Note Access Modes::.
--
--`int O_READ'
-- `fcntl.h' (GNU): *Note Access Modes::.
--
--`int O_SHLOCK'
-- `fcntl.h' (BSD): *Note Open-time Flags::.
--
--`int O_SYNC'
-- `fcntl.h' (BSD): *Note Operating Modes::.
--
--`int O_TRUNC'
-- `fcntl.h' (POSIX.1): *Note Open-time Flags::.
--
--`int O_WRITE'
-- `fcntl.h' (GNU): *Note Access Modes::.
--
--`int O_WRONLY'
-- `fcntl.h' (POSIX.1): *Note Access Modes::.
--
--`tcflag_t OXTABS'
-- `termios.h' (BSD): *Note Output Modes::.
--
--`PA_CHAR'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_DOUBLE'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_FLAG_LONG'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_FLAG_LONG_DOUBLE'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_FLAG_LONG_LONG'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`int PA_FLAG_MASK'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_FLAG_PTR'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_FLAG_SHORT'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_FLOAT'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_INT'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_LAST'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_POINTER'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`tcflag_t PARENB'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`tcflag_t PARMRK'
-- `termios.h' (POSIX.1): *Note Input Modes::.
--
--`tcflag_t PARODD'
-- `termios.h' (POSIX.1): *Note Control Modes::.
--
--`size_t parse_printf_format (const char *TEMPLATE, size_t N, int *ARGTYPES)'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`PA_STRING'
-- `printf.h' (GNU): *Note Parsing a Template String::.
--
--`long int pathconf (const char *FILENAME, int PARAMETER)'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`int PATH_MAX'
-- `limits.h' (POSIX.1): *Note Limits for Files::.
--
--`int pause ()'
-- `unistd.h' (POSIX.1): *Note Using Pause::.
--
--`_PC_ASYNC_IO'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_CHOWN_RESTRICTED'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_LINK_MAX'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`int pclose (FILE *STREAM)'
-- `stdio.h' (POSIX.2, SVID, BSD): *Note Pipe to a Subprocess::.
--
--`_PC_MAX_CANON'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_MAX_INPUT'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_NAME_MAX'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_NO_TRUNC'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_PATH_MAX'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_PIPE_BUF'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_PRIO_IO'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_SOCK_MAXBUF'
-- `unistd.h' (POSIX.1g): *Note Pathconf::.
--
--`_PC_SYNC_IO'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`_PC_VDISABLE'
-- `unistd.h' (POSIX.1): *Note Pathconf::.
--
--`tcflag_t PENDIN'
-- `termios.h' (BSD): *Note Local Modes::.
--
--`void perror (const char *MESSAGE)'
-- `stdio.h' (ISO): *Note Error Messages::.
--
--`int PF_FILE'
-- `sys/socket.h' (GNU): *Note Local Namespace Details::.
--
--`int PF_INET'
-- `sys/socket.h' (BSD): *Note Internet Namespace::.
--
--`int PF_LOCAL'
-- `sys/socket.h' (POSIX): *Note Local Namespace Details::.
--
--`int PF_UNIX'
-- `sys/socket.h' (BSD): *Note Local Namespace Details::.
--
--`pid_t'
-- `sys/types.h' (POSIX.1): *Note Process Identification::.
--
--`int pipe (int FILEDES[2])'
-- `unistd.h' (POSIX.1): *Note Creating a Pipe::.
--
--`int PIPE_BUF'
-- `limits.h' (POSIX.1): *Note Limits for Files::.
--
--`FILE * popen (const char *COMMAND, const char *MODE)'
-- `stdio.h' (POSIX.2, SVID, BSD): *Note Pipe to a Subprocess::.
--
--`_POSIX2_BC_BASE_MAX'
-- `limits.h' (POSIX.2): *Note Utility Minimums::.
--
--`_POSIX2_BC_DIM_MAX'
-- `limits.h' (POSIX.2): *Note Utility Minimums::.
--
--`_POSIX2_BC_SCALE_MAX'
-- `limits.h' (POSIX.2): *Note Utility Minimums::.
--
--`_POSIX2_BC_STRING_MAX'
-- `limits.h' (POSIX.2): *Note Utility Minimums::.
--
--`int _POSIX2_C_DEV'
-- `unistd.h' (POSIX.2): *Note System Options::.
--
--`_POSIX2_COLL_WEIGHTS_MAX'
-- `limits.h' (POSIX.2): *Note Utility Minimums::.
--
--`long int _POSIX2_C_VERSION'
-- `unistd.h' (POSIX.2): *Note Version Supported::.
--
--`_POSIX2_EQUIV_CLASS_MAX'
-- `limits.h' (POSIX.2): *Note Utility Minimums::.
--
--`_POSIX2_EXPR_NEST_MAX'
-- `limits.h' (POSIX.2): *Note Utility Minimums::.
--
--`int _POSIX2_FORT_DEV'
-- `unistd.h' (POSIX.2): *Note System Options::.
--
--`int _POSIX2_FORT_RUN'
-- `unistd.h' (POSIX.2): *Note System Options::.
--
--`_POSIX2_LINE_MAX'
-- `limits.h' (POSIX.2): *Note Utility Minimums::.
--
--`int _POSIX2_LOCALEDEF'
-- `unistd.h' (POSIX.2): *Note System Options::.
--
--`_POSIX2_RE_DUP_MAX'
-- `limits.h' (POSIX.2): *Note Minimums::.
--
--`int _POSIX2_SW_DEV'
-- `unistd.h' (POSIX.2): *Note System Options::.
--
--`_POSIX_AIO_LISTIO_MAX'
-- `limits.h' (POSIX.1): *Note Minimums::.
--
--`_POSIX_AIO_MAX'
-- `limits.h' (POSIX.1): *Note Minimums::.
--
--`_POSIX_ARG_MAX'
-- `limits.h' (POSIX.1): *Note Minimums::.
--
--`_POSIX_CHILD_MAX'
-- `limits.h' (POSIX.1): *Note Minimums::.
--
--`int _POSIX_CHOWN_RESTRICTED'
-- `unistd.h' (POSIX.1): *Note Options for Files::.
--
--`_POSIX_C_SOURCE'
-- (POSIX.2): *Note Feature Test Macros::.
--
--`int _POSIX_JOB_CONTROL'
-- `unistd.h' (POSIX.1): *Note System Options::.
--
--`_POSIX_LINK_MAX'
-- `limits.h' (POSIX.1): *Note File Minimums::.
--
--`_POSIX_MAX_CANON'
-- `limits.h' (POSIX.1): *Note File Minimums::.
--
--`_POSIX_MAX_INPUT'
-- `limits.h' (POSIX.1): *Note File Minimums::.
--
--`_POSIX_NAME_MAX'
-- `limits.h' (POSIX.1): *Note File Minimums::.
--
--`_POSIX_NGROUPS_MAX'
-- `limits.h' (POSIX.1): *Note Minimums::.
--
--`int _POSIX_NO_TRUNC'
-- `unistd.h' (POSIX.1): *Note Options for Files::.
--
--`_POSIX_OPEN_MAX'
-- `limits.h' (POSIX.1): *Note Minimums::.
--
--`_POSIX_PATH_MAX'
-- `limits.h' (POSIX.1): *Note File Minimums::.
--
--`_POSIX_PIPE_BUF'
-- `limits.h' (POSIX.1): *Note File Minimums::.
--
--`int _POSIX_SAVED_IDS'
-- `unistd.h' (POSIX.1): *Note System Options::.
--
--`_POSIX_SOURCE'
-- (POSIX.1): *Note Feature Test Macros::.
--
--`_POSIX_SSIZE_MAX'
-- `limits.h' (POSIX.1): *Note Minimums::.
--
--`_POSIX_STREAM_MAX'
-- `limits.h' (POSIX.1): *Note Minimums::.
--
--`_POSIX_TZNAME_MAX'
-- `limits.h' (POSIX.1): *Note Minimums::.
--
--`unsigned char _POSIX_VDISABLE'
-- `unistd.h' (POSIX.1): *Note Options for Files::.
--
--`long int _POSIX_VERSION'
-- `unistd.h' (POSIX.1): *Note Version Supported::.
--
--`double pow (double BASE, double POWER)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`double pow10 (double X)'
-- `math.h' (GNU): *Note Exponents and Logarithms::.
--
--`float pow10f (float X)'
-- `math.h' (GNU): *Note Exponents and Logarithms::.
--
--`long double pow10l (long double X)'
-- `math.h' (GNU): *Note Exponents and Logarithms::.
--
--`float powf (float BASE, float POWER)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double powl (long double BASE, long double POWER)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`ssize_t pread (int FILEDES, void *BUFFER, size_t SIZE, off_t OFFSET)'
-- `unistd.h' (Unix98): *Note I/O Primitives::.
--
--`ssize_t pread64 (int FILEDES, void *BUFFER, size_t SIZE, off64_t OFFSET)'
-- `unistd.h' (Unix98): *Note I/O Primitives::.
--
--`int printf (const char *TEMPLATE, ...)'
-- `stdio.h' (ISO): *Note Formatted Output Functions::.
--
--`printf_arginfo_function'
-- `printf.h' (GNU): *Note Defining the Output Handler::.
--
--`printf_function'
-- `printf.h' (GNU): *Note Defining the Output Handler::.
--
--`int printf_size (FILE *FP, const struct printf_info *INFO, const void *const *ARGS)'
-- `printf.h' (GNU): *Note Predefined Printf Handlers::.
--
--`int printf_size_info (const struct printf_info *INFO, size_t N, int *ARGTYPES)'
-- `printf.h' (GNU): *Note Predefined Printf Handlers::.
--
--`PRIO_MAX'
-- `sys/resource.h' (BSD): *Note Priority::.
--
--`PRIO_MIN'
-- `sys/resource.h' (BSD): *Note Priority::.
--
--`PRIO_PGRP'
-- `sys/resource.h' (BSD): *Note Priority::.
--
--`PRIO_PROCESS'
-- `sys/resource.h' (BSD): *Note Priority::.
--
--`PRIO_USER'
-- `sys/resource.h' (BSD): *Note Priority::.
--
--`char * program_invocation_name'
-- `errno.h' (GNU): *Note Error Messages::.
--
--`char * program_invocation_short_name'
-- `errno.h' (GNU): *Note Error Messages::.
--
--`void psignal (int SIGNUM, const char *MESSAGE)'
-- `signal.h' (BSD): *Note Signal Messages::.
--
--`int pthread_atfork (void (*PREPARE)(void), void (*PARENT)(void), void (*CHILD)(void))'
-- `pthread.h' (POSIX): *Note Miscellaneous Thread Functions::.
--
--`int pthread_attr_destroy (pthread_attr_t *ATTR)'
-- `pthread.h' (POSIX): *Note Thread Attributes::.
--
--`int pthread_attr_getATTR (const pthread_attr_t *OBJ, int *VALUE)'
-- `pthread.h' (POSIX): *Note Thread Attributes::.
--
--`int pthread_attr_init (pthread_attr_t *ATTR)'
-- `pthread.h' (POSIX): *Note Thread Attributes::.
--
--`int pthread_attr_setATTR (pthread_attr_t *OBJ, int VALUE)'
-- `pthread.h' (POSIX): *Note Thread Attributes::.
--
--`int pthread_cancel (pthread_t THREAD)'
-- `pthread.h' (POSIX): *Note Basic Thread Operations::.
--
--`void pthread_cleanup_pop (int EXECUTE)'
-- `pthread.h' (POSIX): *Note Cleanup Handlers::.
--
--`void pthread_cleanup_pop_restore_np (int EXECUTE)'
-- `pthread.h' (GNU): *Note Cleanup Handlers::.
--
--`void pthread_cleanup_push (void (*ROUTINE) (void *), void *ARG)'
-- `pthread.h' (POSIX): *Note Cleanup Handlers::.
--
--`void pthread_cleanup_push_defer_np (void (*ROUTINE) (void *), void *ARG)'
-- `pthread.h' (GNU): *Note Cleanup Handlers::.
--
--`int pthread_condattr_init (pthread_condattr_t *ATTR)'
-- `pthread.h' (POSIX): *Note Condition Variables::.
--
--`int pthread_cond_broadcast (pthread_cond_t *COND)'
-- `pthread.h' (POSIX): *Note Condition Variables::.
--
--`int pthread_cond_destroy (pthread_cond_t *COND)'
-- `pthread.h' (POSIX): *Note Condition Variables::.
--
--`int pthread_cond_init (pthread_cond_t *COND, pthread_condattr_t *cond_ATTR)'
-- `pthread.h' (POSIX): *Note Condition Variables::.
--
--`int pthread_cond_signal (pthread_cond_t *COND)'
-- `pthread.h' (POSIX): *Note Condition Variables::.
--
--`int pthread_cond_timedwait (pthread_cond_t *COND, pthread_mutex_t *MUTEX, const struct timespec *ABSTIME)'
-- `pthread.h' (POSIX): *Note Condition Variables::.
--
--`int pthread_cond_wait (pthread_cond_t *COND, pthread_mutex_t *MUTEX)'
-- `pthread.h' (POSIX): *Note Condition Variables::.
--
--`int pthread_create (pthread_t * THREAD, pthread_attr_t * ATTR, void * (*START_ROUTINE)(void *), void * ARG)'
-- `pthread.h' (POSIX): *Note Basic Thread Operations::.
--
--`int pthread_detach (pthread_t TH)'
-- `pthread.h' (POSIX): *Note Miscellaneous Thread Functions::.
--
--`int pthread_equal (pthread_t thread1, pthread_t thread2)'
-- `pthread.h' (POSIX): *Note Miscellaneous Thread Functions::.
--
--`void pthread_exit (void *RETVAL)'
-- `pthread.h' (POSIX): *Note Basic Thread Operations::.
--
--`int pthread_getschedparam (pthread_t target_THREAD, int *POLICY, struct sched_param *PARAM)'
-- `pthread.h' (POSIX): *Note Miscellaneous Thread Functions::.
--
--`void * pthread_getspecific (pthread_key_t KEY)'
-- `pthread.h' (POSIX): *Note Thread-Specific Data::.
--
--`int pthread_join (pthread_t TH, void **thread_RETURN)'
-- `pthread.h' (POSIX): *Note Basic Thread Operations::.
--
--`int pthread_key_create (pthread_key_t *KEY, void (*destr_function) (void *))'
-- `pthread.h' (POSIX): *Note Thread-Specific Data::.
--
--`int pthread_key_delete (pthread_key_t KEY)'
-- `pthread.h' (POSIX): *Note Thread-Specific Data::.
--
--`int pthread_kill (pthread_t THREAD, int SIGNO)'
-- `pthread.h' (POSIX): *Note Threads and Signal Handling::.
--
--`void pthread_kill_other_threads_np (VOID)'
-- `pthread.h' (GNU): *Note Miscellaneous Thread Functions::.
--
--`int pthread_mutexattr_destroy (pthread_mutexattr_t *ATTR)'
-- `pthread.h' (POSIX): *Note Mutexes::.
--
--`int pthread_mutexattr_getkind_np (const pthread_mutexattr_t *ATTR, int *KIND)'
-- `pthread.h' (GNU): *Note Mutexes::.
--
--`int pthread_mutexattr_init (pthread_mutexattr_t *ATTR)'
-- `pthread.h' (POSIX): *Note Mutexes::.
--
--`int pthread_mutexattr_setkind_np (pthread_mutexattr_t *ATTR, int KIND)'
-- `pthread.h' (GNU): *Note Mutexes::.
--
--`int pthread_mutex_destroy (pthread_mutex_t *MUTEX)'
-- `pthread.h' (POSIX): *Note Mutexes::.
--
--`int pthread_mutex_init (pthread_mutex_t *MUTEX, const pthread_mutexattr_t *MUTEXATTR)'
-- `pthread.h' (POSIX): *Note Mutexes::.
--
--`int pthread_mutex_lock (pthread_mutex_t *mutex))'
-- `pthread.h' (POSIX): *Note Mutexes::.
--
--`int pthread_mutex_trylock (pthread_mutex_t *MUTEX)'
-- `pthread.h' (POSIX): *Note Mutexes::.
--
--`int pthread_mutex_unlock (pthread_mutex_t *MUTEX)'
-- `pthread.h' (POSIX): *Note Mutexes::.
--
--`int pthread_once (pthread_once_t *once_CONTROL, void (*INIT_ROUTINE) (void))'
-- `pthread.h' (POSIX): *Note Miscellaneous Thread Functions::.
--
--`pthread_t pthread_self (VOID)'
-- `pthread.h' (POSIX): *Note Miscellaneous Thread Functions::.
--
--`int pthread_setcancelstate (int STATE, int *OLDSTATE)'
-- `pthread.h' (POSIX): *Note Cancellation::.
--
--`int pthread_setcanceltype (int TYPE, int *OLDTYPE)'
-- `pthread.h' (POSIX): *Note Cancellation::.
--
--`int pthread_setschedparam (pthread_t target_THREAD, int POLICY, const struct sched_param *PARAM)'
-- `pthread.h' (POSIX): *Note Miscellaneous Thread Functions::.
--
--`int pthread_setspecific (pthread_key_t KEY, const void *POINTER)'
-- `pthread.h' (POSIX): *Note Thread-Specific Data::.
--
--`int pthread_sigmask (int HOW, const sigset_t *NEWMASK, sigset_t *OLDMASK)'
-- `pthread.h' (POSIX): *Note Threads and Signal Handling::.
--
--`void pthread_testcancel (VOID)'
-- `pthread.h' (POSIX): *Note Cancellation::.
--
--`char * P_tmpdir'
-- `stdio.h' (SVID): *Note Temporary Files::.
--
--`ptrdiff_t'
-- `stddef.h' (ISO): *Note Important Data Types::.
--
--`char * ptsname (int FILEDES)'
-- `stdlib.h' (SVID, XPG4.2): *Note Allocation::.
--
--`int ptsname_r (int FILEDES, char *BUF, size_t LEN)'
-- `stdlib.h' (GNU): *Note Allocation::.
--
--`int putc (int C, FILE *STREAM)'
-- `stdio.h' (ISO): *Note Simple Output::.
--
--`int putchar (int C)'
-- `stdio.h' (ISO): *Note Simple Output::.
--
--`int putenv (const char *STRING)'
-- `stdlib.h' (SVID): *Note Environment Access::.
--
--`int putpwent (const struct passwd *P, FILE *STREAM)'
-- `pwd.h' (SVID): *Note Writing a User Entry::.
--
--`int puts (const char *S)'
-- `stdio.h' (ISO): *Note Simple Output::.
--
--`struct utmp * pututline (const struct utmp *UTMP)'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`struct utmpx * pututxline (const struct utmpx *UTMP)'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`int putw (int W, FILE *STREAM)'
-- `stdio.h' (SVID): *Note Simple Output::.
--
--`ssize_t pwrite (int FILEDES, const void *BUFFER, size_t SIZE, off_t OFFSET)'
-- `unistd.h' (Unix98): *Note I/O Primitives::.
--
--`ssize_t pwrite64 (int FILEDES, const void *BUFFER, size_t SIZE, off64_t OFFSET)'
-- `unistd.h' (Unix98): *Note I/O Primitives::.
--
--`char * qecvt (long double VALUE, int NDIGIT, int *DECPT, int *NEG)'
-- `stdlib.h' (GNU): *Note System V Number Conversion::.
--
--`char * qecvt_r (long double VALUE, int NDIGIT, int *DECPT, int *NEG, char *BUF, size_t LEN)'
-- `stdlib.h' (GNU): *Note System V Number Conversion::.
--
--`char * qfcvt (long double VALUE, int NDIGIT, int *DECPT, int *NEG)'
-- `stdlib.h' (GNU): *Note System V Number Conversion::.
--
--`char * qfcvt_r (long double VALUE, int NDIGIT, int *DECPT, int *NEG, char *BUF, size_t LEN)'
-- `stdlib.h' (GNU): *Note System V Number Conversion::.
--
--`char * qgcvt (long double VALUE, int NDIGIT, char *BUF)'
-- `stdlib.h' (GNU): *Note System V Number Conversion::.
--
--`void qsort (void *ARRAY, size_t COUNT, size_t SIZE, comparison_fn_t COMPARE)'
-- `stdlib.h' (ISO): *Note Array Sort Function::.
--
--`int raise (int SIGNUM)'
-- `signal.h' (ISO): *Note Signaling Yourself::.
--
--`int rand (void)'
-- `stdlib.h' (ISO): *Note ISO Random::.
--
--`int RAND_MAX'
-- `stdlib.h' (ISO): *Note ISO Random::.
--
--`int32_t random (void)'
-- `stdlib.h' (BSD): *Note BSD Random::.
--
--`int rand_r (unsigned int *SEED)'
-- `stdlib.h' (POSIX.1): *Note ISO Random::.
--
--`ssize_t read (int FILEDES, void *BUFFER, size_t SIZE)'
-- `unistd.h' (POSIX.1): *Note I/O Primitives::.
--
--`struct dirent * readdir (DIR *DIRSTREAM)'
-- `dirent.h' (POSIX.1): *Note Reading/Closing Directory::.
--
--`int readdir_r (DIR *DIRSTREAM, struct dirent *ENTRY, struct dirent **RESULT)'
-- `dirent.h' (GNU): *Note Reading/Closing Directory::.
--
--`int readlink (const char *FILENAME, char *BUFFER, size_t SIZE)'
-- `unistd.h' (BSD): *Note Symbolic Links::.
--
--`void * realloc (void *PTR, size_t NEWSIZE)'
-- `malloc.h', `stdlib.h' (ISO): *Note Changing Block Size::.
--
--`__realloc_hook'
-- `malloc.h' (GNU): *Note Hooks for Malloc::.
--
--`int recv (int SOCKET, void *BUFFER, size_t SIZE, int FLAGS)'
-- `sys/socket.h' (BSD): *Note Receiving Data::.
--
--`int recvfrom (int SOCKET, void *BUFFER, size_t SIZE, int FLAGS, struct sockaddr *ADDR, socklen_t *LENGTH-PTR)'
-- `sys/socket.h' (BSD): *Note Receiving Datagrams::.
--
--`int recvmsg (int SOCKET, struct msghdr *MESSAGE, int FLAGS)'
-- `sys/socket.h' (BSD): *Note Receiving Datagrams::.
--
--`int RE_DUP_MAX'
-- `limits.h' (POSIX.2): *Note General Limits::.
--
--`_REENTRANT'
-- (GNU): *Note Feature Test Macros::.
--
--`REG_BADBR'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_BADPAT'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_BADRPT'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`int regcomp (regex_t *COMPILED, const char *PATTERN, int CFLAGS)'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_EBRACE'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_EBRACK'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_ECOLLATE'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_ECTYPE'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_EESCAPE'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_EPAREN'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_ERANGE'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`size_t regerror (int ERRCODE, regex_t *COMPILED, char *BUFFER, size_t LENGTH)'
-- `regex.h' (POSIX.2): *Note Regexp Cleanup::.
--
--`REG_ESPACE'
-- `regex.h' (POSIX.2): *Note Matching POSIX Regexps::.
--
--`REG_ESPACE'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_ESUBREG'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`int regexec (regex_t *COMPILED, char *STRING, size_t NMATCH, regmatch_t MATCHPTR [], int EFLAGS)'
-- `regex.h' (POSIX.2): *Note Matching POSIX Regexps::.
--
--`regex_t'
-- `regex.h' (POSIX.2): *Note POSIX Regexp Compilation::.
--
--`REG_EXTENDED'
-- `regex.h' (POSIX.2): *Note Flags for POSIX Regexps::.
--
--`void regfree (regex_t *COMPILED)'
-- `regex.h' (POSIX.2): *Note Regexp Cleanup::.
--
--`REG_ICASE'
-- `regex.h' (POSIX.2): *Note Flags for POSIX Regexps::.
--
--`int register_printf_function (int SPEC, printf_function HANDLER-FUNCTION, printf_arginfo_function ARGINFO-FUNCTION)'
-- `printf.h' (GNU): *Note Registering New Conversions::.
--
--`regmatch_t'
-- `regex.h' (POSIX.2): *Note Regexp Subexpressions::.
--
--`REG_NEWLINE'
-- `regex.h' (POSIX.2): *Note Flags for POSIX Regexps::.
--
--`REG_NOMATCH'
-- `regex.h' (POSIX.2): *Note Matching POSIX Regexps::.
--
--`REG_NOSUB'
-- `regex.h' (POSIX.2): *Note Flags for POSIX Regexps::.
--
--`REG_NOTBOL'
-- `regex.h' (POSIX.2): *Note Matching POSIX Regexps::.
--
--`REG_NOTEOL'
-- `regex.h' (POSIX.2): *Note Matching POSIX Regexps::.
--
--`regoff_t'
-- `regex.h' (POSIX.2): *Note Regexp Subexpressions::.
--
--`double remainder (double NUMERATOR, double DENOMINATOR)'
-- `math.h' (BSD): *Note Remainder Functions::.
--
--`float remainderf (float NUMERATOR, float DENOMINATOR)'
-- `math.h' (BSD): *Note Remainder Functions::.
--
--`long double remainderl (long double NUMERATOR, long double DENOMINATOR)'
-- `math.h' (BSD): *Note Remainder Functions::.
--
--`int remove (const char *FILENAME)'
-- `stdio.h' (ISO): *Note Deleting Files::.
--
--`int rename (const char *OLDNAME, const char *NEWNAME)'
-- `stdio.h' (ISO): *Note Renaming Files::.
--
--`void rewind (FILE *STREAM)'
-- `stdio.h' (ISO): *Note File Positioning::.
--
--`void rewinddir (DIR *DIRSTREAM)'
-- `dirent.h' (POSIX.1): *Note Random Access Directory::.
--
--`char * rindex (const char *STRING, int C)'
-- `string.h' (BSD): *Note Search Functions::.
--
--`double rint (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`float rintf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long double rintl (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`int RLIM_INFINITY'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIMIT_CORE'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIMIT_CPU'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIMIT_DATA'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIMIT_FSIZE'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIMIT_MEMLOCK'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIMIT_NOFILE'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIMIT_NPROC'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIMIT_RSS'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIMIT_STACK'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`RLIM_NLIMITS'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`int rmdir (const char *FILENAME)'
-- `unistd.h' (POSIX.1): *Note Deleting Files::.
--
--`int R_OK'
-- `unistd.h' (POSIX.1): *Note Testing File Access::.
--
--`double round (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`float roundf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long double roundl (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`RUN_LVL'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`RUN_LVL'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`RUSAGE_CHILDREN'
-- `sys/resource.h' (BSD): *Note Resource Usage::.
--
--`RUSAGE_SELF'
-- `sys/resource.h' (BSD): *Note Resource Usage::.
--
--`int SA_NOCLDSTOP'
-- `signal.h' (POSIX.1): *Note Flags for Sigaction::.
--
--`int SA_ONSTACK'
-- `signal.h' (BSD): *Note Flags for Sigaction::.
--
--`int SA_RESTART'
-- `signal.h' (BSD): *Note Flags for Sigaction::.
--
--`_SC_2_C_DEV'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_2_FORT_DEV'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_2_FORT_RUN'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_2_LOCALEDEF'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_2_SW_DEV'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_2_VERSION'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_AIO_LISTIO_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_AIO_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_AIO_PRIO_DELTA_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`double scalb (double VALUE, int EXPONENT)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`float scalbf (float VALUE, int EXPONENT)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long double scalbl (long double VALUE, int EXPONENT)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long long int scalbln (double X, long int n)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long long int scalblnf (float X, long int n)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long long int scalblnl (long double X, long int n)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long long int scalbn (double X, int n)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long long int scalbnf (float X, int n)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long long int scalbnl (long double X, int n)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`int scandir (const char *DIR, struct dirent ***NAMELIST, int (*SELECTOR) (const struct dirent *), int (*CMP) (const void *, const void *))'
-- `dirent.h' (BSD/SVID): *Note Scanning Directory Content::.
--
--`int scandir64 (const char *DIR, struct dirent64 ***NAMELIST, int (*SELECTOR) (const struct dirent64 *), int (*CMP) (const void *, const void *))'
-- `dirent.h' (GNU): *Note Scanning Directory Content::.
--
--`int scanf (const char *TEMPLATE, ...)'
-- `stdio.h' (ISO): *Note Formatted Input Functions::.
--
--`_SC_ARG_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_ASYNCHRONOUS_IO'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_ATEXIT_MAX'
-- `unistd.h' (GNU): *Note Constants for Sysconf::.
--
--`_SC_AVPHYS_PAGES'
-- `unistd.h' (GNU): *Note Constants for Sysconf::.
--
--`_SC_BC_BASE_MAX'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_BC_DIM_MAX'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_BC_SCALE_MAX'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_BC_STRING_MAX'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_CHAR_BIT'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_CHARCLASS_NAME_MAX'
-- `unistd.h' (GNU): *Note Constants for Sysconf::.
--
--`_SC_CHAR_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_CHAR_MIN'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_CHILD_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_CLK_TCK'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_COLL_WEIGHTS_MAX'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_DELAYTIMER_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_EQUIV_CLASS_MAX'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_EXPR_NEST_MAX'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_FSYNC'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_GETGR_R_SIZE_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_GETPW_R_SIZE_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`SCHAR_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`SCHAR_MIN'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`_SC_INT_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_INT_MIN'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_JOB_CONTROL'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_LINE_MAX'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_LOGIN_NAME_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_LONG_BIT'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_MAPPED_FILES'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_MB_LEN_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_MEMLOCK'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_MEMLOCK_RANGE'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_MEMORY_PROTECTION'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_MESSAGE_PASSING'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_MQ_OPEN_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_MQ_PRIO_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_NGROUPS_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_NL_ARGMAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_NL_LANGMAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_NL_MSGMAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_NL_NMAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_NL_SETMAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_NL_TEXTMAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_NPROCESSORS_CONF'
-- `unistd.h' (GNU): *Note Constants for Sysconf::.
--
--`_SC_NPROCESSORS_ONLN'
-- `unistd.h' (GNU): *Note Constants for Sysconf::.
--
--`_SC_NZERO'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_OPEN_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_PAGESIZE'
-- `unistd.h' (GNU): *Note Constants for Sysconf::.
--
--`_SC_PHYS_PAGES'
-- `unistd.h' (GNU): *Note Constants for Sysconf::.
--
--`_SC_PII'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PII_INTERNET'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PII_INTERNET_DGRAM'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PII_INTERNET_STREAM'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PII_OSI'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PII_OSI_CLTS'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PII_OSI_COTS'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PII_OSI_M'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PII_SOCKET'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PII_XTI'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_PRIORITIZED_IO'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_PRIORITY_SCHEDULING'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_REALTIME_SIGNALS'
-- `unistdh.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_RTSIG_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_SAVED_IDS'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_SCHAR_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_SCHAR_MIN'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_SELECT'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_SEMAPHORES'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_SEM_NSEMS_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_SEM_VALUE_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_SHARED_MEMORY_OBJECTS'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_SHRT_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_SHRT_MIN'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_SIGQUEUE_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`SC_SSIZE_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_STREAM_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_SYNCHRONIZED_IO'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_ATTR_STACKADDR'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_ATTR_STACKSIZE'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_DESTRUCTOR_ITERATIONS'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_KEYS_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_PRIO_INHERIT'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_PRIO_PROTECT'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_PRIORITY_SCHEDULING'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_PROCESS_SHARED'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREADS'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_SAFE_FUNCTIONS'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_STACK_MIN'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_THREAD_THREADS_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_TIMER_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_TIMERS'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_T_IOV_MAX'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_TTY_NAME_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_TZNAME_MAX'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_UCHAR_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_UINT_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_UIO_MAXIOV'
-- `unistd.h' (POSIX.1g): *Note Constants for Sysconf::.
--
--`_SC_ULONG_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_USHRT_MAX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_VERSION'
-- `unistd.h' (POSIX.1): *Note Constants for Sysconf::.
--
--`_SC_VERSION'
-- `unistd.h' (POSIX.2): *Note Constants for Sysconf::.
--
--`_SC_WORD_BIT'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_XOPEN_CRYPT'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_XOPEN_ENH_I18N'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_XOPEN_SHM'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_XOPEN_UNIX'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_XOPEN_VERSION'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_XOPEN_XCU_VERSION'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_XOPEN_XPG2'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_XOPEN_XPG3'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`_SC_XOPEN_XPG4'
-- `unistd.h' (X/Open): *Note Constants for Sysconf::.
--
--`unsigned short int * seed48 (unsigned short int SEED16V[3])'
-- `stdlib.h' (SVID): *Note SVID Random::.
--
--`int seed48_r (unsigned short int SEED16V[3], struct drand48_data *BUFFER)'
-- `stdlib.h' (GNU): *Note SVID Random::.
--
--`int SEEK_CUR'
-- `stdio.h' (ISO): *Note File Positioning::.
--
--`void seekdir (DIR *DIRSTREAM, off_t POS)'
-- `dirent.h' (BSD): *Note Random Access Directory::.
--
--`int SEEK_END'
-- `stdio.h' (ISO): *Note File Positioning::.
--
--`int SEEK_SET'
-- `stdio.h' (ISO): *Note File Positioning::.
--
--`int select (int NFDS, fd_set *READ-FDS, fd_set *WRITE-FDS, fd_set *EXCEPT-FDS, struct timeval *TIMEOUT)'
-- `sys/types.h' (BSD): *Note Waiting for I/O::.
--
--`int sem_destroy (sem_t * SEM)'
-- `semaphore.h' (POSIX): *Note POSIX Semaphores::.
--
--`int sem_getvalue (sem_t * SEM, int * SVAL)'
-- `semaphore.h' (POSIX): *Note POSIX Semaphores::.
--
--`int sem_init (sem_t *SEM, int PSHARED, unsigned int VALUE)'
-- `semaphore.h' (POSIX): *Note POSIX Semaphores::.
--
--`int sem_post (sem_t * SEM)'
-- `semaphore.h' (POSIX): *Note POSIX Semaphores::.
--
--`int sem_trywait (sem_t * SEM)'
-- `semaphore.h' (POSIX): *Note POSIX Semaphores::.
--
--`int sem_wait (sem_t * SEM)'
-- `semaphore.h' (POSIX): *Note POSIX Semaphores::.
--
--`int send (int SOCKET, void *BUFFER, size_t SIZE, int FLAGS)'
-- `sys/socket.h' (BSD): *Note Sending Data::.
--
--`int sendmsg (int SOCKET, const struct msghdr *MESSAGE, int FLAGS)'
-- `sys/socket.h' (BSD): *Note Receiving Datagrams::.
--
--`int sendto (int SOCKET, void *BUFFER. size_t SIZE, int FLAGS, struct sockaddr *ADDR, socklen_t LENGTH)'
-- `sys/socket.h' (BSD): *Note Sending Datagrams::.
--
--`void setbuf (FILE *STREAM, char *BUF)'
-- `stdio.h' (ISO): *Note Controlling Buffering::.
--
--`void setbuffer (FILE *STREAM, char *BUF, size_t SIZE)'
-- `stdio.h' (BSD): *Note Controlling Buffering::.
--
--`int setegid (gid_t NEWGID)'
-- `unistd.h' (POSIX.1): *Note Setting Groups::.
--
--`int setenv (const char *NAME, const char *VALUE, int REPLACE)'
-- `stdlib.h' (BSD): *Note Environment Access::.
--
--`int seteuid (uid_t NEWEUID)'
-- `unistd.h' (POSIX.1): *Note Setting User ID::.
--
--`int setfsent (void)'
-- `fstab.h' (BSD): *Note Filesystem handling::.
--
--`int setgid (gid_t NEWGID)'
-- `unistd.h' (POSIX.1): *Note Setting Groups::.
--
--`void setgrent (void)'
-- `grp.h' (SVID, BSD): *Note Scanning All Groups::.
--
--`int setgroups (size_t COUNT, gid_t *GROUPS)'
-- `grp.h' (BSD): *Note Setting Groups::.
--
--`void sethostent (int STAYOPEN)'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`int sethostid (long int ID)'
-- `unistd.h' (BSD): *Note Host Identification::.
--
--`int sethostname (const char *NAME, size_t LENGTH)'
-- `unistd.h' (BSD): *Note Host Identification::.
--
--`int setitimer (int WHICH, struct itimerval *NEW, struct itimerval *OLD)'
-- `sys/time.h' (BSD): *Note Setting an Alarm::.
--
--`int setjmp (jmp_buf STATE)'
-- `setjmp.h' (ISO): *Note Non-Local Details::.
--
--`void setkey (const char * KEY)'
-- `crypt.h' (crypt.h): *Note DES Encryption::.
--
--`void setkey_r (const char * KEY, struct crypt_data * DATA)'
-- `crypt.h' (GNU): *Note DES Encryption::.
--
--`void setlinebuf (FILE *STREAM)'
-- `stdio.h' (BSD): *Note Controlling Buffering::.
--
--`char * setlocale (int CATEGORY, const char *LOCALE)'
-- `locale.h' (ISO): *Note Setting the Locale::.
--
--`FILE * setmntent (const char *FILE, const char *MODE)'
-- `mntent.h' (BSD): *Note Filesystem handling::.
--
--`void setnetent (int STAYOPEN)'
-- `netdb.h' (BSD): *Note Networks Database::.
--
--`int setnetgrent (const char *NETGROUP)'
-- `netdb.h' (BSD): *Note Lookup Netgroup::.
--
--`int setpgid (pid_t PID, pid_t PGID)'
-- `unistd.h' (POSIX.1): *Note Process Group Functions::.
--
--`int setpgrp (pid_t PID, pid_t PGID)'
-- `unistd.h' (BSD): *Note Process Group Functions::.
--
--`int setpriority (int CLASS, int ID, int PRIORITY)'
-- `sys/resource.h' (BSD): *Note Priority::.
--
--`void setprotoent (int STAYOPEN)'
-- `netdb.h' (BSD): *Note Protocols Database::.
--
--`void setpwent (void)'
-- `pwd.h' (SVID, BSD): *Note Scanning All Users::.
--
--`int setregid (gid_t RGID, gid_t EGID)'
-- `unistd.h' (BSD): *Note Setting Groups::.
--
--`int setreuid (uid_t RUID, uid_t EUID)'
-- `unistd.h' (BSD): *Note Setting User ID::.
--
--`int setrlimit (int RESOURCE, const struct rlimit *RLP)'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`int setrlimit64 (int RESOURCE, const struct rlimit64 *RLP)'
-- `sys/resource.h' (Unix98): *Note Limits on Resources::.
--
--`void setservent (int STAYOPEN)'
-- `netdb.h' (BSD): *Note Services Database::.
--
--`pid_t setsid (void)'
-- `unistd.h' (POSIX.1): *Note Process Group Functions::.
--
--`int setsockopt (int SOCKET, int LEVEL, int OPTNAME, void *OPTVAL, socklen_t OPTLEN)'
-- `sys/socket.h' (BSD): *Note Socket Option Functions::.
--
--`void * setstate (void *STATE)'
-- `stdlib.h' (BSD): *Note BSD Random::.
--
--`int settimeofday (const struct timeval *TP, const struct timezone *TZP)'
-- `sys/time.h' (BSD): *Note High-Resolution Calendar::.
--
--`int setuid (uid_t NEWUID)'
-- `unistd.h' (POSIX.1): *Note Setting User ID::.
--
--`void setutent (void)'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`void setutxent (void)'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`int setvbuf (FILE *STREAM, char *BUF, int MODE, size_t SIZE)'
-- `stdio.h' (ISO): *Note Controlling Buffering::.
--
--`SHRT_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`SHRT_MIN'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`int shutdown (int SOCKET, int HOW)'
-- `sys/socket.h' (BSD): *Note Closing a Socket::.
--
--`S_IEXEC'
-- `sys/stat.h' (BSD): *Note Permission Bits::.
--
--`S_IFBLK'
-- `sys/stat.h' (BSD): *Note Testing File Type::.
--
--`S_IFCHR'
-- `sys/stat.h' (BSD): *Note Testing File Type::.
--
--`S_IFDIR'
-- `sys/stat.h' (BSD): *Note Testing File Type::.
--
--`S_IFIFO'
-- `sys/stat.h' (BSD): *Note Testing File Type::.
--
--`S_IFLNK'
-- `sys/stat.h' (BSD): *Note Testing File Type::.
--
--`int S_IFMT'
-- `sys/stat.h' (BSD): *Note Testing File Type::.
--
--`S_IFREG'
-- `sys/stat.h' (BSD): *Note Testing File Type::.
--
--`S_IFSOCK'
-- `sys/stat.h' (BSD): *Note Testing File Type::.
--
--`int SIGABRT'
-- `signal.h' (ISO): *Note Program Error Signals::.
--
--`int sigaction (int SIGNUM, const struct sigaction *ACTION, struct sigaction *OLD-ACTION)'
-- `signal.h' (POSIX.1): *Note Advanced Signal Handling::.
--
--`int sigaddset (sigset_t *SET, int SIGNUM)'
-- `signal.h' (POSIX.1): *Note Signal Sets::.
--
--`int SIGALRM'
-- `signal.h' (POSIX.1): *Note Alarm Signals::.
--
--`int sigaltstack (const struct sigaltstack *STACK, struct sigaltstack *OLDSTACK)'
-- `signal.h' (BSD): *Note Signal Stack::.
--
--`sig_atomic_t'
-- `signal.h' (ISO): *Note Atomic Types::.
--
--`SIG_BLOCK'
-- `signal.h' (POSIX.1): *Note Process Signal Mask::.
--
--`int sigblock (int MASK)'
-- `signal.h' (BSD): *Note Blocking in BSD::.
--
--`int SIGBUS'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`int SIGCHLD'
-- `signal.h' (POSIX.1): *Note Job Control Signals::.
--
--`int SIGCLD'
-- `signal.h' (SVID): *Note Job Control Signals::.
--
--`int SIGCONT'
-- `signal.h' (POSIX.1): *Note Job Control Signals::.
--
--`int sigdelset (sigset_t *SET, int SIGNUM)'
-- `signal.h' (POSIX.1): *Note Signal Sets::.
--
--`int sigemptyset (sigset_t *SET)'
-- `signal.h' (POSIX.1): *Note Signal Sets::.
--
--`int SIGEMT'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`sighandler_t SIG_ERR'
-- `signal.h' (ISO): *Note Basic Signal Handling::.
--
--`int sigfillset (sigset_t *SET)'
-- `signal.h' (POSIX.1): *Note Signal Sets::.
--
--`int SIGFPE'
-- `signal.h' (ISO): *Note Program Error Signals::.
--
--`sighandler_t'
-- `signal.h' (GNU): *Note Basic Signal Handling::.
--
--`int SIGHUP'
-- `signal.h' (POSIX.1): *Note Termination Signals::.
--
--`int SIGILL'
-- `signal.h' (ISO): *Note Program Error Signals::.
--
--`int SIGINFO'
-- `signal.h' (BSD): *Note Miscellaneous Signals::.
--
--`int SIGINT'
-- `signal.h' (ISO): *Note Termination Signals::.
--
--`int siginterrupt (int SIGNUM, int FAILFLAG)'
-- `signal.h' (BSD): *Note BSD Handler::.
--
--`int SIGIO'
-- `signal.h' (BSD): *Note Asynchronous I/O Signals::.
--
--`int SIGIOT'
-- `signal.h' (Unix): *Note Program Error Signals::.
--
--`int sigismember (const sigset_t *SET, int SIGNUM)'
-- `signal.h' (POSIX.1): *Note Signal Sets::.
--
--`sigjmp_buf'
-- `setjmp.h' (POSIX.1): *Note Non-Local Exits and Signals::.
--
--`int SIGKILL'
-- `signal.h' (POSIX.1): *Note Termination Signals::.
--
--`void siglongjmp (sigjmp_buf STATE, int VALUE)'
-- `setjmp.h' (POSIX.1): *Note Non-Local Exits and Signals::.
--
--`int SIGLOST'
-- `signal.h' (GNU): *Note Operation Error Signals::.
--
--`int sigmask (int SIGNUM)'
-- `signal.h' (BSD): *Note Blocking in BSD::.
--
--`sighandler_t signal (int SIGNUM, sighandler_t ACTION)'
-- `signal.h' (ISO): *Note Basic Signal Handling::.
--
--`int signbit (*float-type* X)'
-- `math.h' (ISO): *Note FP Bit Twiddling::.
--
--`long long int significand (double X)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long long int significandf (float X)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`long long int significandl (long double X)'
-- `math.h' (BSD): *Note Normalization Functions::.
--
--`int sigpause (int MASK)'
-- `signal.h' (BSD): *Note Blocking in BSD::.
--
--`int sigpending (sigset_t *SET)'
-- `signal.h' (POSIX.1): *Note Checking for Pending Signals::.
--
--`int SIGPIPE'
-- `signal.h' (POSIX.1): *Note Operation Error Signals::.
--
--`int SIGPOLL'
-- `signal.h' (SVID): *Note Asynchronous I/O Signals::.
--
--`int sigprocmask (int HOW, const sigset_t *SET, sigset_t *OLDSET)'
-- `signal.h' (POSIX.1): *Note Process Signal Mask::.
--
--`int SIGPROF'
-- `signal.h' (BSD): *Note Alarm Signals::.
--
--`int SIGQUIT'
-- `signal.h' (POSIX.1): *Note Termination Signals::.
--
--`int SIGSEGV'
-- `signal.h' (ISO): *Note Program Error Signals::.
--
--`int sigsetjmp (sigjmp_buf STATE, int SAVESIGS)'
-- `setjmp.h' (POSIX.1): *Note Non-Local Exits and Signals::.
--
--`SIG_SETMASK'
-- `signal.h' (POSIX.1): *Note Process Signal Mask::.
--
--`int sigsetmask (int MASK)'
-- `signal.h' (BSD): *Note Blocking in BSD::.
--
--`sigset_t'
-- `signal.h' (POSIX.1): *Note Signal Sets::.
--
--`int sigstack (const struct sigstack *STACK, struct sigstack *OLDSTACK)'
-- `signal.h' (BSD): *Note Signal Stack::.
--
--`int SIGSTOP'
-- `signal.h' (POSIX.1): *Note Job Control Signals::.
--
--`int sigsuspend (const sigset_t *SET)'
-- `signal.h' (POSIX.1): *Note Sigsuspend::.
--
--`int SIGSYS'
-- `signal.h' (Unix): *Note Program Error Signals::.
--
--`int SIGTERM'
-- `signal.h' (ISO): *Note Termination Signals::.
--
--`int SIGTRAP'
-- `signal.h' (BSD): *Note Program Error Signals::.
--
--`int SIGTSTP'
-- `signal.h' (POSIX.1): *Note Job Control Signals::.
--
--`int SIGTTIN'
-- `signal.h' (POSIX.1): *Note Job Control Signals::.
--
--`int SIGTTOU'
-- `signal.h' (POSIX.1): *Note Job Control Signals::.
--
--`SIG_UNBLOCK'
-- `signal.h' (POSIX.1): *Note Process Signal Mask::.
--
--`int SIGURG'
-- `signal.h' (BSD): *Note Asynchronous I/O Signals::.
--
--`int SIGUSR1'
-- `signal.h' (POSIX.1): *Note Miscellaneous Signals::.
--
--`int SIGUSR2'
-- `signal.h' (POSIX.1): *Note Miscellaneous Signals::.
--
--`int sigvec (int SIGNUM, const struct sigvec *ACTION,struct sigvec *OLD-ACTION)'
-- `signal.h' (BSD): *Note BSD Handler::.
--
--`int SIGVTALRM'
-- `signal.h' (BSD): *Note Alarm Signals::.
--
--`int sigwait (const sigset_t *SET, int *SIG)'
-- `pthread.h' (POSIX): *Note Threads and Signal Handling::.
--
--`int SIGWINCH'
-- `signal.h' (BSD): *Note Miscellaneous Signals::.
--
--`int SIGXCPU'
-- `signal.h' (BSD): *Note Operation Error Signals::.
--
--`int SIGXFSZ'
-- `signal.h' (BSD): *Note Operation Error Signals::.
--
--`double sin (double X)'
-- `math.h' (ISO): *Note Trig Functions::.
--
--`void sincos (double X, double *SINX, double *COSX)'
-- `math.h' (GNU): *Note Trig Functions::.
--
--`void sincosf (float X, float *SINX, float *COSX)'
-- `math.h' (GNU): *Note Trig Functions::.
--
--`void sincosl (long double X, long double *SINX, long double *COSX)'
-- `math.h' (GNU): *Note Trig Functions::.
--
--`float sinf (float X)'
-- `math.h' (ISO): *Note Trig Functions::.
--
--`double sinh (double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`float sinhf (float X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double sinhl (long double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double sinl (long double X)'
-- `math.h' (ISO): *Note Trig Functions::.
--
--`S_IREAD'
-- `sys/stat.h' (BSD): *Note Permission Bits::.
--
--`S_IRGRP'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IROTH'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IRUSR'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IRWXG'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IRWXO'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IRWXU'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`int S_ISBLK (mode_t M)'
-- `sys/stat.h' (POSIX): *Note Testing File Type::.
--
--`int S_ISCHR (mode_t M)'
-- `sys/stat.h' (POSIX): *Note Testing File Type::.
--
--`int S_ISDIR (mode_t M)'
-- `sys/stat.h' (POSIX): *Note Testing File Type::.
--
--`int S_ISFIFO (mode_t M)'
-- `sys/stat.h' (POSIX): *Note Testing File Type::.
--
--`S_ISGID'
-- `sys/stat.h' (POSIX): *Note Permission Bits::.
--
--`int S_ISLNK (mode_t M)'
-- `sys/stat.h' (GNU): *Note Testing File Type::.
--
--`int S_ISREG (mode_t M)'
-- `sys/stat.h' (POSIX): *Note Testing File Type::.
--
--`int S_ISSOCK (mode_t M)'
-- `sys/stat.h' (GNU): *Note Testing File Type::.
--
--`S_ISUID'
-- `sys/stat.h' (POSIX): *Note Permission Bits::.
--
--`S_ISVTX'
-- `sys/stat.h' (BSD): *Note Permission Bits::.
--
--`S_IWGRP'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IWOTH'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IWRITE'
-- `sys/stat.h' (BSD): *Note Permission Bits::.
--
--`S_IWUSR'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IXGRP'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IXOTH'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`S_IXUSR'
-- `sys/stat.h' (POSIX.1): *Note Permission Bits::.
--
--`size_t'
-- `stddef.h' (ISO): *Note Important Data Types::.
--
--`unsigned int sleep (unsigned int SECONDS)'
-- `unistd.h' (POSIX.1): *Note Sleeping::.
--
--`int snprintf (char *S, size_t SIZE, const char *TEMPLATE, ...)'
-- `stdio.h' (GNU): *Note Formatted Output Functions::.
--
--`SO_BROADCAST'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`int SOCK_DGRAM'
-- `sys/socket.h' (BSD): *Note Communication Styles::.
--
--`int socket (int NAMESPACE, int STYLE, int PROTOCOL)'
-- `sys/socket.h' (BSD): *Note Creating a Socket::.
--
--`int socketpair (int NAMESPACE, int STYLE, int PROTOCOL, int FILEDES[2])'
-- `sys/socket.h' (BSD): *Note Socket Pairs::.
--
--`int SOCK_RAW'
-- `sys/socket.h' (BSD): *Note Communication Styles::.
--
--`int SOCK_RDM'
-- `sys/socket.h' (BSD): *Note Communication Styles::.
--
--`int SOCK_SEQPACKET'
-- `sys/socket.h' (BSD): *Note Communication Styles::.
--
--`int SOCK_STREAM'
-- `sys/socket.h' (BSD): *Note Communication Styles::.
--
--`SO_DEBUG'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`SO_DONTROUTE'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`SO_ERROR'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`SO_KEEPALIVE'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`SO_LINGER'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`int SOL_SOCKET'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`SO_OOBINLINE'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`SO_RCVBUF'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`SO_REUSEADDR'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`SO_SNDBUF'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`SO_STYLE'
-- `sys/socket.h' (GNU): *Note Socket-Level Options::.
--
--`SO_TYPE'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`speed_t'
-- `termios.h' (POSIX.1): *Note Line Speed::.
--
--`int sprintf (char *S, const char *TEMPLATE, ...)'
-- `stdio.h' (ISO): *Note Formatted Output Functions::.
--
--`double sqrt (double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`float sqrtf (float X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`long double sqrtl (long double X)'
-- `math.h' (ISO): *Note Exponents and Logarithms::.
--
--`void srand (unsigned int SEED)'
-- `stdlib.h' (ISO): *Note ISO Random::.
--
--`void srand48 (long int SEEDVAL))'
-- `stdlib.h' (SVID): *Note SVID Random::.
--
--`int srand48_r (long int SEEDVAL, struct drand48_data *BUFFER)'
-- `stdlib.h' (GNU): *Note SVID Random::.
--
--`void srandom (unsigned int SEED)'
-- `stdlib.h' (BSD): *Note BSD Random::.
--
--`int sscanf (const char *S, const char *TEMPLATE, ...)'
-- `stdio.h' (ISO): *Note Formatted Input Functions::.
--
--`sighandler_t ssignal (int SIGNUM, sighandler_t ACTION)'
-- `signal.h' (SVID): *Note Basic Signal Handling::.
--
--`int SSIZE_MAX'
-- `limits.h' (POSIX.1): *Note General Limits::.
--
--`ssize_t'
-- `unistd.h' (POSIX.1): *Note I/O Primitives::.
--
--`int stat (const char *FILENAME, struct stat *BUF)'
-- `sys/stat.h' (POSIX.1): *Note Reading Attributes::.
--
--`int stat64 (const char *FILENAME, struct stat64 *BUF)'
-- `sys/stat.h' (Unix98): *Note Reading Attributes::.
--
--`FILE * stderr'
-- `stdio.h' (ISO): *Note Standard Streams::.
--
--`STDERR_FILENO'
-- `unistd.h' (POSIX.1): *Note Descriptors and Streams::.
--
--`FILE * stdin'
-- `stdio.h' (ISO): *Note Standard Streams::.
--
--`STDIN_FILENO'
-- `unistd.h' (POSIX.1): *Note Descriptors and Streams::.
--
--`FILE * stdout'
-- `stdio.h' (ISO): *Note Standard Streams::.
--
--`STDOUT_FILENO'
-- `unistd.h' (POSIX.1): *Note Descriptors and Streams::.
--
--`char * stpcpy (char *TO, const char *FROM)'
-- `string.h' (Unknown origin): *Note Copying and Concatenation::.
--
--`char * stpncpy (char *TO, const char *FROM, size_t SIZE)'
-- `string.h' (GNU): *Note Copying and Concatenation::.
--
--`int strcasecmp (const char *S1, const char *S2)'
-- `string.h' (BSD): *Note String/Array Comparison::.
--
--`char * strcat (char *TO, const char *FROM)'
-- `string.h' (ISO): *Note Copying and Concatenation::.
--
--`char * strchr (const char *STRING, int C)'
-- `string.h' (ISO): *Note Search Functions::.
--
--`int strcmp (const char *S1, const char *S2)'
-- `string.h' (ISO): *Note String/Array Comparison::.
--
--`int strcoll (const char *S1, const char *S2)'
-- `string.h' (ISO): *Note Collation Functions::.
--
--`char * strcpy (char *TO, const char *FROM)'
-- `string.h' (ISO): *Note Copying and Concatenation::.
--
--`size_t strcspn (const char *STRING, const char *STOPSET)'
-- `string.h' (ISO): *Note Search Functions::.
--
--`char * strdup (const char *S)'
-- `string.h' (SVID): *Note Copying and Concatenation::.
--
--`char * strdupa (const char *S)'
-- `string.h' (GNU): *Note Copying and Concatenation::.
--
--`int STREAM_MAX'
-- `limits.h' (POSIX.1): *Note General Limits::.
--
--`char * strerror (int ERRNUM)'
-- `string.h' (ISO): *Note Error Messages::.
--
--`char * strerror_r (int ERRNUM, char *BUF, size_t N)'
-- `string.h' (GNU): *Note Error Messages::.
--
--`size_t strftime (char *S, size_t SIZE, const char *TEMPLATE, const struct tm *BROKENTIME)'
-- `time.h' (ISO): *Note Formatting Date and Time::.
--
--`size_t strlen (const char *S)'
-- `string.h' (ISO): *Note String Length::.
--
--`int strncasecmp (const char *S1, const char *S2, size_t N)'
-- `string.h' (BSD): *Note String/Array Comparison::.
--
--`char * strncat (char *TO, const char *FROM, size_t SIZE)'
-- `string.h' (ISO): *Note Copying and Concatenation::.
--
--`int strncmp (const char *S1, const char *S2, size_t SIZE)'
-- `string.h' (ISO): *Note String/Array Comparison::.
--
--`char * strncpy (char *TO, const char *FROM, size_t SIZE)'
-- `string.h' (ISO): *Note Copying and Concatenation::.
--
--`char * strndup (const char *S, size_t SIZE)'
-- `string.h' (GNU): *Note Copying and Concatenation::.
--
--`char * strndupa (const char *S, size_t SIZE)'
-- `string.h' (GNU): *Note Copying and Concatenation::.
--
--`size_t strnlen (const char *S, size_t MAXLEN)'
-- `string.h' (GNU): *Note String Length::.
--
--`char * strpbrk (const char *STRING, const char *STOPSET)'
-- `string.h' (ISO): *Note Search Functions::.
--
--`char * strptime (const char *S, const char *FMT, struct tm *TP)'
-- `time.h' (XPG4): *Note Low-Level Time String Parsing::.
--
--`char * strrchr (const char *STRING, int C)'
-- `string.h' (ISO): *Note Search Functions::.
--
--`char * strsep (char **STRING_PTR, const char *DELIMITER)'
-- `string.h' (BSD): *Note Finding Tokens in a String::.
--
--`char * strsignal (int SIGNUM)'
-- `string.h' (GNU): *Note Signal Messages::.
--
--`size_t strspn (const char *STRING, const char *SKIPSET)'
-- `string.h' (ISO): *Note Search Functions::.
--
--`char * strstr (const char *HAYSTACK, const char *NEEDLE)'
-- `string.h' (ISO): *Note Search Functions::.
--
--`double strtod (const char *STRING, char **TAILPTR)'
-- `stdlib.h' (ISO): *Note Parsing of Floats::.
--
--`float strtof (const char *STRING, char **TAILPTR)'
-- `stdlib.h' (GNU): *Note Parsing of Floats::.
--
--`char * strtok (char *NEWSTRING, const char *DELIMITERS)'
-- `string.h' (ISO): *Note Finding Tokens in a String::.
--
--`char * strtok_r (char *NEWSTRING, const char *DELIMITERS, char **SAVE_PTR)'
-- `string.h' (POSIX): *Note Finding Tokens in a String::.
--
--`long int strtol (const char *STRING, char **TAILPTR, int BASE)'
-- `stdlib.h' (ISO): *Note Parsing of Integers::.
--
--`long double strtold (const char *STRING, char **TAILPTR)'
-- `stdlib.h' (GNU): *Note Parsing of Floats::.
--
--`long long int strtoll (const char *STRING, char **TAILPTR, int BASE)'
-- `stdlib.h' (ISO): *Note Parsing of Integers::.
--
--`long long int strtoq (const char *STRING, char **TAILPTR, int BASE)'
-- `stdlib.h' (BSD): *Note Parsing of Integers::.
--
--`unsigned long int strtoul (const char *STRING, char **TAILPTR, int BASE)'
-- `stdlib.h' (ISO): *Note Parsing of Integers::.
--
--`unsigned long long int strtoull (const char *STRING, char **TAILPTR, int BASE)'
-- `stdlib.h' (ISO): *Note Parsing of Integers::.
--
--`unsigned long long int strtouq (const char *STRING, char **TAILPTR, int BASE)'
-- `stdlib.h' (BSD): *Note Parsing of Integers::.
--
--`struct aiocb'
-- `aio.h' (POSIX.1b): *Note Asynchronous I/O::.
--
--`struct aiocb64'
-- `aio.h' (POSIX.1b): *Note Asynchronous I/O::.
--
--`struct aioinit'
-- `aio.h' (GNU): *Note Configuration of AIO::.
--
--`struct argp'
-- `argp.h' (GNU): *Note Argp Parsers::.
--
--`struct argp_child'
-- `argp.h' (GNU): *Note Argp Children::.
--
--`struct argp_option'
-- `argp.h' (GNU): *Note Argp Option Vectors::.
--
--`struct argp_state'
-- `argp.h' (GNU): *Note Argp Parsing State::.
--
--`struct dirent'
-- `dirent.h' (POSIX.1): *Note Directory Entries::.
--
--`struct exit_status'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`struct flock'
-- `fcntl.h' (POSIX.1): *Note File Locks::.
--
--`struct fstab'
-- `fstab.h' (BSD): *Note Filesystem handling::.
--
--`struct FTW'
-- `ftw.h' (XPG4.2): *Note Working on Directory Trees::.
--
--`struct gconv_step'
-- `gconv.h' (GNU): *Note glibc iconv Implementation::.
--
--`struct gconv_step_data'
-- `gconv.h' (GNU): *Note glibc iconv Implementation::.
--
--`struct group'
-- `grp.h' (POSIX.1): *Note Group Data Structure::.
--
--`struct hostent'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`struct if_nameindex'
-- `net/if.h' (IPv6 basic API): *Note Interface Naming::.
--
--`struct in6_addr'
-- `netinet/in.h' (IPv6 basic API): *Note Host Address Data Type::.
--
--`struct in_addr'
-- `netinet/in.h' (BSD): *Note Host Address Data Type::.
--
--`struct itimerval'
-- `sys/time.h' (BSD): *Note Setting an Alarm::.
--
--`struct lconv'
-- `locale.h' (ISO): *Note The Lame Way to Locale Data::.
--
--`struct linger'
-- `sys/socket.h' (BSD): *Note Socket-Level Options::.
--
--`struct mallinfo'
-- `malloc.h' (GNU): *Note Statistics of Malloc::.
--
--`struct mntent'
-- `fstab.h' (BSD): *Note Filesystem handling::.
--
--`struct msghdr'
-- `sys/socket.h' (BSD): *Note Receiving Datagrams::.
--
--`struct netent'
-- `netdb.h' (BSD): *Note Networks Database::.
--
--`struct obstack'
-- `obstack.h' (GNU): *Note Creating Obstacks::.
--
--`struct option'
-- `getopt.h' (GNU): *Note Getopt Long Options::.
--
--`struct passwd'
-- `pwd.h' (POSIX.1): *Note User Data Structure::.
--
--`struct printf_info'
-- `printf.h' (GNU): *Note Conversion Specifier Options::.
--
--`struct protoent'
-- `netdb.h' (BSD): *Note Protocols Database::.
--
--`struct rlimit'
-- `sys/resource.h' (BSD): *Note Limits on Resources::.
--
--`struct rlimit64'
-- `sys/resource.h' (Unix98): *Note Limits on Resources::.
--
--`struct rusage'
-- `sys/resource.h' (BSD): *Note Resource Usage::.
--
--`struct servent'
-- `netdb.h' (BSD): *Note Services Database::.
--
--`struct sigaction'
-- `signal.h' (POSIX.1): *Note Advanced Signal Handling::.
--
--`struct sigaltstack'
-- `signal.h' (BSD): *Note Signal Stack::.
--
--`struct sigstack'
-- `signal.h' (BSD): *Note Signal Stack::.
--
--`struct sigvec'
-- `signal.h' (BSD): *Note BSD Handler::.
--
--`struct sockaddr'
-- `sys/socket.h' (BSD): *Note Address Formats::.
--
--`struct sockaddr_in'
-- `netinet/in.h' (BSD): *Note Internet Address Formats::.
--
--`struct sockaddr_un'
-- `sys/un.h' (BSD): *Note Local Namespace Details::.
--
--`struct stat'
-- `sys/stat.h' (POSIX.1): *Note Attribute Meanings::.
--
--`struct stat64'
-- `sys/stat.h' (LFS): *Note Attribute Meanings::.
--
--`struct termios'
-- `termios.h' (POSIX.1): *Note Mode Data Types::.
--
--`struct timeval'
-- `sys/time.h' (BSD): *Note High-Resolution Calendar::.
--
--`struct timezone'
-- `sys/time.h' (BSD): *Note High-Resolution Calendar::.
--
--`struct tm'
-- `time.h' (ISO): *Note Broken-down Time::.
--
--`struct tms'
-- `sys/times.h' (POSIX.1): *Note Detailed CPU Time::.
--
--`struct utimbuf'
-- `time.h' (POSIX.1): *Note File Times::.
--
--`struct utsname'
-- `sys/utsname.h' (POSIX.1): *Note Hardware/Software Type ID::.
--
--`int strverscmp (const char *S1, const char *S2)'
-- `string.h' (GNU): *Note String/Array Comparison::.
--
--`size_t strxfrm (char *TO, const char *FROM, size_t SIZE)'
-- `string.h' (ISO): *Note Collation Functions::.
--
--`int SUN_LEN (*struct sockaddr_un ** PTR)'
-- `sys/un.h' (BSD): *Note Local Namespace Details::.
--
--`_SVID_SOURCE'
-- (GNU): *Note Feature Test Macros::.
--
--`int SV_INTERRUPT'
-- `signal.h' (BSD): *Note BSD Handler::.
--
--`int SV_ONSTACK'
-- `signal.h' (BSD): *Note BSD Handler::.
--
--`int SV_RESETHAND'
-- `signal.h' (Sun): *Note BSD Handler::.
--
--`int symlink (const char *OLDNAME, const char *NEWNAME)'
-- `unistd.h' (BSD): *Note Symbolic Links::.
--
--`int sync (void)'
-- `unistd.h' (X/Open): *Note Synchronizing I/O::.
--
--`long int sysconf (int PARAMETER)'
-- `unistd.h' (POSIX.1): *Note Sysconf Definition::.
--
--`int system (const char *COMMAND)'
-- `stdlib.h' (ISO): *Note Running a Command::.
--
--`sighandler_t sysv_signal (int SIGNUM, sighandler_t ACTION)'
-- `signal.h' (GNU): *Note Basic Signal Handling::.
--
--`double tan (double X)'
-- `math.h' (ISO): *Note Trig Functions::.
--
--`float tanf (float X)'
-- `math.h' (ISO): *Note Trig Functions::.
--
--`double tanh (double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`float tanhf (float X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double tanhl (long double X)'
-- `math.h' (ISO): *Note Hyperbolic Functions::.
--
--`long double tanl (long double X)'
-- `math.h' (ISO): *Note Trig Functions::.
--
--`int tcdrain (int FILEDES)'
-- `termios.h' (POSIX.1): *Note Line Control::.
--
--`tcflag_t'
-- `termios.h' (POSIX.1): *Note Mode Data Types::.
--
--`int tcflow (int FILEDES, int ACTION)'
-- `termios.h' (POSIX.1): *Note Line Control::.
--
--`int tcflush (int FILEDES, int QUEUE)'
-- `termios.h' (POSIX.1): *Note Line Control::.
--
--`int tcgetattr (int FILEDES, struct termios *TERMIOS-P)'
-- `termios.h' (POSIX.1): *Note Mode Functions::.
--
--`pid_t tcgetpgrp (int FILEDES)'
-- `unistd.h' (POSIX.1): *Note Terminal Access Functions::.
--
--`pid_t tcgetsid (int FILDES)'
-- `termios.h' (Unix98): *Note Terminal Access Functions::.
--
--`TCSADRAIN'
-- `termios.h' (POSIX.1): *Note Mode Functions::.
--
--`TCSAFLUSH'
-- `termios.h' (POSIX.1): *Note Mode Functions::.
--
--`TCSANOW'
-- `termios.h' (POSIX.1): *Note Mode Functions::.
--
--`TCSASOFT'
-- `termios.h' (BSD): *Note Mode Functions::.
--
--`int tcsendbreak (int FILEDES, int DURATION)'
-- `termios.h' (POSIX.1): *Note Line Control::.
--
--`int tcsetattr (int FILEDES, int WHEN, const struct termios *TERMIOS-P)'
-- `termios.h' (POSIX.1): *Note Mode Functions::.
--
--`int tcsetpgrp (int FILEDES, pid_t PGID)'
-- `unistd.h' (POSIX.1): *Note Terminal Access Functions::.
--
--`void * tdelete (const void *KEY, void **ROOTP, comparison_fn_t COMPAR)'
-- `search.h' (SVID): *Note Tree Search Function::.
--
--`void tdestroy (void *VROOT, __free_fn_t FREEFCT)'
-- `search.h' (GNU): *Note Tree Search Function::.
--
--`off_t telldir (DIR *DIRSTREAM)'
-- `dirent.h' (BSD): *Note Random Access Directory::.
--
--`TEMP_FAILURE_RETRY (EXPRESSION)'
-- `unistd.h' (GNU): *Note Interrupted Primitives::.
--
--`char * tempnam (const char *DIR, const char *PREFIX)'
-- `stdio.h' (SVID): *Note Temporary Files::.
--
--`void * tfind (const void *KEY, void *const *ROOTP, comparison_fn_t COMPAR)'
-- `search.h' (SVID): *Note Tree Search Function::.
--
--`double tgamma (double X)'
-- `math.h' (XPG): *Note Special Functions::.
--
--`float tgammaf (float X)'
-- `math.h' (XPG): *Note Special Functions::.
--
--`long double tgammal (long double X)'
-- `math.h' (XPG): *Note Special Functions::.
--
--`time_t time (time_t *RESULT)'
-- `time.h' (ISO): *Note Simple Calendar Time::.
--
--`clock_t times (struct tms *BUFFER)'
-- `sys/times.h' (POSIX.1): *Note Detailed CPU Time::.
--
--`time_t'
-- `time.h' (ISO): *Note Simple Calendar Time::.
--
--`long int timezone'
-- `time.h' (SVID): *Note Time Zone Functions::.
--
--`FILE * tmpfile (void)'
-- `stdio.h' (ISO): *Note Temporary Files::.
--
--`FILE * tmpfile64 (void)'
-- `stdio.h' (Unix98): *Note Temporary Files::.
--
--`int TMP_MAX'
-- `stdio.h' (ISO): *Note Temporary Files::.
--
--`char * tmpnam (char *RESULT)'
-- `stdio.h' (ISO): *Note Temporary Files::.
--
--`char * tmpnam_r (char *RESULT)'
-- `stdio.h' (GNU): *Note Temporary Files::.
--
--`int toascii (int C)'
-- `ctype.h' (SVID, BSD): *Note Case Conversion::.
--
--`int _tolower (int C)'
-- `ctype.h' (SVID): *Note Case Conversion::.
--
--`int tolower (int C)'
-- `ctype.h' (ISO): *Note Case Conversion::.
--
--`tcflag_t TOSTOP'
-- `termios.h' (POSIX.1): *Note Local Modes::.
--
--`int _toupper (int C)'
-- `ctype.h' (SVID): *Note Case Conversion::.
--
--`int toupper (int C)'
-- `ctype.h' (ISO): *Note Case Conversion::.
--
--`wint_t towctrans (wint_t WC, wctrans_t DESC)'
-- `wctype.h' (ISO): *Note Wide Character Case Conversion::.
--
--`wint_t towlower (wint_t WC)'
-- `wctype.h' (ISO): *Note Wide Character Case Conversion::.
--
--`wint_t towupper (wint_t WC)'
-- `wctype.h' (ISO): *Note Wide Character Case Conversion::.
--
--`double trunc (double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`int truncate (const char *NAME, off_t LENGTH)'
-- `unistd.h' (X/Open): *Note Truncating Files::.
--
--`int truncate64 (const char *NAME, off64_t LENGTH)'
-- `unistd.h' (Unix98): *Note Truncating Files::.
--
--`float truncf (float X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`long double truncl (long double X)'
-- `math.h' (ISO): *Note Rounding Functions::.
--
--`TRY_AGAIN'
-- `netdb.h' (BSD): *Note Host Names::.
--
--`void * tsearch (const void *KEY, void **ROOTP, comparison_fn_t COMPAR)'
-- `search.h' (SVID): *Note Tree Search Function::.
--
--`char * ttyname (int FILEDES)'
-- `unistd.h' (POSIX.1): *Note Is It a Terminal::.
--
--`int ttyname_r (int FILEDES, char *BUF, size_t LEN)'
-- `unistd.h' (POSIX.1): *Note Is It a Terminal::.
--
--`void twalk (const void *ROOT, __action_fn_t ACTION)'
-- `search.h' (SVID): *Note Tree Search Function::.
--
--`char * tzname [2]'
-- `time.h' (POSIX.1): *Note Time Zone Functions::.
--
--`int TZNAME_MAX'
-- `limits.h' (POSIX.1): *Note General Limits::.
--
--`void tzset (void)'
-- `time.h' (POSIX.1): *Note Time Zone Functions::.
--
--`UCHAR_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`uid_t'
-- `sys/types.h' (POSIX.1): *Note Reading Persona::.
--
--`UINT_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`ULONG_LONG_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`ULONG_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`mode_t umask (mode_t MASK)'
-- `sys/stat.h' (POSIX.1): *Note Setting Permissions::.
--
--`int uname (struct utsname *INFO)'
-- `sys/utsname.h' (POSIX.1): *Note Hardware/Software Type ID::.
--
--`int ungetc (int C, FILE *STREAM)'
-- `stdio.h' (ISO): *Note How Unread::.
--
--`union wait'
-- `sys/wait.h' (BSD): *Note BSD Wait Functions::.
--
--`int unlink (const char *FILENAME)'
-- `unistd.h' (POSIX.1): *Note Deleting Files::.
--
--`int unlockpt (int FILEDES)'
-- `stdlib.h' (SVID, XPG4.2): *Note Allocation::.
--
--`void unsetenv (const char *NAME)'
-- `stdlib.h' (BSD): *Note Environment Access::.
--
--`void updwtmp (const char *WTMP_FILE, const struct utmp *UTMP)'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`USER_PROCESS'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`USER_PROCESS'
-- `utmpx.h' (XPG4.2): *Note XPG Functions::.
--
--`USHRT_MAX'
-- `limits.h' (ISO): *Note Range of Type::.
--
--`int utime (const char *FILENAME, const struct utimbuf *TIMES)'
-- `time.h' (POSIX.1): *Note File Times::.
--
--`int utimes (const char *FILENAME, struct timeval TVP[2])'
-- `sys/time.h' (BSD): *Note File Times::.
--
--`int utmpname (const char *FILE)'
-- `utmp.h' (SVID): *Note Manipulating the Database::.
--
--`va_alist'
-- `varargs.h' (Unix): *Note Old Varargs::.
--
--`TYPE va_arg (va_list AP, TYPE)'
-- `stdarg.h' (ISO): *Note Argument Macros::.
--
--`void __va_copy (va_list DEST, va_list SRC)'
-- `stdarg.h' (GNU): *Note Argument Macros::.
--
--`va_dcl'
-- `varargs.h' (Unix): *Note Old Varargs::.
--
--`void va_end (va_list AP)'
-- `stdarg.h' (ISO): *Note Argument Macros::.
--
--`va_list'
-- `stdarg.h' (ISO): *Note Argument Macros::.
--
--`void * valloc (size_t SIZE)'
-- `malloc.h', `stdlib.h' (BSD): *Note Aligned Memory Blocks::.
--
--`int vasprintf (char **PTR, const char *TEMPLATE, va_list AP)'
-- `stdio.h' (GNU): *Note Variable Arguments Output::.
--
--`void va_start (va_list AP)'
-- `varargs.h' (Unix): *Note Old Varargs::.
--
--`void va_start (va_list AP, LAST-REQUIRED)'
-- `stdarg.h' (ISO): *Note Argument Macros::.
--
--`int VDISCARD'
-- `termios.h' (BSD): *Note Other Special::.
--
--`int VDSUSP'
-- `termios.h' (BSD): *Note Signal Characters::.
--
--`int VEOF'
-- `termios.h' (POSIX.1): *Note Editing Characters::.
--
--`int VEOL'
-- `termios.h' (POSIX.1): *Note Editing Characters::.
--
--`int VEOL2'
-- `termios.h' (BSD): *Note Editing Characters::.
--
--`int VERASE'
-- `termios.h' (POSIX.1): *Note Editing Characters::.
--
--`int versionsort (const void *A, const void *B)'
-- `dirent.h' (GNU): *Note Scanning Directory Content::.
--
--`int versionsort64 (const void *A, const void *B)'
-- `dirent.h' (GNU): *Note Scanning Directory Content::.
--
--`pid_t vfork (void)'
-- `unistd.h' (BSD): *Note Creating a Process::.
--
--`int vfprintf (FILE *STREAM, const char *TEMPLATE, va_list AP)'
-- `stdio.h' (ISO): *Note Variable Arguments Output::.
--
--`int vfscanf (FILE *STREAM, const char *TEMPLATE, va_list AP)'
-- `stdio.h' (GNU): *Note Variable Arguments Input::.
--
--`int VINTR'
-- `termios.h' (POSIX.1): *Note Signal Characters::.
--
--`int VKILL'
-- `termios.h' (POSIX.1): *Note Editing Characters::.
--
--`int VLNEXT'
-- `termios.h' (BSD): *Note Other Special::.
--
--`int VMIN'
-- `termios.h' (POSIX.1): *Note Noncanonical Input::.
--
--`int vprintf (const char *TEMPLATE, va_list AP)'
-- `stdio.h' (ISO): *Note Variable Arguments Output::.
--
--`int VQUIT'
-- `termios.h' (POSIX.1): *Note Signal Characters::.
--
--`int VREPRINT'
-- `termios.h' (BSD): *Note Editing Characters::.
--
--`int vscanf (const char *TEMPLATE, va_list AP)'
-- `stdio.h' (GNU): *Note Variable Arguments Input::.
--
--`int vsnprintf (char *S, size_t SIZE, const char *TEMPLATE, va_list AP)'
-- `stdio.h' (GNU): *Note Variable Arguments Output::.
--
--`int vsprintf (char *S, const char *TEMPLATE, va_list AP)'
-- `stdio.h' (ISO): *Note Variable Arguments Output::.
--
--`int vsscanf (const char *S, const char *TEMPLATE, va_list AP)'
-- `stdio.h' (GNU): *Note Variable Arguments Input::.
--
--`int VSTART'
-- `termios.h' (POSIX.1): *Note Start/Stop Characters::.
--
--`int VSTATUS'
-- `termios.h' (BSD): *Note Other Special::.
--
--`int VSTOP'
-- `termios.h' (POSIX.1): *Note Start/Stop Characters::.
--
--`int VSUSP'
-- `termios.h' (POSIX.1): *Note Signal Characters::.
--
--`int VTIME'
-- `termios.h' (POSIX.1): *Note Noncanonical Input::.
--
--`int VWERASE'
-- `termios.h' (BSD): *Note Editing Characters::.
--
--`pid_t wait (int *STATUS-PTR)'
-- `sys/wait.h' (POSIX.1): *Note Process Completion::.
--
--`pid_t wait3 (union wait *STATUS-PTR, int OPTIONS, struct rusage *USAGE)'
-- `sys/wait.h' (BSD): *Note BSD Wait Functions::.
--
--`pid_t wait4 (pid_t PID, int *STATUS-PTR, int OPTIONS, struct rusage *USAGE)'
-- `sys/wait.h' (BSD): *Note Process Completion::.
--
--`pid_t waitpid (pid_t PID, int *STATUS-PTR, int OPTIONS)'
-- `sys/wait.h' (POSIX.1): *Note Process Completion::.
--
--`WCHAR_MAX'
-- `limits.h' (GNU): *Note Range of Type::.
--
--`wint_t WCHAR_MAX'
-- `wchar.h' (ISO): *Note Extended Char Intro::.
--
--`wint_t WCHAR_MIN'
-- `wchar.h' (ISO): *Note Extended Char Intro::.
--
--`wchar_t'
-- `stddef.h' (ISO): *Note Extended Char Intro::.
--
--`int WCOREDUMP (int STATUS)'
-- `sys/wait.h' (BSD): *Note Process Completion Status::.
--
--`size_t wcrtomb (char *restrict S, wchar_t WC, mbstate_t *restrict PS)'
-- `wchar.h' (ISO): *Note Converting a Character::.
--
--`size_t wcsnrtombs (char *restrict DST, const wchar_t **restrict SRC, size_t NWC, size_t LEN, mbstate_t *restrict PS)'
-- `wchar.h' (GNU): *Note Converting Strings::.
--
--`size_t wcsrtombs (char *restrict DST, const wchar_t **restrict SRC, size_t LEN, mbstate_t *restrict PS)'
-- `wchar.h' (ISO): *Note Converting Strings::.
--
--`size_t wcstombs (char *STRING, const wchar_t *WSTRING, size_t SIZE)'
-- `stdlib.h' (ISO): *Note Non-reentrant String Conversion::.
--
--`int wctob (wint_t C)'
-- `wchar.h' (ISO): *Note Converting a Character::.
--
--`int wctomb (char *STRING, wchar_t WCHAR)'
-- `stdlib.h' (ISO): *Note Non-reentrant Character Conversion::.
--
--`wctrans_t wctrans (const char *PROPERTY)'
-- `wctype.h' (ISO): *Note Wide Character Case Conversion::.
--
--`wctrans_t'
-- `wctype.h' (ISO): *Note Wide Character Case Conversion::.
--
--`wctype_t wctype (const char *PROPERTY)'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`wctype_t'
-- `wctype.h' (ISO): *Note Classification of Wide Characters::.
--
--`wint_t WEOF'
-- `wchar.h' (ISO): *Note Extended Char Intro::.
--
--`int WEXITSTATUS (int STATUS)'
-- `sys/wait.h' (POSIX.1): *Note Process Completion Status::.
--
--`int WIFEXITED (int STATUS)'
-- `sys/wait.h' (POSIX.1): *Note Process Completion Status::.
--
--`int WIFSIGNALED (int STATUS)'
-- `sys/wait.h' (POSIX.1): *Note Process Completion Status::.
--
--`int WIFSTOPPED (int STATUS)'
-- `sys/wait.h' (POSIX.1): *Note Process Completion Status::.
--
--`wint_t'
-- `wchar.h' (ISO): *Note Extended Char Intro::.
--
--`int W_OK'
-- `unistd.h' (POSIX.1): *Note Testing File Access::.
--
--`int wordexp (const char *WORDS, wordexp_t *WORD-VECTOR-PTR, int FLAGS)'
-- `wordexp.h' (POSIX.2): *Note Calling Wordexp::.
--
--`wordexp_t'
-- `wordexp.h' (POSIX.2): *Note Calling Wordexp::.
--
--`void wordfree (wordexp_t *WORD-VECTOR-PTR)'
-- `wordexp.h' (POSIX.2): *Note Calling Wordexp::.
--
--`WRDE_APPEND'
-- `wordexp.h' (POSIX.2): *Note Flags for Wordexp::.
--
--`WRDE_BADCHAR'
-- `wordexp.h' (POSIX.2): *Note Calling Wordexp::.
--
--`WRDE_BADVAL'
-- `wordexp.h' (POSIX.2): *Note Calling Wordexp::.
--
--`WRDE_CMDSUB'
-- `wordexp.h' (POSIX.2): *Note Calling Wordexp::.
--
--`WRDE_DOOFFS'
-- `wordexp.h' (POSIX.2): *Note Flags for Wordexp::.
--
--`WRDE_NOCMD'
-- `wordexp.h' (POSIX.2): *Note Flags for Wordexp::.
--
--`WRDE_NOSPACE'
-- `wordexp.h' (POSIX.2): *Note Calling Wordexp::.
--
--`WRDE_REUSE'
-- `wordexp.h' (POSIX.2): *Note Flags for Wordexp::.
--
--`WRDE_SHOWERR'
-- `wordexp.h' (POSIX.2): *Note Flags for Wordexp::.
--
--`WRDE_SYNTAX'
-- `wordexp.h' (POSIX.2): *Note Calling Wordexp::.
--
--`WRDE_UNDEF'
-- `wordexp.h' (POSIX.2): *Note Flags for Wordexp::.
--
--`ssize_t write (int FILEDES, const void *BUFFER, size_t SIZE)'
-- `unistd.h' (POSIX.1): *Note I/O Primitives::.
--
--`int WSTOPSIG (int STATUS)'
-- `sys/wait.h' (POSIX.1): *Note Process Completion Status::.
--
--`int WTERMSIG (int STATUS)'
-- `sys/wait.h' (POSIX.1): *Note Process Completion Status::.
--
--`int X_OK'
-- `unistd.h' (POSIX.1): *Note Testing File Access::.
--
--`_XOPEN_SOURCE'
-- (X/Open): *Note Feature Test Macros::.
--
--`_XOPEN_SOURCE_EXTENDED'
-- (X/Open): *Note Feature Test Macros::.
--
--`double y0 (double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float y0f (float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double y0l (long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`double y1 (double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float y1f (float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double y1l (long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`double yn (int n, double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`float ynf (int n, float X)'
-- `math.h' (SVID): *Note Special Functions::.
--
--`long double ynl (int n, long double X)'
-- `math.h' (SVID): *Note Special Functions::.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-46 glibc-2.1.3/manual/libc.info-46
---- ../glibc-2.1.3/manual/libc.info-46 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-46 1969-12-31 16:00:00.000000000 -0800
-@@ -1,986 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Installation, Next: Maintenance, Prev: Library Summary, Up: Top
--
--Installing the GNU C Library
--****************************
--
-- Before you do anything else, you should read the file `FAQ' found at
--the top level of the source tree. This file answers common questions
--and describes problems you may experience with compilation and
--installation. It is updated more frequently than this manual.
--
-- Features can be added to GNU Libc via "add-on" bundles. These are
--separate tarfiles which you unpack into the top level of the source
--tree. Then you give `configure' the `--enable-add-ons' option to
--activate them, and they will be compiled into the library. As of the
--2.1 release, two important components of glibc are distributed as
--"official" add-ons. Unless you are doing an unusual installation, you
--should get them both.
--
-- Support for POSIX threads is maintained by someone else, so it's in a
--separate package. It is only available for Linux systems, but this will
--change in the future. Get it from the same place you got the main
--bundle; the file is `glibc-linuxthreads-VERSION.tar.gz'. Support for
--the `crypt' function is distributed separately because of United States
--export restrictions. If you are outside the US or Canada, you must get
--`crypt' support from a site outside the US, such as `ftp.gwdg.de'.
--`ftp.gwdg.de' has the crypt distribution in `pub/linux/glibc'. (Most
--non-US mirrors of `ftp.gnu.org' will have it too.) The file you need
--is `glibc-crypt-VERSION.tar.gz'.
--
-- You will need recent versions of several GNU tools: definitely GCC
--and GNU Make, and possibly others. *Note Tools for Compilation::,
--below.
--
--* Menu:
--
--* Configuring and compiling:: How to compile and test GNU libc.
--* Running make install:: How to install it once you've got it compiled.
--* Tools for Compilation:: You'll need these first.
--* Supported Configurations:: What it runs on, what it doesn't.
--* Linux:: Specific advice for Linux systems.
--* Reporting Bugs:: So they'll get fixed.
--
--
--File: libc.info, Node: Configuring and compiling, Next: Running make install, Up: Installation
--
--Configuring and compiling GNU Libc
--==================================
--
-- GNU Libc can be compiled in the source directory but we'd advise to
--build in a separate build directory. For example, if you have unpacked
--the glibc sources in `/src/gnu/glibc-2.1.0', create a directory
--`/src/gnu/glibc-build' to put the object files in.
--
-- From your object directory, run the shell script `configure' found
--at the top level of the source tree. In the scenario above, you'd type
--
-- $ ../glibc-2.1.0/configure ARGS...
--
-- Please note that even if you're building in a separate build
--directory, the compiliation needs to modify a few files in the source
--directory, especially some files in the manual subdirectory.
--
--`configure' takes many options, but you can get away with knowing only
--two: `--prefix' and `--enable-add-ons'. The `--prefix' option tells
--configure where you want glibc installed. This defaults to
--`/usr/local'. The `--enable-add-ons' option tells configure to use all
--the add-on bundles it finds in the source directory. Since important
--functionality is provided in add-ons, you should always give this
--option.
--
-- It may also be useful to set the CC and CFLAGS variables in the
--environment when running `configure'. CC selects the C compiler that
--will be used, and CFLAGS sets optimization options for the compiler.
--
-- Here are all the useful options known by `configure':
--
--`--prefix=DIRECTORY'
-- Install machine-independent data files in subdirectories of
-- `DIRECTORY'. The default is to install in `/usr/local'.
--
--`--exec-prefix=DIRECTORY'
-- Install the library and other machine-dependent files in
-- subdirectories of `DIRECTORY'. The default is to the `--prefix'
-- directory if that option is given, or `/usr/local' otherwise.
--
--`--with-headers=DIRECTORY'
-- Look for kernel header files in DIRECTORY, not `/usr/include'.
-- Glibc needs information from the kernel's private header files.
-- It will normally look in `/usr/include' for them, but if you give
-- this option, it will look in DIRECTORY instead.
--
-- This option is primarily of use on a system where the headers in
-- `/usr/include' come from an older version of glibc. Conflicts can
-- occasionally happen in this case. Note that Linux libc5 qualifies
-- as an older version of glibc. You can also use this option if you
-- want to compile glibc with a newer set of kernel headers than the
-- ones found in `/usr/include'.
--
--`--enable-add-ons[=LIST]'
-- Enable add-on packages in your source tree. If this option is
-- given with no list, it enables all the add-on packages it finds.
-- If you do not wish to use some add-on package that you have
-- present in your source tree, give this option a list of the
-- add-ons that you *do* want used, like this:
-- `--enable-add-ons=crypt,linuxthreads'
--
--`--with-binutils=DIRECTORY'
-- Use the binutils (assembler and linker) in `DIRECTORY', not the
-- ones the C compiler would default to. You could use this option if
-- the default binutils on your system cannot deal with all the
-- constructs in the GNU C library. (`configure' will detect the
-- problem and suppress these constructs, so the library will still
-- be usable, but functionality may be lost--for example, you can not
-- build a shared libc with old binutils.)
--
--`--without-fp'
-- Use this option if your computer lacks hardware floating-point
-- support and your operating system does not emulate an FPU.
--
--`--disable-shared'
-- Don't build shared libraries even if we could. Not all systems
-- support shared libraries; you need ELF support and (currently) the
-- GNU linker.
--
--`--disable-profile'
-- Don't build libraries with profiling information. You may want to
-- use this option if you don't plan to do profiling.
--
--`--enable-omitfp'
-- Use maximum optimization for the normal (static and shared)
-- libraries, and compile separate static libraries with debugging
-- information and no optimisation. We recommend against this. The
-- extra optimization doesn't gain you much, it may provoke compiler
-- bugs, and you won't be able to trace bugs through the C library.
--
--`--disable-versioning'
-- Don't compile the shared libraries with symbol version information.
-- Doing this will make the library that's built incompatible with old
-- binaries, so it's not recommended.
--
--`--enable-static-nss'
-- Compile static versions of the NSS (Name Service Switch) libraries.
-- This is not recommended because it defeats the purpose of NSS; a
-- program linked statically with the NSS libraries cannot be
-- dynamically reconfigured to use a different name database.
--
--`--build=BUILD-SYSTEM'
--`--host=HOST-SYSTEM'
-- These options are for cross-compiling. If you give them both and
-- BUILD-SYSTEM is different from HOST-SYSTEM, `configure' will
-- prepare to cross-compile glibc from BUILD-SYSTEM to be used on
-- HOST-SYSTEM. You'll probably need the `--with-headers' option
-- too, and you may have to override CONFIGURE's selection of the
-- compiler and/or binutils.
--
-- If you give just `--host', configure will prepare for a native
-- compile but use what you say instead of guessing what your system
-- is. This is most useful to change the CPU submodel. For example,
-- if configure guesses your machine as `i586-pc-linux-gnu' but you
-- want to compile a library for 386es, give
-- `--host=i386-pc-linux-gnu' or just `--host=i386-linux' and add the
-- appropriate compiler flags (`-mcpu=i386' will do the trick) to
-- CFLAGS.
--
-- If you give just `--build', configure will get confused.
--
-- To build the library and related programs, type `make'. This will
--produce a lot of output, some of which may look like errors from `make'
--but isn't. Look for error messages from `make' containing `***'.
--Those indicate that something is really wrong.
--
-- The compilation process takes several hours even on fast hardware.
--Expect at least two hours for the default configuration on i586 for
--Linux. For Hurd times are much longer. Except for EGCS 1.1 and GCC
--2.95 (and later versions of GCC), all supported versions of GCC have a
--problem which causes them to take several minutes to compile certain
--files in the iconvdata directory. Do not panic if the compiler appears
--to hang.
--
-- If you want to run a parallel make, you can't just give `make' the
--`-j' option, because it won't be passed down to the sub-makes.
--Instead, edit the generated `Makefile' and uncomment the line
--
-- # PARALLELMFLAGS = -j 4
--
--You can change the `4' to some other number as appropriate for your
--system. Instead of changing the `Makefile', you could give this option
--directly to `make' and call it as, e.g. `make PARALLELMFLAGS=-j4'. If
--you're building in the source directory, you've got to use the latter
--approach since in this case no new `Makefile' is generated which you
--can change.
--
-- To build and run some test programs which exercise some of the
--library facilities, type `make check'. This should complete
--successfully; if it doesn't, do not use the built library, and report a
--bug. *Note Reporting Bugs::, for how to do that. Note that some of
--the tests assume they are not being run by `root'. We recommend you
--compile and test glibc as an unprivileged user.
--
-- To format the `GNU C Library Reference Manual' for printing, type
--`make dvi'. You need a working TeX installation to do this. The
--distribution already includes the on-line formatted version of the
--manual, as Info files. You can regenerate those with `make info', but
--it shouldn't be necessary.
--
--
--File: libc.info, Node: Running make install, Next: Tools for Compilation, Prev: Configuring and compiling, Up: Installation
--
--Installing the C Library
--========================
--
-- To install the library and its header files, and the Info files of
--the manual, type `make install'. This will build things if necessary,
--before installing them. Don't rely on that; compile everything first.
--If you are installing glibc as your primary C library, we recommend you
--shut the system down to single-user mode first, and reboot afterward.
--This minimizes the risk of breaking things when the library changes out
--from underneath.
--
-- If you are upgrading from a previous installation of glibc 2.0 or
--2.1, `make install' will do the entire job. If you're upgrading from
--Linux libc5 or some other C library, you need to rename the old
--`/usr/include' directory out of the way before running `make install',
--or you will end up with a mixture of header files from both libraries,
--and you won't be able to compile anything. You may also need to
--reconfigure GCC to work with the new library. The easiest way to do
--that is to figure out the compiler switches to make it work again
--(`-Wl,--dynamic-linker=/lib/ld-linux.so.2' should work on Linux
--systems) and use them to recompile gcc. You can also edit the specs
--file (`/usr/lib/gcc-lib/TARGET/VERSION/specs'), but that is a bit of a
--black art.
--
-- You can install glibc somewhere other than where you configured it
--to go by setting the `install_root' variable on the command line for
--`make install'. The value of this variable is prepended to all the
--paths for installation. This is useful when setting up a chroot
--environment or preparing a binary distribution. The directory should be
--specified with an absolute file name.
--
-- Glibc 2.1 includes two daemons, `nscd' and `utmpd', which you may or
--may not want to run. `nscd' caches name service lookups; it can
--dramatically improve performance with NIS+, and may help with DNS as
--well. `utmpd' allows programs that use the old format for the `utmp'
--file to coexist with new programs. For more information see the file
--`login/README.utmpd'.
--
-- One auxiliary program, `/usr/libexec/pt_chown', is installed setuid
--`root'. This program is invoked by the `grantpt' function; it sets the
--permissions on a pseudoterminal so it can be used by the calling
--process. This means programs like `xterm' and `screen' do not have to
--be setuid to get a pty. (There may be other reasons why they need
--privileges.) If you are using a 2.1 or newer Linux kernel with the
--`devptsfs' or `devfs' filesystems providing pty slaves, you don't need
--this program; otherwise you do. The source for `pt_chown' is in
--`login/programs/pt_chown.c'.
--
-- After installation you might want to configure the timezone and
--locale installation of your system. The GNU C library comes with a
--locale database which gets configured with `localedef'. For example, to
--set up a German locale with name `de_DE', simply issue the command
--`localedef -i de_DE -f ISO-8859-1 de_DE'. To configure all locales
--that are supported by glibc, you can issue from your build directory the
--command `make localedata/install-locales'.
--
-- To configure the locally used timezone, you can either set the `TZ'
--environment variable. The script `tzselect' helps you to select the
--right value. As an example for Germany, tzselect would tell you to use
--`TZ='Europe/Berlin''. For a system wide installation (the given paths
--are for an installation with `--prefix=/usr'), link the timezone file
--which is in `/usr/share/zoneinfo' to the file `/etc/localtime'. For
--Germany, you might execute `ln -s /usr/share/zoneinfo/Europe/Berlin
--/etc/localtime'.
--
--
--File: libc.info, Node: Tools for Compilation, Next: Supported Configurations, Prev: Running make install, Up: Installation
--
--Recommended Tools for Compilation
--=================================
--
-- We recommend installing the following GNU tools before attempting to
--build the GNU C library:
--
-- * GNU `make' 3.75
--
-- You need the latest version of GNU `make'. Modifying the GNU C
-- Library to work with other `make' programs would be so hard that we
-- recommend you port GNU `make' instead. *Really.* We recommend
-- version GNU `make' version 3.75 or 3.77. All earlier versions
-- have severe bugs or lack features. Version 3.76 is known to have
-- bugs which only show up in big projects like GNU `libc'. Version
-- 3.76.1 seems OK but some people have reported problems.
--
-- * EGCS 1.1.1, 1.1 or 1.0.3, or GCC 2.8.1, 2.95, 2.95.1
--
-- The GNU C library can only be compiled with the GNU C compiler
-- family. As of the 2.1 release, EGCS 1.0.3 or higher is required.
-- GCC 2.8.1 can also be used (but see the FAQ for reasons why you
-- might not want to). Earlier versions simply are too buggy. As of
-- this writing, GCC 2.95.1 is the compiler we advise to use.
--
-- You can use whatever compiler you like to compile programs that
-- use GNU libc, but be aware that both GCC 2.7 and 2.8 have bugs in
-- their floating-point support that may be triggered by the math
-- library.
--
-- On Alpha machines you need at least EGCS 1.1.1. Earlier versions
-- don't work reliably.
--
-- For PPC you might need some patches even on top of the last EGCS
-- version. See the FAQ.
--
-- * GNU `binutils' 2.9.1, 2.9.1.0.16, or later 2.9.1.0.x release
--
-- You must use GNU binutils (as and ld) if you want to build a shared
-- library. Even if you don't, we recommend you use them anyway. No
-- one has tested compilation with non-GNU binutils in a long time.
--
-- The quality of binutils releases has varied a bit recently. The
-- bugs are in obscure features, but glibc uses quite a few of those.
-- 2.9.1, 2.9.1.0.16, and later 2.9.1.0.x releases are known to
-- work. Versions after 2.8.1.0.23 may or may not work. Older
-- versions definitely don't. 2.9.1.0.16 or higher is required on
-- some platforms, like PPC and Arm.
--
-- For PPC you might need some patches even on top of the last
-- binutils version. See the FAQ.
--
-- * GNU `texinfo' 3.12f
--
-- To correctly translate and install the Texinfo documentation you
-- need this version of the `texinfo' package. Earlier versions do
-- not understand all the tags used in the document, and the
-- installation mechanism for the info files is not present or works
-- differently.
--
-- * GNU `awk' 3.0, or some other POSIX awk
--
-- Awk is used in several places to generate files. The scripts
-- should work with any POSIX-compliant awk implementation; `gawk'
-- 3.0 and `mawk' 1.3 are known to work.
--
-- * Perl 5
--
-- Perl is not required, but it is used if present to test the
-- installation. We may decide to use it elsewhere in the future.
--
--If you change any of the `configure.in' files you will also need
--
-- * GNU `autoconf' 2.12 or higher
--
--and if you change any of the message translation files you will need
--
-- * GNU `gettext' 0.10.35 or later (version 0.10.35 is a alpha release
-- and available via ftp from alpha.gnu.org/gnu)
--
--You may also need these packages if you upgrade your source tree using
--patches, although we try to avoid this.
--
--
--File: libc.info, Node: Supported Configurations, Next: Linux, Prev: Tools for Compilation, Up: Installation
--
--Supported Configurations
--========================
--
-- The GNU C Library currently supports configurations that match the
--following patterns:
--
-- alpha-*-linux
-- arm-*-linux
-- arm-*-linuxaout
-- arm-*-none
-- iX86-*-gnu
-- iX86-*-linux
-- m68k-*-linux
-- powerpc-*-linux
-- sparc-*-linux
-- sparc64-*-linux
--
-- Former releases of this library (version 1.09.1 and perhaps earlier
--versions) used to run on the following configurations:
--
-- alpha-dec-osf1
-- alpha-*-linuxecoff
-- iX86-*-bsd4.3
-- iX86-*-isc2.2
-- iX86-*-isc3.N
-- iX86-*-sco3.2
-- iX86-*-sco3.2v4
-- iX86-*-sysv
-- iX86-*-sysv4
-- iX86-force_cpu386-none
-- iX86-sequent-bsd
-- i960-nindy960-none
-- m68k-hp-bsd4.3
-- m68k-mvme135-none
-- m68k-mvme136-none
-- m68k-sony-newsos3
-- m68k-sony-newsos4
-- m68k-sun-sunos4.N
-- mips-dec-ultrix4.N
-- mips-sgi-irix4.N
-- sparc-sun-solaris2.N
-- sparc-sun-sunos4.N
--
-- Since no one has volunteered to test and fix these configurations,
--they are not supported at the moment. They probably don't compile;
--they definitely don't work anymore. Porting the library is not hard.
--If you are interested in doing a port, please contact the glibc
--maintainers by sending electronic mail to <bug-glibc@gnu.org>.
--
-- Each case of `iX86' can be `i386', `i486', `i586', or `i686'. All
--of those configurations produce a library that can run on this
--processor and newer processors. The GCC compiler by default generates
--code that's optimized for the machine it's configured for and will use
--the instructions available on that machine. For example if your GCC is
--configured for `i686', gcc will optimize for `i686' and might issue
--some `i686' specific instructions. To generate code for other models,
--you have to configure for that model and give GCC the appropriate
--`-march=' and `-mcpu=' compiler switches via CFLAGS.
--
--
--File: libc.info, Node: Linux, Next: Reporting Bugs, Prev: Supported Configurations, Up: Installation
--
--Specific advice for Linux systems
--=================================
--
-- If you are installing GNU libc on a Linux system, you need to have
--the header files from a 2.2 kernel around for reference. You do not
--need to use the 2.2 kernel, just have its headers where glibc can get
--at them. The easiest way to do this is to unpack it in a directory
--such as `/usr/src/linux-2.2.1'. In that directory, run `make config'
--and accept all the defaults. Then run `make include/linux/version.h'.
--Finally, configure glibc with the option
--`--with-headers=/usr/src/linux-2.2.1/include'. Use the most recent
--kernel you can get your hands on.
--
-- An alternate tactic is to unpack the 2.2 kernel and run `make
--config' as above. Then rename or delete `/usr/include', create a new
--`/usr/include', and make the usual symbolic links of
--`/usr/include/linux' and `/usr/include/asm' into the 2.2 kernel
--sources. You can then configure glibc with no special options. This
--tactic is recommended if you are upgrading from libc5, since you need
--to get rid of the old header files anyway.
--
-- Note that `/usr/include/net' and `/usr/include/scsi' should *not* be
--symlinks into the kernel sources. GNU libc provides its own versions
--of these files.
--
-- Linux expects some components of the libc installation to be in
--`/lib' and some in `/usr/lib'. This is handled automatically if you
--configure glibc with `--prefix=/usr'. If you set some other prefix or
--allow it to default to `/usr/local', then all the components are
--installed there.
--
-- If you are upgrading from libc5, you need to recompile every shared
--library on your system against the new library for the sake of new code,
--but keep the old libraries around for old binaries to use. This is
--complicated and difficult. Consult the Glibc2 HOWTO at
--`http://www.imaxx.net/~thrytis/glibc' for details.
--
-- You cannot use `nscd' with 2.0 kernels, due to bugs in the
--kernel-side thread support. `nscd' happens to hit these bugs
--particularly hard, but you might have problems with any threaded
--program.
--
--
--File: libc.info, Node: Reporting Bugs, Prev: Linux, Up: Installation
--
--Reporting Bugs
--==============
--
-- There are probably bugs in the GNU C library. There are certainly
--errors and omissions in this manual. If you report them, they will get
--fixed. If you don't, no one will ever know about them and they will
--remain unfixed for all eternity, if not longer.
--
-- It is a good idea to check first that the problem was not reported
--before. Bugs are documented in two places: The file `BUGS' describes a
--number of well known bugs and the bug tracking system has a WWW
--interface at `http://www-gnats.gnu.org:8080/cgi-bin/wwwgnats.pl'. The
--WWW interface gives you access to open and closed reports. The closed
--reports normally include a patch or a hint on solving the problem.
--
-- To report a bug, first you must find it. Hopefully, this will be the
--hard part. Once you've found a bug, make sure it's really a bug. A
--good way to do this is to see if the GNU C library behaves the same way
--some other C library does. If so, probably you are wrong and the
--libraries are right (but not necessarily). If not, one of the libraries
--is probably wrong. It might not be the GNU library. Many historical
--Unix C libraries permit things that we don't, such as closing a file
--twice.
--
-- If you think you have found some way in which the GNU C library does
--not conform to the ISO and POSIX standards (*note Standards and
--Portability::.), that is definitely a bug. Report it!
--
-- Once you're sure you've found a bug, try to narrow it down to the
--smallest test case that reproduces the problem. In the case of a C
--library, you really only need to narrow it down to one library function
--call, if possible. This should not be too difficult.
--
-- The final step when you have a simple test case is to report the bug.
--Do this using the `glibcbug' script. It is installed with libc, or if
--you haven't installed it, will be in your build directory. Send your
--test case, the results you got, the results you expected, and what you
--think the problem might be (if you've thought of anything). `glibcbug'
--will insert the configuration information we need to see, and ship the
--report off to <bugs@gnu.org>. Don't send a message there directly; it
--is fed to a program that expects mail to be formatted in a particular
--way. Use the script.
--
-- If you are not sure how a function should behave, and this manual
--doesn't tell you, that's a bug in the manual. Report that too! If the
--function's behavior disagrees with the manual, then either the library
--or the manual has a bug, so report the disagreement. If you find any
--errors or omissions in this manual, please report them to the Internet
--address <bug-glibc-manual@gnu.org>. If you refer to specific sections
--when reporting on the manual, please include the section names for
--easier identification.
--
--
--File: libc.info, Node: Maintenance, Next: Contributors, Prev: Installation, Up: Top
--
--Library Maintenance
--*******************
--
--* Menu:
--
--* Source Layout:: How to add new functions or header files
-- to the GNU C library.
--* Porting:: How to port the GNU C library to
-- a new machine or operating system.
--
--
--File: libc.info, Node: Source Layout, Next: Porting, Up: Maintenance
--
--Adding New Functions
--====================
--
-- The process of building the library is driven by the makefiles, which
--make heavy use of special features of GNU `make'. The makefiles are
--very complex, and you probably don't want to try to understand them.
--But what they do is fairly straightforward, and only requires that you
--define a few variables in the right places.
--
-- The library sources are divided into subdirectories, grouped by
--topic.
--
-- The `string' subdirectory has all the string-manipulation functions,
--`math' has all the mathematical functions, etc.
--
-- Each subdirectory contains a simple makefile, called `Makefile',
--which defines a few `make' variables and then includes the global
--makefile `Rules' with a line like:
--
-- include ../Rules
--
--The basic variables that a subdirectory makefile defines are:
--
--`subdir'
-- The name of the subdirectory, for example `stdio'. This variable
-- *must* be defined.
--
--`headers'
-- The names of the header files in this section of the library, such
-- as `stdio.h'.
--
--`routines'
--`aux'
-- The names of the modules (source files) in this section of the
-- library. These should be simple names, such as `strlen' (rather
-- than complete file names, such as `strlen.c'). Use `routines' for
-- modules that define functions in the library, and `aux' for
-- auxiliary modules containing things like data definitions. But the
-- values of `routines' and `aux' are just concatenated, so there
-- really is no practical difference.
--
--`tests'
-- The names of test programs for this section of the library. These
-- should be simple names, such as `tester' (rather than complete file
-- names, such as `tester.c'). `make tests' will build and run all
-- the test programs. If a test program needs input, put the test
-- data in a file called `TEST-PROGRAM.input'; it will be given to
-- the test program on its standard input. If a test program wants
-- to be run with arguments, put the arguments (all on a single line)
-- in a file called `TEST-PROGRAM.args'. Test programs should exit
-- with zero status when the test passes, and nonzero status when the
-- test indicates a bug in the library or error in building.
--
--`others'
-- The names of "other" programs associated with this section of the
-- library. These are programs which are not tests per se, but are
-- other small programs included with the library. They are built by
-- `make others'.
--
--`install-lib'
--`install-data'
--`install'
-- Files to be installed by `make install'. Files listed in
-- `install-lib' are installed in the directory specified by `libdir'
-- in `configparms' or `Makeconfig' (*note Installation::.). Files
-- listed in `install-data' are installed in the directory specified
-- by `datadir' in `configparms' or `Makeconfig'. Files listed in
-- `install' are installed in the directory specified by `bindir' in
-- `configparms' or `Makeconfig'.
--
--`distribute'
-- Other files from this subdirectory which should be put into a
-- distribution tar file. You need not list here the makefile itself
-- or the source and header files listed in the other standard
-- variables. Only define `distribute' if there are files used in an
-- unusual way that should go into the distribution.
--
--`generated'
-- Files which are generated by `Makefile' in this subdirectory.
-- These files will be removed by `make clean', and they will never
-- go into a distribution.
--
--`extra-objs'
-- Extra object files which are built by `Makefile' in this
-- subdirectory. This should be a list of file names like `foo.o';
-- the files will actually be found in whatever directory object
-- files are being built in. These files will be removed by
-- `make clean'. This variable is used for secondary object files
-- needed to build `others' or `tests'.
--
--
--File: libc.info, Node: Porting, Prev: Source Layout, Up: Maintenance
--
--Porting the GNU C Library
--=========================
--
-- The GNU C library is written to be easily portable to a variety of
--machines and operating systems. Machine- and operating system-dependent
--functions are well separated to make it easy to add implementations for
--new machines or operating systems. This section describes the layout of
--the library source tree and explains the mechanisms used to select
--machine-dependent code to use.
--
-- All the machine-dependent and operating system-dependent files in the
--library are in the subdirectory `sysdeps' under the top-level library
--source directory. This directory contains a hierarchy of
--subdirectories (*note Hierarchy Conventions::.).
--
-- Each subdirectory of `sysdeps' contains source files for a
--particular machine or operating system, or for a class of machine or
--operating system (for example, systems by a particular vendor, or all
--machines that use IEEE 754 floating-point format). A configuration
--specifies an ordered list of these subdirectories. Each subdirectory
--implicitly appends its parent directory to the list. For example,
--specifying the list `unix/bsd/vax' is equivalent to specifying the list
--`unix/bsd/vax unix/bsd unix'. A subdirectory can also specify that it
--implies other subdirectories which are not directly above it in the
--directory hierarchy. If the file `Implies' exists in a subdirectory,
--it lists other subdirectories of `sysdeps' which are appended to the
--list, appearing after the subdirectory containing the `Implies' file.
--Lines in an `Implies' file that begin with a `#' character are ignored
--as comments. For example, `unix/bsd/Implies' contains:
-- # BSD has Internet-related things.
-- unix/inet
--
--and `unix/Implies' contains:
-- posix
--
--So the final list is `unix/bsd/vax unix/bsd unix/inet unix posix'.
--
-- `sysdeps' has a "special" subdirectory called `generic'. It is
--always implicitly appended to the list of subdirectories, so you
--needn't put it in an `Implies' file, and you should not create any
--subdirectories under it intended to be new specific categories.
--`generic' serves two purposes. First, the makefiles do not bother to
--look for a system-dependent version of a file that's not in `generic'.
--This means that any system-dependent source file must have an analogue
--in `generic', even if the routines defined by that file are not
--implemented on other platforms. Second. the `generic' version of a
--system-dependent file is used if the makefiles do not find a version
--specific to the system you're compiling for.
--
-- If it is possible to implement the routines in a `generic' file in
--machine-independent C, using only other machine-independent functions in
--the C library, then you should do so. Otherwise, make them stubs. A
--"stub" function is a function which cannot be implemented on a
--particular machine or operating system. Stub functions always return an
--error, and set `errno' to `ENOSYS' (Function not implemented). *Note
--Error Reporting::. If you define a stub function, you must place the
--statement `stub_warning(FUNCTION)', where FUNCTION is the name of your
--function, after its definition; also, you must include the file
--`<stub-tag.h>' into your file. This causes the function to be listed
--in the installed `<gnu/stubs.h>', and makes GNU ld warn when the
--function is used.
--
-- Some rare functions are only useful on specific systems and aren't
--defined at all on others; these do not appear anywhere in the
--system-independent source code or makefiles (including the `generic'
--directory), only in the system-dependent `Makefile' in the specific
--system's subdirectory.
--
-- If you come across a file that is in one of the main source
--directories (`string', `stdio', etc.), and you want to write a machine-
--or operating system-dependent version of it, move the file into
--`sysdeps/generic' and write your new implementation in the appropriate
--system-specific subdirectory. Note that if a file is to be
--system-dependent, it *must not* appear in one of the main source
--directories.
--
-- There are a few special files that may exist in each subdirectory of
--`sysdeps':
--
--`Makefile'
-- A makefile for this machine or operating system, or class of
-- machine or operating system. This file is included by the library
-- makefile `Makerules', which is used by the top-level makefile and
-- the subdirectory makefiles. It can change the variables set in the
-- including makefile or add new rules. It can use GNU `make'
-- conditional directives based on the variable `subdir' (see above)
-- to select different sets of variables and rules for different
-- sections of the library. It can also set the `make' variable
-- `sysdep-routines', to specify extra modules to be included in the
-- library. You should use `sysdep-routines' rather than adding
-- modules to `routines' because the latter is used in determining
-- what to distribute for each subdirectory of the main source tree.
--
-- Each makefile in a subdirectory in the ordered list of
-- subdirectories to be searched is included in order. Since several
-- system-dependent makefiles may be included, each should append to
-- `sysdep-routines' rather than simply setting it:
--
-- sysdep-routines := $(sysdep-routines) foo bar
--
--`Subdirs'
-- This file contains the names of new whole subdirectories under the
-- top-level library source tree that should be included for this
-- system. These subdirectories are treated just like the
-- system-independent subdirectories in the library source tree, such
-- as `stdio' and `math'.
--
-- Use this when there are completely new sets of functions and header
-- files that should go into the library for the system this
-- subdirectory of `sysdeps' implements. For example,
-- `sysdeps/unix/inet/Subdirs' contains `inet'; the `inet' directory
-- contains various network-oriented operations which only make sense
-- to put in the library on systems that support the Internet.
--
--`Dist'
-- This file contains the names of files (relative to the
-- subdirectory of `sysdeps' in which it appears) which should be
-- included in the distribution. List any new files used by rules in
-- the `Makefile' in the same directory, or header files used by the
-- source files in that directory. You don't need to list files that
-- are implementations (either C or assembly source) of routines
-- whose names are given in the machine-independent makefiles in the
-- main source tree.
--
--`configure'
-- This file is a shell script fragment to be run at configuration
-- time. The top-level `configure' script uses the shell `.' command
-- to read the `configure' file in each system-dependent directory
-- chosen, in order. The `configure' files are often generated from
-- `configure.in' files using Autoconf.
--
-- A system-dependent `configure' script will usually add things to
-- the shell variables `DEFS' and `config_vars'; see the top-level
-- `configure' script for details. The script can check for
-- `--with-PACKAGE' options that were passed to the top-level
-- `configure'. For an option `--with-PACKAGE=VALUE' `configure'
-- sets the shell variable `with_PACKAGE' (with any dashes in PACKAGE
-- converted to underscores) to VALUE; if the option is just
-- `--with-PACKAGE' (no argument), then it sets `with_PACKAGE' to
-- `yes'.
--
--`configure.in'
-- This file is an Autoconf input fragment to be processed into the
-- file `configure' in this subdirectory. *Note Introduction:
-- (autoconf.info)Introduction, for a description of Autoconf. You
-- should write either `configure' or `configure.in', but not both.
-- The first line of `configure.in' should invoke the `m4' macro
-- `GLIBC_PROVIDES'. This macro does several `AC_PROVIDE' calls for
-- Autoconf macros which are used by the top-level `configure'
-- script; without this, those macros might be invoked again
-- unnecessarily by Autoconf.
--
-- That is the general system for how system-dependencies are isolated.
--
--* Menu:
--
--* Hierarchy Conventions:: The layout of the `sysdeps' hierarchy.
--* Porting to Unix:: Porting the library to an average
-- Unix-like system.
--
--
--File: libc.info, Node: Hierarchy Conventions, Next: Porting to Unix, Up: Porting
--
--Layout of the `sysdeps' Directory Hierarchy
---------------------------------------------
--
-- A GNU configuration name has three parts: the CPU type, the
--manufacturer's name, and the operating system. `configure' uses these
--to pick the list of system-dependent directories to look for. If the
--`--nfp' option is *not* passed to `configure', the directory
--`MACHINE/fpu' is also used. The operating system often has a "base
--operating system"; for example, if the operating system is `Linux', the
--base operating system is `unix/sysv'. The algorithm used to pick the
--list of directories is simple: `configure' makes a list of the base
--operating system, manufacturer, CPU type, and operating system, in that
--order. It then concatenates all these together with slashes in
--between, to produce a directory name; for example, the configuration
--`i686-linux-gnu' results in `unix/sysv/linux/i386/i686'. `configure'
--then tries removing each element of the list in turn, so
--`unix/sysv/linux' and `unix/sysv' are also tried, among others. Since
--the precise version number of the operating system is often not
--important, and it would be very inconvenient, for example, to have
--identical `irix6.2' and `irix6.3' directories, `configure' tries
--successively less specific operating system names by removing trailing
--suffixes starting with a period.
--
-- As an example, here is the complete list of directories that would be
--tried for the configuration `i686-linux-gnu' (with the `crypt' and
--`linuxthreads' add-on):
--
-- sysdeps/i386/elf
-- crypt/sysdeps/unix
-- linuxthreads/sysdeps/unix/sysv/linux
-- linuxthreads/sysdeps/pthread
-- linuxthreads/sysdeps/unix/sysv
-- linuxthreads/sysdeps/unix
-- linuxthreads/sysdeps/i386/i686
-- linuxthreads/sysdeps/i386
-- linuxthreads/sysdeps/pthread/no-cmpxchg
-- sysdeps/unix/sysv/linux/i386
-- sysdeps/unix/sysv/linux
-- sysdeps/gnu
-- sysdeps/unix/common
-- sysdeps/unix/mman
-- sysdeps/unix/inet
-- sysdeps/unix/sysv/i386/i686
-- sysdeps/unix/sysv/i386
-- sysdeps/unix/sysv
-- sysdeps/unix/i386
-- sysdeps/unix
-- sysdeps/posix
-- sysdeps/i386/i686
-- sysdeps/i386/i486
-- sysdeps/libm-i387/i686
-- sysdeps/i386/fpu
-- sysdeps/libm-i387
-- sysdeps/i386
-- sysdeps/wordsize-32
-- sysdeps/ieee754
-- sysdeps/libm-ieee754
-- sysdeps/generic
--
-- Different machine architectures are conventionally subdirectories at
--the top level of the `sysdeps' directory tree. For example,
--`sysdeps/sparc' and `sysdeps/m68k'. These contain files specific to
--those machine architectures, but not specific to any particular
--operating system. There might be subdirectories for specializations of
--those architectures, such as `sysdeps/m68k/68020'. Code which is
--specific to the floating-point coprocessor used with a particular
--machine should go in `sysdeps/MACHINE/fpu'.
--
-- There are a few directories at the top level of the `sysdeps'
--hierarchy that are not for particular machine architectures.
--
--`generic'
-- As described above (*note Porting::.), this is the subdirectory
-- that every configuration implicitly uses after all others.
--
--`ieee754'
-- This directory is for code using the IEEE 754 floating-point
-- format, where the C type `float' is IEEE 754 single-precision
-- format, and `double' is IEEE 754 double-precision format. Usually
-- this directory is referred to in the `Implies' file in a machine
-- architecture-specific directory, such as `m68k/Implies'.
--
--`libm-ieee754'
-- This directory contains an implementation of a mathematical library
-- usable on platforms which use IEEE 754 conformant floating-point
-- arithmetic.
--
--`libm-i387'
-- This is a special case. Ideally the code should be in
-- `sysdeps/i386/fpu' but for various reasons it is kept aside.
--
--`posix'
-- This directory contains implementations of things in the library in
-- terms of POSIX.1 functions. This includes some of the POSIX.1
-- functions themselves. Of course, POSIX.1 cannot be completely
-- implemented in terms of itself, so a configuration using just
-- `posix' cannot be complete.
--
--`unix'
-- This is the directory for Unix-like things. *Note Porting to
-- Unix::. `unix' implies `posix'. There are some special-purpose
-- subdirectories of `unix':
--
-- `unix/common'
-- This directory is for things common to both BSD and System V
-- release 4. Both `unix/bsd' and `unix/sysv/sysv4' imply
-- `unix/common'.
--
-- `unix/inet'
-- This directory is for `socket' and related functions on Unix
-- systems. `unix/inet/Subdirs' enables the `inet' top-level
-- subdirectory. `unix/common' implies `unix/inet'.
--
--`mach'
-- This is the directory for things based on the Mach microkernel
-- from CMU (including the GNU operating system). Other basic
-- operating systems (VMS, for example) would have their own
-- directories at the top level of the `sysdeps' hierarchy, parallel
-- to `unix' and `mach'.
--
--
--File: libc.info, Node: Porting to Unix, Prev: Hierarchy Conventions, Up: Porting
--
--Porting the GNU C Library to Unix Systems
-------------------------------------------
--
-- Most Unix systems are fundamentally very similar. There are
--variations between different machines, and variations in what
--facilities are provided by the kernel. But the interface to the
--operating system facilities is, for the most part, pretty uniform and
--simple.
--
-- The code for Unix systems is in the directory `unix', at the top
--level of the `sysdeps' hierarchy. This directory contains
--subdirectories (and subdirectory trees) for various Unix variants.
--
-- The functions which are system calls in most Unix systems are
--implemented in assembly code, which is generated automatically from
--specifications in files named `syscalls.list'. There are several such
--files, one in `sysdeps/unix' and others in its subdirectories. Some
--special system calls are implemented in files that are named with a
--suffix of `.S'; for example, `_exit.S'. Files ending in `.S' are run
--through the C preprocessor before being fed to the assembler.
--
-- These files all use a set of macros that should be defined in
--`sysdep.h'. The `sysdep.h' file in `sysdeps/unix' partially defines
--them; a `sysdep.h' file in another directory must finish defining them
--for the particular machine and operating system variant. See
--`sysdeps/unix/sysdep.h' and the machine-specific `sysdep.h'
--implementations to see what these macros are and what they should do.
--
-- The system-specific makefile for the `unix' directory
--(`sysdeps/unix/Makefile') gives rules to generate several files from
--the Unix system you are building the library on (which is assumed to be
--the target system you are building the library *for*). All the
--generated files are put in the directory where the object files are
--kept; they should not affect the source tree itself. The files
--generated are `ioctls.h', `errnos.h', `sys/param.h', and `errlist.c'
--(for the `stdio' section of the library).
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-47 glibc-2.1.3/manual/libc.info-47
---- ../glibc-2.1.3/manual/libc.info-47 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-47 1969-12-31 16:00:00.000000000 -0800
-@@ -1,918 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Contributors, Next: Copying, Prev: Maintenance, Up: Top
--
--Contributors to the GNU C Library
--*********************************
--
-- The GNU C library was written originally by Roland McGrath, and is
--currently maintained by Ulrich Drepper. Some parts of the library were
--contributed or worked on by other people.
--
-- * The `getopt' function and related code were written by Richard
-- Stallman, David J. MacKenzie, and Roland McGrath.
--
-- * The merge sort function `qsort' was written by Michael J. Haertel.
--
-- * The quick sort function used as a fallback by `qsort' was written
-- by Douglas C. Schmidt.
--
-- * The memory allocation functions `malloc', `realloc' and `free' and
-- related code were written by Michael J. Haertel, Wolfram Gloger,
-- and Doug Lea.
--
-- * Fast implementations of many of the string functions (`memcpy',
-- `strlen', etc.) were written by Torbj"orn Granlund.
--
-- * The `tar.h' header file was written by David J. MacKenzie.
--
-- * The port to the MIPS DECStation running Ultrix 4
-- (`mips-dec-ultrix4') was contributed by Brendan Kehoe and Ian
-- Lance Taylor.
--
-- * The DES encryption function `crypt' and related functions were
-- contributed by Michael Glad.
--
-- * The `ftw' and `nftw' functions were contributed by Ulrich Drepper.
--
-- * The startup code to support SunOS shared libraries was contributed
-- by Tom Quinn.
--
-- * The `mktime' function was contributed by Paul Eggert.
--
-- * The port to the Sequent Symmetry running Dynix version 3
-- (`i386-sequent-bsd') was contributed by Jason Merrill.
--
-- * The timezone support code is derived from the public-domain
-- timezone package by Arthur David Olson and his many contributors.
--
-- * The port to the DEC Alpha running OSF/1 (`alpha-dec-osf1') was
-- contributed by Brendan Kehoe, using some code written by Roland
-- McGrath.
--
-- * The port to SGI machines running Irix 4 (`mips-sgi-irix4') was
-- contributed by Tom Quinn.
--
-- * The port of the Mach and Hurd code to the MIPS architecture
-- (`mips-ANYTHING-gnu') was contributed by Kazumoto Kojima.
--
-- * The floating-point printing function used by `printf' and friends
-- and the floating-point reading function used by `scanf', `strtod'
-- and friends were written by Ulrich Drepper. The multi-precision
-- integer functions used in those functions are taken from GNU MP,
-- which was contributed by Torbj"orn Granlund.
--
-- * The internationalization support in the library, and the support
-- programs `locale' and `localedef', were written by Ulrich Drepper.
-- Ulrich Drepper adapted the support code for message catalogs
-- (`libintl.h', etc.) from the GNU `gettext' package, which he also
-- wrote. He also contributed the `catgets' support and the entire
-- suite of multi-byte and wide-character support functions
-- (`wctype.h', `wchar.h', etc.).
--
-- * The implementations of the `nsswitch.conf' mechanism and the files
-- and DNS backends for it were designed and written by Ulrich
-- Drepper and Roland McGrath, based on a backend interface defined
-- by Peter Eriksson.
--
-- * The port to Linux i386/ELF (`i386-ANYTHING-linux') was contributed
-- by Ulrich Drepper, based in large part on work done in Hongjiu
-- Lu's Linux version of the GNU C Library.
--
-- * The port to Linux/m68k (`m68k-ANYTHING-linux') was contributed by
-- Andreas Schwab.
--
-- * The ports to Linux/ARM (`arm-ANYTHING-linuxaout') and ARM
-- standalone (`arm-ANYTHING-none'), as well as parts of the IPv6
-- support code, were contributed by Philip Blundell.
--
-- * Richard Henderson contributed the ELF dynamic linking code and
-- other support for the Alpha processor.
--
-- * David Mosberger-Tang contributed the port to Linux/Alpha
-- (`alpha-ANYTHING-linux').
--
-- * The port to Linux on PowerPC (`powerpc-ANYTHING-linux') was
-- contributed by Geoffrey Keating.
--
-- * Miles Bader wrote the argp argument-parsing package, and the
-- argz/envz interfaces.
--
-- * Stephen R. van den Berg contributed a highly-optimized `strstr'
-- function.
--
-- * Ulrich Drepper contributed the `hsearch' and `drand48' families of
-- functions; reentrant `...`_r'' versions of the `random' family;
-- System V shared memory and IPC support code; and several
-- highly-optimized string functions for iX86 processors.
--
-- * The math functions are taken from `fdlibm-5.1' by Sun
-- Microsystems, as modified by J.T. Conklin, Ian Lance Taylor,
-- Ulrich Drepper, Andreas Schwab, and Roland McGrath.
--
-- * The `libio' library used to implement `stdio' functions on some
-- platforms was written by Per Bothner and modified by Ulrich
-- Drepper.
--
-- * Eric Youngdale and Ulrich Drepper implemented versioning of
-- objects on symbol level.
--
-- * Thorsten Kukuk provided an implementation for NIS (YP) and NIS+,
-- securelevel 0, 1 and 2.
--
-- * Andreas Jaeger provided a test suite for the math library.
--
-- * Mark Kettenis implemented the utmpx interface and an utmp daemon.
--
-- * Ulrich Drepper added character conversion functions (`iconv').
--
-- * Thorsten Kukuk provided an implementation for a caching daemon for
-- NSS (nscd).
--
-- * Tim Waugh provided an implementation of the POSIX.2 wordexp
-- function family.
--
-- * Mark Kettenis provided a Hesiod NSS module.
--
-- * The Internet-related code (most of the `inet' subdirectory) and
-- several other miscellaneous functions and header files have been
-- included from 4.4 BSD with little or no modification.
--
-- All code incorporated from 4.4 BSD is under the following
-- copyright:
--
-- Copyright (C) 1991 Regents of the University of California.
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or
-- without modification, are permitted provided that the
-- following conditions are met:
--
-- 1. Redistributions of source code must retain the above
-- copyright notice, this list of conditions and the
-- following disclaimer.
--
-- 2. Redistributions in binary form must reproduce the above
-- copyright notice, this list of conditions and the
-- following disclaimer in the documentation and/or other
-- materials provided with the distribution.
--
-- 3. All advertising materials mentioning features or use of
-- this software must display the following acknowledgement:
-- This product includes software developed by the
-- University of California, Berkeley and its
-- contributors.
--
-- 4. Neither the name of the University nor the names of its
-- contributors may be used to endorse or promote products
-- derived from this software without specific prior
-- written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS
-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-- SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-- OF SUCH DAMAGE.
--
-- * The random number generation functions `random', `srandom',
-- `setstate' and `initstate', which are also the basis for the
-- `rand' and `srand' functions, were written by Earl T. Cohen for
-- the University of California at Berkeley and are copyrighted by the
-- Regents of the University of California. They have undergone minor
-- changes to fit into the GNU C library and to fit the ISO C
-- standard, but the functional code is Berkeley's.
--
-- * The DNS resolver code is taken directly from BIND 4.9.5, which is
-- under both the Berkeley copyright above and also:
--
-- Portions Copyright (C) 1993 by Digital Equipment Corporation.
--
-- Permission to use, copy, modify, and distribute this software
-- for any purpose with or without fee is hereby granted,
-- provided that the above copyright notice and this permission
-- notice appear in all copies, and that the name of Digital
-- Equipment Corporation not be used in advertising or publicity
-- pertaining to distribution of the document or software
-- without specific, written prior permission.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP.
-- DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-- INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-- FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE
-- LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-- WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- * The code to support Sun RPC is taken verbatim from Sun's
-- RPCSRC-4.0 distribution, and is covered by this copyright:
--
-- Copyright (C) 1984, Sun Microsystems, Inc.
--
-- Sun RPC is a product of Sun Microsystems, Inc. and is
-- provided for unrestricted use provided that this legend is
-- included on all tape media and as a part of the software
-- program in whole or part. Users may copy or modify Sun RPC
-- without charge, but are not authorized to license or
-- distribute it to anyone else except as part of a product or
-- program developed by the user.
--
-- SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND
-- INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND
-- FITNESS FOR A PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF
-- DEALING, USAGE OR TRADE PRACTICE.
--
-- Sun RPC is provided with no support and without any
-- obligation on the part of Sun Microsystems, Inc. to assist in
-- its use, correction, modification or enhancement.
--
-- SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT
-- TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY
-- PATENTS BY SUN RPC OR ANY PART THEREOF.
--
-- In no event will Sun Microsystems, Inc. be liable for any
-- lost revenue or profits or other special, indirect and
-- consequential damages, even if Sun has been advised of the
-- possibility of such damages.
--
-- Sun Microsystems, Inc.
-- 2550 Garcia Avenue
-- Mountain View, California 94043
--
-- * Some of the support code for Mach is taken from Mach 3.0 by CMU,
-- and is under the following copyright terms:
--
-- Mach Operating System
-- Copyright (C) 1991,1990,1989 Carnegie Mellon University
-- All Rights Reserved.
--
-- Permission to use, copy, modify and distribute this software
-- and its documentation is hereby granted, provided that both
-- the copyright notice and this permission notice appear in all
-- copies of the software, derivative works or modified
-- versions, and any portions thereof, and that both notices
-- appear in supporting documentation.
--
-- CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS
-- IS" CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF
-- ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
-- THIS SOFTWARE.
--
-- Carnegie Mellon requests users of this software to return to
--
-- Software Distribution Coordinator
-- School of Computer Science
-- Carnegie Mellon University
-- Pittsburgh PA 15213-3890
--
-- or <Software.Distribution@CS.CMU.EDU> any improvements or
-- extensions that they make and grant Carnegie Mellon the
-- rights to redistribute these changes.
--
-- * The code for the database library `libdb' comes from the 2.3
-- release of Berkeley DB. That code is under the same copyright as
-- 4.4 BSD and also:
--
-- Copyright (C) 1990, 1993, 1994, 1995, 1996, 1997
-- Sleepycat Software. All rights reserved.
--
-- Redistribution and use in source and binary forms, with or
-- without modification, are permitted provided that the
-- following conditions are met:
--
-- 1. Redistributions of source code must retain the above
-- copyright notice, this list of conditions and the
-- following disclaimer.
--
-- 2. Redistributions in binary form must reproduce the above
-- copyright notice, this list of conditions and the
-- following disclaimer in the documentation and/or other
-- materials provided with the distribution.
--
-- 3. Redistributions in any form must be accompanied by
-- information on how to obtain complete source code for
-- the DB software and any accompanying software that uses
-- the DB software. The source code must either be
-- included in the distribution or be available for no more
-- than the cost of distribution plus a nominal fee, and
-- must be freely redistributable under reasonable
-- conditions. For an executable file, complete source
-- code means the source code for all modules it contains.
-- It does not mean source code for modules or files that
-- typically accompany the operating system on which the
-- executable file runs, e.g., standard library modules or
-- system header files.
--
-- THIS SOFTWARE IS PROVIDED BY SLEEPYCAT SOFTWARE "AS IS" AND
-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-- SLEEPYCAT SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-- DAMAGE.
--
-- Portions copyright (C) 1995, 1996
-- The President and Fellows of Harvard University.
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or
-- without modification, are permitted provided that the
-- following conditions are met:
-- 1. Redistributions of source code must retain the above
-- copyright notice, this list of conditions and the
-- following disclaimer.
--
-- 2. Redistributions in binary form must reproduce the above
-- copyright notice, this list of conditions and the
-- following disclaimer in the documentation and/or other
-- materials provided with the distribution.
--
-- 3. All advertising materials mentioning features or use of
-- this software must display the following acknowledgement:
-- This product includes software developed by
-- Harvard University and its contributors.
--
-- 4. Neither the name of the University nor the names of its
-- contributors may be used to endorse or promote products
-- derived from this software without specific prior
-- written permission.
--
-- THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS "AS
-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-- SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-- OF SUCH DAMAGE.
--
-- For a license to use, redistribute or sell DB software under
-- conditions other than those described above, or to purchase
-- support for this software, please contact Sleepycat Software
-- at
--
-- Sleepycat Software
-- 394 E. Riding Dr.
-- Carlisle, MA 01741
-- USA
-- +1-508-287-4781
--
-- or <db@sleepycat.com>.
--
--
--
--File: libc.info, Node: Copying, Next: Concept Index, Prev: Contributors, Up: Top
--
--GNU LIBRARY GENERAL PUBLIC LICENSE
--**********************************
--
-- Version 2, June 1991
--
-- Copyright (C) 1991 Free Software Foundation, Inc.
-- 59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA
--
-- Everyone is permitted to copy and distribute verbatim copies
-- of this license document, but changing it is not allowed.
--
-- [This is the first released version of the library GPL. It is
-- numbered 2 because it goes with version 2 of the ordinary GPL.]
--
--Preamble
--========
--
-- The licenses for most software are designed to take away your
--freedom to share and change it. By contrast, the GNU General Public
--Licenses are intended to guarantee your freedom to share and change
--free software--to make sure the software is free for all its users.
--
-- This license, the Library General Public License, applies to some
--specially designated Free Software Foundation software, and to any
--other libraries whose authors decide to use it. You can use it for
--your libraries, too.
--
-- When we speak of free software, we are referring to freedom, not
--price. Our General Public Licenses are designed to make sure that you
--have the freedom to distribute copies of free software (and charge for
--this service if you wish), that you receive source code or can get it
--if you want it, that you can change the software or use pieces of it in
--new free programs; and that you know you can do these things.
--
-- To protect your rights, we need to make restrictions that forbid
--anyone to deny you these rights or to ask you to surrender the rights.
--These restrictions translate to certain responsibilities for you if you
--distribute copies of the library, or if you modify it.
--
-- For example, if you distribute copies of the library, whether gratis
--or for a fee, you must give the recipients all the rights that we gave
--you. You must make sure that they, too, receive or can get the source
--code. If you link a program with the library, you must provide
--complete object files to the recipients so that they can relink them
--with the library, after making changes to the library and recompiling
--it. And you must show them these terms so they know their rights.
--
-- Our method of protecting your rights has two steps: (1) copyright
--the library, and (2) offer you this license which gives you legal
--permission to copy, distribute and/or modify the library.
--
-- Also, for each distributor's protection, we want to make certain
--that everyone understands that there is no warranty for this free
--library. If the library is modified by someone else and passed on, we
--want its recipients to know that what they have is not the original
--version, so that any problems introduced by others will not reflect on
--the original authors' reputations.
--
-- Finally, any free program is threatened constantly by software
--patents. We wish to avoid the danger that companies distributing free
--software will individually obtain patent licenses, thus in effect
--transforming the program into proprietary software. To prevent this,
--we have made it clear that any patent must be licensed for everyone's
--free use or not licensed at all.
--
-- Most GNU software, including some libraries, is covered by the
--ordinary GNU General Public License, which was designed for utility
--programs. This license, the GNU Library General Public License,
--applies to certain designated libraries. This license is quite
--different from the ordinary one; be sure to read it in full, and don't
--assume that anything in it is the same as in the ordinary license.
--
-- The reason we have a separate public license for some libraries is
--that they blur the distinction we usually make between modifying or
--adding to a program and simply using it. Linking a program with a
--library, without changing the library, is in some sense simply using
--the library, and is analogous to running a utility program or
--application program. However, in a textual and legal sense, the linked
--executable is a combined work, a derivative of the original library,
--and the ordinary General Public License treats it as such.
--
-- Because of this blurred distinction, using the ordinary General
--Public License for libraries did not effectively promote software
--sharing, because most developers did not use the libraries. We
--concluded that weaker conditions might promote sharing better.
--
-- However, unrestricted linking of non-free programs would deprive the
--users of those programs of all benefit from the free status of the
--libraries themselves. This Library General Public License is intended
--to permit developers of non-free programs to use free libraries, while
--preserving your freedom as a user of such programs to change the free
--libraries that are incorporated in them. (We have not seen how to
--achieve this as regards changes in header files, but we have achieved
--it as regards changes in the actual functions of the Library.) The
--hope is that this will lead to faster development of free libraries.
--
-- The precise terms and conditions for copying, distribution and
--modification follow. Pay close attention to the difference between a
--"work based on the library" and a "work that uses the library". The
--former contains code derived from the library, while the latter only
--works together with the library.
--
-- Note that it is possible for a library to be covered by the ordinary
--General Public License rather than by this special one.
--
-- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
--
-- 0. This License Agreement applies to any software library which
-- contains a notice placed by the copyright holder or other
-- authorized party saying it may be distributed under the terms of
-- this Library General Public License (also called "this License").
-- Each licensee is addressed as "you".
--
-- A "library" means a collection of software functions and/or data
-- prepared so as to be conveniently linked with application programs
-- (which use some of those functions and data) to form executables.
--
-- The "Library", below, refers to any such software library or work
-- which has been distributed under these terms. A "work based on the
-- Library" means either the Library or any derivative work under
-- copyright law: that is to say, a work containing the Library or a
-- portion of it, either verbatim or with modifications and/or
-- translated straightforwardly into another language. (Hereinafter,
-- translation is included without limitation in the term
-- "modification".)
--
-- "Source code" for a work means the preferred form of the work for
-- making modifications to it. For a library, complete source code
-- means all the source code for all modules it contains, plus any
-- associated interface definition files, plus the scripts used to
-- control compilation and installation of the library.
--
-- Activities other than copying, distribution and modification are
-- not covered by this License; they are outside its scope. The act
-- of running a program using the Library is not restricted, and
-- output from such a program is covered only if its contents
-- constitute a work based on the Library (independent of the use of
-- the Library in a tool for writing it). Whether that is true
-- depends on what the Library does and what the program that uses
-- the Library does.
--
-- 1. You may copy and distribute verbatim copies of the Library's
-- complete source code as you receive it, in any medium, provided
-- that you conspicuously and appropriately publish on each copy an
-- appropriate copyright notice and disclaimer of warranty; keep
-- intact all the notices that refer to this License and to the
-- absence of any warranty; and distribute a copy of this License
-- along with the Library.
--
-- You may charge a fee for the physical act of transferring a copy,
-- and you may at your option offer warranty protection in exchange
-- for a fee.
--
-- 2. You may modify your copy or copies of the Library or any portion
-- of it, thus forming a work based on the Library, and copy and
-- distribute such modifications or work under the terms of Section 1
-- above, provided that you also meet all of these conditions:
--
-- a. The modified work must itself be a software library.
--
-- b. You must cause the files modified to carry prominent notices
-- stating that you changed the files and the date of any change.
--
-- c. You must cause the whole of the work to be licensed at no
-- charge to all third parties under the terms of this License.
--
-- d. If a facility in the modified Library refers to a function or
-- a table of data to be supplied by an application program that
-- uses the facility, other than as an argument passed when the
-- facility is invoked, then you must make a good faith effort
-- to ensure that, in the event an application does not supply
-- such function or table, the facility still operates, and
-- performs whatever part of its purpose remains meaningful.
--
-- (For example, a function in a library to compute square roots
-- has a purpose that is entirely well-defined independent of the
-- application. Therefore, Subsection 2d requires that any
-- application-supplied function or table used by this function
-- must be optional: if the application does not supply it, the
-- square root function must still compute square roots.)
--
-- These requirements apply to the modified work as a whole. If
-- identifiable sections of that work are not derived from the
-- Library, and can be reasonably considered independent and separate
-- works in themselves, then this License, and its terms, do not
-- apply to those sections when you distribute them as separate
-- works. But when you distribute the same sections as part of a
-- whole which is a work based on the Library, the distribution of
-- the whole must be on the terms of this License, whose permissions
-- for other licensees extend to the entire whole, and thus to each
-- and every part regardless of who wrote it.
--
-- Thus, it is not the intent of this section to claim rights or
-- contest your rights to work written entirely by you; rather, the
-- intent is to exercise the right to control the distribution of
-- derivative or collective works based on the Library.
--
-- In addition, mere aggregation of another work not based on the
-- Library with the Library (or with a work based on the Library) on
-- a volume of a storage or distribution medium does not bring the
-- other work under the scope of this License.
--
-- 3. You may opt to apply the terms of the ordinary GNU General Public
-- License instead of this License to a given copy of the Library.
-- To do this, you must alter all the notices that refer to this
-- License, so that they refer to the ordinary GNU General Public
-- License, version 2, instead of to this License. (If a newer
-- version than version 2 of the ordinary GNU General Public License
-- has appeared, then you can specify that version instead if you
-- wish.) Do not make any other change in these notices.
--
-- Once this change is made in a given copy, it is irreversible for
-- that copy, so the ordinary GNU General Public License applies to
-- all subsequent copies and derivative works made from that copy.
--
-- This option is useful when you wish to copy part of the code of
-- the Library into a program that is not a library.
--
-- 4. You may copy and distribute the Library (or a portion or
-- derivative of it, under Section 2) in object code or executable
-- form under the terms of Sections 1 and 2 above provided that you
-- accompany it with the complete corresponding machine-readable
-- source code, which must be distributed under the terms of Sections
-- 1 and 2 above on a medium customarily used for software
-- interchange.
--
-- If distribution of object code is made by offering access to copy
-- from a designated place, then offering equivalent access to copy
-- the source code from the same place satisfies the requirement to
-- distribute the source code, even though third parties are not
-- compelled to copy the source along with the object code.
--
-- 5. A program that contains no derivative of any portion of the
-- Library, but is designed to work with the Library by being
-- compiled or linked with it, is called a "work that uses the
-- Library". Such a work, in isolation, is not a derivative work of
-- the Library, and therefore falls outside the scope of this License.
--
-- However, linking a "work that uses the Library" with the Library
-- creates an executable that is a derivative of the Library (because
-- it contains portions of the Library), rather than a "work that
-- uses the library". The executable is therefore covered by this
-- License. Section 6 states terms for distribution of such
-- executables.
--
-- When a "work that uses the Library" uses material from a header
-- file that is part of the Library, the object code for the work may
-- be a derivative work of the Library even though the source code is
-- not. Whether this is true is especially significant if the work
-- can be linked without the Library, or if the work is itself a
-- library. The threshold for this to be true is not precisely
-- defined by law.
--
-- If such an object file uses only numerical parameters, data
-- structure layouts and accessors, and small macros and small inline
-- functions (ten lines or less in length), then the use of the object
-- file is unrestricted, regardless of whether it is legally a
-- derivative work. (Executables containing this object code plus
-- portions of the Library will still fall under Section 6.)
--
-- Otherwise, if the work is a derivative of the Library, you may
-- distribute the object code for the work under the terms of Section
-- 6. Any executables containing that work also fall under Section 6,
-- whether or not they are linked directly with the Library itself.
--
-- 6. As an exception to the Sections above, you may also compile or
-- link a "work that uses the Library" with the Library to produce a
-- work containing portions of the Library, and distribute that work
-- under terms of your choice, provided that the terms permit
-- modification of the work for the customer's own use and reverse
-- engineering for debugging such modifications.
--
-- You must give prominent notice with each copy of the work that the
-- Library is used in it and that the Library and its use are covered
-- by this License. You must supply a copy of this License. If the
-- work during execution displays copyright notices, you must include
-- the copyright notice for the Library among them, as well as a
-- reference directing the user to the copy of this License. Also,
-- you must do one of these things:
--
-- a. Accompany the work with the complete corresponding
-- machine-readable source code for the Library including
-- whatever changes were used in the work (which must be
-- distributed under Sections 1 and 2 above); and, if the work
-- is an executable linked with the Library, with the complete
-- machine-readable "work that uses the Library", as object code
-- and/or source code, so that the user can modify the Library
-- and then relink to produce a modified executable containing
-- the modified Library. (It is understood that the user who
-- changes the contents of definitions files in the Library will
-- not necessarily be able to recompile the application to use
-- the modified definitions.)
--
-- b. Accompany the work with a written offer, valid for at least
-- three years, to give the same user the materials specified in
-- Subsection 6a, above, for a charge no more than the cost of
-- performing this distribution.
--
-- c. If distribution of the work is made by offering access to copy
-- from a designated place, offer equivalent access to copy the
-- above specified materials from the same place.
--
-- d. Verify that the user has already received a copy of these
-- materials or that you have already sent this user a copy.
--
-- For an executable, the required form of the "work that uses the
-- Library" must include any data and utility programs needed for
-- reproducing the executable from it. However, as a special
-- exception, the source code distributed need not include anything
-- that is normally distributed (in either source or binary form)
-- with the major components (compiler, kernel, and so on) of the
-- operating system on which the executable runs, unless that
-- component itself accompanies the executable.
--
-- It may happen that this requirement contradicts the license
-- restrictions of other proprietary libraries that do not normally
-- accompany the operating system. Such a contradiction means you
-- cannot use both them and the Library together in an executable
-- that you distribute.
--
-- 7. You may place library facilities that are a work based on the
-- Library side-by-side in a single library together with other
-- library facilities not covered by this License, and distribute
-- such a combined library, provided that the separate distribution
-- of the work based on the Library and of the other library
-- facilities is otherwise permitted, and provided that you do these
-- two things:
--
-- a. Accompany the combined library with a copy of the same work
-- based on the Library, uncombined with any other library
-- facilities. This must be distributed under the terms of the
-- Sections above.
--
-- b. Give prominent notice with the combined library of the fact
-- that part of it is a work based on the Library, and explaining
-- where to find the accompanying uncombined form of the same
-- work.
--
-- 8. You may not copy, modify, sublicense, link with, or distribute the
-- Library except as expressly provided under this License. Any
-- attempt otherwise to copy, modify, sublicense, link with, or
-- distribute the Library is void, and will automatically terminate
-- your rights under this License. However, parties who have
-- received copies, or rights, from you under this License will not
-- have their licenses terminated so long as such parties remain in
-- full compliance.
--
-- 9. You are not required to accept this License, since you have not
-- signed it. However, nothing else grants you permission to modify
-- or distribute the Library or its derivative works. These actions
-- are prohibited by law if you do not accept this License.
-- Therefore, by modifying or distributing the Library (or any work
-- based on the Library), you indicate your acceptance of this
-- License to do so, and all its terms and conditions for copying,
-- distributing or modifying the Library or works based on it.
--
-- 10. Each time you redistribute the Library (or any work based on the
-- Library), the recipient automatically receives a license from the
-- original licensor to copy, distribute, link with or modify the
-- Library subject to these terms and conditions. You may not impose
-- any further restrictions on the recipients' exercise of the rights
-- granted herein. You are not responsible for enforcing compliance
-- by third parties to this License.
--
-- 11. If, as a consequence of a court judgment or allegation of patent
-- infringement or for any other reason (not limited to patent
-- issues), conditions are imposed on you (whether by court order,
-- agreement or otherwise) that contradict the conditions of this
-- License, they do not excuse you from the conditions of this
-- License. If you cannot distribute so as to satisfy simultaneously
-- your obligations under this License and any other pertinent
-- obligations, then as a consequence you may not distribute the
-- Library at all. For example, if a patent license would not permit
-- royalty-free redistribution of the Library by all those who
-- receive copies directly or indirectly through you, then the only
-- way you could satisfy both it and this License would be to refrain
-- entirely from distribution of the Library.
--
-- If any portion of this section is held invalid or unenforceable
-- under any particular circumstance, the balance of the section is
-- intended to apply, and the section as a whole is intended to apply
-- in other circumstances.
--
-- It is not the purpose of this section to induce you to infringe any
-- patents or other property right claims or to contest validity of
-- any such claims; this section has the sole purpose of protecting
-- the integrity of the free software distribution system which is
-- implemented by public license practices. Many people have made
-- generous contributions to the wide range of software distributed
-- through that system in reliance on consistent application of that
-- system; it is up to the author/donor to decide if he or she is
-- willing to distribute software through any other system and a
-- licensee cannot impose that choice.
--
-- This section is intended to make thoroughly clear what is believed
-- to be a consequence of the rest of this License.
--
-- 12. If the distribution and/or use of the Library is restricted in
-- certain countries either by patents or by copyrighted interfaces,
-- the original copyright holder who places the Library under this
-- License may add an explicit geographical distribution limitation
-- excluding those countries, so that distribution is permitted only
-- in or among countries not thus excluded. In such case, this
-- License incorporates the limitation as if written in the body of
-- this License.
--
-- 13. The Free Software Foundation may publish revised and/or new
-- versions of the Library General Public License from time to time.
-- Such new versions will be similar in spirit to the present version,
-- but may differ in detail to address new problems or concerns.
--
-- Each version is given a distinguishing version number. If the
-- Library specifies a version number of this License which applies
-- to it and "any later version", you have the option of following
-- the terms and conditions either of that version or of any later
-- version published by the Free Software Foundation. If the Library
-- does not specify a license version number, you may choose any
-- version ever published by the Free Software Foundation.
--
-- 14. If you wish to incorporate parts of the Library into other free
-- programs whose distribution conditions are incompatible with these,
-- write to the author to ask for permission. For software which is
-- copyrighted by the Free Software Foundation, write to the Free
-- Software Foundation; we sometimes make exceptions for this. Our
-- decision will be guided by the two goals of preserving the free
-- status of all derivatives of our free software and of promoting
-- the sharing and reuse of software generally.
--
-- NO WARRANTY
--
-- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-- WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE
-- LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-- HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT
-- WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
-- NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-- FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
-- QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE
-- LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
-- SERVICING, REPAIR OR CORRECTION.
--
-- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-- WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
-- MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
-- LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
-- INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
-- INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
-- DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
-- OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY
-- OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
--
-- END OF TERMS AND CONDITIONS
--
--How to Apply These Terms to Your New Libraries
--==============================================
--
-- If you develop a new library, and you want it to be of the greatest
--possible use to the public, we recommend making it free software that
--everyone can redistribute and change. You can do so by permitting
--redistribution under these terms (or, alternatively, under the terms of
--the ordinary General Public License).
--
-- To apply these terms, attach the following notices to the library.
--It is safest to attach them to the start of each source file to most
--effectively convey the exclusion of warranty; and each file should have
--at least the "copyright" line and a pointer to where the full notice is
--found.
--
-- ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES.
-- Copyright (C) YEAR NAME OF AUTHOR
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Library General Public License as published
-- by the Free Software Foundation; either version 2 of the License, or (at
-- your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Library General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along
-- with this program; if not, write to the Free Software Foundation, Inc.,
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
--
-- Also add information on how to contact you by electronic and paper
--mail.
--
-- You should also get your employer (if you work as a programmer) or
--your school, if any, to sign a "copyright disclaimer" for the library,
--if necessary. Here is a sample; alter the names:
--
-- Yoyodyne, Inc., hereby disclaims all copyright interest in the library
-- `Frob' (a library for tweaking knobs) written by James Random Hacker.
--
-- SIGNATURE OF TY COON, 1 April 1990
-- Ty Coon, President of Vice
--
-- That's all there is to it!
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-48 glibc-2.1.3/manual/libc.info-48
---- ../glibc-2.1.3/manual/libc.info-48 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-48 1969-12-31 16:00:00.000000000 -0800
-@@ -1,977 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Concept Index, Next: Type Index, Prev: Copying, Up: Top
--
--Concept Index
--*************
--
--* Menu:
--
--* /etc/nsswitch.conf: NSS Configuration File.
--* 4.N BSD Unix: Berkeley Unix.
--* __va_copy: Copying and Concatenation.
--* _POSIX_OPTION_ORDER environment variable.: Standard Environment.
--* _POSIX_SAVED_IDS: How Change Persona.
--* abort signal: Program Error Signals.
--* aborting a program: Aborting a Program.
--* absolute file name: File Name Resolution.
--* absolute value functions: Absolute Value.
--* accepting connections: Accepting Connections.
--* access permission for a file: Access Permission.
--* access, testing for: Testing File Access.
--* accessing directories: Accessing Directories.
--* address of socket: Socket Addresses.
--* alarm signal: Alarm Signals.
--* alarms, setting: Setting an Alarm.
--* alignment (in obstacks): Obstacks Data Alignment.
--* alignment (with malloc): Aligned Memory Blocks.
--* alloca disadvantages: Disadvantages of Alloca.
--* alloca function: Variable Size Automatic.
--* allocating pseudo-terminals: Allocation.
--* allocation (obstacks): Allocation in an Obstack.
--* allocation debugging: Allocation Debugging.
--* allocation hooks, for malloc: Hooks for Malloc.
--* allocation of memory with malloc: Basic Allocation.
--* allocation size of string: Representation of Strings.
--* allocation statistics: Statistics of Malloc.
--* alphabetic character <1>: Classification of Wide Characters.
--* alphabetic character: Classification of Characters.
--* alphanumeric character <1>: Classification of Wide Characters.
--* alphanumeric character: Classification of Characters.
--* append-access files: File Position.
--* argc (program argument count): Program Arguments.
--* argp (program argument parser): Argp.
--* argp parser functions: Argp Parser Functions.
--* ARGP_HELP_FMT environment variable: Argp User Customization.
--* argument parsing with argp: Argp.
--* argument promotion: Calling Variadics.
--* argument vectors, null-character separated: Argz and Envz Vectors.
--* arguments (variadic functions): Receiving Arguments.
--* arguments, how many: How Many Arguments.
--* arguments, to program: Program Arguments.
--* argv (program argument vector): Program Arguments.
--* argz vectors (string vectors): Argz and Envz Vectors.
--* arithmetic expansion: Expansion Stages.
--* array comparison functions: String/Array Comparison.
--* array copy functions: Copying and Concatenation.
--* array search function: Array Search Function.
--* array sort function: Array Sort Function.
--* ASCII character: Classification of Characters.
--* assertions: Consistency Checking.
--* attributes of a file: Attribute Meanings.
--* automatic allocation: Memory Concepts.
--* automatic freeing: Variable Size Automatic.
--* automatic storage with variable size: Variable Size Automatic.
--* background job: Concepts of Job Control.
--* background job, launching: Foreground and Background.
--* base (of floating point number): Floating Point Concepts.
--* baud rate: Line Speed.
--* Berkeley Unix: Berkeley Unix.
--* Bessel functions: Special Functions.
--* bias (of floating point number exponent): Floating Point Concepts.
--* big-endian: Byte Order.
--* binary I/O to a stream: Block Input/Output.
--* binary search function (for arrays): Array Search Function.
--* binary stream: Binary Streams.
--* binding a socket address: Socket Addresses.
--* blank character <1>: Classification of Wide Characters.
--* blank character: Classification of Characters.
--* block I/O to a stream: Block Input/Output.
--* blocked signals: Delivery of Signal.
--* blocked signals, checking for: Checking for Pending Signals.
--* blocking signals: Blocking Signals.
--* blocking signals, in a handler: Blocking for Handler.
--* bootstrapping, and services: Actions in the NSS configuration.
--* break condition, detecting: Input Modes.
--* break condition, generating: Line Control.
--* breaking a string into tokens: Finding Tokens in a String.
--* broken pipe signal: Operation Error Signals.
--* broken-down time <1>: Broken-down Time.
--* broken-down time: Calendar Time.
--* BSD compatibility library: Process Group Functions.
--* BSD compatibility library.: Feature Test Macros.
--* BSD Unix: Berkeley Unix.
--* buffering of streams: Stream Buffering.
--* buffering, controlling: Controlling Buffering.
--* bugs, reporting: Reporting Bugs.
--* bus error: Program Error Signals.
--* butterfly: Misc FP Arithmetic.
--* byte order conversion, for socket: Byte Order.
--* byte stream: Socket Concepts.
--* calendar time: Calendar Time.
--* calendar time and broken-down time: Broken-down Time.
--* calling variadic functions: Calling Variadics.
--* canonical input processing: Canonical or Not.
--* capacity limits, POSIX: General Limits.
--* carrier detect: Control Modes.
--* case conversion of characters: Case Conversion.
--* catching signals: Delivery of Signal.
--* categories for locales: Locale Categories.
--* change working directory: Working Directory.
--* changing the locale: Setting the Locale.
--* changing the size of a block (malloc): Changing Block Size.
--* changing the size of a block (obstacks): Growing Objects.
--* channels: Stream/Descriptor Precautions.
--* character case conversion: Case Conversion.
--* character predicates: Classification of Characters.
--* character testing: Classification of Characters.
--* checking for pending signals: Checking for Pending Signals.
--* child process <1>: Process Creation Concepts.
--* child process: Processes.
--* child process signal: Job Control Signals.
--* chunks: Obstack Chunks.
--* classes, floating-point: Floating Point Classes.
--* classification of characters: Classification of Characters.
--* cleaning up a stream: Linked Channels.
--* clearing terminal input queue: Line Control.
--* client: Connections.
--* clock ticks: Processor Time.
--* close-on-exec (file descriptor flag): Descriptor Flags.
--* closing a file descriptor: Opening and Closing Files.
--* closing a socket: Closing a Socket.
--* closing a stream: Closing Streams.
--* collating strings: Collation Functions.
--* combining locales: Choosing Locale.
--* command argument syntax: Argument Syntax.
--* command arguments, parsing: Parsing Program Arguments.
--* command line arguments: Program Arguments.
--* command substitution: Expansion Stages.
--* communication style (of a socket): Socket Concepts.
--* comparing strings and arrays: String/Array Comparison.
--* Comparison Function: Comparison Functions.
--* compiling: Configuring and compiling.
--* complex exponentiation functions: Exponents and Logarithms.
--* complex logarithm functions: Exponents and Logarithms.
--* complex numbers: Complex Numbers.
--* complex trigonometric functions: Trig Functions.
--* concatenating strings: Copying and Concatenation.
--* configurations, all supported: Supported Configurations.
--* configuring: Configuring and compiling.
--* conjugate complex numbers: Operations on Complex.
--* connecting a socket: Connecting.
--* connection: Connections.
--* consistency checking: Consistency Checking.
--* consistency checking, of heap: Heap Consistency Checking.
--* constants: Mathematical Constants.
--* continue signal: Job Control Signals.
--* control character <1>: Classification of Wide Characters.
--* control character: Classification of Characters.
--* control operations on files: Control Operations.
--* controlling process: Controlling Terminal.
--* controlling terminal: Concepts of Job Control.
--* controlling terminal, access to: Access to the Terminal.
--* controlling terminal, determining: Identifying the Terminal.
--* controlling terminal, setting: Open-time Flags.
--* conversion specifications (printf): Formatted Output Basics.
--* conversion specifications (scanf): Formatted Input Basics.
--* converting byte order: Byte Order.
--* converting case of characters: Case Conversion.
--* converting file descriptor to stream: Descriptors and Streams.
--* converting floats to integers: Rounding Functions.
--* converting group ID to group name: Lookup Group.
--* converting group name to group ID: Lookup Group.
--* converting host address to name: Host Names.
--* converting host name to address: Host Names.
--* converting network name to network number: Networks Database.
--* converting network number to network name: Networks Database.
--* converting port number to service name: Services Database.
--* converting service name to port number: Services Database.
--* converting string to collation order: Collation Functions.
--* converting strings to numbers: Parsing of Numbers.
--* converting user ID to user name: Lookup User.
--* converting user name to user ID: Lookup User.
--* cookie, for custom stream: Streams and Cookies.
--* copying strings and arrays: Copying and Concatenation.
--* CPU time: Processor Time.
--* create on open (file status flag): Open-time Flags.
--* creating a directory: Creating Directories.
--* creating a FIFO special file: FIFO Special Files.
--* creating a pipe: Creating a Pipe.
--* creating a pipe to a subprocess: Pipe to a Subprocess.
--* creating a process: Process Creation Concepts.
--* creating a socket: Creating a Socket.
--* creating a socket pair: Socket Pairs.
--* creating special files: Making Special Files.
--* cube root function: Exponents and Logarithms.
--* currency symbols: Currency Symbol.
--* current working directory: Working Directory.
--* custom streams: Custom Streams.
--* customizing printf: Customizing Printf.
--* data loss on sockets: Socket Concepts.
--* databases: Name Service Switch.
--* datagram socket: Datagrams.
--* datagrams, transmitting: Sending Datagrams.
--* date and time: Calendar Time.
--* Daylight Saving Time: Broken-down Time.
--* decimal digit character: Classification of Characters.
--* decimal-point separator: General Numeric.
--* declaration (compared to definition): Header Files.
--* declaring variadic functions: Calling Variadics.
--* decompose complex numbers: Operations on Complex.
--* default action (for a signal): Delivery of Signal.
--* default action for a signal: Basic Signal Handling.
--* default argument promotions: Calling Variadics.
--* default value, and NSS: Notes on NSS Configuration File.
--* defining new printf conversions: Customizing Printf.
--* definition (compared to declaration): Header Files.
--* delayed suspend character: Signal Characters.
--* deleting a directory: Deleting Files.
--* deleting a file: Deleting Files.
--* delivery of signals: Delivery of Signal.
--* descriptors and streams: Stream/Descriptor Precautions.
--* digit character <1>: Classification of Wide Characters.
--* digit character: Classification of Characters.
--* directories, accessing: Accessing Directories.
--* directories, creating: Creating Directories.
--* directories, deleting: Deleting Files.
--* directory: Directories.
--* directory entry: Directories.
--* directory hierarchy: Working on Directory Trees.
--* directory stream: Accessing Directories.
--* disadvantages of alloca: Disadvantages of Alloca.
--* DISCARD character: Other Special.
--* division by zero: FP Exceptions.
--* DNS server unavailable: Actions in the NSS configuration.
--* domain (of socket): Socket Concepts.
--* domain error: Math Error Reporting.
--* dot notation, for Internet addresses: Abstract Host Addresses.
--* DSUSP character: Signal Characters.
--* duplicating file descriptors: Duplicating Descriptors.
--* dynamic allocation: Memory Concepts.
--* EBCDIC: Extended Char Intro.
--* echo of terminal input: Local Modes.
--* effective group ID: Process Persona.
--* effective user ID: Process Persona.
--* efficiency and malloc: Efficiency and Malloc.
--* efficiency and obstacks: Extra Fast Growing.
--* efficiency of chunks: Obstack Chunks.
--* EINTR, and restarting interrupted primitives: Interrupted Primitives.
--* end of file, on a stream: EOF and Errors.
--* end-of-file, on a file descriptor: I/O Primitives.
--* environment: Environment Variables.
--* environment access: Environment Access.
--* environment representation: Environment Access.
--* environment variable: Environment Variables.
--* environment vectors, null-character separated: Argz and Envz Vectors.
--* envz vectors (environment vectors): Argz and Envz Vectors.
--* EOF character: Editing Characters.
--* EOL character: Editing Characters.
--* EOL2 character: Editing Characters.
--* epoch: Simple Calendar Time.
--* ERASE character: Editing Characters.
--* error codes: Error Reporting.
--* error messages, in argp: Argp Helper Functions.
--* error reporting: Error Reporting.
--* errors, mathematical: Math Error Reporting.
--* establishing a handler: Signal Actions.
--* ethers: NSS Basics.
--* EUC: Extended Char Intro.
--* EUC-JP: glibc iconv Implementation.
--* exception <1>: Program Error Signals.
--* exception: FP Exceptions.
--* exclusive lock: File Locks.
--* exec functions: Executing a File.
--* executing a file: Executing a File.
--* exit status: Exit Status.
--* exit status value: Program Termination.
--* expansion of shell words: Word Expansion.
--* exponent (of floating point number): Floating Point Concepts.
--* exponentiation functions: Exponents and Logarithms.
--* extending printf: Customizing Printf.
--* extracting file descriptor from stream: Descriptors and Streams.
--* fcntl function: Control Operations.
--* feature test macros: Feature Test Macros.
--* field splitting: Expansion Stages.
--* FIFO special file: Pipes and FIFOs.
--* file access permission: Access Permission.
--* file access time: File Times.
--* file attribute modification time: File Times.
--* file attributes: Attribute Meanings.
--* file creation mask: Setting Permissions.
--* file descriptor flags: Descriptor Flags.
--* file descriptor sets, for select: Waiting for I/O.
--* file descriptors, standard: Descriptors and Streams.
--* file locks: File Locks.
--* file modification time: File Times.
--* file name: File Names.
--* file name component: Directories.
--* file name errors: File Name Errors.
--* file name resolution: File Name Resolution.
--* file name translation flags: Open-time Flags.
--* file names, multiple: Hard Links.
--* file owner: File Owner.
--* file permission bits: Permission Bits.
--* file pointer: Streams.
--* file position: File Position.
--* file positioning on a file descriptor: File Position Primitive.
--* file positioning on a stream: File Positioning.
--* file status flags: File Status Flags.
--* filtering i/o through subprocess: Pipe to a Subprocess.
--* flag character (printf): Output Conversion Syntax.
--* flag character (scanf): Input Conversion Syntax.
--* flags for sigaction: Flags for Sigaction.
--* flags, file name translation: Open-time Flags.
--* flags, open-time action: Open-time Flags.
--* floating point: Floating Point Numbers.
--* floating point, IEEE: IEEE Floating Point.
--* floating type measurements: Floating Type Macros.
--* floating-point classes: Floating Point Classes.
--* floating-point exception: Program Error Signals.
--* flow control, terminal: Line Control.
--* flushing a stream: Flushing Buffers.
--* flushing terminal output queue: Line Control.
--* foreground job: Concepts of Job Control.
--* foreground job, launching: Foreground and Background.
--* forking a process: Process Creation Concepts.
--* format string, for printf: Formatted Output.
--* format string, for scanf: Formatted Input.
--* formatted input from a stream: Formatted Input.
--* formatted messages: Formatted Messages.
--* formatted output to a stream: Formatted Output.
--* FP arithmetic: FP Bit Twiddling.
--* freeing (obstacks): Freeing Obstack Objects.
--* freeing memory allocated with malloc: Freeing after Malloc.
--* fully buffered stream: Buffering Concepts.
--* function prototypes (variadic): Variadic Prototypes.
--* gamma function: Special Functions.
--* gcvt_r: System V Number Conversion.
--* gencat: The gencat program.
--* generation of signals: Signal Generation.
--* generic i/o control operations: IOCTLs.
--* globbing: Globbing.
--* graphic character <1>: Classification of Wide Characters.
--* graphic character: Classification of Characters.
--* Gregorian calendar: Calendar Time.
--* group: NSS Basics.
--* group database: Group Database.
--* group ID: User and Group IDs.
--* group name: User and Group IDs.
--* group owner of a file: File Owner.
--* grouping of digits: General Numeric.
--* growing objects (in obstacks): Growing Objects.
--* handling multiple signals: Merged Signals.
--* hangup signal: Termination Signals.
--* hard limit: Limits on Resources.
--* hard link: Hard Links.
--* header files: Header Files.
--* heap consistency checking: Heap Consistency Checking.
--* heap, dynamic allocation from: Unconstrained Allocation.
--* heap, freeing memory from: Freeing after Malloc.
--* hexadecimal digit character <1>: Classification of Wide Characters.
--* hexadecimal digit character: Classification of Characters.
--* hidden bit (of floating point number mantissa): Floating Point Concepts.
--* hierarchy, directory: Working on Directory Trees.
--* high-priority data: Out-of-Band Data.
--* high-resolution time: Calendar Time.
--* holes in files: File Position Primitive.
--* home directory: Standard Environment.
--* HOME environment variable: Standard Environment.
--* hook functions (of custom streams): Hook Functions.
--* host address, Internet: Abstract Host Addresses.
--* hosts: NSS Basics.
--* hosts database: Host Names.
--* how many arguments: How Many Arguments.
--* hyperbolic functions: Hyperbolic Functions.
--* identifying terminals: Is It a Terminal.
--* IEEE 754: Floating Point Numbers.
--* IEEE floating point: Floating Point Numbers.
--* IEEE floating point representation: IEEE Floating Point.
--* IEEE Std 1003.1: POSIX.
--* IEEE Std 1003.2: POSIX.
--* ignore action for a signal: Basic Signal Handling.
--* illegal instruction: Program Error Signals.
--* impossible events: Consistency Checking.
--* independent channels: Independent Channels.
--* inexact exception: FP Exceptions.
--* infinity: Infinity and NaN.
--* initial signal actions: Initial Signal Actions.
--* inode number: Attribute Meanings.
--* input available signal: Asynchronous I/O Signals.
--* input conversions, for scanf: Table of Input Conversions.
--* input from multiple files: Waiting for I/O.
--* installation tools: Tools for Compilation.
--* installing: Running make install.
--* integer division functions: Integer Division.
--* integer type range: Range of Type.
--* integer type width: Width of Type.
--* interactive signals, from terminal: Local Modes.
--* interactive stop signal: Job Control Signals.
--* internal representation: Extended Char Intro.
--* internationalization: Locales.
--* Internet host address: Abstract Host Addresses.
--* Internet namespace, for sockets: Internet Namespace.
--* interprocess communication, with FIFO: FIFO Special Files.
--* interprocess communication, with pipes: Creating a Pipe.
--* interprocess communication, with signals: Kill Example.
--* interprocess communication, with sockets: Sockets.
--* interrupt character: Signal Characters.
--* interrupt signal: Termination Signals.
--* interrupt-driven input: Interrupt Input.
--* interrupting primitives: Interrupted Primitives.
--* interval timer, setting: Setting an Alarm.
--* INTR character: Signal Characters.
--* invalid exception: FP Exceptions.
--* inverse complex hyperbolic functions: Hyperbolic Functions.
--* inverse complex trigonometric functions: Inverse Trig Functions.
--* inverse hyperbolic functions: Hyperbolic Functions.
--* inverse trigonometric functions: Inverse Trig Functions.
--* invocation of program: Program Arguments.
--* IOCTLs: IOCTLs.
--* ISO 10646: Extended Char Intro.
--* ISO 2022: Extended Char Intro.
--* ISO 6937: Extended Char Intro.
--* ISO C: ISO C.
--* ISO-2022-JP: glibc iconv Implementation.
--* ISO/IEC 9945-1: POSIX.
--* ISO/IEC 9945-2: POSIX.
--* job: Job Control.
--* job control: Job Control.
--* job control functions: Functions for Job Control.
--* job control is optional: Job Control is Optional.
--* job control signals: Job Control Signals.
--* job control, enabling: Initializing the Shell.
--* Kermit the frog: Search/Sort Example.
--* kernel header files: Linux.
--* KILL character: Editing Characters.
--* kill signal: Termination Signals.
--* killing a process: Signaling Another Process.
--* LANG environment variable <1>: Standard Environment.
--* LANG environment variable: The catgets Functions.
--* launching jobs: Launching Jobs.
--* LC_ALL environment variable <1>: Standard Environment.
--* LC_ALL environment variable: The catgets Functions.
--* LC_COLLATE environment variable: Standard Environment.
--* LC_CTYPE environment variable: Standard Environment.
--* LC_MESSAGES environment variable <1>: Standard Environment.
--* LC_MESSAGES environment variable: The catgets Functions.
--* LC_MONETARY environment variable: Standard Environment.
--* LC_NUMERIC environment variable: Standard Environment.
--* LC_TIME environment variable: Standard Environment.
--* leap second: Broken-down Time.
--* length of string: Representation of Strings.
--* level, for socket options: Socket Options.
--* library: Introduction.
--* limits on resource usage: Limits on Resources.
--* limits, file name length: Limits for Files.
--* limits, floating types: Floating Type Macros.
--* limits, integer types: Range of Type.
--* limits, link count of files: Limits for Files.
--* limits, number of open files: General Limits.
--* limits, number of processes: General Limits.
--* limits, number of supplementary group IDs: General Limits.
--* limits, pipe buffer size: Limits for Files.
--* limits, POSIX: General Limits.
--* limits, program argument size: General Limits.
--* limits, terminal input queue: Limits for Files.
--* limits, time zone name length: General Limits.
--* line buffered stream: Buffering Concepts.
--* line speed: Line Speed.
--* lines (in a text file): Binary Streams.
--* link: Directories.
--* link, hard: Hard Links.
--* link, soft: Symbolic Links.
--* link, symbolic: Symbolic Links.
--* linked channels: Linked Channels.
--* listening (sockets): Listening.
--* little-endian: Byte Order.
--* LNEXT character: Other Special.
--* local namespace, for sockets: Local Namespace.
--* local network address number: Abstract Host Addresses.
--* local time: Calendar Time.
--* locale categories: Locale Categories.
--* locale, changing: Setting the Locale.
--* locales: Locales.
--* locales, parsing numbers and: Parsing of Integers.
--* logarithm functions: Exponents and Logarithms.
--* login name: User and Group IDs.
--* login name, determining: Who Logged In.
--* LOGNAME environment variable: Standard Environment.
--* long jumps: Non-Local Exits.
--* long-named options: Argument Syntax.
--* longjmp: Advantages of Alloca.
--* loss of data on sockets: Socket Concepts.
--* lost resource signal: Operation Error Signals.
--* lower-case character <1>: Classification of Wide Characters.
--* lower-case character: Classification of Characters.
--* macros: Obstack Functions.
--* main function: Program Arguments.
--* malloc debugger: Allocation Debugging.
--* malloc function: Unconstrained Allocation.
--* mantissa (of floating point number): Floating Point Concepts.
--* matching failure, in scanf: Formatted Input Basics.
--* mathematical constants: Mathematical Constants.
--* maximum: Misc FP Arithmetic.
--* maximum field width (scanf): Input Conversion Syntax.
--* measurements of floating types: Floating Type Macros.
--* memory allocation: Memory Allocation.
--* merging of signals: Merged Signals.
--* MIN termios slot: Noncanonical Input.
--* minimum: Misc FP Arithmetic.
--* minimum field width (printf): Output Conversion Syntax.
--* mixing descriptors and streams: Stream/Descriptor Precautions.
--* modem disconnect: Control Modes.
--* modem status lines: Control Modes.
--* monetary value formatting: The Lame Way to Locale Data.
--* multibyte character: Extended Char Intro.
--* multiple names for one file: Hard Links.
--* multiplexing input: Waiting for I/O.
--* multiply-add: Misc FP Arithmetic.
--* name of running program: Error Messages.
--* name of socket: Socket Addresses.
--* Name Service Switch: Name Service Switch.
--* name space: Reserved Names.
--* names of signals: Standard Signals.
--* namespace (of socket): Socket Concepts.
--* NaN <1>: FP Bit Twiddling.
--* NaN: Infinity and NaN.
--* Netgroup: Netgroup Data.
--* netgroup: NSS Basics.
--* network byte order: Byte Order.
--* network number: Abstract Host Addresses.
--* network protocol: Socket Concepts.
--* networks: NSS Basics.
--* networks database: Networks Database.
--* nisplus, and booting: Actions in the NSS configuration.
--* nisplus, and completeness: Actions in the NSS configuration.
--* NLSPATH environment variable <1>: Standard Environment.
--* NLSPATH environment variable: The catgets Functions.
--* non-blocking open: Open-time Flags.
--* non-local exit, from signal handler: Longjmp in Handler.
--* non-local exits: Non-Local Exits.
--* noncanonical input processing: Canonical or Not.
--* normalization functions (floating-point): Normalization Functions.
--* normalized floating point number: Floating Point Concepts.
--* not a number: Infinity and NaN.
--* NSS: Name Service Switch.
--* nsswitch.conf: NSS Configuration File.
--* null character: Representation of Strings.
--* null pointer constant: Null Pointer Constant.
--* number of arguments passed: How Many Arguments.
--* number syntax, parsing: Parsing of Numbers.
--* numeric value formatting: The Lame Way to Locale Data.
--* obstack status: Status of an Obstack.
--* obstacks: Obstacks.
--* open-time action flags: Open-time Flags.
--* opening a file: I/O Concepts.
--* opening a file descriptor: Opening and Closing Files.
--* opening a pipe: Creating a Pipe.
--* opening a pseudo-terminal pair: Pseudo-Terminal Pairs.
--* opening a socket: Creating a Socket.
--* opening a socket pair: Socket Pairs.
--* opening a stream: Opening Streams.
--* Optimization: FP Function Optimizations.
--* optimizing NSS: Notes on NSS Configuration File.
--* option parsing with argp: Argp.
--* optional arguments: Variadic Functions.
--* optional POSIX features: System Options.
--* orphaned process group: Orphaned Process Groups.
--* out-of-band data: Out-of-Band Data.
--* output conversions, for printf: Table of Output Conversions.
--* output possible signal: Asynchronous I/O Signals.
--* overflow exception: FP Exceptions.
--* owner of a file: File Owner.
--* packet: Socket Concepts.
--* page boundary: Aligned Memory Blocks.
--* parent directory: File Name Resolution.
--* parent process <1>: Process Creation Concepts.
--* parent process: Processes.
--* parity checking: Input Modes.
--* parsing a template string: Parsing a Template String.
--* parsing numbers (in formatted input): Parsing of Numbers.
--* parsing numbers and locales: Parsing of Integers.
--* parsing program arguments: Parsing Program Arguments.
--* parsing tokens from a string: Finding Tokens in a String.
--* passwd: NSS Basics.
--* password database: User Database.
--* PATH environment variable: Standard Environment.
--* pause function: Waiting for a Signal.
--* peeking at input: Unreading.
--* pending signals: Delivery of Signal.
--* pending signals, checking for: Checking for Pending Signals.
--* permission to access a file: Access Permission.
--* persona: Process Persona.
--* pi (trigonometric constant): Trig Functions.
--* pipe: Pipes and FIFOs.
--* pipe signal: Operation Error Signals.
--* pipe to a subprocess: Pipe to a Subprocess.
--* port number: Ports.
--* positioning a file descriptor: File Position Primitive.
--* positioning a stream: File Positioning.
--* positive difference: Misc FP Arithmetic.
--* POSIX: POSIX.
--* POSIX capacity limits: General Limits.
--* POSIX optional features: System Options.
--* POSIX.1: POSIX.
--* POSIX.2: POSIX.
--* power functions: Exponents and Logarithms.
--* precision (of floating point number): Floating Point Concepts.
--* precision (printf): Output Conversion Syntax.
--* predicates on arrays: String/Array Comparison.
--* predicates on characters: Classification of Characters.
--* predicates on strings: String/Array Comparison.
--* primitives, interrupting: Interrupted Primitives.
--* printing character <1>: Classification of Wide Characters.
--* printing character: Classification of Characters.
--* priority of a process: Priority.
--* process <1>: Processes.
--* process: Process Startup.
--* process completion: Process Completion.
--* process group functions: Functions for Job Control.
--* process group ID: Launching Jobs.
--* process group leader: Launching Jobs.
--* process groups: Job Control.
--* process ID: Process Creation Concepts.
--* process image: Process Creation Concepts.
--* process lifetime: Process Creation Concepts.
--* process priority: Priority.
--* process signal mask: Process Signal Mask.
--* process termination: Program Termination.
--* processor time: Processor Time.
--* profiling alarm signal: Alarm Signals.
--* profiling timer: Setting an Alarm.
--* program argument syntax: Argument Syntax.
--* program arguments: Program Arguments.
--* program arguments, parsing: Parsing Program Arguments.
--* program error signals: Program Error Signals.
--* program name: Error Messages.
--* program startup: Program Arguments.
--* program termination: Program Termination.
--* program termination signals: Termination Signals.
--* programming your own streams: Custom Streams.
--* project complex numbers: Operations on Complex.
--* protocol (of socket): Socket Concepts.
--* protocol family: Socket Concepts.
--* protocols: NSS Basics.
--* protocols database: Protocols Database.
--* prototypes for variadic functions: Variadic Prototypes.
--* pseudo-random numbers: Pseudo-Random Numbers.
--* pseudo-terminals: Pseudo-Terminals.
--* punctuation character <1>: Classification of Wide Characters.
--* punctuation character: Classification of Characters.
--* pushing input back: Unreading.
--* quick sort function (for arrays): Array Sort Function.
--* QUIT character: Signal Characters.
--* quit signal: Termination Signals.
--* quote removal: Expansion Stages.
--* race conditions, relating to job control: Launching Jobs.
--* race conditions, relating to signals: Signals in Handler.
--* radix (of floating point number): Floating Point Concepts.
--* raising signals: Generating Signals.
--* random numbers: Pseudo-Random Numbers.
--* random-access files: File Position.
--* range error: Math Error Reporting.
--* range of integer type: Range of Type.
--* read lock: File Locks.
--* reading from a directory: Accessing Directories.
--* reading from a file descriptor: I/O Primitives.
--* reading from a socket: Transferring Data.
--* reading from a stream, by blocks: Block Input/Output.
--* reading from a stream, by characters: Character Input.
--* reading from a stream, formatted: Formatted Input.
--* real group ID: Process Persona.
--* real user ID: Process Persona.
--* real-time timer: Setting an Alarm.
--* receiving datagrams: Receiving Datagrams.
--* record locking: File Locks.
--* redirecting input and output: Duplicating Descriptors.
--* reentrant functions: Nonreentrancy.
--* reentrant NSS functions: NSS Module Names.
--* relative file name: File Name Resolution.
--* removal of quotes: Expansion Stages.
--* removing a file: Deleting Files.
--* removing macros that shadow functions: Macro Definitions.
--* renaming a file: Renaming Files.
--* reporting bugs: Reporting Bugs.
--* reporting errors: Error Reporting.
--* REPRINT character: Editing Characters.
--* reserved names: Reserved Names.
--* resource limits: Limits on Resources.
--* restarting interrupted primitives: Interrupted Primitives.
--* restrictions on signal handler functions: Nonreentrancy.
--* root directory: File Name Resolution.
--* rpc: NSS Basics.
--* running a command: Running a Command.
--* saved set-group-ID: How Change Persona.
--* saved set-user-ID: How Change Persona.
--* scanning the group list: Scanning All Groups.
--* scanning the user list: Scanning All Users.
--* scatter-gather: Scatter-Gather.
--* search function (for arrays): Array Search Function.
--* search functions (for strings): Search Functions.
--* seed (for random numbers): Pseudo-Random Numbers.
--* seeking on a file descriptor: File Position Primitive.
--* seeking on a stream: File Positioning.
--* segmentation violation: Program Error Signals.
--* sending a datagram: Sending Datagrams.
--* sending signals: Generating Signals.
--* sequential-access files: File Position.
--* server: Connections.
--* services: NSS Basics.
--* services database: Services Database.
--* session <1>: Concepts of Job Control.
--* session: Job Control.
--* session leader: Concepts of Job Control.
--* setting an alarm: Setting an Alarm.
--* setuid programs: How Change Persona.
--* setuid programs and file access: Testing File Access.
--* severity class <1>: Adding Severity Classes.
--* severity class: Printing Formatted Messages.
--* shadow: NSS Basics.
--* shadowing functions with macros: Macro Definitions.
--* shared lock: File Locks.
--* shell: Concepts of Job Control.
--* shift state: Keeping the state.
--* shrinking objects: Growing Objects.
--* shutting down a socket: Closing a Socket.
--* sigaction flags: Flags for Sigaction.
--* sigaction function: Advanced Signal Handling.
--* SIGCHLD, handling of: Stopped and Terminated Jobs.
--* sign (of floating point number): Floating Point Concepts.
--* signal <1>: Signal Handling.
--* signal: FP Exceptions.
--* signal action: Delivery of Signal.
--* signal actions: Signal Actions.
--* signal flags: Flags for Sigaction.
--* signal function: Basic Signal Handling.
--* signal handler function: Defining Handlers.
--* signal mask: Process Signal Mask.
--* signal messages: Signal Messages.
--* signal names: Standard Signals.
--* signal number: Standard Signals.
--* signal set: Signal Sets.
--* signals, generating: Generating Signals.
--* significand (of floating point number): Floating Point Concepts.
--* SIGTTIN, from background job: Access to the Terminal.
--* SIGTTOU, from background job: Access to the Terminal.
--* size of string: Representation of Strings.
--* SJIS: Extended Char Intro.
--* socket: Sockets.
--* socket address (name) binding: Socket Addresses.
--* socket domain: Socket Concepts.
--* socket namespace: Socket Concepts.
--* socket option level: Socket Options.
--* socket options: Socket Options.
--* socket pair: Socket Pairs.
--* socket protocol: Socket Concepts.
--* socket shutdown: Closing a Socket.
--* socket, client actions: Connecting.
--* socket, closing: Closing a Socket.
--* socket, connecting: Connecting.
--* socket, creating: Creating a Socket.
--* socket, initiating a connection: Connecting.
--* sockets, accepting connections: Accepting Connections.
--* sockets, listening: Listening.
--* sockets, server actions: Listening.
--* soft limit: Limits on Resources.
--* soft link: Symbolic Links.
--* sort function (for arrays): Array Sort Function.
--* sparse files: File Position Primitive.
--* special files: Making Special Files.
--* special functions: Special Functions.
--* specified action (for a signal): Delivery of Signal.
--* square root function: Exponents and Logarithms.
--* stable sorting: Array Sort Function.
--* standard dot notation, for Internet addresses: Abstract Host Addresses.
--* standard environment variables: Standard Environment.
--* standard error file descriptor: Descriptors and Streams.
--* standard error stream: Standard Streams.
--* standard file descriptors: Descriptors and Streams.
--* standard input file descriptor: Descriptors and Streams.
--* standard input stream: Standard Streams.
--* standard output file descriptor: Descriptors and Streams.
--* standard output stream: Standard Streams.
--* standard streams: Standard Streams.
--* standards: Standards and Portability.
--* START character: Start/Stop Characters.
--* startup of program: Program Arguments.
--* stateful <1>: glibc iconv Implementation.
--* stateful <2>: iconv Examples.
--* stateful <3>: Generic Conversion Interface.
--* stateful <4>: Converting Strings.
--* stateful <5>: Converting a Character.
--* stateful: Keeping the state.
--* static allocation: Memory Concepts.
--* STATUS character: Other Special.
--* status codes: Error Reporting.
--* status of a file: Attribute Meanings.
--* status of obstack: Status of an Obstack.
--* sticky bit: Permission Bits.
--* STOP character: Start/Stop Characters.
--* stop signal: Job Control Signals.
--* stopped job: Concepts of Job Control.
--* stopped jobs, continuing: Continuing Stopped Jobs.
--* stopped jobs, detecting: Stopped and Terminated Jobs.
--* storage allocation: Memory Allocation.
--* stream (sockets): Socket Concepts.
--* stream, for I/O to a string: String Streams.
--* streams and descriptors: Stream/Descriptor Precautions.
--* streams, and file descriptors: Descriptors and Streams.
--* streams, standard: Standard Streams.
--* string: Representation of Strings.
--* string allocation: Representation of Strings.
--* string collation functions: Collation Functions.
--* string comparison functions: String/Array Comparison.
--* string concatenation functions: Copying and Concatenation.
--* string copy functions: Copying and Concatenation.
--* string length: Representation of Strings.
--* string literal: Representation of Strings.
--* string search functions: Search Functions.
--* string stream: String Streams.
--* string vectors, null-character separated: Argz and Envz Vectors.
--* string, representation of: Representation of Strings.
--* style of communication (of a socket): Socket Concepts.
--* subshell: Initializing the Shell.
--* substitution of variables and commands: Expansion Stages.
--* successive signals: Merged Signals.
--* summer time: Broken-down Time.
--* SunOS: Berkeley Unix.
--* supplementary group IDs: Process Persona.
--* SUSP character: Signal Characters.
--* suspend character: Signal Characters.
--* SVID: SVID.
--* symbolic link: Symbolic Links.
--* symbolic link, opening: Open-time Flags.
--* synchronizing <1>: Synchronizing AIO Operations.
--* synchronizing: Synchronizing I/O.
--* syntax error messages, in argp: Argp Helper Functions.
--* syntax, for program arguments: Argument Syntax.
--* syntax, for reading numbers: Parsing of Numbers.
--* System V Unix: SVID.
--* TCP (Internet protocol): Protocols Database.
--* template, for printf: Formatted Output.
--* template, for scanf: Formatted Input.
--* TERM environment variable: Standard Environment.
--* terminal flow control: Line Control.
--* terminal identification: Is It a Terminal.
--* terminal input queue: I/O Queues.
--* terminal input queue, clearing: Line Control.
--* terminal input signal: Job Control Signals.
--* terminal line control functions: Line Control.
--* terminal line speed: Line Speed.
--* terminal mode data types: Mode Data Types.
--* terminal mode functions: Mode Functions.
--* terminal output queue: I/O Queues.
--* terminal output queue, flushing: Line Control.
--* terminal output signal: Job Control Signals.
--* terminated jobs, detecting: Stopped and Terminated Jobs.
--* termination signal: Termination Signals.
--* testing access permission: Testing File Access.
--* testing exit status of child process: Process Completion.
--* text stream: Binary Streams.
--* ticks, clock: Processor Time.
--* tilde expansion: Expansion Stages.
--* TIME termios slot: Noncanonical Input.
--* time zone: TZ Variable.
--* time zone database: TZ Variable.
--* time, calendar: Calendar Time.
--* time, elapsed CPU: Processor Time.
--* time, high precision: Precision Time.
--* timer, profiling: Setting an Alarm.
--* timer, real-time: Setting an Alarm.
--* timer, virtual: Setting an Alarm.
--* timers, setting: Setting an Alarm.
--* timing error in signal handling: Remembering a Signal.
--* TMPDIR environment variable: Temporary Files.
--* tokenizing strings: Finding Tokens in a String.
--* tools, for installing library: Tools for Compilation.
--* transmitting datagrams: Sending Datagrams.
--* tree, directory: Working on Directory Trees.
--* triangulation: glibc iconv Implementation.
--* trigonometric functions: Trig Functions.
--* type measurements, floating: Floating Type Macros.
--* type measurements, integer: Width of Type.
--* type modifier character (printf): Output Conversion Syntax.
--* type modifier character (scanf): Input Conversion Syntax.
--* typeahead buffer: I/O Queues.
--* TZ environment variable: Standard Environment.
--* UCS2: Extended Char Intro.
--* UCS4: Extended Char Intro.
--* umask: Setting Permissions.
--* unbuffered stream: Buffering Concepts.
--* unconstrained storage allocation: Unconstrained Allocation.
--* undefining macros that shadow functions: Macro Definitions.
--* underflow exception: FP Exceptions.
--* Unicode: Extended Char Intro.
--* Unix, Berkeley: Berkeley Unix.
--* Unix, System V: SVID.
--* unlinking a file: Deleting Files.
--* unordered comparison: FP Comparison Functions.
--* unreading characters: Unreading.
--* upgrading from libc5: Linux.
--* upper-case character <1>: Classification of Wide Characters.
--* upper-case character: Classification of Characters.
--* urgent data signal: Asynchronous I/O Signals.
--* urgent socket condition: Out-of-Band Data.
--* usage limits: Limits on Resources.
--* usage messages, in argp: Argp Helper Functions.
--* user accounting database: User Accounting Database.
--* user database: User Database.
--* user ID: User and Group IDs.
--* user ID, determining: Who Logged In.
--* user name: User and Group IDs.
--* user signals: Miscellaneous Signals.
--* usual file name errors: File Name Errors.
--* UTF-7: Extended Char Intro.
--* UTF-8: Extended Char Intro.
--* va_copy: Copying and Concatenation.
--* variable number of arguments: Variadic Functions.
--* variable substitution: Expansion Stages.
--* variable-sized arrays: GNU C Variable-Size Arrays.
--* variadic function argument access: Receiving Arguments.
--* variadic function prototypes: Variadic Prototypes.
--* variadic functions: Variadic Functions.
--* variadic functions, calling: Calling Variadics.
--* virtual time alarm signal: Alarm Signals.
--* virtual timer: Setting an Alarm.
--* volatile declarations: Nonreentrancy.
--* waiting for a signal: Waiting for a Signal.
--* waiting for completion of child process: Process Completion.
--* waiting for input or output: Waiting for I/O.
--* WERASE character: Editing Characters.
--* whitespace character <1>: Classification of Wide Characters.
--* whitespace character: Classification of Characters.
--* wide character: Extended Char Intro.
--* width of integer type: Width of Type.
--* wildcard expansion: Expansion Stages.
--* word expansion: Word Expansion.
--* working directory: Working Directory.
--* write lock: File Locks.
--* writing to a file descriptor: I/O Primitives.
--* writing to a socket: Transferring Data.
--* writing to a stream, by blocks: Block Input/Output.
--* writing to a stream, by characters: Simple Output.
--* writing to a stream, formatted: Formatted Output.
--* zero divide: FP Exceptions.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-49 glibc-2.1.3/manual/libc.info-49
---- ../glibc-2.1.3/manual/libc.info-49 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-49 1969-12-31 16:00:00.000000000 -0800
-@@ -1,160 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Type Index, Next: Function Index, Prev: Concept Index, Up: Top
--
--Type Index
--**********
--
--* Menu:
--
--* __ftw64_func_t: Working on Directory Trees.
--* __ftw_func_t: Working on Directory Trees.
--* __nftw64_func_t: Working on Directory Trees.
--* __nftw_func_t: Working on Directory Trees.
--* blkcnt64_t: Attribute Meanings.
--* blkcnt_t: Attribute Meanings.
--* cc_t: Mode Data Types.
--* clock_t: Basic CPU Time.
--* comparison_fn_t: Comparison Functions.
--* cookie_close_function: Hook Functions.
--* cookie_io_functions_t: Streams and Cookies.
--* cookie_read_function: Hook Functions.
--* cookie_seek_function: Hook Functions.
--* cookie_write_function: Hook Functions.
--* dev_t: Attribute Meanings.
--* DIR: Opening a Directory.
--* div_t: Integer Division.
--* enum mcheck_status: Heap Consistency Checking.
--* fd_set: Waiting for I/O.
--* FILE: Streams.
--* fpos64_t: Portable Positioning.
--* fpos_t: Portable Positioning.
--* gid_t: Reading Persona.
--* glob_t: Calling Glob.
--* iconv_t: Generic Conversion Interface.
--* imaxdiv_t: Integer Division.
--* ino64_t: Attribute Meanings.
--* ino_t: Attribute Meanings.
--* jmp_buf: Non-Local Details.
--* ldiv_t: Integer Division.
--* lldiv_t: Integer Division.
--* mbstate_t: Keeping the state.
--* mode_t: Attribute Meanings.
--* nlink_t: Attribute Meanings.
--* off64_t: File Position Primitive.
--* off_t: File Position Primitive.
--* pid_t: Process Identification.
--* printf_arginfo_function: Defining the Output Handler.
--* printf_function: Defining the Output Handler.
--* ptrdiff_t: Important Data Types.
--* regex_t: POSIX Regexp Compilation.
--* regmatch_t: Regexp Subexpressions.
--* regoff_t: Regexp Subexpressions.
--* sig_atomic_t: Atomic Types.
--* sighandler_t: Basic Signal Handling.
--* sigjmp_buf: Non-Local Exits and Signals.
--* sigset_t: Signal Sets.
--* size_t: Important Data Types.
--* speed_t: Line Speed.
--* ssize_t: I/O Primitives.
--* struct aiocb: Asynchronous I/O.
--* struct aiocb64: Asynchronous I/O.
--* struct aioinit: Configuration of AIO.
--* struct argp: Argp Parsers.
--* struct argp_child: Argp Children.
--* struct argp_option: Argp Option Vectors.
--* struct argp_state: Argp Parsing State.
--* struct dirent: Directory Entries.
--* struct ENTRY: Hash Search Function.
--* struct exit_status: Manipulating the Database.
--* struct flock: File Locks.
--* struct fstab: Filesystem handling.
--* struct FTW: Working on Directory Trees.
--* struct gconv_step: glibc iconv Implementation.
--* struct gconv_step_data: glibc iconv Implementation.
--* struct group: Group Data Structure.
--* struct hostent: Host Names.
--* struct if_nameindex: Interface Naming.
--* struct in6_addr: Host Address Data Type.
--* struct in_addr: Host Address Data Type.
--* struct iovec: Scatter-Gather.
--* struct itimerval: Setting an Alarm.
--* struct lconv: The Lame Way to Locale Data.
--* struct linger: Socket-Level Options.
--* struct mallinfo: Statistics of Malloc.
--* struct mntent: Filesystem handling.
--* struct netent: Networks Database.
--* struct ntptimeval: Precision Time.
--* struct obstack: Creating Obstacks.
--* struct option: Getopt Long Options.
--* struct passwd: User Data Structure.
--* struct printf_info: Conversion Specifier Options.
--* struct protoent: Protocols Database.
--* struct rlimit: Limits on Resources.
--* struct rlimit64: Limits on Resources.
--* struct rusage: Resource Usage.
--* struct servent: Services Database.
--* struct sigaction: Advanced Signal Handling.
--* struct sigaltstack: Signal Stack.
--* struct sigstack: Signal Stack.
--* struct sigvec: BSD Handler.
--* struct sockaddr: Address Formats.
--* struct sockaddr_in: Internet Address Formats.
--* struct sockaddr_in6: Internet Address Formats.
--* struct sockaddr_un: Local Namespace Details.
--* struct stat: Attribute Meanings.
--* struct stat64: Attribute Meanings.
--* struct termios: Mode Data Types.
--* struct timeval: High-Resolution Calendar.
--* struct timex: Precision Time.
--* struct timezone: High-Resolution Calendar.
--* struct tm: Broken-down Time.
--* struct tms: Detailed CPU Time.
--* struct utimbuf: File Times.
--* struct utmp: Manipulating the Database.
--* struct utmpx: XPG Functions.
--* struct utsname: Hardware/Software Type ID.
--* tcflag_t: Mode Data Types.
--* time_t: Simple Calendar Time.
--* uid_t: Reading Persona.
--* union wait: BSD Wait Functions.
--* va_list: Argument Macros.
--* VISIT: Tree Search Function.
--* wchar_t: Extended Char Intro.
--* wctrans_t: Wide Character Case Conversion.
--* wctype_t: Classification of Wide Characters.
--* wint_t: Extended Char Intro.
--* wordexp_t: Calling Wordexp.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-5 glibc-2.1.3/manual/libc.info-5
---- ../glibc-2.1.3/manual/libc.info-5 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-5 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1317 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Alloca Example, Next: Advantages of Alloca, Up: Variable Size Automatic
--
--`alloca' Example
------------------
--
-- As an example of use of `alloca', here is a function that opens a
--file name made from concatenating two argument strings, and returns a
--file descriptor or minus one signifying failure:
--
-- int
-- open2 (char *str1, char *str2, int flags, int mode)
-- {
-- char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
-- stpcpy (stpcpy (name, str1), str2);
-- return open (name, flags, mode);
-- }
--
--Here is how you would get the same results with `malloc' and `free':
--
-- int
-- open2 (char *str1, char *str2, int flags, int mode)
-- {
-- char *name = (char *) malloc (strlen (str1) + strlen (str2) + 1);
-- int desc;
-- if (name == 0)
-- fatal ("virtual memory exceeded");
-- stpcpy (stpcpy (name, str1), str2);
-- desc = open (name, flags, mode);
-- free (name);
-- return desc;
-- }
--
-- As you can see, it is simpler with `alloca'. But `alloca' has
--other, more important advantages, and some disadvantages.
--
--
--File: libc.info, Node: Advantages of Alloca, Next: Disadvantages of Alloca, Prev: Alloca Example, Up: Variable Size Automatic
--
--Advantages of `alloca'
------------------------
--
-- Here are the reasons why `alloca' may be preferable to `malloc':
--
-- * Using `alloca' wastes very little space and is very fast. (It is
-- open-coded by the GNU C compiler.)
--
-- * Since `alloca' does not have separate pools for different sizes of
-- block, space used for any size block can be reused for any other
-- size. `alloca' does not cause storage fragmentation.
--
-- * Nonlocal exits done with `longjmp' (*note Non-Local Exits::.)
-- automatically free the space allocated with `alloca' when they exit
-- through the function that called `alloca'. This is the most
-- important reason to use `alloca'.
--
-- To illustrate this, suppose you have a function
-- `open_or_report_error' which returns a descriptor, like `open', if
-- it succeeds, but does not return to its caller if it fails. If
-- the file cannot be opened, it prints an error message and jumps
-- out to the command level of your program using `longjmp'. Let's
-- change `open2' (*note Alloca Example::.) to use this subroutine:
--
-- int
-- open2 (char *str1, char *str2, int flags, int mode)
-- {
-- char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
-- stpcpy (stpcpy (name, str1), str2);
-- return open_or_report_error (name, flags, mode);
-- }
--
-- Because of the way `alloca' works, the storage it allocates is
-- freed even when an error occurs, with no special effort required.
--
-- By contrast, the previous definition of `open2' (which uses
-- `malloc' and `free') would develop a storage leak if it were
-- changed in this way. Even if you are willing to make more changes
-- to fix it, there is no easy way to do so.
--
--
--File: libc.info, Node: Disadvantages of Alloca, Next: GNU C Variable-Size Arrays, Prev: Advantages of Alloca, Up: Variable Size Automatic
--
--Disadvantages of `alloca'
---------------------------
--
-- These are the disadvantages of `alloca' in comparison with `malloc':
--
-- * If you try to allocate more storage than the machine can provide,
-- you don't get a clean error message. Instead you get a fatal
-- signal like the one you would get from an infinite recursion;
-- probably a segmentation violation (*note Program Error Signals::.).
--
-- * Some non-GNU systems fail to support `alloca', so it is less
-- portable. However, a slower emulation of `alloca' written in C is
-- available for use on systems with this deficiency.
--
--
--File: libc.info, Node: GNU C Variable-Size Arrays, Prev: Disadvantages of Alloca, Up: Variable Size Automatic
--
--GNU C Variable-Size Arrays
----------------------------
--
-- In GNU C, you can replace most uses of `alloca' with an array of
--variable size. Here is how `open2' would look then:
--
-- int open2 (char *str1, char *str2, int flags, int mode)
-- {
-- char name[strlen (str1) + strlen (str2) + 1];
-- stpcpy (stpcpy (name, str1), str2);
-- return open (name, flags, mode);
-- }
--
-- But `alloca' is not always equivalent to a variable-sized array, for
--several reasons:
--
-- * A variable size array's space is freed at the end of the scope of
-- the name of the array. The space allocated with `alloca' remains
-- until the end of the function.
--
-- * It is possible to use `alloca' within a loop, allocating an
-- additional block on each iteration. This is impossible with
-- variable-sized arrays.
--
-- *Note:* If you mix use of `alloca' and variable-sized arrays within
--one function, exiting a scope in which a variable-sized array was
--declared frees all blocks allocated with `alloca' during the execution
--of that scope.
--
--
--File: libc.info, Node: Character Handling, Next: String and Array Utilities, Prev: Memory Allocation, Up: Top
--
--Character Handling
--******************
--
-- Programs that work with characters and strings often need to
--classify a character--is it alphabetic, is it a digit, is it
--whitespace, and so on--and perform case conversion operations on
--characters. The functions in the header file `ctype.h' are provided
--for this purpose.
--
-- Since the choice of locale and character set can alter the
--classifications of particular character codes, all of these functions
--are affected by the current locale. (More precisely, they are affected
--by the locale currently selected for character classification--the
--`LC_CTYPE' category; see *Note Locale Categories::.)
--
-- The ISO C standard specifies two different sets of functions. The
--one set works on `char' type characters, the other one on `wchar_t'
--wide character (*note Extended Char Intro::.).
--
--* Menu:
--
--* Classification of Characters:: Testing whether characters are
-- letters, digits, punctuation, etc.
--
--* Case Conversion:: Case mapping, and the like.
--* Classification of Wide Characters:: Character class determination for
-- wide characters.
--* Using Wide Char Classes:: Notes on using the wide character
-- classes.
--* Wide Character Case Conversion:: Mapping of wide characters.
--
--
--File: libc.info, Node: Classification of Characters, Next: Case Conversion, Up: Character Handling
--
--Classification of Characters
--============================
--
-- This section explains the library functions for classifying
--characters. For example, `isalpha' is the function to test for an
--alphabetic character. It takes one argument, the character to test,
--and returns a nonzero integer if the character is alphabetic, and zero
--otherwise. You would use it like this:
--
-- if (isalpha (c))
-- printf ("The character `%c' is alphabetic.\n", c);
--
-- Each of the functions in this section tests for membership in a
--particular class of characters; each has a name starting with `is'.
--Each of them takes one argument, which is a character to test, and
--returns an `int' which is treated as a boolean value. The character
--argument is passed as an `int', and it may be the constant value `EOF'
--instead of a real character.
--
-- The attributes of any given character can vary between locales.
--*Note Locales::, for more information on locales.
--
-- These functions are declared in the header file `ctype.h'.
--
-- - Function: int islower (int C)
-- Returns true if C is a lower-case letter. The letter need not be
-- from the Latin alphabet, any alphabet representable is valid.
--
-- - Function: int isupper (int C)
-- Returns true if C is an upper-case letter. The letter need not be
-- from the Latin alphabet, any alphabet representable is valid.
--
-- - Function: int isalpha (int C)
-- Returns true if C is an alphabetic character (a letter). If
-- `islower' or `isupper' is true of a character, then `isalpha' is
-- also true.
--
-- In some locales, there may be additional characters for which
-- `isalpha' is true--letters which are neither upper case nor lower
-- case. But in the standard `"C"' locale, there are no such
-- additional characters.
--
-- - Function: int isdigit (int C)
-- Returns true if C is a decimal digit (`0' through `9').
--
-- - Function: int isalnum (int C)
-- Returns true if C is an alphanumeric character (a letter or
-- number); in other words, if either `isalpha' or `isdigit' is true
-- of a character, then `isalnum' is also true.
--
-- - Function: int isxdigit (int C)
-- Returns true if C is a hexadecimal digit. Hexadecimal digits
-- include the normal decimal digits `0' through `9' and the letters
-- `A' through `F' and `a' through `f'.
--
-- - Function: int ispunct (int C)
-- Returns true if C is a punctuation character. This means any
-- printing character that is not alphanumeric or a space character.
--
-- - Function: int isspace (int C)
-- Returns true if C is a "whitespace" character. In the standard
-- `"C"' locale, `isspace' returns true for only the standard
-- whitespace characters:
--
-- `' ''
-- space
--
-- `'\f''
-- formfeed
--
-- `'\n''
-- newline
--
-- `'\r''
-- carriage return
--
-- `'\t''
-- horizontal tab
--
-- `'\v''
-- vertical tab
--
-- - Function: int isblank (int C)
-- Returns true if C is a blank character; that is, a space or a tab.
-- This function is a GNU extension.
--
-- - Function: int isgraph (int C)
-- Returns true if C is a graphic character; that is, a character
-- that has a glyph associated with it. The whitespace characters
-- are not considered graphic.
--
-- - Function: int isprint (int C)
-- Returns true if C is a printing character. Printing characters
-- include all the graphic characters, plus the space (` ') character.
--
-- - Function: int iscntrl (int C)
-- Returns true if C is a control character (that is, a character that
-- is not a printing character).
--
-- - Function: int isascii (int C)
-- Returns true if C is a 7-bit `unsigned char' value that fits into
-- the US/UK ASCII character set. This function is a BSD extension
-- and is also an SVID extension.
--
--
--File: libc.info, Node: Case Conversion, Next: Classification of Wide Characters, Prev: Classification of Characters, Up: Character Handling
--
--Case Conversion
--===============
--
-- This section explains the library functions for performing
--conversions such as case mappings on characters. For example, `toupper'
--converts any character to upper case if possible. If the character
--can't be converted, `toupper' returns it unchanged.
--
-- These functions take one argument of type `int', which is the
--character to convert, and return the converted character as an `int'.
--If the conversion is not applicable to the argument given, the argument
--is returned unchanged.
--
-- *Compatibility Note:* In pre-ISO C dialects, instead of returning
--the argument unchanged, these functions may fail when the argument is
--not suitable for the conversion. Thus for portability, you may need to
--write `islower(c) ? toupper(c) : c' rather than just `toupper(c)'.
--
-- These functions are declared in the header file `ctype.h'.
--
-- - Function: int tolower (int C)
-- If C is an upper-case letter, `tolower' returns the corresponding
-- lower-case letter. If C is not an upper-case letter, C is
-- returned unchanged.
--
-- - Function: int toupper (int C)
-- If C is a lower-case letter, `toupper' returns the corresponding
-- upper-case letter. Otherwise C is returned unchanged.
--
-- - Function: int toascii (int C)
-- This function converts C to a 7-bit `unsigned char' value that
-- fits into the US/UK ASCII character set, by clearing the high-order
-- bits. This function is a BSD extension and is also an SVID
-- extension.
--
-- - Function: int _tolower (int C)
-- This is identical to `tolower', and is provided for compatibility
-- with the SVID. *Note SVID::.
--
-- - Function: int _toupper (int C)
-- This is identical to `toupper', and is provided for compatibility
-- with the SVID.
--
--
--File: libc.info, Node: Classification of Wide Characters, Next: Using Wide Char Classes, Prev: Case Conversion, Up: Character Handling
--
--Character class determination for wide characters
--=================================================
--
-- The second amendment to ISO C89 defines functions to classify wide
--character. Although the original ISO C89 standard already defined the
--type `wchar_t' but no functions operating on them were defined.
--
-- The general design of the classification functions for wide
--characters is more general. It allows to extend the set of available
--classification beyond the set which is always available. The POSIX
--standard specifies a way how the extension can be done and this is
--already implemented in the GNU C library implementation of the
--`localedef' program.
--
-- The character class functions are normally implemented using bitsets.
--I.e., for the character in question the appropriate bitset is read from
--a table and a test is performed whether a certain bit is set in this
--bitset. Which bit is tested for is determined by the class.
--
-- For the wide character classification functions this is made visible.
--There is a type representing the classification, a function to retrieve
--this value for a specific class, and a function to test using the
--classification value whether a given character is in this class. On top
--of this the normal character classification functions as used for
--`char' objects can be defined.
--
-- - Data type: wctype_t
-- The `wctype_t' can hold a value which represents a character class.
-- The ony defined way to generate such a value is by using the
-- `wctype' function.
--
-- This type is defined in `wctype.h'.
--
-- - Function: wctype_t wctype (const char *PROPERTY)
-- The `wctype' returns a value representing a class of wide
-- characters which is identified by the string PROPERTY. Beside
-- some standard properties each locale can define its own ones. In
-- case no property with the given name is known for the current
-- locale for the `LC_CTYPE' category the function returns zero.
--
-- The properties known in every locale are:
--
-- `"alnum"' `"alpha"' `"cntrl"' `"digit"'
-- `"graph"' `"lower"' `"print"' `"punct"'
-- `"space"' `"upper"' `"xdigit"'
--
-- This function is declared in `wctype.h'.
--
-- To test the membership of a character to one of the non-standard
--classes the ISO C standard defines a completely new function.
--
-- - Function: int iswctype (wint_t WC, wctype_t DESC)
-- This function returns a nonzero value if WC is in the character
-- class specified by DESC. DESC must previously be returned by a
-- successful call to `wctype'.
--
-- This function is declared in `wctype.h'.
--
-- The make it easier to use the commonly used classification functions
--they are defined in the C library. There is no need to use `wctype' is
--the property string is one of the known character classes. In some
--situations it is desirable to construct the property string and then it
--gets important that `wctype' can also handle the standard classes.
--
-- - Function: int iswalnum (wint_t WC)
-- This function returns a nonzero value if WC is an alphanumeric
-- character (a letter or number); in other words, if either
-- `iswalpha' or `iswdigit' is true of a character, then `iswalnum'
-- is also true.
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("alnum"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswalpha (wint_t WC)
-- Returns true if WC is an alphabetic character (a letter). If
-- `iswlower' or `iswupper' is true of a character, then `iswalpha'
-- is also true.
--
-- In some locales, there may be additional characters for which
-- `iswalpha' is true--letters which are neither upper case nor lower
-- case. But in the standard `"C"' locale, there are no such
-- additional characters.
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("alpha"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswcntrl (wint_t WC)
-- Returns true if WC is a control character (that is, a character
-- that is not a printing character).
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("cntrl"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswdigit (wint_t WC)
-- Returns true if WC is a digit (e.g., `0' through `9'). Please
-- note that this function does not only return a nonzero value for
-- *decimal* digits, but for all kinds of digits. A consequence is
-- that code like the following will *not* work unconditionally for
-- wide characters:
--
-- n = 0;
-- while (iswctype (*wc))
-- {
-- n *= 10;
-- n += *wc++ - L'0';
-- }
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("digit"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswgraph (wint_t WC)
-- Returns true if WC is a graphic character; that is, a character
-- that has a glyph associated with it. The whitespace characters
-- are not considered graphic.
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("graph"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswlower (wint_t WC)
-- Returns true if WC is a lower-case letter. The letter need not be
-- from the Latin alphabet, any alphabet representable is valid.
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("lower"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswprint (wint_t WC)
-- Returns true if WC is a printing character. Printing characters
-- include all the graphic characters, plus the space (` ') character.
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("print"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswpunct (wint_t WC)
-- Returns true if WC is a punctuation character. This means any
-- printing character that is not alphanumeric or a space character.
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("punct"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswspace (wint_t WC)
-- Returns true if WC is a "whitespace" character. In the standard
-- `"C"' locale, `iswspace' returns true for only the standard
-- whitespace characters:
--
-- `L' ''
-- space
--
-- `L'\f''
-- formfeed
--
-- `L'\n''
-- newline
--
-- `L'\r''
-- carriage return
--
-- `L'\t''
-- horizontal tab
--
-- `L'\v''
-- vertical tab
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("space"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswupper (wint_t WC)
-- Returns true if WC is an upper-case letter. The letter need not be
-- from the Latin alphabet, any alphabet representable is valid.
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("upper"))
--
-- It is declared in `wctype.h'.
--
-- - Function: int iswxdigit (wint_t WC)
-- Returns true if WC is a hexadecimal digit. Hexadecimal digits
-- include the normal decimal digits `0' through `9' and the letters
-- `A' through `F' and `a' through `f'.
--
-- This function can be implemented using
--
-- iswctype (wc, wctype ("xdigit"))
--
-- It is declared in `wctype.h'.
--
-- The GNu C library provides also a function which is not defined in
--the ISO C standard but which is available as a version for single byte
--characters as well.
--
-- - Function: int iswblank (wint_t WC)
-- Returns true if WC is a blank character; that is, a space or a tab.
-- This function is a GNU extension. It is declared in `wchar.h'.
--
--
--File: libc.info, Node: Using Wide Char Classes, Next: Wide Character Case Conversion, Prev: Classification of Wide Characters, Up: Character Handling
--
--Notes on using the wide character classes
--=========================================
--
-- The first note is probably nothing astonishing but still
--occasionally a cause of problems. The `iswXXX' functions can be
--implemented using macros and in fact, the GNU C library does this.
--They are still available as real functions but when the `wctype.h'
--header is included the macros will be used. This is nothing new
--compared to the `char' type versions of these functions.
--
-- The second notes covers something which is new. It can be best
--illustrated by a (real-world) example. The first piece of code is an
--excerpt from the original code. It is truncated a bit but the intention
--should be clear.
--
-- int
-- is_in_class (int c, const char *class)
-- {
-- if (strcmp (class, "alnum") == 0)
-- return isalnum (c);
-- if (strcmp (class, "alpha") == 0)
-- return isalpha (c);
-- if (strcmp (class, "cntrl") == 0)
-- return iscntrl (c);
-- ...
-- return 0;
-- }
--
-- Now with the `wctype' and `iswctype' one could avoid the `if'
--cascades. But rewriting the code as follows is wrong:
--
-- int
-- is_in_class (int c, const char *class)
-- {
-- wctype_t desc = wctype (class);
-- return desc ? iswctype ((wint_t) c, desc) : 0;
-- }
--
-- The problem is that it is not guarateed that the wide character
--representation of a single-byte character can be found using casting.
--In fact, usually this fails miserably. The correct solution for this
--problem is to write the code as follows:
--
-- int
-- is_in_class (int c, const char *class)
-- {
-- wctype_t desc = wctype (class);
-- return desc ? iswctype (btowc (c), desc) : 0;
-- }
--
-- *Note Converting a Character::, for more information on `btowc'.
--Please note that this change probably does not improve the performance
--of the program a lot since the `wctype' function still has to make the
--string comparisons. But it gets really interesting if the
--`is_in_class' function would be called more than once using the same
--class name. In this case the variable DESC could be computed once and
--reused for all the calls. Therefore the above form of the function is
--probably not the final one.
--
--
--File: libc.info, Node: Wide Character Case Conversion, Prev: Using Wide Char Classes, Up: Character Handling
--
--Mapping of wide characters.
--===========================
--
-- As for the classification functions the ISO C standard also
--generalizes the mapping functions. Instead of only allowing the two
--standard mappings the locale can contain others. Again, the
--`localedef' program already supports generating such locale data files.
--
-- - Data Type: wctrans_t
-- This data type is defined as a scalar type which can hold a value
-- representing the locale-dependent character mapping. There is no
-- way to construct such a value beside using the return value of the
-- `wctrans' function.
--
-- This type is defined in `wctype.h'.
--
-- - Function: wctrans_t wctrans (const char *PROPERTY)
-- The `wctrans' function has to be used to find out whether a named
-- mapping is defined in the current locale selected for the
-- `LC_CTYPE' category. If the returned value is non-zero it can
-- afterwards be used in calls to `towctrans'. If the return value is
-- zero no such mapping is known in the current locale.
--
-- Beside locale-specific mappings there are two mappings which are
-- guaranteed to be available in every locale:
--
-- `"tolower"' `"toupper"'
--
-- This function is declared in `wctype.h'.
--
-- - Function: wint_t towctrans (wint_t WC, wctrans_t DESC)
-- The `towctrans' function maps the input character WC according to
-- the rules of the mapping for which DESC is an descriptor and
-- returns the so found value. The DESC value must be obtained by a
-- successful call to `wctrans'.
--
-- This function is declared in `wctype.h'.
--
-- The ISO C standard also defines for the generally available mappings
--convenient shortcuts so that it is not necesary to call `wctrans' for
--them.
--
-- - Function: wint_t towlower (wint_t WC)
-- If WC is an upper-case letter, `towlower' returns the corresponding
-- lower-case letter. If WC is not an upper-case letter, WC is
-- returned unchanged.
--
-- `towlower' can be implemented using
--
-- towctrans (wc, wctrans ("tolower"))
--
-- This function is declared in `wctype.h'.
--
-- - Function: wint_t towupper (wint_t WC)
-- If WC is a lower-case letter, `towupper' returns the corresponding
-- upper-case letter. Otherwise WC is returned unchanged.
--
-- `towupper' can be implemented using
--
-- towctrans (wc, wctrans ("toupper"))
--
-- This function is declared in `wctype.h'.
--
-- The same warnings given in the last section for the use of the wide
--character classiffication function applies here. It is not possible to
--simply cast a `char' type value to a `wint_t' and use it as an argument
--for `towctrans' calls.
--
--
--File: libc.info, Node: String and Array Utilities, Next: Character Set Handling, Prev: Character Handling, Up: Top
--
--String and Array Utilities
--**************************
--
-- Operations on strings (or arrays of characters) are an important
--part of many programs. The GNU C library provides an extensive set of
--string utility functions, including functions for copying,
--concatenating, comparing, and searching strings. Many of these
--functions can also operate on arbitrary regions of storage; for
--example, the `memcpy' function can be used to copy the contents of any
--kind of array.
--
-- It's fairly common for beginning C programmers to "reinvent the
--wheel" by duplicating this functionality in their own code, but it pays
--to become familiar with the library functions and to make use of them,
--since this offers benefits in maintenance, efficiency, and portability.
--
-- For instance, you could easily compare one string to another in two
--lines of C code, but if you use the built-in `strcmp' function, you're
--less likely to make a mistake. And, since these library functions are
--typically highly optimized, your program may run faster too.
--
--* Menu:
--
--* Representation of Strings:: Introduction to basic concepts.
--* String/Array Conventions:: Whether to use a string function or an
-- arbitrary array function.
--* String Length:: Determining the length of a string.
--* Copying and Concatenation:: Functions to copy the contents of strings
-- and arrays.
--* String/Array Comparison:: Functions for byte-wise and character-wise
-- comparison.
--* Collation Functions:: Functions for collating strings.
--* Search Functions:: Searching for a specific element or substring.
--* Finding Tokens in a String:: Splitting a string into tokens by looking
-- for delimiters.
--* Encode Binary Data:: Encoding and Decoding of Binary Data.
--* Argz and Envz Vectors:: Null-separated string vectors.
--
--
--File: libc.info, Node: Representation of Strings, Next: String/Array Conventions, Up: String and Array Utilities
--
--Representation of Strings
--=========================
--
-- This section is a quick summary of string concepts for beginning C
--programmers. It describes how character strings are represented in C
--and some common pitfalls. If you are already familiar with this
--material, you can skip this section.
--
-- A "string" is an array of `char' objects. But string-valued
--variables are usually declared to be pointers of type `char *'. Such
--variables do not include space for the text of a string; that has to be
--stored somewhere else--in an array variable, a string constant, or
--dynamically allocated memory (*note Memory Allocation::.). It's up to
--you to store the address of the chosen memory space into the pointer
--variable. Alternatively you can store a "null pointer" in the pointer
--variable. The null pointer does not point anywhere, so attempting to
--reference the string it points to gets an error.
--
-- By convention, a "null character", `'\0'', marks the end of a
--string. For example, in testing to see whether the `char *' variable P
--points to a null character marking the end of a string, you can write
--`!*P' or `*P == '\0''.
--
-- A null character is quite different conceptually from a null pointer,
--although both are represented by the integer `0'.
--
-- "String literals" appear in C program source as strings of
--characters between double-quote characters (`"'). In ISO C, string
--literals can also be formed by "string concatenation": `"a" "b"' is the
--same as `"ab"'. Modification of string literals is not allowed by the
--GNU C compiler, because literals are placed in read-only storage.
--
-- Character arrays that are declared `const' cannot be modified
--either. It's generally good style to declare non-modifiable string
--pointers to be of type `const char *', since this often allows the C
--compiler to detect accidental modifications as well as providing some
--amount of documentation about what your program intends to do with the
--string.
--
-- The amount of memory allocated for the character array may extend
--past the null character that normally marks the end of the string. In
--this document, the term "allocated size" is always used to refer to the
--total amount of memory allocated for the string, while the term
--"length" refers to the number of characters up to (but not including)
--the terminating null character.
--
-- A notorious source of program bugs is trying to put more characters
--in a string than fit in its allocated size. When writing code that
--extends strings or moves characters into a pre-allocated array, you
--should be very careful to keep track of the length of the text and make
--explicit checks for overflowing the array. Many of the library
--functions *do not* do this for you! Remember also that you need to
--allocate an extra byte to hold the null character that marks the end of
--the string.
--
--
--File: libc.info, Node: String/Array Conventions, Next: String Length, Prev: Representation of Strings, Up: String and Array Utilities
--
--String and Array Conventions
--============================
--
-- This chapter describes both functions that work on arbitrary arrays
--or blocks of memory, and functions that are specific to null-terminated
--arrays of characters.
--
-- Functions that operate on arbitrary blocks of memory have names
--beginning with `mem' (such as `memcpy') and invariably take an argument
--which specifies the size (in bytes) of the block of memory to operate
--on. The array arguments and return values for these functions have
--type `void *', and as a matter of style, the elements of these arrays
--are referred to as "bytes". You can pass any kind of pointer to these
--functions, and the `sizeof' operator is useful in computing the value
--for the size argument.
--
-- In contrast, functions that operate specifically on strings have
--names beginning with `str' (such as `strcpy') and look for a null
--character to terminate the string instead of requiring an explicit size
--argument to be passed. (Some of these functions accept a specified
--maximum length, but they also check for premature termination with a
--null character.) The array arguments and return values for these
--functions have type `char *', and the array elements are referred to as
--"characters".
--
-- In many cases, there are both `mem' and `str' versions of a
--function. The one that is more appropriate to use depends on the exact
--situation. When your program is manipulating arbitrary arrays or
--blocks of storage, then you should always use the `mem' functions. On
--the other hand, when you are manipulating null-terminated strings it is
--usually more convenient to use the `str' functions, unless you already
--know the length of the string in advance.
--
--
--File: libc.info, Node: String Length, Next: Copying and Concatenation, Prev: String/Array Conventions, Up: String and Array Utilities
--
--String Length
--=============
--
-- You can get the length of a string using the `strlen' function.
--This function is declared in the header file `string.h'.
--
-- - Function: size_t strlen (const char *S)
-- The `strlen' function returns the length of the null-terminated
-- string S. (In other words, it returns the offset of the
-- terminating null character within the array.)
--
-- For example,
-- strlen ("hello, world")
-- => 12
--
-- When applied to a character array, the `strlen' function returns
-- the length of the string stored there, not its allocated size.
-- You can get the allocated size of the character array that holds a
-- string using the `sizeof' operator:
--
-- char string[32] = "hello, world";
-- sizeof (string)
-- => 32
-- strlen (string)
-- => 12
--
-- But beware, this will not work unless STRING is the character
-- array itself, not a pointer to it. For example:
--
-- char string[32] = "hello, world";
-- char *ptr = string;
-- sizeof (string)
-- => 32
-- sizeof (ptr)
-- => 4 /* (on a machine with 4 byte pointers) */
--
-- This is an easy mistake to make when you are working with
-- functions that take string arguments; those arguments are always
-- pointers, not arrays.
--
--
-- - Function: size_t strnlen (const char *S, size_t MAXLEN)
-- The `strnlen' function returns the length of the null-terminated
-- string S is this length is smaller than MAXLEN. Otherwise it
-- returns MAXLEN. Therefore this function is equivalent to `(strlen
-- (S) < n ? strlen (S) : MAXLEN)' but it is more efficient.
--
-- char string[32] = "hello, world";
-- strnlen (string, 32)
-- => 12
-- strnlen (string, 5)
-- => 5
--
-- This function is a GNU extension.
--
--
--File: libc.info, Node: Copying and Concatenation, Next: String/Array Comparison, Prev: String Length, Up: String and Array Utilities
--
--Copying and Concatenation
--=========================
--
-- You can use the functions described in this section to copy the
--contents of strings and arrays, or to append the contents of one string
--to another. These functions are declared in the header file `string.h'.
--
-- A helpful way to remember the ordering of the arguments to the
--functions in this section is that it corresponds to an assignment
--expression, with the destination array specified to the left of the
--source array. All of these functions return the address of the
--destination array.
--
-- Most of these functions do not work properly if the source and
--destination arrays overlap. For example, if the beginning of the
--destination array overlaps the end of the source array, the original
--contents of that part of the source array may get overwritten before it
--is copied. Even worse, in the case of the string functions, the null
--character marking the end of the string may be lost, and the copy
--function might get stuck in a loop trashing all the memory allocated to
--your program.
--
-- All functions that have problems copying between overlapping arrays
--are explicitly identified in this manual. In addition to functions in
--this section, there are a few others like `sprintf' (*note Formatted
--Output Functions::.) and `scanf' (*note Formatted Input Functions::.).
--
-- - Function: void * memcpy (void *TO, const void *FROM, size_t SIZE)
-- The `memcpy' function copies SIZE bytes from the object beginning
-- at FROM into the object beginning at TO. The behavior of this
-- function is undefined if the two arrays TO and FROM overlap; use
-- `memmove' instead if overlapping is possible.
--
-- The value returned by `memcpy' is the value of TO.
--
-- Here is an example of how you might use `memcpy' to copy the
-- contents of an array:
--
-- struct foo *oldarray, *newarray;
-- int arraysize;
-- ...
-- memcpy (new, old, arraysize * sizeof (struct foo));
--
-- - Function: void * mempcpy (void *TO, const void *FROM, size_t SIZE)
-- The `mempcpy' function is nearly identical to the `memcpy'
-- function. It copies SIZE bytes from the object beginning at
-- `from' into the object pointed to by TO. But instead of returning
-- the value of `to' it returns a pointer to the byte following the
-- last written byte in the object beginning at TO. I.e., the value
-- is `((void *) ((char *) TO + SIZE))'.
--
-- This function is useful in situations where a number of objects
-- shall be copied to consecutive memory positions.
--
-- void *
-- combine (void *o1, size_t s1, void *o2, size_t s2)
-- {
-- void *result = malloc (s1 + s2);
-- if (result != NULL)
-- mempcpy (mempcpy (result, o1, s1), o2, s2);
-- return result;
-- }
--
-- This function is a GNU extension.
--
-- - Function: void * memmove (void *TO, const void *FROM, size_t SIZE)
-- `memmove' copies the SIZE bytes at FROM into the SIZE bytes at TO,
-- even if those two blocks of space overlap. In the case of
-- overlap, `memmove' is careful to copy the original values of the
-- bytes in the block at FROM, including those bytes which also
-- belong to the block at TO.
--
-- - Function: void * memccpy (void *TO, const void *FROM, int C, size_t
-- SIZE)
-- This function copies no more than SIZE bytes from FROM to TO,
-- stopping if a byte matching C is found. The return value is a
-- pointer into TO one byte past where C was copied, or a null
-- pointer if no byte matching C appeared in the first SIZE bytes of
-- FROM.
--
-- - Function: void * memset (void *BLOCK, int C, size_t SIZE)
-- This function copies the value of C (converted to an `unsigned
-- char') into each of the first SIZE bytes of the object beginning
-- at BLOCK. It returns the value of BLOCK.
--
-- - Function: char * strcpy (char *TO, const char *FROM)
-- This copies characters from the string FROM (up to and including
-- the terminating null character) into the string TO. Like
-- `memcpy', this function has undefined results if the strings
-- overlap. The return value is the value of TO.
--
-- - Function: char * strncpy (char *TO, const char *FROM, size_t SIZE)
-- This function is similar to `strcpy' but always copies exactly
-- SIZE characters into TO.
--
-- If the length of FROM is more than SIZE, then `strncpy' copies
-- just the first SIZE characters. Note that in this case there is
-- no null terminator written into TO.
--
-- If the length of FROM is less than SIZE, then `strncpy' copies all
-- of FROM, followed by enough null characters to add up to SIZE
-- characters in all. This behavior is rarely useful, but it is
-- specified by the ISO C standard.
--
-- The behavior of `strncpy' is undefined if the strings overlap.
--
-- Using `strncpy' as opposed to `strcpy' is a way to avoid bugs
-- relating to writing past the end of the allocated space for TO.
-- However, it can also make your program much slower in one common
-- case: copying a string which is probably small into a potentially
-- large buffer. In this case, SIZE may be large, and when it is,
-- `strncpy' will waste a considerable amount of time copying null
-- characters.
--
-- - Function: char * strdup (const char *S)
-- This function copies the null-terminated string S into a newly
-- allocated string. The string is allocated using `malloc'; see
-- *Note Unconstrained Allocation::. If `malloc' cannot allocate
-- space for the new string, `strdup' returns a null pointer.
-- Otherwise it returns a pointer to the new string.
--
-- - Function: char * strndup (const char *S, size_t SIZE)
-- This function is similar to `strdup' but always copies at most
-- SIZE characters into the newly allocated string.
--
-- If the length of S is more than SIZE, then `strndup' copies just
-- the first SIZE characters and adds a closing null terminator.
-- Otherwise all characters are copied and the string is terminated.
--
-- This function is different to `strncpy' in that it always
-- terminates the destination string.
--
-- `strndup' is a GNU extension.
--
-- - Function: char * stpcpy (char *TO, const char *FROM)
-- This function is like `strcpy', except that it returns a pointer to
-- the end of the string TO (that is, the address of the terminating
-- null character) rather than the beginning.
--
-- For example, this program uses `stpcpy' to concatenate `foo' and
-- `bar' to produce `foobar', which it then prints.
--
-- #include <string.h>
-- #include <stdio.h>
--
-- int
-- main (void)
-- {
-- char buffer[10];
-- char *to = buffer;
-- to = stpcpy (to, "foo");
-- to = stpcpy (to, "bar");
-- puts (buffer);
-- return 0;
-- }
--
-- This function is not part of the ISO or POSIX standards, and is not
-- customary on Unix systems, but we did not invent it either.
-- Perhaps it comes from MS-DOG.
--
-- Its behavior is undefined if the strings overlap.
--
-- - Function: char * stpncpy (char *TO, const char *FROM, size_t SIZE)
-- This function is similar to `stpcpy' but copies always exactly
-- SIZE characters into TO.
--
-- If the length of FROM is more then SIZE, then `stpncpy' copies
-- just the first SIZE characters and returns a pointer to the
-- character directly following the one which was copied last. Note
-- that in this case there is no null terminator written into TO.
--
-- If the length of FROM is less than SIZE, then `stpncpy' copies all
-- of FROM, followed by enough null characters to add up to SIZE
-- characters in all. This behaviour is rarely useful, but it is
-- implemented to be useful in contexts where this behaviour of the
-- `strncpy' is used. `stpncpy' returns a pointer to the *first*
-- written null character.
--
-- This function is not part of ISO or POSIX but was found useful
-- while developing the GNU C Library itself.
--
-- Its behaviour is undefined if the strings overlap.
--
-- - Macro: char * strdupa (const char *S)
-- This function is similar to `strdup' but allocates the new string
-- using `alloca' instead of `malloc' (*note Variable Size
-- Automatic::.). This means of course the returned string has the
-- same limitations as any block of memory allocated using `alloca'.
--
-- For obvious reasons `strdupa' is implemented only as a macro; you
-- cannot get the address of this function. Despite this limitation
-- it is a useful function. The following code shows a situation
-- where using `malloc' would be a lot more expensive.
--
-- #include <paths.h>
-- #include <string.h>
-- #include <stdio.h>
--
-- const char path[] = _PATH_STDPATH;
--
-- int
-- main (void)
-- {
-- char *wr_path = strdupa (path);
-- char *cp = strtok (wr_path, ":");
--
-- while (cp != NULL)
-- {
-- puts (cp);
-- cp = strtok (NULL, ":");
-- }
-- return 0;
-- }
--
-- Please note that calling `strtok' using PATH directly is invalid.
--
-- This function is only available if GNU CC is used.
--
-- - Macro: char * strndupa (const char *S, size_t SIZE)
-- This function is similar to `strndup' but like `strdupa' it
-- allocates the new string using `alloca' *note Variable Size
-- Automatic::.. The same advantages and limitations of `strdupa'
-- are valid for `strndupa', too.
--
-- This function is implemented only as a macro, just like `strdupa'.
--
-- `strndupa' is only available if GNU CC is used.
--
-- - Function: char * strcat (char *TO, const char *FROM)
-- The `strcat' function is similar to `strcpy', except that the
-- characters from FROM are concatenated or appended to the end of
-- TO, instead of overwriting it. That is, the first character from
-- FROM overwrites the null character marking the end of TO.
--
-- An equivalent definition for `strcat' would be:
--
-- char *
-- strcat (char *to, const char *from)
-- {
-- strcpy (to + strlen (to), from);
-- return to;
-- }
--
-- This function has undefined results if the strings overlap.
--
-- Programmers using the `strcat' function (or the following `strncat'
--function for that matter) can easily be recognize as lazy. In almost
--all situations the lengths of the participating strings are known. Or
--at least, one could know them if one keeps track of the results of the
--various function calls. But then it is very inefficient to use
--`strcat'. A lot of time is wasted finding the end of the destination
--string so that the actual copying can start. This is a common example:
--
-- /* This function concats arbitrary many strings. The last
-- parameter must be `NULL'. */
-- char *
-- concat (const char *str, ...)
-- {
-- va_list ap, ap2;
-- size_t total = 1;
-- const char *s;
-- char *result;
--
-- va_start (ap, str);
-- /* Actually `va_copy', but this is the name more gcc versions
-- understand. */
-- __va_copy (ap2, ap);
--
-- /* Determine how much space we need. */
-- for (s = str; s != NULL; s = va_arg (ap, const char *))
-- total += strlen (s);
--
-- va_end (ap);
--
-- result = (char *) malloc (total);
-- if (result != NULL)
-- {
-- result[0] = '\0';
--
-- /* Copy the strings. */
-- for (s = str; s != NULL; s = va_arg (ap2, const char *))
-- strcat (result, s);
-- }
--
-- va_end (ap2);
--
-- return result;
-- }
--
-- This looks quite simple, especially the second loop where the strings
--are actually copied. But these innocent lines hide a major performance
--penalty. Just imagine that ten strings of 100 bytes each have to be
--concatenated. For the second string we search the already stored 100
--bytes for the end of the string so that we can append the next string.
--For all strings in total the comparisons necessary to find the end of
--the intermediate results sums up to 5500! If we combine the copying
--with the search for the allocation we can write this function more
--efficent:
--
-- char *
-- concat (const char *str, ...)
-- {
-- va_list ap;
-- size_t allocated = 100;
-- char *result = (char *) malloc (allocated);
-- char *wp;
--
-- if (allocated != NULL)
-- {
-- char *newp;
--
-- va_start (ap, atr);
--
-- wp = result;
-- for (s = str; s != NULL; s = va_arg (ap, const char *))
-- {
-- size_t len = strlen (s);
--
-- /* Resize the allocated memory if necessary. */
-- if (wp + len + 1 > result + allocated)
-- {
-- allocated = (allocated + len) * 2;
-- newp = (char *) realloc (result, allocated);
-- if (newp == NULL)
-- {
-- free (result);
-- return NULL;
-- }
-- wp = newp + (wp - result);
-- result = newp;
-- }
--
-- wp = mempcpy (wp, s, len);
-- }
--
-- /* Terminate the result string. */
-- *wp++ = '\0';
--
-- /* Resize memory to the optimal size. */
-- newp = realloc (result, wp - result);
-- if (newp != NULL)
-- result = newp;
--
-- va_end (ap);
-- }
--
-- return result;
-- }
--
-- With a bit more knowledge about the input strings one could fine-tune
--the memory allocation. The difference we are pointing to here is that
--we don't use `strcat' anymore. We always keep track of the length of
--the current intermediate result so we can safe us the search for the
--end of the string and use `mempcpy'. Please note that we also don't
--use `stpcpy' which might seem more natural since we handle with
--strings. But this is not necessary since we already know the length of
--the string and therefore can use the faster memory copying function.
--
-- Whenever a programmer feels the need to use `strcat' she or he
--should think twice and look through the program whether the code cannot
--be rewritten to take advantage of already calculated results. Again: it
--is almost always unnecessary to use `strcat'.
--
-- - Function: char * strncat (char *TO, const char *FROM, size_t SIZE)
-- This function is like `strcat' except that not more than SIZE
-- characters from FROM are appended to the end of TO. A single null
-- character is also always appended to TO, so the total allocated
-- size of TO must be at least `SIZE + 1' bytes longer than its
-- initial length.
--
-- The `strncat' function could be implemented like this:
--
-- char *
-- strncat (char *to, const char *from, size_t size)
-- {
-- strncpy (to + strlen (to), from, size);
-- return to;
-- }
--
-- The behavior of `strncat' is undefined if the strings overlap.
--
-- Here is an example showing the use of `strncpy' and `strncat'.
--Notice how, in the call to `strncat', the SIZE parameter is computed to
--avoid overflowing the character array `buffer'.
--
-- #include <string.h>
-- #include <stdio.h>
--
-- #define SIZE 10
--
-- static char buffer[SIZE];
--
-- main ()
-- {
-- strncpy (buffer, "hello", SIZE);
-- puts (buffer);
-- strncat (buffer, ", world", SIZE - strlen (buffer) - 1);
-- puts (buffer);
-- }
--
--The output produced by this program looks like:
--
-- hello
-- hello, wo
--
-- - Function: void bcopy (const void *FROM, void *TO, size_t SIZE)
-- This is a partially obsolete alternative for `memmove', derived
-- from BSD. Note that it is not quite equivalent to `memmove',
-- because the arguments are not in the same order and there is no
-- return value.
--
-- - Function: void bzero (void *BLOCK, size_t SIZE)
-- This is a partially obsolete alternative for `memset', derived from
-- BSD. Note that it is not as general as `memset', because the only
-- value it can store is zero.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-50 glibc-2.1.3/manual/libc.info-50
---- ../glibc-2.1.3/manual/libc.info-50 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-50 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1181 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Function Index, Next: Variable Index, Prev: Type Index, Up: Top
--
--Function and Macro Index
--************************
--
--* Menu:
--
--* __va_copy: Argument Macros.
--* _Exit: Termination Internals.
--* _exit: Termination Internals.
--* _tolower: Case Conversion.
--* _toupper: Case Conversion.
--* a64l: Encode Binary Data.
--* abort: Aborting a Program.
--* abs: Absolute Value.
--* accept: Accepting Connections.
--* access: Testing File Access.
--* acos: Inverse Trig Functions.
--* acosf: Inverse Trig Functions.
--* acosh: Hyperbolic Functions.
--* acoshf: Hyperbolic Functions.
--* acoshl: Hyperbolic Functions.
--* acosl: Inverse Trig Functions.
--* addmntent: Filesystem handling.
--* addseverity: Adding Severity Classes.
--* adjtime: High-Resolution Calendar.
--* aio_cancel: Cancel AIO Operations.
--* aio_cancel64: Cancel AIO Operations.
--* aio_error: Status of AIO Operations.
--* aio_error64: Status of AIO Operations.
--* aio_fsync: Synchronizing AIO Operations.
--* aio_fsync64: Synchronizing AIO Operations.
--* aio_init: Configuration of AIO.
--* aio_read: Asynchronous Reads/Writes.
--* aio_read64: Asynchronous Reads/Writes.
--* aio_return: Status of AIO Operations.
--* aio_return64: Status of AIO Operations.
--* aio_suspend: Synchronizing AIO Operations.
--* aio_suspend64: Synchronizing AIO Operations.
--* aio_write: Asynchronous Reads/Writes.
--* aio_write64: Asynchronous Reads/Writes.
--* alarm: Setting an Alarm.
--* alloca: Variable Size Automatic.
--* alphasort: Scanning Directory Content.
--* alphasort64: Scanning Directory Content.
--* argp_error: Argp Helper Functions.
--* argp_failure: Argp Helper Functions.
--* argp_help: Argp Help.
--* argp_parse: Argp.
--* argp_state_help: Argp Helper Functions.
--* argp_usage: Argp Helper Functions.
--* argz_add: Argz Functions.
--* argz_add_sep: Argz Functions.
--* argz_append: Argz Functions.
--* argz_count: Argz Functions.
--* argz_create: Argz Functions.
--* argz_create_sep: Argz Functions.
--* argz_delete: Argz Functions.
--* argz_extract: Argz Functions.
--* argz_insert: Argz Functions.
--* argz_next: Argz Functions.
--* argz_replace: Argz Functions.
--* argz_stringify: Argz Functions.
--* asctime: Formatting Date and Time.
--* asctime_r: Formatting Date and Time.
--* asin: Inverse Trig Functions.
--* asinf: Inverse Trig Functions.
--* asinh: Hyperbolic Functions.
--* asinhf: Hyperbolic Functions.
--* asinhl: Hyperbolic Functions.
--* asinl: Inverse Trig Functions.
--* asprintf: Dynamic Output.
--* assert: Consistency Checking.
--* assert_perror: Consistency Checking.
--* atan: Inverse Trig Functions.
--* atan2: Inverse Trig Functions.
--* atan2f: Inverse Trig Functions.
--* atan2l: Inverse Trig Functions.
--* atanf: Inverse Trig Functions.
--* atanh: Hyperbolic Functions.
--* atanhf: Hyperbolic Functions.
--* atanhl: Hyperbolic Functions.
--* atanl: Inverse Trig Functions.
--* atexit: Cleanups on Exit.
--* atof: Parsing of Floats.
--* atoi: Parsing of Integers.
--* atol: Parsing of Integers.
--* atoll: Parsing of Integers.
--* bcmp: String/Array Comparison.
--* bcopy: Copying and Concatenation.
--* bind: Setting Address.
--* bindtextdomain: Locating gettext catalog.
--* bsearch: Array Search Function.
--* btowc: Converting a Character.
--* bzero: Copying and Concatenation.
--* cabs: Absolute Value.
--* cabsf: Absolute Value.
--* cabsl: Absolute Value.
--* cacos: Inverse Trig Functions.
--* cacosf: Inverse Trig Functions.
--* cacosh: Hyperbolic Functions.
--* cacoshf: Hyperbolic Functions.
--* cacoshl: Hyperbolic Functions.
--* cacosl: Inverse Trig Functions.
--* calloc: Allocating Cleared Space.
--* carg: Operations on Complex.
--* cargf: Operations on Complex.
--* cargl: Operations on Complex.
--* casin: Inverse Trig Functions.
--* casinf: Inverse Trig Functions.
--* casinh: Hyperbolic Functions.
--* casinhf: Hyperbolic Functions.
--* casinhl: Hyperbolic Functions.
--* casinl: Inverse Trig Functions.
--* catan: Inverse Trig Functions.
--* catanf: Inverse Trig Functions.
--* catanh: Hyperbolic Functions.
--* catanhf: Hyperbolic Functions.
--* catanhl: Hyperbolic Functions.
--* catanl: Inverse Trig Functions.
--* catclose: The catgets Functions.
--* catgets: The catgets Functions.
--* catopen: The catgets Functions.
--* cbc_crypt: DES Encryption.
--* cbrt: Exponents and Logarithms.
--* cbrtf: Exponents and Logarithms.
--* cbrtl: Exponents and Logarithms.
--* ccos: Trig Functions.
--* ccosf: Trig Functions.
--* ccosh: Hyperbolic Functions.
--* ccoshf: Hyperbolic Functions.
--* ccoshl: Hyperbolic Functions.
--* ccosl: Trig Functions.
--* ceil: Rounding Functions.
--* ceilf: Rounding Functions.
--* ceill: Rounding Functions.
--* cexp: Exponents and Logarithms.
--* cexpf: Exponents and Logarithms.
--* cexpl: Exponents and Logarithms.
--* cfgetispeed: Line Speed.
--* cfgetospeed: Line Speed.
--* cfmakeraw: Noncanonical Input.
--* cfree: Freeing after Malloc.
--* cfsetispeed: Line Speed.
--* cfsetospeed: Line Speed.
--* cfsetspeed: Line Speed.
--* chdir: Working Directory.
--* chmod: Setting Permissions.
--* chown: File Owner.
--* cimag: Operations on Complex.
--* cimagf: Operations on Complex.
--* cimagl: Operations on Complex.
--* clearenv: Environment Access.
--* clearerr: EOF and Errors.
--* clock: Basic CPU Time.
--* clog: Exponents and Logarithms.
--* clog10: Exponents and Logarithms.
--* clog10f: Exponents and Logarithms.
--* clog10l: Exponents and Logarithms.
--* clogf: Exponents and Logarithms.
--* clogl: Exponents and Logarithms.
--* close: Opening and Closing Files.
--* closedir: Reading/Closing Directory.
--* confstr: String Parameters.
--* conj: Operations on Complex.
--* conjf: Operations on Complex.
--* conjl: Operations on Complex.
--* connect: Connecting.
--* copysign: FP Bit Twiddling.
--* copysignf: FP Bit Twiddling.
--* copysignl: FP Bit Twiddling.
--* cos: Trig Functions.
--* cosf: Trig Functions.
--* cosh: Hyperbolic Functions.
--* coshf: Hyperbolic Functions.
--* coshl: Hyperbolic Functions.
--* cosl: Trig Functions.
--* cpow: Exponents and Logarithms.
--* cpowf: Exponents and Logarithms.
--* cpowl: Exponents and Logarithms.
--* cproj: Operations on Complex.
--* cprojf: Operations on Complex.
--* cprojl: Operations on Complex.
--* creal: Operations on Complex.
--* crealf: Operations on Complex.
--* creall: Operations on Complex.
--* creat: Opening and Closing Files.
--* creat64: Opening and Closing Files.
--* crypt: crypt.
--* crypt_r: crypt.
--* csin: Trig Functions.
--* csinf: Trig Functions.
--* csinh: Hyperbolic Functions.
--* csinhf: Hyperbolic Functions.
--* csinhl: Hyperbolic Functions.
--* csinl: Trig Functions.
--* csqrt: Exponents and Logarithms.
--* csqrtf: Exponents and Logarithms.
--* csqrtl: Exponents and Logarithms.
--* ctan: Trig Functions.
--* ctanf: Trig Functions.
--* ctanh: Hyperbolic Functions.
--* ctanhf: Hyperbolic Functions.
--* ctanhl: Hyperbolic Functions.
--* ctanl: Trig Functions.
--* ctermid: Identifying the Terminal.
--* ctime: Formatting Date and Time.
--* ctime_r: Formatting Date and Time.
--* cuserid: Who Logged In.
--* dcgettext: Translation with gettext.
--* DES_DECRYPT: DES Encryption.
--* DES_ENCRYPT: DES Encryption.
--* DES_FAILED: DES Encryption.
--* DES_HW: DES Encryption.
--* des_setparity: DES Encryption.
--* DES_SW: DES Encryption.
--* DESERR_BADPARAM: DES Encryption.
--* DESERR_HWERROR: DES Encryption.
--* DESERR_NOHWDEVICE: DES Encryption.
--* DESERR_NONE: DES Encryption.
--* dgettext: Translation with gettext.
--* difftime: Simple Calendar Time.
--* div: Integer Division.
--* drand48: SVID Random.
--* drand48_r: SVID Random.
--* drem: Remainder Functions.
--* dremf: Remainder Functions.
--* dreml: Remainder Functions.
--* DTTOIF: Directory Entries.
--* dup: Duplicating Descriptors.
--* dup2: Duplicating Descriptors.
--* ecb_crypt: DES Encryption.
--* ecvt: System V Number Conversion.
--* ecvt_r: System V Number Conversion.
--* encrypt: DES Encryption.
--* encrypt_r: DES Encryption.
--* endfsent: Filesystem handling.
--* endgrent: Scanning All Groups.
--* endhostent: Host Names.
--* endmntent: Filesystem handling.
--* endnetent: Networks Database.
--* endnetgrent: Lookup Netgroup.
--* endprotoent: Protocols Database.
--* endpwent: Scanning All Users.
--* endservent: Services Database.
--* endutent: Manipulating the Database.
--* endutxent: XPG Functions.
--* envz_add: Envz Functions.
--* envz_entry: Envz Functions.
--* envz_get: Envz Functions.
--* envz_merge: Envz Functions.
--* envz_strip: Envz Functions.
--* erand48: SVID Random.
--* erand48_r: SVID Random.
--* erf: Special Functions.
--* erfc: Special Functions.
--* erfcf: Special Functions.
--* erfcl: Special Functions.
--* erff: Special Functions.
--* erfl: Special Functions.
--* execl: Executing a File.
--* execle: Executing a File.
--* execlp: Executing a File.
--* execv: Executing a File.
--* execve: Executing a File.
--* execvp: Executing a File.
--* exit: Normal Termination.
--* exp: Exponents and Logarithms.
--* exp10: Exponents and Logarithms.
--* exp10f: Exponents and Logarithms.
--* exp10l: Exponents and Logarithms.
--* exp2: Exponents and Logarithms.
--* exp2f: Exponents and Logarithms.
--* exp2l: Exponents and Logarithms.
--* expf: Exponents and Logarithms.
--* expl: Exponents and Logarithms.
--* expm1: Exponents and Logarithms.
--* expm1f: Exponents and Logarithms.
--* expm1l: Exponents and Logarithms.
--* fabs: Absolute Value.
--* fabsf: Absolute Value.
--* fabsl: Absolute Value.
--* fchmod: Setting Permissions.
--* fchown: File Owner.
--* fclean: Cleaning Streams.
--* fclose: Closing Streams.
--* fcloseall: Closing Streams.
--* fcntl: Control Operations.
--* fcvt: System V Number Conversion.
--* fcvt_r: System V Number Conversion.
--* FD_CLR: Waiting for I/O.
--* FD_ISSET: Waiting for I/O.
--* FD_SET: Waiting for I/O.
--* FD_ZERO: Waiting for I/O.
--* fdatasync: Synchronizing I/O.
--* fdim: Misc FP Arithmetic.
--* fdimf: Misc FP Arithmetic.
--* fdiml: Misc FP Arithmetic.
--* fdopen: Descriptors and Streams.
--* feclearexcept: Status bit operations.
--* fegetenv: Control Functions.
--* fegetexceptflag: Status bit operations.
--* fegetround: Rounding.
--* feholdexcept: Control Functions.
--* feof: EOF and Errors.
--* ferror: EOF and Errors.
--* fesetenv: Control Functions.
--* fesetexceptflag: Status bit operations.
--* fesetround: Rounding.
--* fetestexcept: Status bit operations.
--* feupdateenv: Control Functions.
--* fflush: Flushing Buffers.
--* fgetc: Character Input.
--* fgetgrent: Scanning All Groups.
--* fgetgrent_r: Scanning All Groups.
--* fgetpos: Portable Positioning.
--* fgetpos64: Portable Positioning.
--* fgetpwent: Scanning All Users.
--* fgetpwent_r: Scanning All Users.
--* fgets: Line Input.
--* fileno: Descriptors and Streams.
--* finite: Floating Point Classes.
--* finitef: Floating Point Classes.
--* finitel: Floating Point Classes.
--* floor: Rounding Functions.
--* floorf: Rounding Functions.
--* floorl: Rounding Functions.
--* fma: Misc FP Arithmetic.
--* fmaf: Misc FP Arithmetic.
--* fmal: Misc FP Arithmetic.
--* fmax: Misc FP Arithmetic.
--* fmaxf: Misc FP Arithmetic.
--* fmaxl: Misc FP Arithmetic.
--* fmemopen: String Streams.
--* fmin: Misc FP Arithmetic.
--* fminf: Misc FP Arithmetic.
--* fminl: Misc FP Arithmetic.
--* fmod: Remainder Functions.
--* fmodf: Remainder Functions.
--* fmodl: Remainder Functions.
--* fmtmsg: Printing Formatted Messages.
--* fnmatch: Wildcard Matching.
--* fopen: Opening Streams.
--* fopen64: Opening Streams.
--* fopencookie: Streams and Cookies.
--* fork: Creating a Process.
--* forkpty: Pseudo-Terminal Pairs.
--* fpathconf: Pathconf.
--* fpclassify: Floating Point Classes.
--* fprintf: Formatted Output Functions.
--* fputc: Simple Output.
--* fputs: Simple Output.
--* fread: Block Input/Output.
--* free: Freeing after Malloc.
--* freopen: Opening Streams.
--* freopen64: Opening Streams.
--* frexp: Normalization Functions.
--* frexpf: Normalization Functions.
--* frexpl: Normalization Functions.
--* fscanf: Formatted Input Functions.
--* fseek: File Positioning.
--* fseeko: File Positioning.
--* fseeko64: File Positioning.
--* fsetpos: Portable Positioning.
--* fsetpos64: Portable Positioning.
--* fstat: Reading Attributes.
--* fstat64: Reading Attributes.
--* fsync: Synchronizing I/O.
--* ftell: File Positioning.
--* ftello: File Positioning.
--* ftello64: File Positioning.
--* ftruncate <1>: File Size.
--* ftruncate: Truncating Files.
--* ftruncate64: Truncating Files.
--* ftw: Working on Directory Trees.
--* ftw64: Working on Directory Trees.
--* fwrite: Block Input/Output.
--* gamma: Special Functions.
--* gammaf: Special Functions.
--* gammal: Special Functions.
--* gcvt: System V Number Conversion.
--* getc: Character Input.
--* getchar: Character Input.
--* getcwd: Working Directory.
--* getdate: General Time String Parsing.
--* getdate_r: General Time String Parsing.
--* getdelim: Line Input.
--* getegid: Reading Persona.
--* getenv: Environment Access.
--* geteuid: Reading Persona.
--* getfsent: Filesystem handling.
--* getfsfile: Filesystem handling.
--* getfsspec: Filesystem handling.
--* getgid: Reading Persona.
--* getgrent: Scanning All Groups.
--* getgrent_r: Scanning All Groups.
--* getgrgid: Lookup Group.
--* getgrgid_r: Lookup Group.
--* getgrnam: Lookup Group.
--* getgrnam_r: Lookup Group.
--* getgroups: Reading Persona.
--* gethostbyaddr: Host Names.
--* gethostbyaddr_r: Host Names.
--* gethostbyname: Host Names.
--* gethostbyname2: Host Names.
--* gethostbyname2_r: Host Names.
--* gethostbyname_r: Host Names.
--* gethostent: Host Names.
--* gethostid: Host Identification.
--* gethostname: Host Identification.
--* getitimer: Setting an Alarm.
--* getline: Line Input.
--* getlogin: Who Logged In.
--* getmntent: Filesystem handling.
--* getmntent_r: Filesystem handling.
--* getnetbyaddr: Networks Database.
--* getnetbyname: Networks Database.
--* getnetent: Networks Database.
--* getnetgrent: Lookup Netgroup.
--* getnetgrent_r: Lookup Netgroup.
--* getopt: Using Getopt.
--* getopt_long: Getopt Long Options.
--* getpass: getpass.
--* getpeername: Who is Connected.
--* getpgid: Process Group Functions.
--* getpgrp: Process Group Functions.
--* getpid: Process Identification.
--* getppid: Process Identification.
--* getpriority: Priority.
--* getprotobyname: Protocols Database.
--* getprotobynumber: Protocols Database.
--* getprotoent: Protocols Database.
--* getpt: Allocation.
--* getpwent: Scanning All Users.
--* getpwent_r: Scanning All Users.
--* getpwnam: Lookup User.
--* getpwnam_r: Lookup User.
--* getpwuid: Lookup User.
--* getpwuid_r: Lookup User.
--* getrlimit: Limits on Resources.
--* getrlimit64: Limits on Resources.
--* getrusage: Resource Usage.
--* gets: Line Input.
--* getservbyname: Services Database.
--* getservbyport: Services Database.
--* getservent: Services Database.
--* getsid: Process Group Functions.
--* getsockname: Reading Address.
--* getsockopt: Socket Option Functions.
--* getsubopt: Suboptions.
--* gettext: Translation with gettext.
--* gettimeofday: High-Resolution Calendar.
--* getuid: Reading Persona.
--* getumask: Setting Permissions.
--* getutent: Manipulating the Database.
--* getutent_r: Manipulating the Database.
--* getutid: Manipulating the Database.
--* getutid_r: Manipulating the Database.
--* getutline: Manipulating the Database.
--* getutline_r: Manipulating the Database.
--* getutxent: XPG Functions.
--* getutxid: XPG Functions.
--* getutxline: XPG Functions.
--* getw: Character Input.
--* getwd: Working Directory.
--* glob: Calling Glob.
--* globfree: More Flags for Globbing.
--* gmtime: Broken-down Time.
--* gmtime_r: Broken-down Time.
--* grantpt: Allocation.
--* gsignal: Signaling Yourself.
--* hasmntopt: Filesystem handling.
--* hcreate: Hash Search Function.
--* hcreate_r: Hash Search Function.
--* hdestroy: Hash Search Function.
--* hdestroy_r: Hash Search Function.
--* hsearch: Hash Search Function.
--* hsearch_r: Hash Search Function.
--* htonl: Byte Order.
--* htons: Byte Order.
--* hypot: Exponents and Logarithms.
--* hypotf: Exponents and Logarithms.
--* hypotl: Exponents and Logarithms.
--* iconv: Generic Conversion Interface.
--* iconv_close: Generic Conversion Interface.
--* iconv_open: Generic Conversion Interface.
--* if_freenameindex: Interface Naming.
--* if_indextoname: Interface Naming.
--* if_nameindex: Interface Naming.
--* if_nametoindex: Interface Naming.
--* IFTODT: Directory Entries.
--* ilogb: Exponents and Logarithms.
--* ilogbf: Exponents and Logarithms.
--* ilogbl: Exponents and Logarithms.
--* imaxabs: Absolute Value.
--* imaxdiv: Integer Division.
--* index: Search Functions.
--* inet_addr: Host Address Functions.
--* inet_aton: Host Address Functions.
--* inet_lnaof: Host Address Functions.
--* inet_makeaddr: Host Address Functions.
--* inet_netof: Host Address Functions.
--* inet_network: Host Address Functions.
--* inet_ntoa: Host Address Functions.
--* inet_ntop: Host Address Functions.
--* inet_pton: Host Address Functions.
--* infnan: Floating Point Classes.
--* initgroups: Setting Groups.
--* initstate: BSD Random.
--* innetgr: Netgroup Membership.
--* ioctl: IOCTLs.
--* isalnum: Classification of Characters.
--* isalpha: Classification of Characters.
--* isascii: Classification of Characters.
--* isatty: Is It a Terminal.
--* isblank: Classification of Characters.
--* iscntrl: Classification of Characters.
--* isdigit: Classification of Characters.
--* isfinite: Floating Point Classes.
--* isgraph: Classification of Characters.
--* isgreater: FP Comparison Functions.
--* isgreaterequal: FP Comparison Functions.
--* isinf: Floating Point Classes.
--* isinff: Floating Point Classes.
--* isinfl: Floating Point Classes.
--* isless: FP Comparison Functions.
--* islessequal: FP Comparison Functions.
--* islessgreater: FP Comparison Functions.
--* islower: Classification of Characters.
--* isnan: Floating Point Classes.
--* isnanf: Floating Point Classes.
--* isnanl: Floating Point Classes.
--* isnormal: Floating Point Classes.
--* isprint: Classification of Characters.
--* ispunct: Classification of Characters.
--* isspace: Classification of Characters.
--* isunordered: FP Comparison Functions.
--* isupper: Classification of Characters.
--* iswalnum: Classification of Wide Characters.
--* iswalpha: Classification of Wide Characters.
--* iswblank: Classification of Wide Characters.
--* iswcntrl: Classification of Wide Characters.
--* iswctype: Classification of Wide Characters.
--* iswdigit: Classification of Wide Characters.
--* iswgraph: Classification of Wide Characters.
--* iswlower: Classification of Wide Characters.
--* iswprint: Classification of Wide Characters.
--* iswpunct: Classification of Wide Characters.
--* iswspace: Classification of Wide Characters.
--* iswupper: Classification of Wide Characters.
--* iswxdigit: Classification of Wide Characters.
--* isxdigit: Classification of Characters.
--* ITIMER_PROF: Setting an Alarm.
--* ITIMER_REAL: Setting an Alarm.
--* ITIMER_VIRTUAL: Setting an Alarm.
--* j0: Special Functions.
--* j0f: Special Functions.
--* j0l: Special Functions.
--* j1: Special Functions.
--* j1f: Special Functions.
--* j1l: Special Functions.
--* jn: Special Functions.
--* jnf: Special Functions.
--* jnl: Special Functions.
--* jrand48: SVID Random.
--* jrand48_r: SVID Random.
--* kill: Signaling Another Process.
--* killpg: Signaling Another Process.
--* l64a: Encode Binary Data.
--* labs: Absolute Value.
--* lcong48: SVID Random.
--* lcong48_r: SVID Random.
--* ldexp: Normalization Functions.
--* ldexpf: Normalization Functions.
--* ldexpl: Normalization Functions.
--* ldiv: Integer Division.
--* lfind: Array Search Function.
--* lgamma: Special Functions.
--* lgamma_r: Special Functions.
--* lgammaf: Special Functions.
--* lgammaf_r: Special Functions.
--* lgammal: Special Functions.
--* lgammal_r: Special Functions.
--* link: Hard Links.
--* lio_listio: Asynchronous Reads/Writes.
--* lio_listio64: Asynchronous Reads/Writes.
--* listen: Listening.
--* llabs: Absolute Value.
--* lldiv: Integer Division.
--* llrint: Rounding Functions.
--* llrintf: Rounding Functions.
--* llrintl: Rounding Functions.
--* llround: Rounding Functions.
--* llroundf: Rounding Functions.
--* llroundl: Rounding Functions.
--* localeconv: The Lame Way to Locale Data.
--* localtime: Broken-down Time.
--* localtime_r: Broken-down Time.
--* log: Exponents and Logarithms.
--* log10: Exponents and Logarithms.
--* log10f: Exponents and Logarithms.
--* log10l: Exponents and Logarithms.
--* log1p: Exponents and Logarithms.
--* log1pf: Exponents and Logarithms.
--* log1pl: Exponents and Logarithms.
--* log2: Exponents and Logarithms.
--* log2f: Exponents and Logarithms.
--* log2l: Exponents and Logarithms.
--* logb <1>: Normalization Functions.
--* logb: Exponents and Logarithms.
--* logbf <1>: Normalization Functions.
--* logbf: Exponents and Logarithms.
--* logbl <1>: Normalization Functions.
--* logbl: Exponents and Logarithms.
--* logf: Exponents and Logarithms.
--* login: Logging In and Out.
--* login_tty: Logging In and Out.
--* logl: Exponents and Logarithms.
--* logout: Logging In and Out.
--* logwtmp: Logging In and Out.
--* longjmp: Non-Local Details.
--* lrand48: SVID Random.
--* lrand48_r: SVID Random.
--* lrint: Rounding Functions.
--* lrintf: Rounding Functions.
--* lrintl: Rounding Functions.
--* lround: Rounding Functions.
--* lroundf: Rounding Functions.
--* lroundl: Rounding Functions.
--* lsearch: Array Search Function.
--* lseek: File Position Primitive.
--* lseek64: File Position Primitive.
--* lstat: Reading Attributes.
--* lstat64: Reading Attributes.
--* main: Program Arguments.
--* mallinfo: Statistics of Malloc.
--* malloc: Basic Allocation.
--* mallopt: Malloc Tunable Parameters.
--* matherr: FP Exceptions.
--* mblen: Non-reentrant Character Conversion.
--* mbrlen: Converting a Character.
--* mbrtowc: Converting a Character.
--* mbsinit: Keeping the state.
--* mbsnrtowcs: Converting Strings.
--* mbsrtowcs: Converting Strings.
--* mbstowcs: Non-reentrant String Conversion.
--* mbtowc: Non-reentrant Character Conversion.
--* mcheck: Heap Consistency Checking.
--* memalign: Aligned Memory Blocks.
--* memccpy: Copying and Concatenation.
--* memchr: Search Functions.
--* memcmp: String/Array Comparison.
--* memcpy: Copying and Concatenation.
--* memmem: Search Functions.
--* memmove: Copying and Concatenation.
--* mempcpy: Copying and Concatenation.
--* memset: Copying and Concatenation.
--* mkdir: Creating Directories.
--* mkfifo: FIFO Special Files.
--* mknod: Making Special Files.
--* mkstemp: Temporary Files.
--* mktemp: Temporary Files.
--* mktime: Broken-down Time.
--* mmap: Memory-mapped I/O.
--* modf: Rounding Functions.
--* modff: Rounding Functions.
--* modfl: Rounding Functions.
--* mprobe: Heap Consistency Checking.
--* mrand48: SVID Random.
--* mrand48_r: SVID Random.
--* mremap: Memory-mapped I/O.
--* msync: Memory-mapped I/O.
--* mtrace: Tracing malloc.
--* munmap: Memory-mapped I/O.
--* muntrace: Tracing malloc.
--* nan: FP Bit Twiddling.
--* nanf: FP Bit Twiddling.
--* nanl: FP Bit Twiddling.
--* nanosleep: Sleeping.
--* nearbyint: Rounding Functions.
--* nearbyintf: Rounding Functions.
--* nearbyintl: Rounding Functions.
--* nextafter: FP Bit Twiddling.
--* nextafterf: FP Bit Twiddling.
--* nextafterl: FP Bit Twiddling.
--* nexttoward: FP Bit Twiddling.
--* nexttowardf: FP Bit Twiddling.
--* nexttowardl: FP Bit Twiddling.
--* nftw: Working on Directory Trees.
--* nftw64: Working on Directory Trees.
--* nice: Priority.
--* nl_langinfo: The Elegant and Fast Way.
--* notfound: Actions in the NSS configuration.
--* nrand48: SVID Random.
--* nrand48_r: SVID Random.
--* NSS_STATUS_NOTFOUND: NSS Modules Interface.
--* NSS_STATUS_SUCCESS: NSS Modules Interface.
--* NSS_STATUS_TRYAGAIN: NSS Modules Interface.
--* NSS_STATUS_UNAVAIL: NSS Modules Interface.
--* ntohl: Byte Order.
--* ntohs: Byte Order.
--* ntp_adjtime: Precision Time.
--* ntp_gettime: Precision Time.
--* obstack_1grow: Growing Objects.
--* obstack_1grow_fast: Extra Fast Growing.
--* obstack_alignment_mask: Obstacks Data Alignment.
--* obstack_alloc: Allocation in an Obstack.
--* obstack_base: Status of an Obstack.
--* obstack_blank: Growing Objects.
--* obstack_blank_fast: Extra Fast Growing.
--* obstack_chunk_alloc: Preparing for Obstacks.
--* obstack_chunk_free: Preparing for Obstacks.
--* obstack_chunk_size: Obstack Chunks.
--* obstack_copy: Allocation in an Obstack.
--* obstack_copy0: Allocation in an Obstack.
--* obstack_finish: Growing Objects.
--* obstack_free: Freeing Obstack Objects.
--* obstack_grow: Growing Objects.
--* obstack_grow0: Growing Objects.
--* obstack_init: Preparing for Obstacks.
--* obstack_int_grow: Growing Objects.
--* obstack_int_grow_fast: Extra Fast Growing.
--* obstack_next_free: Status of an Obstack.
--* obstack_object_size <1>: Status of an Obstack.
--* obstack_object_size: Growing Objects.
--* obstack_printf: Dynamic Output.
--* obstack_ptr_grow: Growing Objects.
--* obstack_ptr_grow_fast: Extra Fast Growing.
--* obstack_room: Extra Fast Growing.
--* obstack_vprintf: Variable Arguments Output.
--* offsetof: Structure Measurement.
--* on_exit: Cleanups on Exit.
--* open: Opening and Closing Files.
--* open64: Opening and Closing Files.
--* open_memstream: String Streams.
--* open_obstack_stream: Obstack Streams.
--* opendir: Opening a Directory.
--* openpty: Pseudo-Terminal Pairs.
--* parse_printf_format: Parsing a Template String.
--* pathconf: Pathconf.
--* pause: Using Pause.
--* pclose: Pipe to a Subprocess.
--* perror: Error Messages.
--* pipe: Creating a Pipe.
--* popen: Pipe to a Subprocess.
--* pow: Exponents and Logarithms.
--* pow10: Exponents and Logarithms.
--* pow10f: Exponents and Logarithms.
--* pow10l: Exponents and Logarithms.
--* powf: Exponents and Logarithms.
--* powl: Exponents and Logarithms.
--* pread: I/O Primitives.
--* pread64: I/O Primitives.
--* printf: Formatted Output Functions.
--* printf_size: Predefined Printf Handlers.
--* printf_size_info: Predefined Printf Handlers.
--* psignal: Signal Messages.
--* pthread_atfork: Miscellaneous Thread Functions.
--* pthread_attr_destroy: Thread Attributes.
--* pthread_attr_get: Thread Attributes.
--* pthread_attr_getinheritsched: Thread Attributes.
--* pthread_attr_getschedparam: Thread Attributes.
--* pthread_attr_getschedpolicy: Thread Attributes.
--* pthread_attr_getscope: Thread Attributes.
--* pthread_attr_init: Thread Attributes.
--* pthread_attr_set: Thread Attributes.
--* pthread_attr_setinheritsched: Thread Attributes.
--* pthread_attr_setschedparam: Thread Attributes.
--* pthread_attr_setschedpolicy: Thread Attributes.
--* pthread_attr_setscope: Thread Attributes.
--* pthread_cancel: Basic Thread Operations.
--* pthread_cleanup_pop: Cleanup Handlers.
--* pthread_cleanup_pop_restore_np: Cleanup Handlers.
--* pthread_cleanup_push: Cleanup Handlers.
--* pthread_cleanup_push_defer_np: Cleanup Handlers.
--* pthread_cond_broadcast: Condition Variables.
--* pthread_cond_destroy: Condition Variables.
--* pthread_cond_init: Condition Variables.
--* pthread_cond_signal: Condition Variables.
--* pthread_cond_timedwait: Condition Variables.
--* pthread_cond_wait: Condition Variables.
--* pthread_condattr_destroy: Condition Variables.
--* pthread_condattr_init: Condition Variables.
--* pthread_create: Basic Thread Operations.
--* pthread_detach: Miscellaneous Thread Functions.
--* pthread_equal: Miscellaneous Thread Functions.
--* pthread_exit: Basic Thread Operations.
--* pthread_getschedparam: Miscellaneous Thread Functions.
--* pthread_getspecific: Thread-Specific Data.
--* pthread_join: Basic Thread Operations.
--* pthread_key_create: Thread-Specific Data.
--* pthread_key_delete: Thread-Specific Data.
--* pthread_kill: Threads and Signal Handling.
--* pthread_kill_other_threads_np: Miscellaneous Thread Functions.
--* pthread_mutex_destroy: Mutexes.
--* pthread_mutex_init: Mutexes.
--* pthread_mutex_lock: Mutexes.
--* pthread_mutex_trylock: Mutexes.
--* pthread_mutex_unlock: Mutexes.
--* pthread_mutexattr_destroy: Mutexes.
--* pthread_mutexattr_getkind_np: Mutexes.
--* pthread_mutexattr_init: Mutexes.
--* pthread_mutexattr_setkind_np: Mutexes.
--* pthread_once: Miscellaneous Thread Functions.
--* pthread_self: Miscellaneous Thread Functions.
--* pthread_setcancelstate: Cancellation.
--* pthread_setcanceltype: Cancellation.
--* pthread_setschedparam: Miscellaneous Thread Functions.
--* pthread_setspecific: Thread-Specific Data.
--* pthread_sigmask: Threads and Signal Handling.
--* pthread_testcancel: Cancellation.
--* ptsname: Allocation.
--* ptsname_r: Allocation.
--* putc: Simple Output.
--* putchar: Simple Output.
--* putenv: Environment Access.
--* putpwent: Writing a User Entry.
--* puts: Simple Output.
--* pututline: Manipulating the Database.
--* pututxline: XPG Functions.
--* putw: Simple Output.
--* pwrite: I/O Primitives.
--* pwrite64: I/O Primitives.
--* qecvt: System V Number Conversion.
--* qecvt_r: System V Number Conversion.
--* qfcvt: System V Number Conversion.
--* qfcvt_r: System V Number Conversion.
--* qgcvt: System V Number Conversion.
--* qsort: Array Sort Function.
--* raise: Signaling Yourself.
--* rand: ISO Random.
--* rand_r: ISO Random.
--* random: BSD Random.
--* read: I/O Primitives.
--* readdir: Reading/Closing Directory.
--* readdir_r: Reading/Closing Directory.
--* readlink: Symbolic Links.
--* readv: Scatter-Gather.
--* realloc: Changing Block Size.
--* recv: Receiving Data.
--* recvfrom: Receiving Datagrams.
--* regcomp: POSIX Regexp Compilation.
--* regerror: Regexp Cleanup.
--* regexec: Matching POSIX Regexps.
--* regfree: Regexp Cleanup.
--* register_printf_function: Registering New Conversions.
--* remainder: Remainder Functions.
--* remainderf: Remainder Functions.
--* remainderl: Remainder Functions.
--* remove: Deleting Files.
--* rename: Renaming Files.
--* rewind: File Positioning.
--* rewinddir: Random Access Directory.
--* rindex: Search Functions.
--* rint: Rounding Functions.
--* rintf: Rounding Functions.
--* rintl: Rounding Functions.
--* rmdir: Deleting Files.
--* round: Rounding Functions.
--* roundf: Rounding Functions.
--* roundl: Rounding Functions.
--* S_ISBLK: Testing File Type.
--* S_ISCHR: Testing File Type.
--* S_ISDIR: Testing File Type.
--* S_ISFIFO: Testing File Type.
--* S_ISLNK: Testing File Type.
--* S_ISREG: Testing File Type.
--* S_ISSOCK: Testing File Type.
--* scalb: Normalization Functions.
--* scalbf: Normalization Functions.
--* scalbl: Normalization Functions.
--* scalbln: Normalization Functions.
--* scalblnf: Normalization Functions.
--* scalblnl: Normalization Functions.
--* scalbn: Normalization Functions.
--* scalbnf: Normalization Functions.
--* scalbnl: Normalization Functions.
--* scandir: Scanning Directory Content.
--* scandir64: Scanning Directory Content.
--* scanf: Formatted Input Functions.
--* seed48: SVID Random.
--* seed48_r: SVID Random.
--* seekdir: Random Access Directory.
--* select: Waiting for I/O.
--* sem_destroy: POSIX Semaphores.
--* sem_getvalue: POSIX Semaphores.
--* sem_init: POSIX Semaphores.
--* sem_post: POSIX Semaphores.
--* sem_trywait: POSIX Semaphores.
--* sem_wait: POSIX Semaphores.
--* send: Sending Data.
--* sendto: Sending Datagrams.
--* setbuf: Controlling Buffering.
--* setbuffer: Controlling Buffering.
--* setegid: Setting Groups.
--* setenv: Environment Access.
--* seteuid: Setting User ID.
--* setfsent: Filesystem handling.
--* setgid: Setting Groups.
--* setgrent: Scanning All Groups.
--* setgroups: Setting Groups.
--* sethostent: Host Names.
--* sethostid: Host Identification.
--* sethostname: Host Identification.
--* setitimer: Setting an Alarm.
--* setjmp: Non-Local Details.
--* setkey: DES Encryption.
--* setkey_r: DES Encryption.
--* setlinebuf: Controlling Buffering.
--* setlocale: Setting the Locale.
--* setmntent: Filesystem handling.
--* setnetent: Networks Database.
--* setnetgrent: Lookup Netgroup.
--* setpgid: Process Group Functions.
--* setpgrp: Process Group Functions.
--* setpriority: Priority.
--* setprotoent: Protocols Database.
--* setpwent: Scanning All Users.
--* setregid: Setting Groups.
--* setreuid: Setting User ID.
--* setrlimit: Limits on Resources.
--* setrlimit64: Limits on Resources.
--* setservent: Services Database.
--* setsid: Process Group Functions.
--* setsockopt: Socket Option Functions.
--* setstate: BSD Random.
--* settimeofday: High-Resolution Calendar.
--* setuid: Setting User ID.
--* setutent: Manipulating the Database.
--* setutxent: XPG Functions.
--* setvbuf: Controlling Buffering.
--* shutdown: Closing a Socket.
--* sigaction: Advanced Signal Handling.
--* sigaddset: Signal Sets.
--* sigaltstack: Signal Stack.
--* sigblock: Blocking in BSD.
--* sigdelset: Signal Sets.
--* sigemptyset: Signal Sets.
--* sigfillset: Signal Sets.
--* siginterrupt: BSD Handler.
--* sigismember: Signal Sets.
--* siglongjmp: Non-Local Exits and Signals.
--* sigmask: Blocking in BSD.
--* signal: Basic Signal Handling.
--* signbit: FP Bit Twiddling.
--* significand: Normalization Functions.
--* significandf: Normalization Functions.
--* significandl: Normalization Functions.
--* sigpause: Blocking in BSD.
--* sigpending: Checking for Pending Signals.
--* sigprocmask: Process Signal Mask.
--* sigsetjmp: Non-Local Exits and Signals.
--* sigsetmask: Blocking in BSD.
--* sigstack: Signal Stack.
--* sigsuspend: Sigsuspend.
--* sigvec: BSD Handler.
--* sigwait: Threads and Signal Handling.
--* sin: Trig Functions.
--* sincos: Trig Functions.
--* sincosf: Trig Functions.
--* sincosl: Trig Functions.
--* sinf: Trig Functions.
--* sinh: Hyperbolic Functions.
--* sinhf: Hyperbolic Functions.
--* sinhl: Hyperbolic Functions.
--* sinl: Trig Functions.
--* sleep: Sleeping.
--* snprintf: Formatted Output Functions.
--* socket: Creating a Socket.
--* socketpair: Socket Pairs.
--* sprintf: Formatted Output Functions.
--* sqrt: Exponents and Logarithms.
--* sqrtf: Exponents and Logarithms.
--* sqrtl: Exponents and Logarithms.
--* srand: ISO Random.
--* srand48: SVID Random.
--* srand48_r: SVID Random.
--* srandom: BSD Random.
--* sscanf: Formatted Input Functions.
--* ssignal: Basic Signal Handling.
--* stat: Reading Attributes.
--* stat64: Reading Attributes.
--* stpcpy: Copying and Concatenation.
--* stpncpy: Copying and Concatenation.
--* strcasecmp: String/Array Comparison.
--* strcat: Copying and Concatenation.
--* strchr: Search Functions.
--* strcmp: String/Array Comparison.
--* strcoll: Collation Functions.
--* strcpy: Copying and Concatenation.
--* strcspn: Search Functions.
--* strdup: Copying and Concatenation.
--* strdupa: Copying and Concatenation.
--* strerror: Error Messages.
--* strerror_r: Error Messages.
--* strfmon: Formatting Numbers.
--* strftime: Formatting Date and Time.
--* strlen: String Length.
--* strncasecmp: String/Array Comparison.
--* strncat: Copying and Concatenation.
--* strncmp: String/Array Comparison.
--* strncpy: Copying and Concatenation.
--* strndup: Copying and Concatenation.
--* strndupa: Copying and Concatenation.
--* strnlen: String Length.
--* strpbrk: Search Functions.
--* strptime: Low-Level Time String Parsing.
--* strrchr: Search Functions.
--* strsep: Finding Tokens in a String.
--* strsignal: Signal Messages.
--* strspn: Search Functions.
--* strstr: Search Functions.
--* strtod: Parsing of Floats.
--* strtof: Parsing of Floats.
--* strtok: Finding Tokens in a String.
--* strtok_r: Finding Tokens in a String.
--* strtol: Parsing of Integers.
--* strtol_l: Parsing of Integers.
--* strtold: Parsing of Floats.
--* strtoll: Parsing of Integers.
--* strtoll_l: Parsing of Integers.
--* strtoq: Parsing of Integers.
--* strtoul: Parsing of Integers.
--* strtoul_l: Parsing of Integers.
--* strtoull: Parsing of Integers.
--* strtoull_l: Parsing of Integers.
--* strtouq: Parsing of Integers.
--* strverscmp: String/Array Comparison.
--* strxfrm: Collation Functions.
--* success: Actions in the NSS configuration.
--* SUN_LEN: Local Namespace Details.
--* symlink: Symbolic Links.
--* sync: Synchronizing I/O.
--* sysconf: Sysconf Definition.
--* system: Running a Command.
--* sysv_signal: Basic Signal Handling.
--* tan: Trig Functions.
--* tanf: Trig Functions.
--* tanh: Hyperbolic Functions.
--* tanhf: Hyperbolic Functions.
--* tanhl: Hyperbolic Functions.
--* tanl: Trig Functions.
--* tcdrain: Line Control.
--* tcflow: Line Control.
--* tcflush: Line Control.
--* tcgetattr: Mode Functions.
--* tcgetpgrp: Terminal Access Functions.
--* tcgetsid: Terminal Access Functions.
--* tcsendbreak: Line Control.
--* tcsetattr: Mode Functions.
--* tcsetpgrp: Terminal Access Functions.
--* tdelete: Tree Search Function.
--* tdestroy: Tree Search Function.
--* telldir: Random Access Directory.
--* TEMP_FAILURE_RETRY: Interrupted Primitives.
--* tempnam: Temporary Files.
--* textdomain: Locating gettext catalog.
--* tfind: Tree Search Function.
--* tgamma: Special Functions.
--* tgammaf: Special Functions.
--* tgammal: Special Functions.
--* time: Simple Calendar Time.
--* times: Detailed CPU Time.
--* tmpfile: Temporary Files.
--* tmpfile64: Temporary Files.
--* tmpnam: Temporary Files.
--* tmpnam_r: Temporary Files.
--* toascii: Case Conversion.
--* tolower: Case Conversion.
--* toupper: Case Conversion.
--* towctrans: Wide Character Case Conversion.
--* towlower: Wide Character Case Conversion.
--* towupper: Wide Character Case Conversion.
--* trunc: Rounding Functions.
--* truncate <1>: File Size.
--* truncate: Truncating Files.
--* truncate64: Truncating Files.
--* truncf: Rounding Functions.
--* truncl: Rounding Functions.
--* tryagain: Actions in the NSS configuration.
--* tsearch: Tree Search Function.
--* ttyname: Is It a Terminal.
--* ttyname_r: Is It a Terminal.
--* twalk: Tree Search Function.
--* tzset: Time Zone Functions.
--* umask: Setting Permissions.
--* uname: Hardware/Software Type ID.
--* unavail: Actions in the NSS configuration.
--* ungetc: How Unread.
--* unlink: Deleting Files.
--* unlockpt: Allocation.
--* unsetenv: Environment Access.
--* updwtmp: Manipulating the Database.
--* utime: File Times.
--* utimes: File Times.
--* utmpname: Manipulating the Database.
--* va_alist: Old Varargs.
--* va_arg: Argument Macros.
--* va_dcl: Old Varargs.
--* va_end: Argument Macros.
--* va_start <1>: Old Varargs.
--* va_start: Argument Macros.
--* valloc: Aligned Memory Blocks.
--* vasprintf: Variable Arguments Output.
--* versionsort: Scanning Directory Content.
--* versionsort64: Scanning Directory Content.
--* vfork: Creating a Process.
--* vfprintf: Variable Arguments Output.
--* vfscanf: Variable Arguments Input.
--* vprintf: Variable Arguments Output.
--* vscanf: Variable Arguments Input.
--* vsnprintf: Variable Arguments Output.
--* vsprintf: Variable Arguments Output.
--* vsscanf: Variable Arguments Input.
--* wait: Process Completion.
--* wait3: BSD Wait Functions.
--* wait4: Process Completion.
--* waitpid: Process Completion.
--* WCOREDUMP: Process Completion Status.
--* wcrtomb: Converting a Character.
--* wcsnrtombs: Converting Strings.
--* wcsrtombs: Converting Strings.
--* wcstombs: Non-reentrant String Conversion.
--* wctob: Converting a Character.
--* wctomb: Non-reentrant Character Conversion.
--* wctrans: Wide Character Case Conversion.
--* wctype: Classification of Wide Characters.
--* WEXITSTATUS: Process Completion Status.
--* WIFEXITED: Process Completion Status.
--* WIFSIGNALED: Process Completion Status.
--* WIFSTOPPED: Process Completion Status.
--* wordexp: Calling Wordexp.
--* wordfree: Calling Wordexp.
--* write: I/O Primitives.
--* writev: Scatter-Gather.
--* WSTOPSIG: Process Completion Status.
--* WTERMSIG: Process Completion Status.
--* y0: Special Functions.
--* y0f: Special Functions.
--* y0l: Special Functions.
--* y1: Special Functions.
--* y1f: Special Functions.
--* y1l: Special Functions.
--* yn: Special Functions.
--* ynf: Special Functions.
--* ynl: Special Functions.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-51 glibc-2.1.3/manual/libc.info-51
---- ../glibc-2.1.3/manual/libc.info-51 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-51 1969-12-31 16:00:00.000000000 -0800
-@@ -1,900 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Variable Index, Next: File Index, Prev: Function Index, Up: Top
--
--Variable and Constant Macro Index
--*********************************
--
--* Menu:
--
--* (: glibc iconv Implementation.
--* __free_hook: Hooks for Malloc.
--* __malloc_hook: Hooks for Malloc.
--* __memalign_hook: Hooks for Malloc.
--* __realloc_hook: Hooks for Malloc.
--* _BSD_SOURCE: Feature Test Macros.
--* _Complex_I: Complex Numbers.
--* _FILE_OFFSET_BITS: Feature Test Macros.
--* _GNU_SOURCE: Feature Test Macros.
--* _IOFBF: Controlling Buffering.
--* _IOLBF: Controlling Buffering.
--* _IONBF: Controlling Buffering.
--* _LARGEFILE64_SOURCE: Feature Test Macros.
--* _LARGEFILE_SOURCE: Feature Test Macros.
--* _PATH_FSTAB: Filesystem handling.
--* _PATH_MNTTAB: Filesystem handling.
--* _PATH_MOUNTED: Filesystem handling.
--* _PATH_UTMP: Manipulating the Database.
--* _PATH_WTMP: Manipulating the Database.
--* _POSIX2_C_DEV: System Options.
--* _POSIX2_C_VERSION: Version Supported.
--* _POSIX2_FORT_DEV: System Options.
--* _POSIX2_FORT_RUN: System Options.
--* _POSIX2_LOCALEDEF: System Options.
--* _POSIX2_SW_DEV: System Options.
--* _POSIX_C_SOURCE: Feature Test Macros.
--* _POSIX_CHOWN_RESTRICTED: Options for Files.
--* _POSIX_JOB_CONTROL: System Options.
--* _POSIX_NO_TRUNC: Options for Files.
--* _POSIX_SAVED_IDS: System Options.
--* _POSIX_SOURCE: Feature Test Macros.
--* _POSIX_VDISABLE <1>: Options for Files.
--* _POSIX_VDISABLE: Special Characters.
--* _POSIX_VERSION: Version Supported.
--* _REENTRANT: Feature Test Macros.
--* _SVID_SOURCE: Feature Test Macros.
--* _THREAD_SAFE: Feature Test Macros.
--* _XOPEN_SOURCE: Feature Test Macros.
--* _XOPEN_SOURCE_EXTENDED: Feature Test Macros.
--* ABDAY_1: The Elegant and Fast Way.
--* ABDAY_2: The Elegant and Fast Way.
--* ABDAY_3: The Elegant and Fast Way.
--* ABDAY_4: The Elegant and Fast Way.
--* ABDAY_5: The Elegant and Fast Way.
--* ABDAY_6: The Elegant and Fast Way.
--* ABDAY_7: The Elegant and Fast Way.
--* ABMON_1: The Elegant and Fast Way.
--* ABMON_10: The Elegant and Fast Way.
--* ABMON_11: The Elegant and Fast Way.
--* ABMON_12: The Elegant and Fast Way.
--* ABMON_2: The Elegant and Fast Way.
--* ABMON_3: The Elegant and Fast Way.
--* ABMON_4: The Elegant and Fast Way.
--* ABMON_5: The Elegant and Fast Way.
--* ABMON_6: The Elegant and Fast Way.
--* ABMON_7: The Elegant and Fast Way.
--* ABMON_8: The Elegant and Fast Way.
--* ABMON_9: The Elegant and Fast Way.
--* ACCOUNTING: Manipulating the Database.
--* AF_FILE: Address Formats.
--* AF_INET: Address Formats.
--* AF_INET6: Internet Namespace.
--* AF_LOCAL: Address Formats.
--* AF_UNIX: Address Formats.
--* AF_UNSPEC: Address Formats.
--* aliases: NSS Basics.
--* ALT_DIGITS: The Elegant and Fast Way.
--* ALTWERASE: Local Modes.
--* AM_STR: The Elegant and Fast Way.
--* ARG_MAX: General Limits.
--* argp_err_exit_status: Argp Global Variables.
--* ARGP_ERR_UNKNOWN: Argp Parser Functions.
--* ARGP_HELP_BUG_ADDR: Argp Help Flags.
--* ARGP_HELP_DOC: Argp Help Flags.
--* ARGP_HELP_EXIT_ERR: Argp Help Flags.
--* ARGP_HELP_EXIT_OK: Argp Help Flags.
--* ARGP_HELP_LONG: Argp Help Flags.
--* ARGP_HELP_LONG_ONLY: Argp Help Flags.
--* ARGP_HELP_POST_DOC: Argp Help Flags.
--* ARGP_HELP_PRE_DOC: Argp Help Flags.
--* ARGP_HELP_SEE: Argp Help Flags.
--* ARGP_HELP_SHORT_USAGE: Argp Help Flags.
--* ARGP_HELP_STD_ERR: Argp Help Flags.
--* ARGP_HELP_STD_HELP: Argp Help Flags.
--* ARGP_HELP_STD_USAGE: Argp Help Flags.
--* ARGP_HELP_USAGE: Argp Help Flags.
--* ARGP_IN_ORDER: Argp Flags.
--* ARGP_KEY_ARG: Argp Special Keys.
--* ARGP_KEY_ARGS: Argp Special Keys.
--* ARGP_KEY_END: Argp Special Keys.
--* ARGP_KEY_ERROR: Argp Special Keys.
--* ARGP_KEY_FINI: Argp Special Keys.
--* ARGP_KEY_HELP_ARGS_DOC: Argp Help Filter Keys.
--* ARGP_KEY_HELP_DUP_ARGS_NOTE: Argp Help Filter Keys.
--* ARGP_KEY_HELP_EXTRA: Argp Help Filter Keys.
--* ARGP_KEY_HELP_HEADER: Argp Help Filter Keys.
--* ARGP_KEY_HELP_POST_DOC: Argp Help Filter Keys.
--* ARGP_KEY_HELP_PRE_DOC: Argp Help Filter Keys.
--* ARGP_KEY_INIT: Argp Special Keys.
--* ARGP_KEY_NO_ARGS: Argp Special Keys.
--* ARGP_KEY_SUCCESS: Argp Special Keys.
--* ARGP_LONG_ONLY: Argp Flags.
--* ARGP_NO_ARGS: Argp Flags.
--* ARGP_NO_ERRS: Argp Flags.
--* ARGP_NO_EXIT: Argp Flags.
--* ARGP_NO_HELP: Argp Flags.
--* ARGP_PARSE_ARGV0: Argp Flags.
--* argp_program_bug_address: Argp Global Variables.
--* argp_program_version: Argp Global Variables.
--* argp_program_version_hook: Argp Global Variables.
--* ARGP_SILENT: Argp Flags.
--* B0: Line Speed.
--* B110: Line Speed.
--* B115200: Line Speed.
--* B1200: Line Speed.
--* B134: Line Speed.
--* B150: Line Speed.
--* B1800: Line Speed.
--* B19200: Line Speed.
--* B200: Line Speed.
--* B230400: Line Speed.
--* B2400: Line Speed.
--* B300: Line Speed.
--* B38400: Line Speed.
--* B460800: Line Speed.
--* B4800: Line Speed.
--* B50: Line Speed.
--* B57600: Line Speed.
--* B600: Line Speed.
--* B75: Line Speed.
--* B9600: Line Speed.
--* BC_BASE_MAX: Utility Limits.
--* BC_DIM_MAX: Utility Limits.
--* BC_SCALE_MAX: Utility Limits.
--* BC_STRING_MAX: Utility Limits.
--* BOOT_TIME <1>: XPG Functions.
--* BOOT_TIME: Manipulating the Database.
--* BRKINT: Input Modes.
--* BUFSIZ: Controlling Buffering.
--* CCTS_OFLOW: Control Modes.
--* CHAR_MAX: Range of Type.
--* CHAR_MIN: Range of Type.
--* CHILD_MAX: General Limits.
--* CIGNORE: Control Modes.
--* CLK_TCK: Basic CPU Time.
--* CLOCAL: Control Modes.
--* CLOCKS_PER_SEC: Basic CPU Time.
--* COLL_WEIGHTS_MAX: Utility Limits.
--* COREFILE: Program Error Signals.
--* CREAD: Control Modes.
--* CRNCYSTR: The Elegant and Fast Way.
--* CRTS_IFLOW: Control Modes.
--* CS5: Control Modes.
--* CS6: Control Modes.
--* CS7: Control Modes.
--* CS8: Control Modes.
--* CSIZE: Control Modes.
--* CSTOPB: Control Modes.
--* CURRENCY_SYMBOL: The Elegant and Fast Way.
--* D_FMT: The Elegant and Fast Way.
--* D_T_FMT: The Elegant and Fast Way.
--* DAY_1: The Elegant and Fast Way.
--* DAY_2: The Elegant and Fast Way.
--* DAY_3: The Elegant and Fast Way.
--* DAY_4: The Elegant and Fast Way.
--* DAY_5: The Elegant and Fast Way.
--* DAY_6: The Elegant and Fast Way.
--* DAY_7: The Elegant and Fast Way.
--* daylight: Time Zone Functions.
--* DBL_DIG: Floating Point Parameters.
--* DBL_EPSILON: Floating Point Parameters.
--* DBL_MANT_DIG: Floating Point Parameters.
--* DBL_MAX: Floating Point Parameters.
--* DBL_MAX_10_EXP: Floating Point Parameters.
--* DBL_MAX_EXP: Floating Point Parameters.
--* DBL_MIN: Floating Point Parameters.
--* DBL_MIN_10_EXP: Floating Point Parameters.
--* DBL_MIN_EXP: Floating Point Parameters.
--* DEAD_PROCESS <1>: XPG Functions.
--* DEAD_PROCESS: Manipulating the Database.
--* DECIMAL_POINT: The Elegant and Fast Way.
--* E2BIG: Error Codes.
--* EACCES: Error Codes.
--* EADDRINUSE: Error Codes.
--* EADDRNOTAVAIL: Error Codes.
--* EADV: Error Codes.
--* EAFNOSUPPORT: Error Codes.
--* EAGAIN: Error Codes.
--* EALREADY: Error Codes.
--* EAUTH: Error Codes.
--* EBACKGROUND: Error Codes.
--* EBADE: Error Codes.
--* EBADF <1>: Line Control.
--* EBADF: Error Codes.
--* EBADFD: Error Codes.
--* EBADMSG: Error Codes.
--* EBADR: Error Codes.
--* EBADRPC: Error Codes.
--* EBADRQC: Error Codes.
--* EBADSLT: Error Codes.
--* EBFONT: Error Codes.
--* EBUSY: Error Codes.
--* ECHILD: Error Codes.
--* ECHO: Local Modes.
--* ECHOCTL: Local Modes.
--* ECHOE: Local Modes.
--* ECHOK: Local Modes.
--* ECHOKE: Local Modes.
--* ECHONL: Local Modes.
--* ECHOPRT: Local Modes.
--* ECHRNG: Error Codes.
--* ECOMM: Error Codes.
--* ECONNABORTED: Error Codes.
--* ECONNREFUSED: Error Codes.
--* ECONNRESET: Error Codes.
--* ED: Error Codes.
--* EDEADLK: Error Codes.
--* EDEADLOCK: Error Codes.
--* EDESTADDRREQ: Error Codes.
--* EDIED: Error Codes.
--* EDOM: Error Codes.
--* EDOTDOT: Error Codes.
--* EDQUOT: Error Codes.
--* EEXIST: Error Codes.
--* EFAULT: Error Codes.
--* EFBIG: Error Codes.
--* EFTYPE: Error Codes.
--* EGRATUITOUS: Error Codes.
--* EGREGIOUS: Error Codes.
--* EHOSTDOWN: Error Codes.
--* EHOSTUNREACH: Error Codes.
--* EIDRM: Error Codes.
--* EIEIO: Error Codes.
--* EILSEQ: Error Codes.
--* EINPROGRESS: Error Codes.
--* EINTR: Error Codes.
--* EINVAL <1>: Line Control.
--* EINVAL: Error Codes.
--* EIO: Error Codes.
--* EISCONN: Error Codes.
--* EISDIR: Error Codes.
--* EISNAM: Error Codes.
--* EL2HLT: Error Codes.
--* EL2NSYNC: Error Codes.
--* EL3HLT: Error Codes.
--* EL3RST: Error Codes.
--* ELIBACC: Error Codes.
--* ELIBBAD: Error Codes.
--* ELIBEXEC: Error Codes.
--* ELIBMAX: Error Codes.
--* ELIBSCN: Error Codes.
--* ELNRNG: Error Codes.
--* ELOOP: Error Codes.
--* EMEDIUMTYPE: Error Codes.
--* EMFILE: Error Codes.
--* EMLINK: Error Codes.
--* EMPTY <1>: XPG Functions.
--* EMPTY: Manipulating the Database.
--* EMSGSIZE: Error Codes.
--* EMULTIHOP: Error Codes.
--* ENAMETOOLONG: Error Codes.
--* ENAVAIL: Error Codes.
--* ENEEDAUTH: Error Codes.
--* ENETDOWN: Error Codes.
--* ENETRESET: Error Codes.
--* ENETUNREACH: Error Codes.
--* ENFILE: Error Codes.
--* ENOANO: Error Codes.
--* ENOBUFS: Error Codes.
--* ENOCSI: Error Codes.
--* ENODATA: Error Codes.
--* ENODEV: Error Codes.
--* ENOENT: Error Codes.
--* ENOEXEC: Error Codes.
--* ENOLCK: Error Codes.
--* ENOLINK: Error Codes.
--* ENOMEDIUM: Error Codes.
--* ENOMEM: Error Codes.
--* ENOMSG: Error Codes.
--* ENONET: Error Codes.
--* ENOPKG: Error Codes.
--* ENOPROTOOPT: Error Codes.
--* ENOSPC: Error Codes.
--* ENOSR: Error Codes.
--* ENOSTR: Error Codes.
--* ENOSYS: Error Codes.
--* ENOTBLK: Error Codes.
--* ENOTCONN: Error Codes.
--* ENOTDIR: Error Codes.
--* ENOTEMPTY: Error Codes.
--* ENOTNAM: Error Codes.
--* ENOTSOCK: Error Codes.
--* ENOTSUP: Error Codes.
--* ENOTTY <1>: Line Control.
--* ENOTTY: Error Codes.
--* ENOTUNIQ: Error Codes.
--* environ: Environment Access.
--* ENXIO: Error Codes.
--* EOF: EOF and Errors.
--* EOPNOTSUPP: Error Codes.
--* EOVERFLOW: Error Codes.
--* EPERM: Error Codes.
--* EPFNOSUPPORT: Error Codes.
--* EPIPE: Error Codes.
--* EPROCLIM: Error Codes.
--* EPROCUNAVAIL: Error Codes.
--* EPROGMISMATCH: Error Codes.
--* EPROGUNAVAIL: Error Codes.
--* EPROTO: Error Codes.
--* EPROTONOSUPPORT: Error Codes.
--* EPROTOTYPE: Error Codes.
--* EQUIV_CLASS_MAX: Utility Limits.
--* ERA: The Elegant and Fast Way.
--* ERA_D_FMT: The Elegant and Fast Way.
--* ERA_D_T_FMT: The Elegant and Fast Way.
--* ERA_T_FMT: The Elegant and Fast Way.
--* ERA_YEAR: The Elegant and Fast Way.
--* ERANGE: Error Codes.
--* EREMCHG: Error Codes.
--* EREMOTE: Error Codes.
--* EREMOTEIO: Error Codes.
--* ERESTART: Error Codes.
--* EROFS: Error Codes.
--* ERPCMISMATCH: Error Codes.
--* errno: Checking for Errors.
--* ESHUTDOWN: Error Codes.
--* ESOCKTNOSUPPORT: Error Codes.
--* ESPIPE: Error Codes.
--* ESRCH: Error Codes.
--* ESRMNT: Error Codes.
--* ESTALE: Error Codes.
--* ESTRPIPE: Error Codes.
--* ethers: NSS Basics.
--* ETIME: Error Codes.
--* ETIMEDOUT: Error Codes.
--* ETOOMANYREFS: Error Codes.
--* ETXTBSY: Error Codes.
--* EUCLEAN: Error Codes.
--* EUNATCH: Error Codes.
--* EUSERS: Error Codes.
--* EWOULDBLOCK: Error Codes.
--* EXDEV: Error Codes.
--* EXFULL: Error Codes.
--* EXIT_FAILURE: Exit Status.
--* EXIT_SUCCESS: Exit Status.
--* EXPR_NEST_MAX: Utility Limits.
--* EXTA: Line Speed.
--* EXTB: Line Speed.
--* F_DUPFD: Duplicating Descriptors.
--* F_GETFD: Descriptor Flags.
--* F_GETFL: Getting File Status Flags.
--* F_GETLK: File Locks.
--* F_GETOWN: Interrupt Input.
--* F_OK: Testing File Access.
--* F_RDLCK: File Locks.
--* F_SETFD: Descriptor Flags.
--* F_SETFL: Getting File Status Flags.
--* F_SETLK: File Locks.
--* F_SETLKW: File Locks.
--* F_SETOWN: Interrupt Input.
--* F_UNLCK: File Locks.
--* F_WRLCK: File Locks.
--* FD_CLOEXEC: Descriptor Flags.
--* FD_SETSIZE: Waiting for I/O.
--* FE_DFL_ENV: Control Functions.
--* FE_DIVBYZERO: Status bit operations.
--* FE_DOWNWARD: Rounding.
--* FE_INEXACT: Status bit operations.
--* FE_INVALID: Status bit operations.
--* FE_NOMASK_ENV: Control Functions.
--* FE_OVERFLOW: Status bit operations.
--* FE_TONEAREST: Rounding.
--* FE_TOWARDZERO: Rounding.
--* FE_UNDERFLOW: Status bit operations.
--* FE_UPWARD: Rounding.
--* FILENAME_MAX: Limits for Files.
--* FLT_DIG: Floating Point Parameters.
--* FLT_EPSILON: Floating Point Parameters.
--* FLT_MANT_DIG: Floating Point Parameters.
--* FLT_MAX: Floating Point Parameters.
--* FLT_MAX_10_EXP: Floating Point Parameters.
--* FLT_MAX_EXP: Floating Point Parameters.
--* FLT_MIN: Floating Point Parameters.
--* FLT_MIN_10_EXP: Floating Point Parameters.
--* FLT_MIN_EXP: Floating Point Parameters.
--* FLT_RADIX: Floating Point Parameters.
--* FLT_ROUNDS: Floating Point Parameters.
--* FLUSHO: Local Modes.
--* FOPEN_MAX: Opening Streams.
--* FP_FAST_FMA: Misc FP Arithmetic.
--* FP_ILOGB0: Exponents and Logarithms.
--* FP_ILOGBNAN: Exponents and Logarithms.
--* FP_INFINITE: Floating Point Classes.
--* FP_NAN: Floating Point Classes.
--* FP_NORMAL: Floating Point Classes.
--* FP_SUBNORMAL: Floating Point Classes.
--* FP_ZERO: Floating Point Classes.
--* FPE_DECOVF_TRAP: Program Error Signals.
--* FPE_FLTDIV_TRAP: Program Error Signals.
--* FPE_FLTOVF_TRAP: Program Error Signals.
--* FPE_FLTUND_TRAP: Program Error Signals.
--* FPE_INTDIV_TRAP: Program Error Signals.
--* FPE_INTOVF_TRAP: Program Error Signals.
--* FPE_SUBRNG_TRAP: Program Error Signals.
--* FRAC_DIGITS: The Elegant and Fast Way.
--* FSTAB: Filesystem handling.
--* FSTAB_RO: Filesystem handling.
--* FSTAB_RQ: Filesystem handling.
--* FSTAB_RW: Filesystem handling.
--* FSTAB_SW: Filesystem handling.
--* FSTAB_XX: Filesystem handling.
--* FTW_CHDIR: Working on Directory Trees.
--* FTW_D: Working on Directory Trees.
--* FTW_DEPTH: Working on Directory Trees.
--* FTW_DNR: Working on Directory Trees.
--* FTW_DP: Working on Directory Trees.
--* FTW_F: Working on Directory Trees.
--* FTW_MOUNT: Working on Directory Trees.
--* FTW_NS: Working on Directory Trees.
--* FTW_PHYS: Working on Directory Trees.
--* FTW_SL: Working on Directory Trees.
--* FTW_SLN: Working on Directory Trees.
--* getdate_err: General Time String Parsing.
--* group: NSS Basics.
--* GROUPING: The Elegant and Fast Way.
--* h_errno: Host Names.
--* HOST_NOT_FOUND: Host Names.
--* hosts: NSS Basics.
--* HUGE_VAL: Math Error Reporting.
--* HUGE_VALF: Math Error Reporting.
--* HUGE_VALL: Math Error Reporting.
--* HUPCL: Control Modes.
--* I: Complex Numbers.
--* ICANON: Local Modes.
--* ICRNL: Input Modes.
--* IEXTEN: Local Modes.
--* IFNAMSIZ: Interface Naming.
--* IGNBRK: Input Modes.
--* IGNCR: Input Modes.
--* IGNPAR: Input Modes.
--* IMAXBEL: Input Modes.
--* in6addr_any: Host Address Data Type.
--* in6addr_loopback: Host Address Data Type.
--* INADDR_ANY: Host Address Data Type.
--* INADDR_BROADCAST: Host Address Data Type.
--* INADDR_LOOPBACK: Host Address Data Type.
--* INADDR_NONE: Host Address Data Type.
--* INFINITY: Infinity and NaN.
--* INIT_PROCESS <1>: XPG Functions.
--* INIT_PROCESS: Manipulating the Database.
--* INLCR: Input Modes.
--* INPCK: Input Modes.
--* INT_CURR_SYMBOL: The Elegant and Fast Way.
--* INT_FRAC_DIGITS: The Elegant and Fast Way.
--* INT_MAX: Range of Type.
--* INT_MIN: Range of Type.
--* IPPORT_RESERVED: Ports.
--* IPPORT_USERRESERVED: Ports.
--* ISIG: Local Modes.
--* ISTRIP: Input Modes.
--* IXANY: Input Modes.
--* IXOFF: Input Modes.
--* IXON: Input Modes.
--* L_ctermid: Identifying the Terminal.
--* L_cuserid: Who Logged In.
--* L_INCR: File Positioning.
--* L_SET: File Positioning.
--* L_tmpnam: Temporary Files.
--* L_XTND: File Positioning.
--* LANG: Locale Categories.
--* LANGUAGE: Locale Categories.
--* LC_ALL: Locale Categories.
--* LC_COLLATE: Locale Categories.
--* LC_CTYPE: Locale Categories.
--* LC_MESSAGES: Locale Categories.
--* LC_MONETARY: Locale Categories.
--* LC_NUMERIC: Locale Categories.
--* LC_TIME: Locale Categories.
--* LDBL_DIG: Floating Point Parameters.
--* LDBL_EPSILON: Floating Point Parameters.
--* LDBL_MANT_DIG: Floating Point Parameters.
--* LDBL_MAX: Floating Point Parameters.
--* LDBL_MAX_10_EXP: Floating Point Parameters.
--* LDBL_MAX_EXP: Floating Point Parameters.
--* LDBL_MIN: Floating Point Parameters.
--* LDBL_MIN_10_EXP: Floating Point Parameters.
--* LDBL_MIN_EXP: Floating Point Parameters.
--* LINE_MAX: Utility Limits.
--* LINK_MAX: Limits for Files.
--* LIO_NOP: Asynchronous I/O.
--* LIO_READ: Asynchronous I/O.
--* LIO_WRITE: Asynchronous I/O.
--* LOGIN_PROCESS <1>: XPG Functions.
--* LOGIN_PROCESS: Manipulating the Database.
--* LONG_LONG_MAX: Range of Type.
--* LONG_LONG_MIN: Range of Type.
--* LONG_MAX: Range of Type.
--* LONG_MIN: Range of Type.
--* M_1_PI: Mathematical Constants.
--* M_2_PI: Mathematical Constants.
--* M_2_SQRTPI: Mathematical Constants.
--* M_E: Mathematical Constants.
--* M_LN10: Mathematical Constants.
--* M_LN2: Mathematical Constants.
--* M_LOG10E: Mathematical Constants.
--* M_LOG2E: Mathematical Constants.
--* M_PI: Mathematical Constants.
--* M_PI_2: Mathematical Constants.
--* M_PI_4: Mathematical Constants.
--* M_SQRT1_2: Mathematical Constants.
--* M_SQRT2: Mathematical Constants.
--* MAP_ANON: Memory-mapped I/O.
--* MAP_ANONYMOUS: Memory-mapped I/O.
--* MAP_FIXED: Memory-mapped I/O.
--* MAP_PRIVATE: Memory-mapped I/O.
--* MAP_SHARED: Memory-mapped I/O.
--* MAX_CANON: Limits for Files.
--* MAX_INPUT: Limits for Files.
--* MAXNAMLEN: Limits for Files.
--* MB_CUR_MAX: Selecting the Conversion.
--* MB_LEN_MAX: Selecting the Conversion.
--* MDMBUF: Control Modes.
--* MINSIGSTKSZ: Signal Stack.
--* MM_APPL: Printing Formatted Messages.
--* MM_CONSOLE: Printing Formatted Messages.
--* MM_ERROR: Printing Formatted Messages.
--* MM_FIRM: Printing Formatted Messages.
--* MM_HALT: Printing Formatted Messages.
--* MM_HARD: Printing Formatted Messages.
--* MM_INFO: Printing Formatted Messages.
--* MM_NOSEV: Printing Formatted Messages.
--* MM_NRECOV: Printing Formatted Messages.
--* MM_NULLACT: Printing Formatted Messages.
--* MM_NULLLBL: Printing Formatted Messages.
--* MM_NULLMC: Printing Formatted Messages.
--* MM_NULLSEV: Printing Formatted Messages.
--* MM_NULLTAG: Printing Formatted Messages.
--* MM_NULLTXT: Printing Formatted Messages.
--* MM_OPSYS: Printing Formatted Messages.
--* MM_PRINT: Printing Formatted Messages.
--* MM_RECOVER: Printing Formatted Messages.
--* MM_SOFT: Printing Formatted Messages.
--* MM_UTIL: Printing Formatted Messages.
--* MM_WARNING: Printing Formatted Messages.
--* MNTOPT_DEFAULTS: Filesystem handling.
--* MNTOPT_NOAUTO: Filesystem handling.
--* MNTOPT_NOSUID: Filesystem handling.
--* MNTOPT_RO: Filesystem handling.
--* MNTOPT_RW: Filesystem handling.
--* MNTOPT_SUID: Filesystem handling.
--* MNTTYPE_IGNORE: Filesystem handling.
--* MNTTYPE_NFS: Filesystem handling.
--* MNTTYPE_SWAP: Filesystem handling.
--* MON_1: The Elegant and Fast Way.
--* MON_10: The Elegant and Fast Way.
--* MON_11: The Elegant and Fast Way.
--* MON_12: The Elegant and Fast Way.
--* MON_2: The Elegant and Fast Way.
--* MON_3: The Elegant and Fast Way.
--* MON_4: The Elegant and Fast Way.
--* MON_5: The Elegant and Fast Way.
--* MON_6: The Elegant and Fast Way.
--* MON_7: The Elegant and Fast Way.
--* MON_8: The Elegant and Fast Way.
--* MON_9: The Elegant and Fast Way.
--* MON_DECIMAL_POINT: The Elegant and Fast Way.
--* MON_GROUPING: The Elegant and Fast Way.
--* MON_THOUSANDS_SEP: The Elegant and Fast Way.
--* MS_ASYNC: Memory-mapped I/O.
--* MS_SYNC: Memory-mapped I/O.
--* MSG_DONTROUTE: Socket Data Options.
--* MSG_OOB: Socket Data Options.
--* MSG_PEEK: Socket Data Options.
--* N_CS_PRECEDES: The Elegant and Fast Way.
--* N_SEP_BY_SPACE: The Elegant and Fast Way.
--* N_SIGN_POSN: The Elegant and Fast Way.
--* NAME_MAX: Limits for Files.
--* NAN: Infinity and NaN.
--* NCCS: Mode Data Types.
--* NDEBUG: Consistency Checking.
--* NEGATIVE_SIGN: The Elegant and Fast Way.
--* netgroup: NSS Basics.
--* networks: NSS Basics.
--* NEW_TIME <1>: XPG Functions.
--* NEW_TIME: Manipulating the Database.
--* NGROUPS_MAX: General Limits.
--* NL_ARGMAX: Output Conversion Syntax.
--* NO_ADDRESS: Host Names.
--* NO_RECOVERY: Host Names.
--* NOEXPR: The Elegant and Fast Way.
--* NOFLSH: Local Modes.
--* NOKERNINFO: Local Modes.
--* NOSTR: The Elegant and Fast Way.
--* NSIG: Standard Signals.
--* NSS_STATUS_NOTFOUND: NSS Modules Interface.
--* NSS_STATUS_SUCCESS: NSS Modules Interface.
--* NSS_STATUS_TRYAGAIN: NSS Modules Interface.
--* NSS_STATUS_UNAVAIL: NSS Modules Interface.
--* NULL: Null Pointer Constant.
--* O_ACCMODE: Access Modes.
--* O_APPEND: Operating Modes.
--* O_ASYNC: Operating Modes.
--* O_CREAT: Open-time Flags.
--* O_EXCL: Open-time Flags.
--* O_EXEC: Access Modes.
--* O_EXLOCK: Open-time Flags.
--* O_FSYNC: Operating Modes.
--* O_IGNORE_CTTY: Open-time Flags.
--* O_NDELAY: Operating Modes.
--* O_NOATIME: Operating Modes.
--* O_NOCTTY: Open-time Flags.
--* O_NOLINK: Open-time Flags.
--* O_NONBLOCK <1>: Operating Modes.
--* O_NONBLOCK: Open-time Flags.
--* O_NOTRANS: Open-time Flags.
--* O_RDONLY: Access Modes.
--* O_RDWR: Access Modes.
--* O_READ: Access Modes.
--* O_SHLOCK: Open-time Flags.
--* O_SYNC: Operating Modes.
--* O_TRUNC: Open-time Flags.
--* O_WRITE: Access Modes.
--* O_WRONLY: Access Modes.
--* obstack_alloc_failed_handler: Preparing for Obstacks.
--* OLD_TIME <1>: XPG Functions.
--* OLD_TIME: Manipulating the Database.
--* ONLCR: Output Modes.
--* ONOEOT: Output Modes.
--* OPEN_MAX: General Limits.
--* OPOST: Output Modes.
--* optarg: Using Getopt.
--* opterr: Using Getopt.
--* optind: Using Getopt.
--* OPTION_ALIAS: Argp Option Flags.
--* OPTION_ARG_OPTIONAL: Argp Option Flags.
--* OPTION_DOC: Argp Option Flags.
--* OPTION_HIDDEN: Argp Option Flags.
--* OPTION_NO_USAGE: Argp Option Flags.
--* optopt: Using Getopt.
--* OXTABS: Output Modes.
--* P_CS_PRECEDES: The Elegant and Fast Way.
--* P_SEP_BY_SPACE: The Elegant and Fast Way.
--* P_SIGN_POSN: The Elegant and Fast Way.
--* P_tmpdir: Temporary Files.
--* PA_CHAR: Parsing a Template String.
--* PA_DOUBLE: Parsing a Template String.
--* PA_FLAG_LONG: Parsing a Template String.
--* PA_FLAG_LONG_DOUBLE: Parsing a Template String.
--* PA_FLAG_LONG_LONG: Parsing a Template String.
--* PA_FLAG_MASK: Parsing a Template String.
--* PA_FLAG_PTR: Parsing a Template String.
--* PA_FLAG_SHORT: Parsing a Template String.
--* PA_FLOAT: Parsing a Template String.
--* PA_INT: Parsing a Template String.
--* PA_LAST: Parsing a Template String.
--* PA_POINTER: Parsing a Template String.
--* PA_STRING: Parsing a Template String.
--* PARENB: Control Modes.
--* PARMRK: Input Modes.
--* PARODD: Control Modes.
--* passwd: NSS Basics.
--* PATH_MAX: Limits for Files.
--* PENDIN: Local Modes.
--* PF_CCITT: Misc Namespaces.
--* PF_FILE: Local Namespace Details.
--* PF_IMPLINK: Misc Namespaces.
--* PF_INET: Internet Namespace.
--* PF_ISO: Misc Namespaces.
--* PF_LOCAL: Local Namespace Details.
--* PF_NS: Misc Namespaces.
--* PF_ROUTE: Misc Namespaces.
--* PF_UNIX: Local Namespace Details.
--* PI: Mathematical Constants.
--* PIPE_BUF: Limits for Files.
--* PM_STR: The Elegant and Fast Way.
--* POSITIVE_SIGN: The Elegant and Fast Way.
--* PRIO_MAX: Priority.
--* PRIO_MIN: Priority.
--* PRIO_PGRP: Priority.
--* PRIO_PROCESS: Priority.
--* PRIO_USER: Priority.
--* program_invocation_name: Error Messages.
--* program_invocation_short_name: Error Messages.
--* PROT_EXEC: Memory-mapped I/O.
--* PROT_READ: Memory-mapped I/O.
--* PROT_WRITE: Memory-mapped I/O.
--* protocols: NSS Basics.
--* R_OK: Testing File Access.
--* RADIXCHAR: The Elegant and Fast Way.
--* RAND_MAX: ISO Random.
--* RE_DUP_MAX: General Limits.
--* RLIM_INFINITY: Limits on Resources.
--* RLIM_NLIMITS: Limits on Resources.
--* RLIMIT_CORE: Limits on Resources.
--* RLIMIT_CPU: Limits on Resources.
--* RLIMIT_DATA: Limits on Resources.
--* RLIMIT_FSIZE: Limits on Resources.
--* RLIMIT_NOFILE: Limits on Resources.
--* RLIMIT_OFILE: Limits on Resources.
--* RLIMIT_RSS: Limits on Resources.
--* RLIMIT_STACK: Limits on Resources.
--* rpc: NSS Basics.
--* RUN_LVL <1>: XPG Functions.
--* RUN_LVL: Manipulating the Database.
--* S_IEXEC: Permission Bits.
--* S_IFBLK: Testing File Type.
--* S_IFCHR: Testing File Type.
--* S_IFDIR: Testing File Type.
--* S_IFIFO: Testing File Type.
--* S_IFLNK: Testing File Type.
--* S_IFMT: Testing File Type.
--* S_IFREG: Testing File Type.
--* S_IFSOCK: Testing File Type.
--* S_IREAD: Permission Bits.
--* S_IRGRP: Permission Bits.
--* S_IROTH: Permission Bits.
--* S_IRUSR: Permission Bits.
--* S_IRWXG: Permission Bits.
--* S_IRWXO: Permission Bits.
--* S_IRWXU: Permission Bits.
--* S_ISGID: Permission Bits.
--* S_ISUID: Permission Bits.
--* S_ISVTX: Permission Bits.
--* S_IWGRP: Permission Bits.
--* S_IWOTH: Permission Bits.
--* S_IWRITE: Permission Bits.
--* S_IWUSR: Permission Bits.
--* S_IXGRP: Permission Bits.
--* S_IXOTH: Permission Bits.
--* S_IXUSR: Permission Bits.
--* SA_NOCLDSTOP: Flags for Sigaction.
--* SA_ONSTACK: Flags for Sigaction.
--* SA_RESTART: Flags for Sigaction.
--* SCHAR_MAX: Range of Type.
--* SCHAR_MIN: Range of Type.
--* SEEK_CUR: File Positioning.
--* SEEK_END: File Positioning.
--* SEEK_SET: File Positioning.
--* SEM_VALUE_MAX: POSIX Semaphores.
--* services: NSS Basics.
--* shadow: NSS Basics.
--* SHRT_MAX: Range of Type.
--* SHRT_MIN: Range of Type.
--* SIG_BLOCK: Process Signal Mask.
--* SIG_DFL: Basic Signal Handling.
--* SIG_ERR: Basic Signal Handling.
--* SIG_IGN: Basic Signal Handling.
--* SIG_SETMASK: Process Signal Mask.
--* SIG_UNBLOCK: Process Signal Mask.
--* SIGABRT: Program Error Signals.
--* SIGALRM: Alarm Signals.
--* SIGBUS: Program Error Signals.
--* SIGCHLD: Job Control Signals.
--* SIGCLD: Job Control Signals.
--* SIGCONT: Job Control Signals.
--* SIGEMT: Program Error Signals.
--* SIGFPE: Program Error Signals.
--* SIGHUP: Termination Signals.
--* SIGILL: Program Error Signals.
--* SIGINFO: Miscellaneous Signals.
--* SIGINT: Termination Signals.
--* SIGIO: Asynchronous I/O Signals.
--* SIGIOT: Program Error Signals.
--* SIGKILL: Termination Signals.
--* SIGLOST: Operation Error Signals.
--* signgam: Special Functions.
--* SIGPIPE: Operation Error Signals.
--* SIGPOLL: Asynchronous I/O Signals.
--* SIGPROF: Alarm Signals.
--* SIGQUIT: Termination Signals.
--* SIGSEGV: Program Error Signals.
--* SIGSTKSZ: Signal Stack.
--* SIGSTOP: Job Control Signals.
--* SIGSYS: Program Error Signals.
--* SIGTERM: Termination Signals.
--* SIGTRAP: Program Error Signals.
--* SIGTSTP: Job Control Signals.
--* SIGTTIN: Job Control Signals.
--* SIGTTOU: Job Control Signals.
--* SIGURG: Asynchronous I/O Signals.
--* SIGUSR1: Miscellaneous Signals.
--* SIGUSR2: Miscellaneous Signals.
--* SIGVTALRM: Alarm Signals.
--* SIGWINCH: Miscellaneous Signals.
--* SIGXCPU: Operation Error Signals.
--* SIGXFSZ: Operation Error Signals.
--* SOCK_DGRAM: Communication Styles.
--* SOCK_RAW: Communication Styles.
--* SOCK_STREAM: Communication Styles.
--* SOL_SOCKET: Socket-Level Options.
--* SS_DISABLE: Signal Stack.
--* SS_ONSTACK: Signal Stack.
--* SSIZE_MAX: General Limits.
--* stderr: Standard Streams.
--* STDERR_FILENO: Descriptors and Streams.
--* stdin: Standard Streams.
--* STDIN_FILENO: Descriptors and Streams.
--* stdout: Standard Streams.
--* STDOUT_FILENO: Descriptors and Streams.
--* STREAM_MAX: General Limits.
--* SV_INTERRUPT: BSD Handler.
--* SV_ONSTACK: BSD Handler.
--* SV_RESETHAND: BSD Handler.
--* sys_siglist: Signal Messages.
--* T_FMT: The Elegant and Fast Way.
--* T_FMT_AMPM: The Elegant and Fast Way.
--* TCIFLUSH: Line Control.
--* TCIOFF: Line Control.
--* TCIOFLUSH: Line Control.
--* TCION: Line Control.
--* TCOFLUSH: Line Control.
--* TCOOFF: Line Control.
--* TCOON: Line Control.
--* TCSADRAIN: Mode Functions.
--* TCSAFLUSH: Mode Functions.
--* TCSANOW: Mode Functions.
--* TCSASOFT: Mode Functions.
--* THOUSANDS_SEP: The Elegant and Fast Way.
--* THOUSEP: The Elegant and Fast Way.
--* timezone: Time Zone Functions.
--* TMP_MAX: Temporary Files.
--* TOSTOP: Local Modes.
--* TRY_AGAIN: Host Names.
--* tzname: Time Zone Functions.
--* TZNAME_MAX: General Limits.
--* UCHAR_MAX: Range of Type.
--* UINT_MAX: Range of Type.
--* ULONG_LONG_MAX: Range of Type.
--* ULONG_MAX: Range of Type.
--* USER_PROCESS <1>: XPG Functions.
--* USER_PROCESS: Manipulating the Database.
--* USHRT_MAX: Range of Type.
--* VDISCARD: Other Special.
--* VDSUSP: Signal Characters.
--* VEOF: Editing Characters.
--* VEOL: Editing Characters.
--* VEOL2: Editing Characters.
--* VERASE: Editing Characters.
--* VINTR: Signal Characters.
--* VKILL: Editing Characters.
--* VLNEXT: Other Special.
--* VMIN: Noncanonical Input.
--* VQUIT: Signal Characters.
--* VREPRINT: Editing Characters.
--* VSTART: Start/Stop Characters.
--* VSTATUS: Other Special.
--* VSTOP: Start/Stop Characters.
--* VSUSP: Signal Characters.
--* VTIME: Noncanonical Input.
--* VWERASE: Editing Characters.
--* W_OK: Testing File Access.
--* WCHAR_MAX <1>: Range of Type.
--* WCHAR_MAX: Extended Char Intro.
--* WCHAR_MIN: Extended Char Intro.
--* WEOF: Extended Char Intro.
--* X_OK: Testing File Access.
--* YESEXPR: The Elegant and Fast Way.
--* YESSTR: The Elegant and Fast Way.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-52 glibc-2.1.3/manual/libc.info-52
---- ../glibc-2.1.3/manual/libc.info-52 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-52 1969-12-31 16:00:00.000000000 -0800
-@@ -1,287 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: File Index, Prev: Variable Index, Up: Top
--
--Program and File Index
--**********************
--
--* Menu:
--
--* -lbsd-compat <1>: Process Group Functions.
--* -lbsd-compat: Feature Test Macros.
--* /etc/group: Group Database.
--* /etc/hosts: Host Names.
--* /etc/localtime: TZ Variable.
--* /etc/networks: Networks Database.
--* /etc/passwd: User Database.
--* /etc/protocols: Protocols Database.
--* /etc/services: Services Database.
--* /share/lib/zoneinfo: TZ Variable.
--* argp.h: Argp.
--* argz.h: Argz Functions.
--* arpa/inet.h: Host Address Functions.
--* assert.h: Consistency Checking.
--* bsd-compat <1>: Process Group Functions.
--* bsd-compat: Feature Test Macros.
--* cd: Working Directory.
--* chgrp: File Owner.
--* chown: File Owner.
--* complex.h <1>: Operations on Complex.
--* complex.h <2>: Complex Numbers.
--* complex.h: Mathematics.
--* ctype.h <1>: Case Conversion.
--* ctype.h <2>: Classification of Characters.
--* ctype.h: Character Handling.
--* dirent.h <1>: Random Access Directory.
--* dirent.h <2>: Reading/Closing Directory.
--* dirent.h <3>: Opening a Directory.
--* dirent.h <4>: Directory Entries.
--* dirent.h: Reserved Names.
--* envz.h: Envz Functions.
--* errno.h <1>: Error Codes.
--* errno.h <2>: Checking for Errors.
--* errno.h: Error Reporting.
--* fcntl.h <1>: Interrupt Input.
--* fcntl.h <2>: File Locks.
--* fcntl.h <3>: File Status Flags.
--* fcntl.h <4>: Descriptor Flags.
--* fcntl.h <5>: Duplicating Descriptors.
--* fcntl.h <6>: Control Operations.
--* fcntl.h <7>: Opening and Closing Files.
--* fcntl.h: Reserved Names.
--* float.h: Floating Point Parameters.
--* fnmatch.h: Wildcard Matching.
--* gcc: ISO C.
--* gconv.h: glibc iconv Implementation.
--* grp.h <1>: Group Data Structure.
--* grp.h <2>: Setting Groups.
--* grp.h: Reserved Names.
--* hostid: Host Identification.
--* hostname: Host Identification.
--* iconv.h: Generic Conversion Interface.
--* kill: Termination Signals.
--* limits.h <1>: Width of Type.
--* limits.h <2>: Limits for Files.
--* limits.h <3>: General Limits.
--* limits.h <4>: Selecting the Conversion.
--* limits.h: Reserved Names.
--* locale.h <1>: The Lame Way to Locale Data.
--* locale.h: Setting the Locale.
--* localtime: TZ Variable.
--* ls: File Attributes.
--* malloc.h <1>: Statistics of Malloc.
--* malloc.h <2>: Hooks for Malloc.
--* malloc.h: Malloc Tunable Parameters.
--* math.h <1>: Rounding Functions.
--* math.h <2>: Normalization Functions.
--* math.h <3>: Absolute Value.
--* math.h <4>: Floating Point Classes.
--* math.h: Mathematics.
--* mcheck.h: Heap Consistency Checking.
--* mkdir: Creating Directories.
--* netdb.h <1>: Networks Database.
--* netdb.h <2>: Protocols Database.
--* netdb.h <3>: Services Database.
--* netdb.h: Host Names.
--* netinet/in.h <1>: Byte Order.
--* netinet/in.h <2>: Ports.
--* netinet/in.h <3>: Host Address Data Type.
--* netinet/in.h: Internet Address Formats.
--* obstack.h: Creating Obstacks.
--* printf.h <1>: Conversion Specifier Options.
--* printf.h: Registering New Conversions.
--* pwd.h <1>: User Data Structure.
--* pwd.h: Reserved Names.
--* setjmp.h <1>: Non-Local Exits and Signals.
--* setjmp.h: Non-Local Details.
--* sh: Running a Command.
--* signal.h <1>: BSD Signal Handling.
--* signal.h <2>: Checking for Pending Signals.
--* signal.h <3>: Process Signal Mask.
--* signal.h <4>: Signal Sets.
--* signal.h <5>: Signaling Another Process.
--* signal.h <6>: Signaling Yourself.
--* signal.h <7>: Flags for Sigaction.
--* signal.h <8>: Advanced Signal Handling.
--* signal.h <9>: Basic Signal Handling.
--* signal.h <10>: Standard Signals.
--* signal.h: Reserved Names.
--* stdarg.h <1>: Argument Macros.
--* stdarg.h: Receiving Arguments.
--* stddef.h: Important Data Types.
--* stdio.h <1>: Who Logged In.
--* stdio.h <2>: Identifying the Terminal.
--* stdio.h <3>: Signal Messages.
--* stdio.h <4>: Temporary Files.
--* stdio.h <5>: Deleting Files.
--* stdio.h <6>: Descriptors and Streams.
--* stdio.h <7>: Streams and Cookies.
--* stdio.h <8>: String Streams.
--* stdio.h <9>: Controlling Buffering.
--* stdio.h <10>: Flushing Buffers.
--* stdio.h <11>: Portable Positioning.
--* stdio.h <12>: File Positioning.
--* stdio.h <13>: EOF and Errors.
--* stdio.h <14>: Formatted Input Functions.
--* stdio.h <15>: Variable Arguments Output.
--* stdio.h <16>: Formatted Output Functions.
--* stdio.h <17>: Block Input/Output.
--* stdio.h <18>: Character Input.
--* stdio.h <19>: Simple Output.
--* stdio.h <20>: Opening Streams.
--* stdio.h <21>: Standard Streams.
--* stdio.h: Streams.
--* stdlib.h <1>: Running a Command.
--* stdlib.h <2>: Aborting a Program.
--* stdlib.h <3>: Exit Status.
--* stdlib.h <4>: Environment Access.
--* stdlib.h <5>: Parsing of Floats.
--* stdlib.h <6>: Parsing of Integers.
--* stdlib.h <7>: Integer Division.
--* stdlib.h <8>: Absolute Value.
--* stdlib.h <9>: BSD Random.
--* stdlib.h <10>: ISO Random.
--* stdlib.h <11>: Allocation.
--* stdlib.h <12>: Array Sort Function.
--* stdlib.h <13>: Array Search Function.
--* stdlib.h <14>: Non-reentrant Character Conversion.
--* stdlib.h <15>: Selecting the Conversion.
--* stdlib.h <16>: Variable Size Automatic.
--* stdlib.h <17>: Aligned Memory Blocks.
--* stdlib.h <18>: Allocating Cleared Space.
--* stdlib.h <19>: Changing Block Size.
--* stdlib.h <20>: Freeing after Malloc.
--* stdlib.h: Basic Allocation.
--* string.h <1>: Signal Messages.
--* string.h <2>: Finding Tokens in a String.
--* string.h <3>: Search Functions.
--* string.h <4>: Collation Functions.
--* string.h <5>: String/Array Comparison.
--* string.h <6>: Copying and Concatenation.
--* string.h: String Length.
--* sys/param.h: Host Identification.
--* sys/resource.h <1>: Priority.
--* sys/resource.h <2>: Limits on Resources.
--* sys/resource.h: Resource Usage.
--* sys/socket.h <1>: Socket-Level Options.
--* sys/socket.h <2>: Socket Option Functions.
--* sys/socket.h <3>: Sending Datagrams.
--* sys/socket.h <4>: Socket Data Options.
--* sys/socket.h <5>: Receiving Data.
--* sys/socket.h <6>: Sending Data.
--* sys/socket.h <7>: Socket Pairs.
--* sys/socket.h <8>: Closing a Socket.
--* sys/socket.h <9>: Creating a Socket.
--* sys/socket.h <10>: Internet Namespace.
--* sys/socket.h <11>: Local Namespace Details.
--* sys/socket.h <12>: Reading Address.
--* sys/socket.h <13>: Setting Address.
--* sys/socket.h <14>: Address Formats.
--* sys/socket.h: Communication Styles.
--* sys/stat.h <1>: FIFO Special Files.
--* sys/stat.h <2>: Making Special Files.
--* sys/stat.h <3>: Setting Permissions.
--* sys/stat.h <4>: Permission Bits.
--* sys/stat.h <5>: Testing File Type.
--* sys/stat.h <6>: Attribute Meanings.
--* sys/stat.h <7>: Creating Directories.
--* sys/stat.h: Reserved Names.
--* sys/time.h <1>: Setting an Alarm.
--* sys/time.h <2>: High-Resolution Calendar.
--* sys/time.h: File Times.
--* sys/times.h <1>: Detailed CPU Time.
--* sys/times.h: Reserved Names.
--* sys/timex.h: Precision Time.
--* sys/types.h <1>: Setting Groups.
--* sys/types.h <2>: Setting User ID.
--* sys/types.h <3>: Reading Persona.
--* sys/types.h <4>: Terminal Access Functions.
--* sys/types.h <5>: Process Group Functions.
--* sys/types.h <6>: Process Identification.
--* sys/types.h: Waiting for I/O.
--* sys/un.h: Local Namespace Details.
--* sys/utsname.h: Hardware/Software Type ID.
--* sys/wait.h <1>: BSD Wait Functions.
--* sys/wait.h <2>: Process Completion Status.
--* sys/wait.h: Process Completion.
--* termios.h <1>: Terminal Modes.
--* termios.h: Reserved Names.
--* time.h <1>: TZ Variable.
--* time.h <2>: Formatting Date and Time.
--* time.h <3>: Simple Calendar Time.
--* time.h <4>: Basic CPU Time.
--* time.h: File Times.
--* umask: Setting Permissions.
--* unistd.h <1>: Options for Files.
--* unistd.h <2>: System Options.
--* unistd.h <3>: Host Identification.
--* unistd.h <4>: Who Logged In.
--* unistd.h <5>: Setting Groups.
--* unistd.h <6>: Setting User ID.
--* unistd.h <7>: Reading Persona.
--* unistd.h <8>: Terminal Access Functions.
--* unistd.h <9>: Process Group Functions.
--* unistd.h <10>: Executing a File.
--* unistd.h <11>: Creating a Process.
--* unistd.h <12>: Process Identification.
--* unistd.h <13>: Termination Internals.
--* unistd.h <14>: Using Getopt.
--* unistd.h <15>: Setting an Alarm.
--* unistd.h <16>: Is It a Terminal.
--* unistd.h <17>: Creating a Pipe.
--* unistd.h <18>: Testing File Access.
--* unistd.h <19>: File Owner.
--* unistd.h <20>: Deleting Files.
--* unistd.h <21>: Symbolic Links.
--* unistd.h <22>: Hard Links.
--* unistd.h <23>: Working Directory.
--* unistd.h <24>: Duplicating Descriptors.
--* unistd.h <25>: Descriptors and Streams.
--* unistd.h <26>: I/O Primitives.
--* unistd.h: Opening and Closing Files.
--* utime.h: File Times.
--* utmp.h <1>: Logging In and Out.
--* utmp.h: Manipulating the Database.
--* utmpx.h: XPG Functions.
--* varargs.h: Old Varargs.
--* wchar.h <1>: Converting Strings.
--* wchar.h <2>: Converting a Character.
--* wchar.h <3>: Keeping the state.
--* wchar.h: Extended Char Intro.
--* wctype.h <1>: Wide Character Case Conversion.
--* wctype.h: Classification of Wide Characters.
--* zoneinfo: TZ Variable.
--
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-6 glibc-2.1.3/manual/libc.info-6
---- ../glibc-2.1.3/manual/libc.info-6 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-6 1969-12-31 16:00:00.000000000 -0800
-@@ -1,998 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: String/Array Comparison, Next: Collation Functions, Prev: Copying and Concatenation, Up: String and Array Utilities
--
--String/Array Comparison
--=======================
--
-- You can use the functions in this section to perform comparisons on
--the contents of strings and arrays. As well as checking for equality,
--these functions can also be used as the ordering functions for sorting
--operations. *Note Searching and Sorting::, for an example of this.
--
-- Unlike most comparison operations in C, the string comparison
--functions return a nonzero value if the strings are *not* equivalent
--rather than if they are. The sign of the value indicates the relative
--ordering of the first characters in the strings that are not
--equivalent: a negative value indicates that the first string is "less"
--than the second, while a positive value indicates that the first string
--is "greater".
--
-- The most common use of these functions is to check only for equality.
--This is canonically done with an expression like `! strcmp (s1, s2)'.
--
-- All of these functions are declared in the header file `string.h'.
--
-- - Function: int memcmp (const void *A1, const void *A2, size_t SIZE)
-- The function `memcmp' compares the SIZE bytes of memory beginning
-- at A1 against the SIZE bytes of memory beginning at A2. The value
-- returned has the same sign as the difference between the first
-- differing pair of bytes (interpreted as `unsigned char' objects,
-- then promoted to `int').
--
-- If the contents of the two blocks are equal, `memcmp' returns `0'.
--
-- On arbitrary arrays, the `memcmp' function is mostly useful for
--testing equality. It usually isn't meaningful to do byte-wise ordering
--comparisons on arrays of things other than bytes. For example, a
--byte-wise comparison on the bytes that make up floating-point numbers
--isn't likely to tell you anything about the relationship between the
--values of the floating-point numbers.
--
-- You should also be careful about using `memcmp' to compare objects
--that can contain "holes", such as the padding inserted into structure
--objects to enforce alignment requirements, extra space at the end of
--unions, and extra characters at the ends of strings whose length is less
--than their allocated size. The contents of these "holes" are
--indeterminate and may cause strange behavior when performing byte-wise
--comparisons. For more predictable results, perform an explicit
--component-wise comparison.
--
-- For example, given a structure type definition like:
--
-- struct foo
-- {
-- unsigned char tag;
-- union
-- {
-- double f;
-- long i;
-- char *p;
-- } value;
-- };
--
--you are better off writing a specialized comparison function to compare
--`struct foo' objects instead of comparing them with `memcmp'.
--
-- - Function: int strcmp (const char *S1, const char *S2)
-- The `strcmp' function compares the string S1 against S2, returning
-- a value that has the same sign as the difference between the first
-- differing pair of characters (interpreted as `unsigned char'
-- objects, then promoted to `int').
--
-- If the two strings are equal, `strcmp' returns `0'.
--
-- A consequence of the ordering used by `strcmp' is that if S1 is an
-- initial substring of S2, then S1 is considered to be "less than"
-- S2.
--
-- - Function: int strcasecmp (const char *S1, const char *S2)
-- This function is like `strcmp', except that differences in case are
-- ignored. How uppercase and lowercase characters are related is
-- determined by the currently selected locale. In the standard `"C"'
-- locale the characters "A and "a do not match but in a locale which
-- regards these characters as parts of the alphabet they do match.
--
-- `strcasecmp' is derived from BSD.
--
-- - Function: int strncasecmp (const char *S1, const char *S2, size_t N)
-- This function is like `strncmp', except that differences in case
-- are ignored. Like `strcasecmp', it is locale dependent how
-- uppercase and lowercase characters are related.
--
-- `strncasecmp' is a GNU extension.
--
-- - Function: int strncmp (const char *S1, const char *S2, size_t SIZE)
-- This function is the similar to `strcmp', except that no more than
-- SIZE characters are compared. In other words, if the two strings
-- are the same in their first SIZE characters, the return value is
-- zero.
--
-- Here are some examples showing the use of `strcmp' and `strncmp'.
--These examples assume the use of the ASCII character set. (If some
--other character set--say, EBCDIC--is used instead, then the glyphs are
--associated with different numeric codes, and the return values and
--ordering may differ.)
--
-- strcmp ("hello", "hello")
-- => 0 /* These two strings are the same. */
-- strcmp ("hello", "Hello")
-- => 32 /* Comparisons are case-sensitive. */
-- strcmp ("hello", "world")
-- => -15 /* The character `'h'' comes before `'w''. */
-- strcmp ("hello", "hello, world")
-- => -44 /* Comparing a null character against a comma. */
-- strncmp ("hello", "hello, world", 5)
-- => 0 /* The initial 5 characters are the same. */
-- strncmp ("hello, world", "hello, stupid world!!!", 5)
-- => 0 /* The initial 5 characters are the same. */
--
-- - Function: int strverscmp (const char *S1, const char *S2)
-- The `strverscmp' function compares the string S1 against S2,
-- considering them as holding indices/version numbers. Return value
-- follows the same conventions as found in the `strverscmp'
-- function. In fact, if S1 and S2 contain no digits, `strverscmp'
-- behaves like `strcmp'.
--
-- Basically, we compare strings normally (character by character),
-- until we find a digit in each string - then we enter a special
-- comparison mode, where each sequence of digits is taken as a
-- whole. If we reach the end of these two parts without noticing a
-- difference, we return to the standard comparison mode. There are
-- two types of numeric parts: "integral" and "fractional" (those
-- begin with a '0'). The types of the numeric parts affect the way
-- we sort them:
--
-- * integral/integral: we compare values as you would expect.
--
-- * fractional/integral: the fractional part is less than the
-- integral one. Again, no surprise.
--
-- * fractional/fractional: the things become a bit more complex.
-- If the common prefix contains only leading zeroes, the
-- longest part is less than the other one; else the comparison
-- behaves normally.
--
-- strverscmp ("no digit", "no digit")
-- => 0 /* same behaviour as strcmp. */
-- strverscmp ("item#99", "item#100")
-- => <0 /* same prefix, but 99 < 100. */
-- strverscmp ("alpha1", "alpha001")
-- => >0 /* fractional part inferior to integral one. */
-- strverscmp ("part1_f012", "part1_f01")
-- => >0 /* two fractional parts. */
-- strverscmp ("foo.009", "foo.0")
-- => <0 /* idem, but with leading zeroes only. */
--
-- This function is especially useful when dealing with filename
-- sorting, because filenames frequently hold indices/version numbers.
--
-- `strverscmp' is a GNU extension.
--
-- - Function: int bcmp (const void *A1, const void *A2, size_t SIZE)
-- This is an obsolete alias for `memcmp', derived from BSD.
--
--
--File: libc.info, Node: Collation Functions, Next: Search Functions, Prev: String/Array Comparison, Up: String and Array Utilities
--
--Collation Functions
--===================
--
-- In some locales, the conventions for lexicographic ordering differ
--from the strict numeric ordering of character codes. For example, in
--Spanish most glyphs with diacritical marks such as accents are not
--considered distinct letters for the purposes of collation. On the
--other hand, the two-character sequence `ll' is treated as a single
--letter that is collated immediately after `l'.
--
-- You can use the functions `strcoll' and `strxfrm' (declared in the
--header file `string.h') to compare strings using a collation ordering
--appropriate for the current locale. The locale used by these functions
--in particular can be specified by setting the locale for the
--`LC_COLLATE' category; see *Note Locales::.
--
-- In the standard C locale, the collation sequence for `strcoll' is
--the same as that for `strcmp'.
--
-- Effectively, the way these functions work is by applying a mapping to
--transform the characters in a string to a byte sequence that represents
--the string's position in the collating sequence of the current locale.
--Comparing two such byte sequences in a simple fashion is equivalent to
--comparing the strings with the locale's collating sequence.
--
-- The function `strcoll' performs this translation implicitly, in
--order to do one comparison. By contrast, `strxfrm' performs the
--mapping explicitly. If you are making multiple comparisons using the
--same string or set of strings, it is likely to be more efficient to use
--`strxfrm' to transform all the strings just once, and subsequently
--compare the transformed strings with `strcmp'.
--
-- - Function: int strcoll (const char *S1, const char *S2)
-- The `strcoll' function is similar to `strcmp' but uses the
-- collating sequence of the current locale for collation (the
-- `LC_COLLATE' locale).
--
-- Here is an example of sorting an array of strings, using `strcoll'
--to compare them. The actual sort algorithm is not written here; it
--comes from `qsort' (*note Array Sort Function::.). The job of the code
--shown here is to say how to compare the strings while sorting them.
--(Later on in this section, we will show a way to do this more
--efficiently using `strxfrm'.)
--
-- /* This is the comparison function used with `qsort'. */
--
-- int
-- compare_elements (char **p1, char **p2)
-- {
-- return strcoll (*p1, *p2);
-- }
--
-- /* This is the entry point--the function to sort
-- strings using the locale's collating sequence. */
--
-- void
-- sort_strings (char **array, int nstrings)
-- {
-- /* Sort `temp_array' by comparing the strings. */
-- qsort (array, nstrings,
-- sizeof (char *), compare_elements);
-- }
--
-- - Function: size_t strxfrm (char *TO, const char *FROM, size_t SIZE)
-- The function `strxfrm' transforms STRING using the collation
-- transformation determined by the locale currently selected for
-- collation, and stores the transformed string in the array TO. Up
-- to SIZE characters (including a terminating null character) are
-- stored.
--
-- The behavior is undefined if the strings TO and FROM overlap; see
-- *Note Copying and Concatenation::.
--
-- The return value is the length of the entire transformed string.
-- This value is not affected by the value of SIZE, but if it is
-- greater or equal than SIZE, it means that the transformed string
-- did not entirely fit in the array TO. In this case, only as much
-- of the string as actually fits was stored. To get the whole
-- transformed string, call `strxfrm' again with a bigger output
-- array.
--
-- The transformed string may be longer than the original string, and
-- it may also be shorter.
--
-- If SIZE is zero, no characters are stored in TO. In this case,
-- `strxfrm' simply returns the number of characters that would be
-- the length of the transformed string. This is useful for
-- determining what size string to allocate. It does not matter what
-- TO is if SIZE is zero; TO may even be a null pointer.
--
-- Here is an example of how you can use `strxfrm' when you plan to do
--many comparisons. It does the same thing as the previous example, but
--much faster, because it has to transform each string only once, no
--matter how many times it is compared with other strings. Even the time
--needed to allocate and free storage is much less than the time we save,
--when there are many strings.
--
-- struct sorter { char *input; char *transformed; };
--
-- /* This is the comparison function used with `qsort'
-- to sort an array of `struct sorter'. */
--
-- int
-- compare_elements (struct sorter *p1, struct sorter *p2)
-- {
-- return strcmp (p1->transformed, p2->transformed);
-- }
--
-- /* This is the entry point--the function to sort
-- strings using the locale's collating sequence. */
--
-- void
-- sort_strings_fast (char **array, int nstrings)
-- {
-- struct sorter temp_array[nstrings];
-- int i;
--
-- /* Set up `temp_array'. Each element contains
-- one input string and its transformed string. */
-- for (i = 0; i < nstrings; i++)
-- {
-- size_t length = strlen (array[i]) * 2;
-- char *transformed;
-- size_t transformed_length;
--
-- temp_array[i].input = array[i];
--
-- /* First try a buffer perhaps big enough. */
-- transformed = (char *) xmalloc (length);
--
-- /* Transform `array[i]'. */
-- transformed_length = strxfrm (transformed, array[i], length);
--
-- /* If the buffer was not large enough, resize it
-- and try again. */
-- if (transformed_length >= length)
-- {
-- /* Allocate the needed space. +1 for terminating
-- `NUL' character. */
-- transformed = (char *) xrealloc (transformed,
-- transformed_length + 1);
--
-- /* The return value is not interesting because we know
-- how long the transformed string is. */
-- (void) strxfrm (transformed, array[i],
-- transformed_length + 1);
-- }
--
-- temp_array[i].transformed = transformed;
-- }
--
-- /* Sort `temp_array' by comparing transformed strings. */
-- qsort (temp_array, sizeof (struct sorter),
-- nstrings, compare_elements);
--
-- /* Put the elements back in the permanent array
-- in their sorted order. */
-- for (i = 0; i < nstrings; i++)
-- array[i] = temp_array[i].input;
--
-- /* Free the strings we allocated. */
-- for (i = 0; i < nstrings; i++)
-- free (temp_array[i].transformed);
-- }
--
-- *Compatibility Note:* The string collation functions are a new
--feature of ISO C 89. Older C dialects have no equivalent feature.
--
--
--File: libc.info, Node: Search Functions, Next: Finding Tokens in a String, Prev: Collation Functions, Up: String and Array Utilities
--
--Search Functions
--================
--
-- This section describes library functions which perform various kinds
--of searching operations on strings and arrays. These functions are
--declared in the header file `string.h'.
--
-- - Function: void * memchr (const void *BLOCK, int C, size_t SIZE)
-- This function finds the first occurrence of the byte C (converted
-- to an `unsigned char') in the initial SIZE bytes of the object
-- beginning at BLOCK. The return value is a pointer to the located
-- byte, or a null pointer if no match was found.
--
-- - Function: char * strchr (const char *STRING, int C)
-- The `strchr' function finds the first occurrence of the character
-- C (converted to a `char') in the null-terminated string beginning
-- at STRING. The return value is a pointer to the located
-- character, or a null pointer if no match was found.
--
-- For example,
-- strchr ("hello, world", 'l')
-- => "llo, world"
-- strchr ("hello, world", '?')
-- => NULL
--
-- The terminating null character is considered to be part of the
-- string, so you can use this function get a pointer to the end of a
-- string by specifying a null character as the value of the C
-- argument.
--
-- - Function: char * index (const char *STRING, int C)
-- `index' is another name for `strchr'; they are exactly the same.
-- New code should always use `strchr' since this name is defined in
-- ISO C while `index' is a BSD invention which never was available
-- on System V derived systems.
--
-- One useful, but unusual, use of the `strchr' or `index' function is
--when one wants to have a pointer pointing to the NUL byte terminating a
--string. This is often written in this way:
--
-- s += strlen (s);
--
--This is almost optimal but the addition operation duplicated a bit of
--the work already done in the `strlen' function. A better solution is
--this:
--
-- s = strchr (s, '\0');
--
-- There is no restriction on the second parameter of `strchr' so it
--could very well also be the NUL character. Those readers thinking very
--hard about this might now point out that the `strchr' function is more
--expensive than the `strlen' function since we have two abort criteria.
--This is right. But when using the GNU C library is used this `strchr'
--call gets optimized in a special way so that this version actually is
--faster.
--
-- - Function: char * strrchr (const char *STRING, int C)
-- The function `strrchr' is like `strchr', except that it searches
-- backwards from the end of the string STRING (instead of forwards
-- from the front).
--
-- For example,
-- strrchr ("hello, world", 'l')
-- => "ld"
--
-- - Function: char * rindex (const char *STRING, int C)
-- `rindex' is another name for `strrchr'; they are exactly the same.
-- New code should always use `strrchr' since this name is defined in
-- ISO C while `rindex' is a BSD invention which never was available
-- on System V derived systems.
--
-- - Function: char * strstr (const char *HAYSTACK, const char *NEEDLE)
-- This is like `strchr', except that it searches HAYSTACK for a
-- substring NEEDLE rather than just a single character. It returns
-- a pointer into the string HAYSTACK that is the first character of
-- the substring, or a null pointer if no match was found. If NEEDLE
-- is an empty string, the function returns HAYSTACK.
--
-- For example,
-- strstr ("hello, world", "l")
-- => "llo, world"
-- strstr ("hello, world", "wo")
-- => "world"
--
-- - Function: void * memmem (const void *HAYSTACK, size_t HAYSTACK-LEN,
-- const void *NEEDLE, size_t NEEDLE-LEN)
-- This is like `strstr', but NEEDLE and HAYSTACK are byte arrays
-- rather than null-terminated strings. NEEDLE-LEN is the length of
-- NEEDLE and HAYSTACK-LEN is the length of HAYSTACK.
--
-- This function is a GNU extension.
--
-- - Function: size_t strspn (const char *STRING, const char *SKIPSET)
-- The `strspn' ("string span") function returns the length of the
-- initial substring of STRING that consists entirely of characters
-- that are members of the set specified by the string SKIPSET. The
-- order of the characters in SKIPSET is not important.
--
-- For example,
-- strspn ("hello, world", "abcdefghijklmnopqrstuvwxyz")
-- => 5
--
-- - Function: size_t strcspn (const char *STRING, const char *STOPSET)
-- The `strcspn' ("string complement span") function returns the
-- length of the initial substring of STRING that consists entirely
-- of characters that are *not* members of the set specified by the
-- string STOPSET. (In other words, it returns the offset of the
-- first character in STRING that is a member of the set STOPSET.)
--
-- For example,
-- strcspn ("hello, world", " \t\n,.;!?")
-- => 5
--
-- - Function: char * strpbrk (const char *STRING, const char *STOPSET)
-- The `strpbrk' ("string pointer break") function is related to
-- `strcspn', except that it returns a pointer to the first character
-- in STRING that is a member of the set STOPSET instead of the
-- length of the initial substring. It returns a null pointer if no
-- such character from STOPSET is found.
--
-- For example,
--
-- strpbrk ("hello, world", " \t\n,.;!?")
-- => ", world"
--
--
--File: libc.info, Node: Finding Tokens in a String, Next: Encode Binary Data, Prev: Search Functions, Up: String and Array Utilities
--
--Finding Tokens in a String
--==========================
--
-- It's fairly common for programs to have a need to do some simple
--kinds of lexical analysis and parsing, such as splitting a command
--string up into tokens. You can do this with the `strtok' function,
--declared in the header file `string.h'.
--
-- - Function: char * strtok (char *NEWSTRING, const char *DELIMITERS)
-- A string can be split into tokens by making a series of calls to
-- the function `strtok'.
--
-- The string to be split up is passed as the NEWSTRING argument on
-- the first call only. The `strtok' function uses this to set up
-- some internal state information. Subsequent calls to get
-- additional tokens from the same string are indicated by passing a
-- null pointer as the NEWSTRING argument. Calling `strtok' with
-- another non-null NEWSTRING argument reinitializes the state
-- information. It is guaranteed that no other library function ever
-- calls `strtok' behind your back (which would mess up this internal
-- state information).
--
-- The DELIMITERS argument is a string that specifies a set of
-- delimiters that may surround the token being extracted. All the
-- initial characters that are members of this set are discarded.
-- The first character that is *not* a member of this set of
-- delimiters marks the beginning of the next token. The end of the
-- token is found by looking for the next character that is a member
-- of the delimiter set. This character in the original string
-- NEWSTRING is overwritten by a null character, and the pointer to
-- the beginning of the token in NEWSTRING is returned.
--
-- On the next call to `strtok', the searching begins at the next
-- character beyond the one that marked the end of the previous token.
-- Note that the set of delimiters DELIMITERS do not have to be the
-- same on every call in a series of calls to `strtok'.
--
-- If the end of the string NEWSTRING is reached, or if the remainder
-- of string consists only of delimiter characters, `strtok' returns
-- a null pointer.
--
-- *Warning:* Since `strtok' alters the string it is parsing, you
--should always copy the string to a temporary buffer before parsing it
--with `strtok'. If you allow `strtok' to modify a string that came from
--another part of your program, you are asking for trouble; that string
--might be used for other purposes after `strtok' has modified it, and it
--would not have the expected value.
--
-- The string that you are operating on might even be a constant. Then
--when `strtok' tries to modify it, your program will get a fatal signal
--for writing in read-only memory. *Note Program Error Signals::.
--
-- This is a special case of a general principle: if a part of a program
--does not have as its purpose the modification of a certain data
--structure, then it is error-prone to modify the data structure
--temporarily.
--
-- The function `strtok' is not reentrant. *Note Nonreentrancy::, for
--a discussion of where and why reentrancy is important.
--
-- Here is a simple example showing the use of `strtok'.
--
-- #include <string.h>
-- #include <stddef.h>
--
-- ...
--
-- const char string[] = "words separated by spaces -- and, punctuation!";
-- const char delimiters[] = " .,;:!-";
-- char *token, *cp;
--
-- ...
--
-- cp = strdupa (string); /* Make writable copy. */
-- token = strtok (cp, delimiters); /* token => "words" */
-- token = strtok (NULL, delimiters); /* token => "separated" */
-- token = strtok (NULL, delimiters); /* token => "by" */
-- token = strtok (NULL, delimiters); /* token => "spaces" */
-- token = strtok (NULL, delimiters); /* token => "and" */
-- token = strtok (NULL, delimiters); /* token => "punctuation" */
-- token = strtok (NULL, delimiters); /* token => NULL */
--
-- The GNU C library contains two more functions for tokenizing a string
--which overcome the limitation of non-reentrancy.
--
-- - Function: char * strtok_r (char *NEWSTRING, const char *DELIMITERS,
-- char **SAVE_PTR)
-- Just like `strtok', this function splits the string into several
-- tokens which can be accessed by successive calls to `strtok_r'.
-- The difference is that the information about the next token is
-- stored in the space pointed to by the third argument, SAVE_PTR,
-- which is a pointer to a string pointer. Calling `strtok_r' with a
-- null pointer for NEWSTRING and leaving SAVE_PTR between the calls
-- unchanged does the job without hindering reentrancy.
--
-- This function is defined in POSIX-1 and can be found on many
-- systems which support multi-threading.
--
-- - Function: char * strsep (char **STRING_PTR, const char *DELIMITER)
-- This function is just `strtok_r' with the NEWSTRING argument
-- replaced by the SAVE_PTR argument. The initialization of the
-- moving pointer has to be done by the user. Successive calls to
-- `strsep' move the pointer along the tokens separated by DELIMITER,
-- returning the address of the next token and updating STRING_PTR to
-- point to the beginning of the next token.
--
-- If the input string contains more than one character from
-- DELIMITER in a row `strsep' returns an empty string for each pair
-- of characters from DELIMITER. This means that a program normally
-- should test for `strsep' returning an empty string before
-- processing it.
--
-- This function was introduced in 4.3BSD and therefore is widely
-- available.
--
-- Here is how the above example looks like when `strsep' is used.
--
-- #include <string.h>
-- #include <stddef.h>
--
-- ...
--
-- const char string[] = "words separated by spaces -- and, punctuation!";
-- const char delimiters[] = " .,;:!-";
-- char *running;
-- char *token;
--
-- ...
--
-- running = strdupa (string);
-- token = strsep (&running, delimiters); /* token => "words" */
-- token = strsep (&running, delimiters); /* token => "separated" */
-- token = strsep (&running, delimiters); /* token => "by" */
-- token = strsep (&running, delimiters); /* token => "spaces" */
-- token = strsep (&running, delimiters); /* token => "" */
-- token = strsep (&running, delimiters); /* token => "" */
-- token = strsep (&running, delimiters); /* token => "" */
-- token = strsep (&running, delimiters); /* token => "and" */
-- token = strsep (&running, delimiters); /* token => "" */
-- token = strsep (&running, delimiters); /* token => "punctuation" */
-- token = strsep (&running, delimiters); /* token => "" */
-- token = strsep (&running, delimiters); /* token => NULL */
--
--
--File: libc.info, Node: Encode Binary Data, Next: Argz and Envz Vectors, Prev: Finding Tokens in a String, Up: String and Array Utilities
--
--Encode Binary Data
--==================
--
-- To store or transfer binary data in environments which only support
--text one has to encode the binary data by mapping the input bytes to
--characters in the range allowed for storing or transfering. SVID
--systems (and nowadays XPG compliant systems) provide minimal support for
--this task.
--
-- - Function: char * l64a (long int N)
-- This function encodes a 32-bit input value using characters from
-- the basic character set. It returns a pointer to a 6 character
-- buffer which contains an encoded version of N. To encode a series
-- of bytes the user must copy the returned string to a destination
-- buffer. It returns the empty string if N is zero, which is
-- somewhat bizarre but mandated by the standard.
-- *Warning:* Since a static buffer is used this function should not
-- be used in multi-threaded programs. There is no thread-safe
-- alternative to this function in the C library.
-- *Compatibility Note:* The XPG standard states that the return
-- value of `l64a' is undefined if N is negative. In the GNU
-- implementation, `l64a' treats its argument as unsigned, so it will
-- return a sensible encoding for any nonzero N; however, portable
-- programs should not rely on this.
--
-- To encode a large buffer `l64a' must be called in a loop, once for
-- each 32-bit word of the buffer. For example, one could do
-- something like this:
--
-- char *
-- encode (const void *buf, size_t len)
-- {
-- /* We know in advance how long the buffer has to be. */
-- unsigned char *in = (unsigned char *) buf;
-- char *out = malloc (6 + ((len + 3) / 4) * 6 + 1);
-- char *cp = out;
--
-- /* Encode the length. */
-- /* Using `htonl' is necessary so that the data can be
-- decoded even on machines with different byte order. */
--
-- cp = mempcpy (cp, l64a (htonl (len)), 6);
--
-- while (len > 3)
-- {
-- unsigned long int n = *in++;
-- n = (n << 8) | *in++;
-- n = (n << 8) | *in++;
-- n = (n << 8) | *in++;
-- len -= 4;
-- if (n)
-- cp = mempcpy (cp, l64a (htonl (n)), 6);
-- else
-- /* `l64a' returns the empty string for n==0, so we
-- must generate its encoding ("......") by hand. */
-- cp = stpcpy (cp, "......");
-- }
-- if (len > 0)
-- {
-- unsigned long int n = *in++;
-- if (--len > 0)
-- {
-- n = (n << 8) | *in++;
-- if (--len > 0)
-- n = (n << 8) | *in;
-- }
-- memcpy (cp, l64a (htonl (n)), 6);
-- cp += 6;
-- }
-- *cp = '\0';
-- return out;
-- }
--
-- It is strange that the library does not provide the complete
-- functionality needed but so be it.
--
--
-- To decode data produced with `l64a' the following function should be
--used.
--
-- - Function: long int a64l (const char *STRING)
-- The parameter STRING should contain a string which was produced by
-- a call to `l64a'. The function processes at least 6 characters of
-- this string, and decodes the characters it finds according to the
-- table below. It stops decoding when it finds a character not in
-- the table, rather like `atoi'; if you have a buffer which has been
-- broken into lines, you must be careful to skip over the
-- end-of-line characters.
--
-- The decoded number is returned as a `long int' value.
--
-- The `l64a' and `a64l' functions use a base 64 encoding, in which
--each character of an encoded string represents six bits of an input
--word. These symbols are used for the base 64 digits:
--
-- 0 1 2 3 4 5 6 7
--0 `.' `/' `0' `1' `2' `3' `4' `5'
--8 `6' `7' `8' `9' `A' `B' `C' `D'
--16 `E' `F' `G' `H' `I' `J' `K' `L'
--24 `M' `N' `O' `P' `Q' `R' `S' `T'
--32 `U' `V' `W' `X' `Y' `Z' `a' `b'
--40 `c' `d' `e' `f' `g' `h' `i' `j'
--48 `k' `l' `m' `n' `o' `p' `q' `r'
--56 `s' `t' `u' `v' `w' `x' `y' `z'
--
-- This encoding scheme is not standard. There are some other encoding
--methods which are much more widely used (UU encoding, MIME encoding).
--Generally, it is better to use one of these encodings.
--
--
--File: libc.info, Node: Argz and Envz Vectors, Prev: Encode Binary Data, Up: String and Array Utilities
--
--Argz and Envz Vectors
--=====================
--
-- "argz vectors" are vectors of strings in a contiguous block of
--memory, each element separated from its neighbors by null-characters
--(`'\0'').
--
-- "Envz vectors" are an extension of argz vectors where each element
--is a name-value pair, separated by a `'='' character (as in a Unix
--environment).
--
--* Menu:
--
--* Argz Functions:: Operations on argz vectors.
--* Envz Functions:: Additional operations on environment vectors.
--
--
--File: libc.info, Node: Argz Functions, Next: Envz Functions, Up: Argz and Envz Vectors
--
--Argz Functions
----------------
--
-- Each argz vector is represented by a pointer to the first element, of
--type `char *', and a size, of type `size_t', both of which can be
--initialized to `0' to represent an empty argz vector. All argz
--functions accept either a pointer and a size argument, or pointers to
--them, if they will be modified.
--
-- The argz functions use `malloc'/`realloc' to allocate/grow argz
--vectors, and so any argz vector creating using these functions may be
--freed by using `free'; conversely, any argz function that may grow a
--string expects that string to have been allocated using `malloc' (those
--argz functions that only examine their arguments or modify them in
--place will work on any sort of memory). *Note Unconstrained
--Allocation::.
--
-- All argz functions that do memory allocation have a return type of
--`error_t', and return `0' for success, and `ENOMEM' if an allocation
--error occurs.
--
-- These functions are declared in the standard include file `argz.h'.
--
-- - Function: error_t argz_create (char *const ARGV[], char **ARGZ,
-- size_t *ARGZ_LEN)
-- The `argz_create' function converts the Unix-style argument vector
-- ARGV (a vector of pointers to normal C strings, terminated by
-- `(char *)0'; *note Program Arguments::.) into an argz vector with
-- the same elements, which is returned in ARGZ and ARGZ_LEN.
--
-- - Function: error_t argz_create_sep (const char *STRING, int SEP, char
-- **ARGZ, size_t *ARGZ_LEN)
-- The `argz_create_sep' function converts the null-terminated string
-- STRING into an argz vector (returned in ARGZ and ARGZ_LEN) by
-- splitting it into elements at every occurance of the character SEP.
--
-- - Function: size_t argz_count (const char *ARGZ, size_t ARG_LEN)
-- Returns the number of elements in the argz vector ARGZ and
-- ARGZ_LEN.
--
-- - Function: void argz_extract (char *ARGZ, size_t ARGZ_LEN, char
-- **ARGV)
-- The `argz_extract' function converts the argz vector ARGZ and
-- ARGZ_LEN into a Unix-style argument vector stored in ARGV, by
-- putting pointers to every element in ARGZ into successive
-- positions in ARGV, followed by a terminator of `0'. ARGV must be
-- pre-allocated with enough space to hold all the elements in ARGZ
-- plus the terminating `(char *)0' (`(argz_count (ARGZ, ARGZ_LEN) +
-- 1) * sizeof (char *)' bytes should be enough). Note that the
-- string pointers stored into ARGV point into ARGZ--they are not
-- copies--and so ARGZ must be copied if it will be changed while
-- ARGV is still active. This function is useful for passing the
-- elements in ARGZ to an exec function (*note Executing a File::.).
--
-- - Function: void argz_stringify (char *ARGZ, size_t LEN, int SEP)
-- The `argz_stringify' converts ARGZ into a normal string with the
-- elements separated by the character SEP, by replacing each `'\0''
-- inside ARGZ (except the last one, which terminates the string)
-- with SEP. This is handy for printing ARGZ in a readable manner.
--
-- - Function: error_t argz_add (char **ARGZ, size_t *ARGZ_LEN, const
-- char *STR)
-- The `argz_add' function adds the string STR to the end of the argz
-- vector `*ARGZ', and updates `*ARGZ' and `*ARGZ_LEN' accordingly.
--
-- - Function: error_t argz_add_sep (char **ARGZ, size_t *ARGZ_LEN, const
-- char *STR, int DELIM)
-- The `argz_add_sep' function is similar to `argz_add', but STR is
-- split into separate elements in the result at occurances of the
-- character DELIM. This is useful, for instance, for adding the
-- components of a Unix search path to an argz vector, by using a
-- value of `':'' for DELIM.
--
-- - Function: error_t argz_append (char **ARGZ, size_t *ARGZ_LEN, const
-- char *BUF, size_t BUF_LEN)
-- The `argz_append' function appends BUF_LEN bytes starting at BUF
-- to the argz vector `*ARGZ', reallocating `*ARGZ' to accommodate
-- it, and adding BUF_LEN to `*ARGZ_LEN'.
--
-- - Function: error_t argz_delete (char **ARGZ, size_t *ARGZ_LEN, char
-- *ENTRY)
-- If ENTRY points to the beginning of one of the elements in the
-- argz vector `*ARGZ', the `argz_delete' function will remove this
-- entry and reallocate `*ARGZ', modifying `*ARGZ' and `*ARGZ_LEN'
-- accordingly. Note that as destructive argz functions usually
-- reallocate their argz argument, pointers into argz vectors such as
-- ENTRY will then become invalid.
--
-- - Function: error_t argz_insert (char **ARGZ, size_t *ARGZ_LEN, char
-- *BEFORE, const char *ENTRY)
-- The `argz_insert' function inserts the string ENTRY into the argz
-- vector `*ARGZ' at a point just before the existing element pointed
-- to by BEFORE, reallocating `*ARGZ' and updating `*ARGZ' and
-- `*ARGZ_LEN'. If BEFORE is `0', ENTRY is added to the end instead
-- (as if by `argz_add'). Since the first element is in fact the
-- same as `*ARGZ', passing in `*ARGZ' as the value of BEFORE will
-- result in ENTRY being inserted at the beginning.
--
-- - Function: char * argz_next (char *ARGZ, size_t ARGZ_LEN, const char
-- *ENTRY)
-- The `argz_next' function provides a convenient way of iterating
-- over the elements in the argz vector ARGZ. It returns a pointer
-- to the next element in ARGZ after the element ENTRY, or `0' if
-- there are no elements following ENTRY. If ENTRY is `0', the first
-- element of ARGZ is returned.
--
-- This behavior suggests two styles of iteration:
--
-- char *entry = 0;
-- while ((entry = argz_next (ARGZ, ARGZ_LEN, entry)))
-- ACTION;
--
-- (the double parentheses are necessary to make some C compilers
-- shut up about what they consider a questionable `while'-test) and:
--
-- char *entry;
-- for (entry = ARGZ;
-- entry;
-- entry = argz_next (ARGZ, ARGZ_LEN, entry))
-- ACTION;
--
-- Note that the latter depends on ARGZ having a value of `0' if it
-- is empty (rather than a pointer to an empty block of memory); this
-- invariant is maintained for argz vectors created by the functions
-- here.
--
-- - Function: error_t argz_replace (char **ARGZ, size_t *ARGZ_LEN,
-- const char *STR, const char *WITH, unsigned *REPLACE_COUNT)
-- Replace any occurances of the string STR in ARGZ with WITH,
-- reallocating ARGZ as necessary. If REPLACE_COUNT is non-zero,
-- `*REPLACE_COUNT' will be incremented by number of replacements
-- performed.
--
--
--File: libc.info, Node: Envz Functions, Prev: Argz Functions, Up: Argz and Envz Vectors
--
--Envz Functions
----------------
--
-- Envz vectors are just argz vectors with additional constraints on
--the form of each element; as such, argz functions can also be used on
--them, where it makes sense.
--
-- Each element in an envz vector is a name-value pair, separated by a
--`'='' character; if multiple `'='' characters are present in an
--element, those after the first are considered part of the value, and
--treated like all other non-`'\0'' characters.
--
-- If *no* `'='' characters are present in an element, that element is
--considered the name of a "null" entry, as distinct from an entry with an
--empty value: `envz_get' will return `0' if given the name of null
--entry, whereas an entry with an empty value would result in a value of
--`""'; `envz_entry' will still find such entries, however. Null entries
--can be removed with `envz_strip' function.
--
-- As with argz functions, envz functions that may allocate memory (and
--thus fail) have a return type of `error_t', and return either `0' or
--`ENOMEM'.
--
-- These functions are declared in the standard include file `envz.h'.
--
-- - Function: char * envz_entry (const char *ENVZ, size_t ENVZ_LEN,
-- const char *NAME)
-- The `envz_entry' function finds the entry in ENVZ with the name
-- NAME, and returns a pointer to the whole entry--that is, the argz
-- element which begins with NAME followed by a `'='' character. If
-- there is no entry with that name, `0' is returned.
--
-- - Function: char * envz_get (const char *ENVZ, size_t ENVZ_LEN, const
-- char *NAME)
-- The `envz_get' function finds the entry in ENVZ with the name NAME
-- (like `envz_entry'), and returns a pointer to the value portion of
-- that entry (following the `'=''). If there is no entry with that
-- name (or only a null entry), `0' is returned.
--
-- - Function: error_t envz_add (char **ENVZ, size_t *ENVZ_LEN, const
-- char *NAME, const char *VALUE)
-- The `envz_add' function adds an entry to `*ENVZ' (updating `*ENVZ'
-- and `*ENVZ_LEN') with the name NAME, and value VALUE. If an entry
-- with the same name already exists in ENVZ, it is removed first.
-- If VALUE is `0', then the new entry will the special null type of
-- entry (mentioned above).
--
-- - Function: error_t envz_merge (char **ENVZ, size_t *ENVZ_LEN, const
-- char *ENVZ2, size_t ENVZ2_LEN, int OVERRIDE)
-- The `envz_merge' function adds each entry in ENVZ2 to ENVZ, as if
-- with `envz_add', updating `*ENVZ' and `*ENVZ_LEN'. If OVERRIDE is
-- true, then values in ENVZ2 will supersede those with the same name
-- in ENVZ, otherwise not.
--
-- Null entries are treated just like other entries in this respect,
-- so a null entry in ENVZ can prevent an entry of the same name in
-- ENVZ2 from being added to ENVZ, if OVERRIDE is false.
--
-- - Function: void envz_strip (char **ENVZ, size_t *ENVZ_LEN)
-- The `envz_strip' function removes any null entries from ENVZ,
-- updating `*ENVZ' and `*ENVZ_LEN'.
--
--
--File: libc.info, Node: Character Set Handling, Next: Locales, Prev: String and Array Utilities, Up: Top
--
--Character Set Handling
--**********************
--
-- Character sets used in the early days of computing had only six,
--seven, or eight bits for each character: there was never a case where
--more than eight bits (one byte) were used to represent a single
--character. The limitations of this approach became more apparent as
--more people grappled with non-Roman character sets, where not all the
--characters that make up a language's character set can be represented
--by 2^8 choices. This chapter shows the functionality which was added
--to the C library to correctly support multiple character sets.
--
--* Menu:
--
--* Extended Char Intro:: Introduction to Extended Characters.
--* Charset Function Overview:: Overview about Character Handling
-- Functions.
--* Restartable multibyte conversion:: Restartable multibyte conversion
-- Functions.
--* Non-reentrant Conversion:: Non-reentrant Conversion Function.
--* Generic Charset Conversion:: Generic Charset Conversion.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-7 glibc-2.1.3/manual/libc.info-7
---- ../glibc-2.1.3/manual/libc.info-7 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-7 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1041 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Extended Char Intro, Next: Charset Function Overview, Up: Character Set Handling
--
--Introduction to Extended Characters
--===================================
--
-- A variety of solutions to overcome the differences between character
--sets with a 1:1 relation between bytes and characters and character
--sets with ratios of 2:1 or 4:1 exist. The remainder of this section
--gives a few examples to help understand the design decisions made while
--developing the functionality of the C library.
--
-- A distinction we have to make right away is between internal and
--external representation. "Internal representation" means the
--representation used by a program while keeping the text in memory.
--External representations are used when text is stored or transmitted
--through whatever communication channel. Examples of external
--representations include files lying in a directory that are going to be
--read and parsed.
--
-- Traditionally there was no difference between the two
--representations. It was equally comfortable and useful to use the same
--one-byte representation internally and externally. This changes with
--more and larger character sets.
--
-- One of the problems to overcome with the internal representation is
--handling text which is externally encoded using different character
--sets. Assume a program which reads two texts and compares them using
--some metric. The comparison can be usefully done only if the texts are
--internally kept in a common format.
--
-- For such a common format (= character set) eight bits are certainly
--no longer enough. So the smallest entity will have to grow: "wide
--characters" will now be used. Instead of one byte, two or four will be
--used instead. (Three are not good to address in memory and more than
--four bytes seem not to be necessary).
--
-- As shown in some other part of this manual, there exists a
--completely new family of functions which can handle texts of this kind
--in memory. The most commonly used character set for such internal wide
--character representations are Unicode and ISO 10646. The former is a
--subset of the latter and used when wide characters are chosen to by 2
--bytes (= 16 bits) wide. The standard names of the encodings used in
--these cases are UCS2 (= 16 bits) and UCS4 (= 32 bits).
--
-- To represent wide characters the `char' type is not suitable. For
--this reason the ISO C standard introduces a new type which is designed
--to keep one character of a wide character string. To maintain the
--similarity there is also a type corresponding to `int' for those
--functions which take a single wide character.
--
-- - Data type: wchar_t
-- This data type is used as the base type for wide character strings.
-- I.e., arrays of objects of this type are the equivalent of `char[]'
-- for multibyte character strings. The type is defined in
-- `stddef.h'.
--
-- The ISO C89 standard, where this type was introduced, does not say
-- anything specific about the representation. It only requires that
-- this type is capable to store all elements of the basic character
-- set. Therefore it would be legitimate to define `wchar_t' and
-- `char'. This might make sense for embedded systems.
--
-- But for GNU systems this type is always 32 bits wide. It is
-- therefore capable to represent all UCS4 value therefore covering
-- all of ISO 10646. Some Unix systems define `wchar_t' as a 16 bit
-- type and thereby follow Unicode very strictly. This is perfectly
-- fine with the standard but it also means that to represent all
-- characters from Unicode and ISO 10646 one has to use surrogate
-- character which is in fact a multi-wide-character encoding. But
-- this contradicts the purpose of the `wchar_t' type.
--
-- - Data type: wint_t
-- `wint_t' is a data type used for parameters and variables which
-- contain a single wide character. As the name already suggests it
-- is the equivalent to `int' when using the normal `char' strings.
-- The types `wchar_t' and `wint_t' have often the same
-- representation if their size if 32 bits wide but if `wchar_t' is
-- defined as `char' the type `wint_t' must be defined as `int' due
-- to the parameter promotion.
--
-- This type is defined in `wchar.h' and got introduced in the second
-- amendment to ISO C 89.
--
-- As there are for the `char' data type there also exist macros
--specifying the minimum and maximum value representable in an object of
--type `wchar_t'.
--
-- - Macro: wint_t WCHAR_MIN
-- The macro `WCHAR_MIN' evaluates to the minimum value representable
-- by an object of type `wint_t'.
--
-- This macro got introduced in the second amendment to ISO C89.
--
-- - Macro: wint_t WCHAR_MAX
-- The macro `WCHAR_MIN' evaluates to the maximum value representable
-- by an object of type `wint_t'.
--
-- This macro got introduced in the second amendment to ISO C89.
--
-- Another special wide character value is the equivalent to `EOF'.
--
-- - Macro: wint_t WEOF
-- The macro `WEOF' evaluates to a constant expression of type
-- `wint_t' whose value is different from any member of the extended
-- character set.
--
-- `WEOF' need not be the same value as `EOF' and unlike `EOF' it
-- also need *not* be negative. I.e., sloppy code like
--
-- {
-- int c;
-- ...
-- while ((c = getc (fp)) < 0)
-- ...
-- }
--
-- has to be rewritten to explicitly use `WEOF' when wide characters
-- are used.
--
-- {
-- wint_t c;
-- ...
-- while ((c = wgetc (fp)) != WEOF)
-- ...
-- }
--
-- This macro was introduced in the second amendment to ISO C89 and is
-- defined in `wchar.h'.
--
-- These internal representations present problems when it comes to
--storing and transmittal, since a single wide character consists of more
--than one byte they are effected by byte-ordering. I.e., machines with
--different endianesses would see different value accessing the same data.
--This also applies for communication protocols which are all byte-based
--and therefore the sender has to decide about splitting the wide
--character in bytes. A last (but not least important) point is that wide
--characters often require more storage space than an customized byte
--oriented character set.
--
-- For all the above reasons, an external encoding which is different
--from the internal encoding is often used if the latter is UCS2 or UCS4.
--The external encoding is byte-based and can be chosen appropriately for
--the environment and for the texts to be handled. There exist a variety
--of different character sets which can be used for this external
--encoding. Information which will not be exhaustively presented
--here-instead, a description of the major groups will suffice. All of
--the ASCII-based character sets [_bkoz_: do you mean Roman character
--sets? If not, what do you mean here?] fulfill one requirement: they are
--"filesystem safe". This means that the character `'/'' is used in the
--encoding *only* to represent itself. Things are a bit different for
--character sets like EBCDIC (Extended Binary Coded Decimal Interchange
--Code, a character set family used by IBM) but if the operation system
--does not understand EBCDIC directly the parameters to system calls have
--to be converted first anyhow.
--
-- * The simplest character sets are one-byte character sets. There
-- can be only up to 256 characters (for 8 bit character sets) which
-- is not sufficient to cover all languages but might be sufficient
-- to handle a specific text. Another reason to choose this is
-- because of constraints from interaction with other programs (which
-- might not be 8-bit clean).
--
-- * The ISO 2022 standard defines a mechanism for extended character
-- sets where one character *can* be represented by more than one
-- byte. This is achieved by associating a state with the text.
-- Embedded in the text can be characters which can be used to change
-- the state. Each byte in the text might have a different
-- interpretation in each state. The state might even influence
-- whether a given byte stands for a character on its own or whether
-- it has to be combined with some more bytes.
--
-- In most uses of ISO 2022 the defined character sets do not allow
-- state changes which cover more than the next character. This has
-- the big advantage that whenever one can identify the beginning of
-- the byte sequence of a character one can interpret a text
-- correctly. Examples of character sets using this policy are the
-- various EUC character sets (used by Sun's operations systems,
-- EUC-JP, EUC-KR, EUC-TW, and EUC-CN) or SJIS (Shift JIS, a Japanese
-- encoding).
--
-- But there are also character sets using a state which is valid for
-- more than one character and has to be changed by another byte
-- sequence. Examples for this are ISO-2022-JP, ISO-2022-KR, and
-- ISO-2022-CN.
--
-- * Early attempts to fix 8 bit character sets for other languages
-- using the Roman alphabet lead to character sets like ISO 6937.
-- Here bytes representing characters like the acute accent do not
-- produce output themselves: one has to combine them with other
-- characters to get the desired result. E.g., the byte sequence
-- `0xc2 0x61' (non-spacing acute accent, following by lower-case
-- `a') to get the "small a with acute" character. To get the acute
-- accent character on its on one has to write `0xc2 0x20' (the
-- non-spacing acute followed by a space).
--
-- This type of characters sets is quite frequently used in embedded
-- systems such as video text.
--
-- * Instead of converting the Unicode or ISO 10646 text used internally
-- it is often also sufficient to simply use an encoding different
-- than UCS2/UCS4. The Unicode and ISO 10646 standards even specify
-- such an encoding: UTF-8. This encoding is able to represent all
-- of ISO 10464 31 bits in a byte string of length one to seven.
--
-- There were a few other attempts to encode ISO 10646 such as UTF-7
-- but UTF-8 is today the only encoding which should be used. In
-- fact, UTF-8 will hopefully soon be the only external which has to
-- be supported. It proves to be universally usable and the only
-- disadvantage is that it favor Roman languages very much by making
-- the byte string representation of other scripts (Cyrillic, Greek,
-- Asian scripts) longer than necessary if using a specific character
-- set for these scripts. Methods like the Unicode compression
-- scheme can alleviate these problems.
--
-- The question remaining is: how to select the character set or
--encoding to use. The answer: you cannot decide about it yourself, it
--is decided by the developers of the system or the majority of the
--users. Since the goal is interoperability one has to use whatever the
--other people one works with use. If there are no constraints the
--selection is based on the requirements the expected circle of users
--will have. I.e., if a project is expected to only be used in, say,
--Russia it is fine to use KOI8-R or a similar character set. But if at
--the same time people from, say, Greece are participating one should use
--a character set which allows all people to collaborate.
--
-- The most widely useful solution seems to be: go with the most general
--character set, namely ISO 10646. Use UTF-8 as the external encoding
--and problems about users not being able to use their own language
--adequately are a thing of the past.
--
-- One final comment about the choice of the wide character
--representation is necessary at this point. We have said above that the
--natural choice is using Unicode or ISO 10646. This is not specified in
--any standard, though. The ISO C standard does not specify anything
--specific about the `wchar_t' type. There might be systems where the
--developers decided differently. Therefore one should as much as
--possible avoid making assumption about the wide character representation
--although GNU systems will always work as described above. If the
--programmer uses only the functions provided by the C library to handle
--wide character strings there should not be any compatibility problems
--with other systems.
--
--
--File: libc.info, Node: Charset Function Overview, Next: Restartable multibyte conversion, Prev: Extended Char Intro, Up: Character Set Handling
--
--Overview about Character Handling Functions
--===========================================
--
-- A Unix C library contains three different sets of functions in two
--families to handle character set conversion. The one function family
--is specified in the ISO C standard and therefore is portable even
--beyond the Unix world.
--
-- The most commonly known set of functions, coming from the ISO C89
--standard, is unfortunately the least useful one. In fact, these
--functions should be avoided whenever possible, especially when
--developing libraries (as opposed to applications).
--
-- The second family of functions got introduced in the early Unix
--standards (XPG2) and is still part of the latest and greatest Unix
--standard: Unix 98. It is also the most powerful and useful set of
--functions. But we will start with the functions defined in the second
--amendment to ISO C89.
--
--
--File: libc.info, Node: Restartable multibyte conversion, Next: Non-reentrant Conversion, Prev: Charset Function Overview, Up: Character Set Handling
--
--Restartable Multibyte Conversion Functions
--==========================================
--
-- The ISO C standard defines functions to convert strings from a
--multibyte representation to wide character strings. There are a number
--of peculiarities:
--
-- * The character set assumed for the multibyte encoding is not
-- specified as an argument to the functions. Instead the character
-- set specified by the `LC_CTYPE' category of the current locale is
-- used; see *Note Locale Categories::.
--
-- * The functions handling more than one character at a time require
-- NUL terminated strings as the argument. I.e., converting blocks
-- of text does not work unless one can add a NUL byte at an
-- appropriate place. The GNU C library contains some extensions the
-- standard which allow specifying a size but basically they also
-- expect terminated strings.
--
-- Despite these limitations the ISO C functions can very well be used
--in many contexts. In graphical user interfaces, for instance, it is not
--uncommon to have functions which require text to be displayed in a wide
--character string if it is not simple ASCII. The text itself might come
--from a file with translations and the user should decide about the
--current locale which determines the translation and therefore also the
--external encoding used. In such a situation (and many others) the
--functions described here are perfect. If more freedom while performing
--the conversion is necessary take a look at the `iconv' functions (*note
--Generic Charset Conversion::.).
--
--* Menu:
--
--* Selecting the Conversion:: Selecting the conversion and its properties.
--* Keeping the state:: Representing the state of the conversion.
--* Converting a Character:: Converting Single Characters.
--* Converting Strings:: Converting Multibyte and Wide Character
-- Strings.
--* Multibyte Conversion Example:: A Complete Multibyte Conversion Example.
--
--
--File: libc.info, Node: Selecting the Conversion, Next: Keeping the state, Up: Restartable multibyte conversion
--
--Selecting the conversion and its properties
---------------------------------------------
--
-- We already said above that the currently selected locale for the
--`LC_CTYPE' category decides about the conversion which is performed by
--the functions we are about to describe. Each locale uses its own
--character set (given as an argument to `localedef') and this is the one
--assumed as the external multibyte encoding. The wide character
--character set always is UCS4, at least on GNU systems.
--
-- A characteristic of each multibyte character set is the maximum
--number of bytes which can be necessary to represent one character. This
--information is quite important when writing code which uses the
--conversion functions. In the examples below we will see some examples.
--The ISO C standard defines two macros which provide this information.
--
-- - Macro: int MB_LEN_MAX
-- This macro specifies the maximum number of bytes in the multibyte
-- sequence for a single character in any of the supported locales.
-- It is a compile-time constant and it is defined in `limits.h'.
--
-- - Macro: int MB_CUR_MAX
-- `MB_CUR_MAX' expands into a positive integer expression that is the
-- maximum number of bytes in a multibyte character in the current
-- locale. The value is never greater than `MB_LEN_MAX'. Unlike
-- `MB_LEN_MAX' this macro need not be a compile-time constant and in
-- fact, in the GNU C library it is not.
--
-- `MB_CUR_MAX' is defined in `stdlib.h'.
--
-- Two different macros are necessary since strictly ISO C89 compilers
--do not allow variable length array definitions but still it is desirable
--to avoid dynamic allocation. This incomplete piece of code shows the
--problem:
--
-- {
-- char buf[MB_LEN_MAX];
-- ssize_t len = 0;
--
-- while (! feof (fp))
-- {
-- fread (&buf[len], 1, MB_CUR_MAX - len, fp);
-- /* ... process buf */
-- len -= used;
-- }
-- }
--
-- The code in the inner loop is expected to have always enough bytes in
--the array BUF to convert one multibyte character. The array BUF has to
--be sized statically since many compilers do not allow a variable size.
--The `fread' call makes sure that always `MB_CUR_MAX' bytes are
--available in BUF. Note that it isn't a problem if `MB_CUR_MAX' is not
--a compile-time constant.
--
--
--File: libc.info, Node: Keeping the state, Next: Converting a Character, Prev: Selecting the Conversion, Up: Restartable multibyte conversion
--
--Representing the state of the conversion
------------------------------------------
--
-- In the introduction of this chapter it was said that certain
--character sets use a "stateful" encoding. I.e., the encoded values
--depend in some way on the previous bytes in the text.
--
-- Since the conversion functions allow converting a text in more than
--one step we must have a way to pass this information from one call of
--the functions to another.
--
-- - Data type: mbstate_t
-- A variable of type `mbstate_t' can contain all the information
-- about the "shift state" needed from one call to a conversion
-- function to another.
--
-- This type is defined in `wchar.h'. It got introduced in the second
-- amendment to ISO C89.
--
-- To use objects of this type the programmer has to define such objects
--(normally as local variables on the stack) and pass a pointer to the
--object to the conversion functions. This way the conversion function
--can update the object if the current multibyte character set is
--stateful.
--
-- There is no specific function or initializer to put the state object
--in any specific state. The rules are that the object should always
--represent the initial state before the first use and this is achieved by
--clearing the whole variable with code such as follows:
--
-- {
-- mbstate_t state;
-- memset (&state, '\0', sizeof (state));
-- /* from now on STATE can be used. */
-- ...
-- }
--
-- When using the conversion functions to generate output it is often
--necessary to test whether the current state corresponds to the initial
--state. This is necessary, for example, to decide whether or not to emit
--escape sequences to set the state to the initial state at certain
--sequence points. Communication protocols often require this.
--
-- - Function: int mbsinit (const mbstate_t *PS)
-- This function determines whether the state object pointed to by PS
-- is in the initial state or not. If PS is a null pointer or the
-- object is in the initial state the return value is nonzero.
-- Otherwise it is zero.
--
-- This function was introduced in the second amendment to ISO C89 and
-- is declared in `wchar.h'.
--
-- Code using this function often looks similar to this:
--
-- {
-- mbstate_t state;
-- memset (&state, '\0', sizeof (state));
-- /* Use STATE. */
-- ...
-- if (! mbsinit (&state))
-- {
-- /* Emit code to return to initial state. */
-- const char empty[] = "";
-- const char **srcp = &empty;
-- wcsrtombs (outbuf, &srcp, outbuflen, &state);
-- }
-- ...
-- }
--
-- The code to emit the escape sequence to get back to the initial
--state is interesting. The `wcsrtombs' function can be used to
--determine the necessary output code (*note Converting Strings::.).
--Please note that on GNU systems it is not necessary to perform this
--extra action for the conversion from multibyte text ot wide character
--text since the wide character encoding is not stateful. But there is
--nothing mentioned in any standard which prohibits making `wchar_t'
--using a stateful encoding.
--
--
--File: libc.info, Node: Converting a Character, Next: Converting Strings, Prev: Keeping the state, Up: Restartable multibyte conversion
--
--Converting Single Characters
------------------------------
--
-- The most fundamental of the conversion functions are those dealing
--with single characters. Please note that this does not always mean
--single bytes. But since there is very often a subset of the multibyte
--character set which consists of single byte sequences there are
--functions to help with converting bytes. One very important and often
--applicable scenario is where ASCII is a subpart of the multibyte
--character set. I.e., all ASCII characters stand for itself and all
--other characters have at least a first byte which is beyond the range 0
--to 127.
--
-- - Function: wint_t btowc (int C)
-- The `btowc' function ("byte to wide character") converts a valid
-- single byte character C in the initial shift state into the wide
-- character equivalent using the conversion rules from the currently
-- selected locale of the `LC_CTYPE' category.
--
-- If `(unsigned char) C' is no valid single byte multibyte character
-- or if C is `EOF' the function returns `WEOF'.
--
-- Please note the restriction of C being tested for validity only in
-- the initial shift state. There is no `mbstate_t' object used from
-- which the state information is taken and the function also does
-- not use any static state.
--
-- This function was introduced in the second amendment of ISO C89 and
-- is declared in `wchar.h'.
--
-- Despite the limitation that the single byte value always is
--interpreted in the initial state this function is actually useful most
--of the time. Most characters are either entirely single-byte character
--sets or they are extension to ASCII. But then it is possible to write
--code like this (not that this specific example is very useful):
--
-- wchar_t *
-- itow (unsigned long int val)
-- {
-- static wchar_t buf[30];
-- wchar_t *wcp = &buf[29];
-- *wcp = L'\0';
-- while (val != 0)
-- {
-- *--wcp = btowc ('0' + val % 10);
-- val /= 10;
-- }
-- if (wcp == &buf[29])
-- *--wcp = L'0';
-- return wcp;
-- }
--
-- Why is it necessary to use such a complicated implementation and not
--simply cast `'0' + val % 10' to a wide character? The answer is that
--there is no guarantee that one can perform this kind of arithmetic on
--the character of the character set used for `wchar_t' representation.
--In other situations the bytes are not constant at compile time and so
--the compiler cannot do the work. In situations like this it is
--necessary `btowc'.
--
--There also is a function for the conversion in the other direction.
--
-- - Function: int wctob (wint_t C)
-- The `wctob' function ("wide character to byte") takes as the
-- parameter a valid wide character. If the multibyte representation
-- for this character in the initial state is exactly one byte long
-- the return value of this function is this character. Otherwise
-- the return value is `EOF'.
--
-- This function was introduced in the second amendment of ISO C89 and
-- is declared in `wchar.h'.
--
-- There are more general functions to convert single character from
--multibyte representation to wide characters and vice versa. These
--functions pose no limit on the length of the multibyte representation
--and they also do not require it to be in the initial state.
--
-- - Function: size_t mbrtowc (wchar_t *restrict PWC, const char
-- *restrict S, size_t N, mbstate_t *restrict PS)
-- The `mbrtowc' function ("multibyte restartable to wide character")
-- converts the next multibyte character in the string pointed to by
-- S into a wide character and stores it in the wide character string
-- pointed to by PWC. The conversion is performed according to the
-- locale currently selected for the `LC_CTYPE' category. If the
-- conversion for the character set used in the locale requires a
-- state the multibyte string is interpreted in the state represented
-- by the object pointed to by PS. If PS is a null pointer an static,
-- internal state variable used only by the `mbrtowc' variable is
-- used.
--
-- If the next multibyte character corresponds to the NUL wide
-- character the return value of the function is 0 and the state
-- object is afterwards in the initial state. If the next N or fewer
-- bytes form a correct multibyte character the return value is the
-- number of bytes starting from S which form the multibyte
-- character. The conversion state is updated according to the bytes
-- consumed in the conversion. In both cases the wide character
-- (either the `L'\0'' or the one found in the conversion) is stored
-- in the string pointer to by PWC iff PWC is not null.
--
-- If the first N bytes of the multibyte string possibly form a valid
-- multibyte character but there are more than N bytes needed to
-- complete it the return value of the function is `(size_t) -2' and
-- no value is stored. Please note that this can happen even if N
-- has a value greater or equal to `MB_CUR_MAX' since the input might
-- contain redundant shift sequences.
--
-- If the first `n' bytes of the multibyte string cannot possibly form
-- a valid multibyte character also no value is stored, the global
-- variable `errno' is set to the value `EILSEQ' and the function
-- returns `(size_t) -1'. The conversion state is afterwards
-- undefined.
--
-- This function was introduced in the second amendment to ISO C89 and
-- is declared in `wchar.h'.
--
-- Using this function is straight forward. A function which copies a
--multibyte string into a wide character string while at the same time
--converting all lowercase character into uppercase could look like this
--(this is not the final version, just an example; it has no error
--checking, and leaks sometimes memory):
--
-- wchar_t *
-- mbstouwcs (const char *s)
-- {
-- size_t len = strlen (s);
-- wchar_t *result = malloc ((len + 1) * sizeof (wchar_t));
-- wchar_t *wcp = result;
-- wchar_t tmp[1];
-- mbstate_t state;
-- memset (&state, '\0', sizeof (state));
-- size_t nbytes;
-- while ((nbytes = mbrtowc (tmp, s, len, &state)) > 0)
-- {
-- if (nbytes >= (size_t) -2)
-- /* Invalid input string. */
-- return NULL;
-- *result++ = towupper (tmp[0]);
-- len -= nbytes;
-- s += nbytes;
-- }
-- return result;
-- }
--
-- The use of `mbrtowc' should be clear. A single wide character is
--stored in `TMP[0]' and the number of consumed bytes is stored in the
--variable NBYTES. In case the the conversion was successful the
--uppercase variant of the wide character is stored in the RESULT array
--and the pointer to the input string and the number of available bytes
--is adjusted.
--
-- The only non-obvious thing about the function might be the way
--memory is allocated for the result. The above code uses the fact that
--there can never be more wide characters in the converted results than
--there are bytes in the multibyte input string. This method yields to a
--pessimistic guess about the size of the result and if many wide
--character strings have to be constructed this way or the strings are
--long, the extra memory required allocated because the input string
--contains multibzte characters might be significant. It would be
--possible to resize the allocated memory block to the correct size before
--returning it. A better solution might be to allocate just the right
--amount of space for the result right away. Unfortunately there is no
--function to compute the length of the wide character string directly
--from the multibyte string. But there is a function which does part of
--the work.
--
-- - Function: size_t mbrlen (const char *restrict S, size_t N, mbstate_t
-- *PS)
-- The `mbrlen' function ("multibyte restartable length") computes
-- the number of at most N bytes starting at S which form the next
-- valid and complete multibyte character.
--
-- If the next multibyte character corresponds to the NUL wide
-- character the return value is 0. If the next N bytes form a valid
-- multibyte character the number of bytes belonging to this multibyte
-- character byte sequence is returned.
--
-- If the the first N bytes possibly form a valid multibyte character
-- but it is incomplete the return value is `(size_t) -2'. Otherwise
-- the multibyte character sequence is invalid and the return value
-- is `(size_t) -1'.
--
-- The multibyte sequence is interpreted in the state represented by
-- the object pointer to by PS. If PS is a null pointer an state
-- object local to `mbrlen' is used.
--
-- This function was introduced in the second amendment to ISO C89 and
-- is declared in `wchar.h'.
--
-- The tentative reader now will of course note that `mbrlen' can be
--implemented as
--
-- mbrtowc (NULL, s, n, ps != NULL ? ps : &internal)
--
-- This is true and in fact is mentioned in the official specification.
--Now, how can this function be used to determine the length of the wide
--character string created from a multibyte character string? It is not
--directly usable but we can define a function `mbslen' using it:
--
-- size_t
-- mbslen (const char *s)
-- {
-- mbstate_t state;
-- size_t result = 0;
-- size_t nbytes;
-- memset (&state, '\0', sizeof (state));
-- while ((nbytes = mbrlen (s, MB_LEN_MAX, &state)) > 0)
-- {
-- if (nbytes >= (size_t) -2)
-- /* Something is wrong. */
-- return (size_t) -1;
-- s += nbytes;
-- ++result;
-- }
-- return result;
-- }
--
-- This function simply calls `mbrlen' for each multibyte character in
--the string and counts the number of function calls. Please note that
--we here use `MB_LEN_MAX' as the size argument in the `mbrlen' call.
--This is OK since a) this value is larger then the length of the longest
--multibyte character sequence and b) because we know that the string S
--ends with a NUL byte which cannot be part of any other multibyte
--character sequence but the one representing the NUL wide character.
--Therefore the `mbrlen' function will never read invalid memory.
--
-- Now that this function is available (just to make this clear, this
--function is *not* part of the GNU C library) we can compute the number
--of wide character required to store the converted multibyte character
--string S using
--
-- wcs_bytes = (mbslen (s) + 1) * sizeof (wchar_t);
--
-- Please note that the `mbslen' function is quite inefficient. The
--implementation of `mbstouwcs' implemented using `mbslen' would have to
--perform the conversion of the multibyte character input string twice
--and this conversion might be quite expensive. So it is necessary to
--think about the consequences of using the easier but imprecise method
--before doing the work twice.
--
-- - Function: size_t wcrtomb (char *restrict S, wchar_t WC, mbstate_t
-- *restrict PS)
-- The `wcrtomb' function ("wide character restartable to multibyte")
-- converts a single wide character into a multibyte string
-- corresponding to that wide character.
--
-- If S is a null pointer the function resets the the state stored in
-- the objects pointer to by PS (or the internal `mbstate_t' object)
-- to the initial state. This can also be achieved by a call like
-- this:
--
-- wcrtombs (temp_buf, L'\0', ps)
--
-- since if S is a null pointer `wcrtomb' performs as if it writes
-- into an internal buffer which is guaranteed to be large enough.
--
-- If WC is the NUL wide character `wcrtomb' emits, if necessary, a
-- shift sequence to get the state PS into the initial state followed
-- by a single NUL byte is stored in the string S.
--
-- Otherwise a byte sequence (possibly including shift sequences) is
-- written into the string S. This of only happens if WC is a valid
-- wide character, i.e., it has a multibyte representation in the
-- character set selected by locale of the `LC_CTYPE' category. If
-- WC is no valid wide character nothing is stored in the strings S,
-- `errno' is set to `EILSEQ', the conversion state in PS is
-- undefined and the return value is `(size_t) -1'.
--
-- If no error occurred the function returns the number of bytes
-- stored in the string S. This includes all byte representing shift
-- sequences.
--
-- One word about the interface of the function: there is no parameter
-- specifying the length of the array S. Instead the function
-- assumes that there are at least `MB_CUR_MAX' bytes available since
-- this is the maximum length of any byte sequence representing a
-- single character. So the caller has to make sure that there is
-- enough space available, otherwise buffer overruns can occur.
--
-- This function was introduced in the second amendment to ISO C and
-- is declared in `wchar.h'.
--
-- Using this function is as easy as using `mbrtowc'. The following
--example appends a wide character string to a multibyte character string.
--Again, the code is not really useful (and correct), it is simply here to
--demonstrate the use and some problems.
--
-- char *
-- mbscatwc (char *s, size_t len, const wchar_t *ws)
-- {
-- mbstate_t state;
-- /* Find the end of the existing string. */
-- char *wp = strchr (s, '\0');
-- len -= wp - s;
-- memset (&state, '\0', sizeof (state));
-- do
-- {
-- size_t nbytes;
-- if (len < MB_CUR_LEN)
-- {
-- /* We cannot guarantee that the next
-- character fits into the buffer, so
-- return an error. */
-- errno = E2BIG;
-- return NULL;
-- }
-- nbytes = wcrtomb (wp, *ws, &state);
-- if (nbytes == (size_t) -1)
-- /* Error in the conversion. */
-- return NULL;
-- len -= nbytes;
-- wp += nbytes;
-- }
-- while (*ws++ != L'\0');
-- return s;
-- }
--
-- First the function has to find the end of the string currently in the
--array S. The `strchr' call does this very efficiently since a
--requirement for multibyte character representations is that the NUL byte
--never is used except to represent itself (and in this context, the end
--of the string).
--
-- After initializing the state object the loop is entered where the
--first task is to make sure there is enough room in the array S. We
--abort if there are not at least `MB_CUR_LEN' bytes available. This is
--not always optimal but we have no other choice. We might have less
--than `MB_CUR_LEN' bytes available but the next multibyte character
--might also be only one byte long. At the time the `wcrtomb' call
--returns it is too late to decide whether the buffer was large enough or
--not. If this solution is really unsuitable there is a very slow but
--more accurate solution.
--
-- ...
-- if (len < MB_CUR_LEN)
-- {
-- mbstate_t temp_state;
-- memcpy (&temp_state, &state, sizeof (state));
-- if (wcrtomb (NULL, *ws, &temp_state) > len)
-- {
-- /* We cannot guarantee that the next
-- character fits into the buffer, so
-- return an error. */
-- errno = E2BIG;
-- return NULL;
-- }
-- }
-- ...
--
-- Here we do perform the conversion which might overflow the buffer so
--that we are afterwards in the position to make an exact decision about
--the buffer size. Please note the `NULL' argument for the destination
--buffer in the new `wcrtomb' call; since we are not interested in the
--converted text at this point this is a nice way to express this. The
--most unusual thing about this piece of code certainly is the
--duplication of the conversion state object. But think about this: if a
--change of the state is necessary to emit the next multibyte character
--we want to have the same shift state change performed in the real
--conversion. Therefore we have to preserve the initial shift state
--information.
--
-- There are certainly many more and even better solutions to this
--problem. This example is only meant for educational purposes.
--
--
--File: libc.info, Node: Converting Strings, Next: Multibyte Conversion Example, Prev: Converting a Character, Up: Restartable multibyte conversion
--
--Converting Multibyte and Wide Character Strings
-------------------------------------------------
--
-- The functions described in the previous section only convert a single
--character at a time. Most operations to be performed in real-world
--programs include strings and therefore the ISO C standard also defines
--conversions on entire strings. However, the defined set of functions
--is quite limited, thus the GNU C library contains a few extensions
--which can help in some important situations.
--
-- - Function: size_t mbsrtowcs (wchar_t *restrict DST, const char
-- **restrict SRC, size_t LEN, mbstate_t *restrict PS)
-- The `mbsrtowcs' function ("multibyte string restartable to wide
-- character string") converts an NUL terminated multibyte character
-- string at `*SRC' into an equivalent wide character string,
-- including the NUL wide character at the end. The conversion is
-- started using the state information from the object pointed to by
-- PS or from an internal object of `mbsrtowcs' if PS is a null
-- pointer. Before returning the state object to match the state
-- after the last converted character. The state is the initial
-- state if the terminating NUL byte is reached and converted.
--
-- If DST is not a null pointer the result is stored in the array
-- pointed to by DST, otherwise the conversion result is not
-- available since it is stored in an internal buffer.
--
-- If LEN wide characters are stored in the array DST before reaching
-- the end of the input string the conversion stops and LEN is
-- returned. If DST is a null pointer LEN is never checked.
--
-- Another reason for a premature return from the function call is if
-- the input string contains an invalid multibyte sequence. In this
-- case the global variable `errno' is set to `EILSEQ' and the
-- function returns `(size_t) -1'.
--
-- In all other cases the function returns the number of wide
-- characters converted during this call. If DST is not null
-- `mbsrtowcs' stores in the pointer pointed to by SRC a null pointer
-- (if the NUL byte in the input string was reached) or the address
-- of the byte following the last converted multibyte character.
--
-- This function was introduced in the second amendment to ISO C and
-- is declared in `wchar.h'.
--
-- The definition of this function has one limitation which has to be
--understood. The requirement that DST has to be a NUL terminated string
--provides problems if one wants to convert buffers with text. A buffer
--is normally no collection of NUL terminated strings but instead a
--continuous collection of lines, separated by newline characters. Now
--assume a function to convert one line from a buffer is needed. Since
--the line is not NUL terminated the source pointer cannot directly point
--into the unmodified text buffer. This means, either one inserts the NUL
--byte at the appropriate place for the time of the `mbsrtowcs' function
--call (which is not doable for a read-only buffer or in a multi-threaded
--application) or one copies the line in an extra buffer where it can be
--terminated by a NUL byte. Note that it is not in general possible to
--limit the number of characters to convert by setting the parameter LEN
--to any specific value. Since it is not known how many bytes each
--multibyte character sequence is in length one always could do only a
--guess.
--
-- There is still a problem with the method of NUL-terminating a line
--right after the newline character which could lead to very strange
--results. As said in the description of the MBSRTOWCS function above the
--conversion state is guaranteed to be in the initial shift state after
--processing the NUL byte at the end of the input string. But this NUL
--byte is not really part of the text. I.e., the conversion state after
--the newline in the original text could be something different than the
--initial shift state and therefore the first character of the next line
--is encoded using this state. But the state in question is never
--accessible to the user since the conversion stops after the NUL byte
--(which resets the state). Most stateful character sets in use today
--require that the shift state after a newline is the initial state-but
--this is not a strict guarantee. Therefore simply NUL terminating a
--piece of a running text is not always an adequate solution and therefore
--never should be used in generally used code.
--
-- The generic conversion interface (*note Generic Charset
--Conversion::.) does not have this limitation (it simply works on
--buffers, not strings), and the GNU C library contains a set of
--functions which take additional parameters specifying the maximal
--number of bytes which are consumed from the input string. This way the
--problem of `mbsrtowcs''s example above could be solved by determining
--the line length and passing this length to the function.
--
-- - Function: size_t wcsrtombs (char *restrict DST, const wchar_t
-- **restrict SRC, size_t LEN, mbstate_t *restrict PS)
-- The `wcsrtombs' function ("wide character string restartable to
-- multibyte string") converts the NUL terminated wide character
-- string at `*SRC' into an equivalent multibyte character string and
-- stores the result in the array pointed to by DST. The NUL wide
-- character is also converted. The conversion starts in the state
-- described in the object pointed to by PS or by a state object
-- locally to `wcsrtombs' in case PS is a null pointer. If DST is a
-- null pointer the conversion is performed as usual but the result
-- is not available. If all characters of the input string were
-- successfully converted and if DST is not a null pointer the
-- pointer pointed to by SRC gets assigned a null pointer.
--
-- If one of the wide characters in the input string has no valid
-- multibyte character equivalent the conversion stops early, sets
-- the global variable `errno' to `EILSEQ', and returns `(size_t) -1'.
--
-- Another reason for a premature stop is if DST is not a null
-- pointer and the next converted character would require more than
-- LEN bytes in total to the array DST. In this case (and if DEST is
-- not a null pointer) the pointer pointed to by SRC is assigned a
-- value pointing to the wide character right after the last one
-- successfully converted.
--
-- Except in the case of an encoding error the return value of the
-- function is the number of bytes in all the multibyte character
-- sequences stored in DST. Before returning the state in the object
-- pointed to by PS (or the internal object in case PS is a null
-- pointer) is updated to reflect the state after the last
-- conversion. The state is the initial shift state in case the
-- terminating NUL wide character was converted.
--
-- This function was introduced in the second amendment to ISO C and
-- is declared in `wchar.h'.
--
-- The restriction mentions above for the `mbsrtowcs' function applies
--also here. There is no possibility to directly control the number of
--input characters. One has to place the NUL wide character at the
--correct place or control the consumed input indirectly via the available
--output array size (the LEN parameter).
--
-- - Function: size_t mbsnrtowcs (wchar_t *restrict DST, const char
-- **restrict SRC, size_t NMC, size_t LEN, mbstate_t *restrict
-- PS)
-- The `mbsnrtowcs' function is very similar to the `mbsrtowcs'
-- function. All the parameters are the same except for NMC which is
-- new. The return value is the same as for `mbsrtowcs'.
--
-- This new parameter specifies how many bytes at most can be used
-- from the multibyte character string. I.e., the multibyte
-- character string `*SRC' need not be NUL terminated. But if a NUL
-- byte is found within the NMC first bytes of the string the
-- conversion stops here.
--
-- This function is a GNU extensions. It is meant to work around the
-- problems mentioned above. Now it is possible to convert buffer
-- with multibyte character text piece for piece without having to
-- care about inserting NUL bytes and the effect of NUL bytes on the
-- conversion state.
--
-- A function to convert a multibyte string into a wide character string
--and display it could be written like this (this is not a really useful
--example):
--
-- void
-- showmbs (const char *src, FILE *fp)
-- {
-- mbstate_t state;
-- int cnt = 0;
-- memset (&state, '\0', sizeof (state));
-- while (1)
-- {
-- wchar_t linebuf[100];
-- const char *endp = strchr (src, '\n');
-- size_t n;
--
-- /* Exit if there is no more line. */
-- if (endp == NULL)
-- break;
--
-- n = mbsnrtowcs (linebuf, &src, endp - src, 99, &state);
-- linebuf[n] = L'\0';
-- fprintf (fp, "line %d: \"%S\"\n", linebuf);
-- }
-- }
--
-- There is no problem with the state after a call to `mbsnrtowcs'.
--Since we don't insert characters in the strings which were not in there
--right from the beginning and we use STATE only for the conversion of
--the given buffer there is no problem with altering the state.
--
-- - Function: size_t wcsnrtombs (char *restrict DST, const wchar_t
-- **restrict SRC, size_t NWC, size_t LEN, mbstate_t *restrict
-- PS)
-- The `wcsnrtombs' function implements the conversion from wide
-- character strings to multibyte character strings. It is similar to
-- `wcsrtombs' but it takes, just like `mbsnrtowcs', an extra
-- parameter which specifies the length of the input string.
--
-- No more than NWC wide characters from the input string `*SRC' are
-- converted. If the input string contains a NUL wide character in
-- the first NWC character to conversion stops at this place.
--
-- This function is a GNU extension and just like `mbsnrtowcs' is
-- helps in situations where no NUL terminated input strings are
-- available.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-8 glibc-2.1.3/manual/libc.info-8
---- ../glibc-2.1.3/manual/libc.info-8 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-8 1969-12-31 16:00:00.000000000 -0800
-@@ -1,889 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: Multibyte Conversion Example, Prev: Converting Strings, Up: Restartable multibyte conversion
--
--A Complete Multibyte Conversion Example
-----------------------------------------
--
-- The example programs given in the last sections are only brief and do
--not contain all the error checking etc. Presented here is a complete
--and documented example. It features the `mbrtowc' function but it
--should be easy to derive versions using the other functions.
--
-- int
-- file_mbsrtowcs (int input, int output)
-- {
-- /* Note the use of `MB_LEN_MAX'.
-- `MB_CUR_MAX' cannot portably be used here. */
-- char buffer[BUFSIZ + MB_LEN_MAX];
-- mbstate_t state;
-- int filled = 0;
-- int eof = 0;
--
-- /* Initialize the state. */
-- memset (&state, '\0', sizeof (state));
--
-- while (!eof)
-- {
-- ssize_t nread;
-- ssize_t nwrite;
-- char *inp = buffer;
-- wchar_t outbuf[BUFSIZ];
-- wchar_t *outp = outbuf;
--
-- /* Fill up the buffer from the input file. */
-- nread = read (input, buffer + filled, BUFSIZ);
-- if (nread < 0)
-- {
-- perror ("read");
-- return 0;
-- }
-- /* If we reach end of file, make a note to read no more. */
-- if (nread == 0)
-- eof = 1;
--
-- /* `filled' is now the number of bytes in `buffer'. */
-- filled += nread;
--
-- /* Convert those bytes to wide characters-as many as we can. */
-- while (1)
-- {
-- size_t thislen = mbrtowc (outp, inp, filled, &state);
-- /* Stop converting at invalid character;
-- this can mean we have read just the first part
-- of a valid character. */
-- if (thislen == (size_t) -1)
-- break;
-- /* We want to handle embedded NUL bytes
-- but the return value is 0. Correct this. */
-- if (thislen == 0)
-- thislen = 1;
-- /* Advance past this character. */
-- inp += thislen;
-- filled -= thislen;
-- ++outp;
-- }
--
-- /* Write the wide characters we just made. */
-- nwrite = write (output, outbuf,
-- (outp - outbuf) * sizeof (wchar_t));
-- if (nwrite < 0)
-- {
-- perror ("write");
-- return 0;
-- }
--
-- /* See if we have a *real* invalid character. */
-- if ((eof && filled > 0) || filled >= MB_CUR_MAX)
-- {
-- error (0, 0, "invalid multibyte character");
-- return 0;
-- }
--
-- /* If any characters must be carried forward,
-- put them at the beginning of `buffer'. */
-- if (filled > 0)
-- memmove (inp, buffer, filled);
-- }
--
-- return 1;
-- }
--
--
--File: libc.info, Node: Non-reentrant Conversion, Next: Generic Charset Conversion, Prev: Restartable multibyte conversion, Up: Character Set Handling
--
--Non-reentrant Conversion Function
--=================================
--
-- The functions described in the last chapter are defined in the second
--amendment to ISO C89. But the original ISO C89 standard also contained
--functions for character set conversion. The reason that they are not
--described in the first place is that they are almost entirely useless.
--
-- The problem is that all the functions for conversion defined in
--ISO C89 use a local state. This implies that multiple conversions at
--the same time (not only when using threads) cannot be done, and that you
--cannot first convert single characters and then strings since you cannot
--tell the conversion functions which state to use.
--
-- These functions are therefore usable only in a very limited set of
--situations. One must complete converting the entire string before
--starting a new one and each string/text must be converted with the same
--function (there is no problem with the library itself; it is guaranteed
--that no library function changes the state of any of these functions).
--*For the above reasons it is highly requested that the functions from
--the last section are used in place of non-reentrant conversion
--functions.*
--
--* Menu:
--
--* Non-reentrant Character Conversion:: Non-reentrant Conversion of Single
-- Characters.
--* Non-reentrant String Conversion:: Non-reentrant Conversion of Strings.
--* Shift State:: States in Non-reentrant Functions.
--
--
--File: libc.info, Node: Non-reentrant Character Conversion, Next: Non-reentrant String Conversion, Up: Non-reentrant Conversion
--
--Non-reentrant Conversion of Single Characters
-----------------------------------------------
--
-- - Function: int mbtowc (wchar_t *restrict RESULT, const char *restrict
-- STRING, size_t SIZE)
-- The `mbtowc' ("multibyte to wide character") function when called
-- with non-null STRING converts the first multibyte character
-- beginning at STRING to its corresponding wide character code. It
-- stores the result in `*RESULT'.
--
-- `mbtowc' never examines more than SIZE bytes. (The idea is to
-- supply for SIZE the number of bytes of data you have in hand.)
--
-- `mbtowc' with non-null STRING distinguishes three possibilities:
-- the first SIZE bytes at STRING start with valid multibyte
-- character, they start with an invalid byte sequence or just part
-- of a character, or STRING points to an empty string (a null
-- character).
--
-- For a valid multibyte character, `mbtowc' converts it to a wide
-- character and stores that in `*RESULT', and returns the number of
-- bytes in that character (always at least 1, and never more than
-- SIZE).
--
-- For an invalid byte sequence, `mbtowc' returns -1. For an empty
-- string, it returns 0, also storing `'\0'' in `*RESULT'.
--
-- If the multibyte character code uses shift characters, then
-- `mbtowc' maintains and updates a shift state as it scans. If you
-- call `mbtowc' with a null pointer for STRING, that initializes the
-- shift state to its standard initial value. It also returns
-- nonzero if the multibyte character code in use actually has a
-- shift state. *Note Shift State::.
--
-- - Function: int wctomb (char *STRING, wchar_t WCHAR)
-- The `wctomb' ("wide character to multibyte") function converts the
-- wide character code WCHAR to its corresponding multibyte character
-- sequence, and stores the result in bytes starting at STRING. At
-- most `MB_CUR_MAX' characters are stored.
--
-- `wctomb' with non-null STRING distinguishes three possibilities
-- for WCHAR: a valid wide character code (one that can be translated
-- to a multibyte character), an invalid code, and `L'\0''.
--
-- Given a valid code, `wctomb' converts it to a multibyte character,
-- storing the bytes starting at STRING. Then it returns the number
-- of bytes in that character (always at least 1, and never more than
-- `MB_CUR_MAX').
--
-- If WCHAR is an invalid wide character code, `wctomb' returns -1.
-- If WCHAR is `L'\0'', it returns `0', also storing `'\0'' in
-- `*STRING'.
--
-- If the multibyte character code uses shift characters, then
-- `wctomb' maintains and updates a shift state as it scans. If you
-- call `wctomb' with a null pointer for STRING, that initializes the
-- shift state to its standard initial value. It also returns
-- nonzero if the multibyte character code in use actually has a
-- shift state. *Note Shift State::.
--
-- Calling this function with a WCHAR argument of zero when STRING is
-- not null has the side-effect of reinitializing the stored shift
-- state *as well as* storing the multibyte character `'\0'' and
-- returning 0.
--
-- Similar to `mbrlen' there is also a non-reentrant function which
--computes the length of a multibyte character. It can be defined in
--terms of `mbtowc'.
--
-- - Function: int mblen (const char *STRING, size_t SIZE)
-- The `mblen' function with a non-null STRING argument returns the
-- number of bytes that make up the multibyte character beginning at
-- STRING, never examining more than SIZE bytes. (The idea is to
-- supply for SIZE the number of bytes of data you have in hand.)
--
-- The return value of `mblen' distinguishes three possibilities: the
-- first SIZE bytes at STRING start with valid multibyte character,
-- they start with an invalid byte sequence or just part of a
-- character, or STRING points to an empty string (a null character).
--
-- For a valid multibyte character, `mblen' returns the number of
-- bytes in that character (always at least `1', and never more than
-- SIZE). For an invalid byte sequence, `mblen' returns -1. For an
-- empty string, it returns 0.
--
-- If the multibyte character code uses shift characters, then `mblen'
-- maintains and updates a shift state as it scans. If you call
-- `mblen' with a null pointer for STRING, that initializes the shift
-- state to its standard initial value. It also returns a nonzero
-- value if the multibyte character code in use actually has a shift
-- state. *Note Shift State::.
--
-- The function `mblen' is declared in `stdlib.h'.
--
--
--File: libc.info, Node: Non-reentrant String Conversion, Next: Shift State, Prev: Non-reentrant Character Conversion, Up: Non-reentrant Conversion
--
--Non-reentrant Conversion of Strings
-------------------------------------
--
-- For convenience reasons the ISO C89 standard defines also functions
--to convert entire strings instead of single characters. These functions
--suffer from the same problems as their reentrant counterparts from the
--second amendment to ISO C89; see *Note Converting Strings::.
--
-- - Function: size_t mbstowcs (wchar_t *WSTRING, const char *STRING,
-- size_t SIZE)
-- The `mbstowcs' ("multibyte string to wide character string")
-- function converts the null-terminated string of multibyte
-- characters STRING to an array of wide character codes, storing not
-- more than SIZE wide characters into the array beginning at WSTRING.
-- The terminating null character counts towards the size, so if SIZE
-- is less than the actual number of wide characters resulting from
-- STRING, no terminating null character is stored.
--
-- The conversion of characters from STRING begins in the initial
-- shift state.
--
-- If an invalid multibyte character sequence is found, this function
-- returns a value of -1. Otherwise, it returns the number of wide
-- characters stored in the array WSTRING. This number does not
-- include the terminating null character, which is present if the
-- number is less than SIZE.
--
-- Here is an example showing how to convert a string of multibyte
-- characters, allocating enough space for the result.
--
-- wchar_t *
-- mbstowcs_alloc (const char *string)
-- {
-- size_t size = strlen (string) + 1;
-- wchar_t *buf = xmalloc (size * sizeof (wchar_t));
--
-- size = mbstowcs (buf, string, size);
-- if (size == (size_t) -1)
-- return NULL;
-- buf = xrealloc (buf, (size + 1) * sizeof (wchar_t));
-- return buf;
-- }
--
--
-- - Function: size_t wcstombs (char *STRING, const wchar_t *WSTRING,
-- size_t SIZE)
-- The `wcstombs' ("wide character string to multibyte string")
-- function converts the null-terminated wide character array WSTRING
-- into a string containing multibyte characters, storing not more
-- than SIZE bytes starting at STRING, followed by a terminating null
-- character if there is room. The conversion of characters begins in
-- the initial shift state.
--
-- The terminating null character counts towards the size, so if SIZE
-- is less than or equal to the number of bytes needed in WSTRING, no
-- terminating null character is stored.
--
-- If a code that does not correspond to a valid multibyte character
-- is found, this function returns a value of -1. Otherwise, the
-- return value is the number of bytes stored in the array STRING.
-- This number does not include the terminating null character, which
-- is present if the number is less than SIZE.
--
--
--File: libc.info, Node: Shift State, Prev: Non-reentrant String Conversion, Up: Non-reentrant Conversion
--
--States in Non-reentrant Functions
-----------------------------------
--
-- In some multibyte character codes, the *meaning* of any particular
--byte sequence is not fixed; it depends on what other sequences have come
--earlier in the same string. Typically there are just a few sequences
--that can change the meaning of other sequences; these few are called
--"shift sequences" and we say that they set the "shift state" for other
--sequences that follow.
--
-- To illustrate shift state and shift sequences, suppose we decide that
--the sequence `0200' (just one byte) enters Japanese mode, in which
--pairs of bytes in the range from `0240' to `0377' are single
--characters, while `0201' enters Latin-1 mode, in which single bytes in
--the range from `0240' to `0377' are characters, and interpreted
--according to the ISO Latin-1 character set. This is a multibyte code
--which has two alternative shift states ("Japanese mode" and "Latin-1
--mode"), and two shift sequences that specify particular shift states.
--
-- When the multibyte character code in use has shift states, then
--`mblen', `mbtowc' and `wctomb' must maintain and update the current
--shift state as they scan the string. To make this work properly, you
--must follow these rules:
--
-- * Before starting to scan a string, call the function with a null
-- pointer for the multibyte character address--for example, `mblen
-- (NULL, 0)'. This initializes the shift state to its standard
-- initial value.
--
-- * Scan the string one character at a time, in order. Do not "back
-- up" and rescan characters already scanned, and do not intersperse
-- the processing of different strings.
--
-- Here is an example of using `mblen' following these rules:
--
-- void
-- scan_string (char *s)
-- {
-- int length = strlen (s);
--
-- /* Initialize shift state. */
-- mblen (NULL, 0);
--
-- while (1)
-- {
-- int thischar = mblen (s, length);
-- /* Deal with end of string and invalid characters. */
-- if (thischar == 0)
-- break;
-- if (thischar == -1)
-- {
-- error ("invalid multibyte character");
-- break;
-- }
-- /* Advance past this character. */
-- s += thischar;
-- length -= thischar;
-- }
-- }
--
-- The functions `mblen', `mbtowc' and `wctomb' are not reentrant when
--using a multibyte code that uses a shift state. However, no other
--library functions call these functions, so you don't have to worry that
--the shift state will be changed mysteriously.
--
--
--File: libc.info, Node: Generic Charset Conversion, Prev: Non-reentrant Conversion, Up: Character Set Handling
--
--Generic Charset Conversion
--==========================
--
-- The conversion functions mentioned so far in this chapter all had in
--common that they operate on character sets which are not directly
--specified by the functions. The multibyte encoding used is specified by
--the currently selected locale for the `LC_CTYPE' category. The wide
--character set is fixed by the implementation (in the case of GNU C
--library it always is UCS4 encoded ISO 10646.
--
-- This has of course several problems when it comes to general
--character conversion:
--
-- * For every conversion where neither the source or destination
-- character set is the character set of the locale for the
-- `LC_CTYPE' category, one has to change the `LC_CTYPE' locale using
-- `setlocale'.
--
-- This introduces major problems for the rest of the programs since
-- several more functions (e.g., the character classification
-- functions, *note Classification of Characters::.) use the
-- `LC_CTYPE' category.
--
-- * Parallel conversions to and from different character sets are not
-- possible since the `LC_CTYPE' selection is global and shared by all
-- threads.
--
-- * If neither the source nor the destination character set is the
-- character set used for `wchar_t' representation there is at least
-- a two-step process necessary to convert a text using the functions
-- above. One would have to select the source character set as the
-- multibyte encoding, convert the text into a `wchar_t' text, select
-- the destination character set as the multibyte encoding and
-- convert the wide character text to the multibyte (= destination)
-- character set.
--
-- Even if this is possible (which is not guaranteed) it is a very
-- tiring work. Plus it suffers from the other two raised points
-- even more due to the steady changing of the locale.
--
-- The XPG2 standard defines a completely new set of functions which has
--none of these limitations. They are not at all coupled to the selected
--locales and they but no constraints on the character sets selected for
--source and destination. Only the set of available conversions is
--limiting them. The standard does not specify that any conversion at all
--must be available. It is a measure of the quality of the
--implementation.
--
-- In the following text first the interface to `iconv', the conversion
--function, will be described. Comparisons with other implementations
--will show what pitfalls lie on the way of portable applications. At
--last, the implementation is described as far as interesting to the
--advanced user who wants to extend the conversion capabilities.
--
--* Menu:
--
--* Generic Conversion Interface:: Generic Character Set Conversion Interface.
--* iconv Examples:: A complete `iconv' example.
--* Other iconv Implementations:: Some Details about other `iconv'
-- Implementations.
--* glibc iconv Implementation:: The `iconv' Implementation in the GNU C
-- library.
--
--
--File: libc.info, Node: Generic Conversion Interface, Next: iconv Examples, Up: Generic Charset Conversion
--
--Generic Character Set Conversion Interface
--------------------------------------------
--
-- This set of functions follows the traditional cycle of using a
--resource: open-use-close. The interface consists of three functions,
--each of which implement one step.
--
-- Before the interfaces are described it is necessary to introduce a
--datatype. Just like other open-use-close interface the functions
--introduced here work using a handles and the `iconv.h' header defines a
--special type for the handles used.
--
-- - Data Type: iconv_t
-- This data type is an abstract type defined in `iconv.h'. The user
-- must not assume anything about the definition of this type, it
-- must be completely opaque.
--
-- Objects of this type can get assigned handles for the conversions
-- using the `iconv' functions. The objects themselves need not be
-- freed but the conversions for which the handles stand for have to.
--
--The first step is the function to create a handle.
--
-- - Function: iconv_t iconv_open (const char *TOCODE, const char
-- *FROMCODE)
-- The `iconv_open' function has to be used before starting a
-- conversion. The two parameters this function takes determine the
-- source and destination character set for the conversion and if the
-- implementation has the possibility to perform such a conversion the
-- function returns a handle.
--
-- If the wanted conversion is not available the function returns
-- `(iconv_t) -1'. In this case the global variable `errno' can have
-- the following values:
--
-- `EMFILE'
-- The process already has `OPEN_MAX' file descriptors open.
--
-- `ENFILE'
-- The system limit of open file is reached.
--
-- `ENOMEM'
-- Not enough memory to carry out the operation.
--
-- `EINVAL'
-- The conversion from FROMCODE to TOCODE is not supported.
--
-- It is not possible to use the same descriptor in different threads
-- to perform independent conversions. Within the data structures
-- associated with the descriptor there is information about the
-- conversion state. This must not be messed up by using it in
-- different conversions.
--
-- An `iconv' descriptor is like a file descriptor as for every use a
-- new descriptor must be created. The descriptor does not stand for
-- all of the conversions from FROMSET to TOSET.
--
-- The GNU C library implementation of `iconv_open' has one
-- significant extension to other implementations. To ease the
-- extension of the set of available conversions the implementation
-- allows to store the necessary files with data and code in
-- arbitrary many directories. How this extensions have to be
-- written will be explained below (*note glibc iconv
-- Implementation::.). Here it is only important to say that all
-- directories mentioned in the `GCONV_PATH' environment variable are
-- considered if they contain a file `gconv-modules'. These
-- directories need not necessarily be created by the system
-- administrator. In fact, this extension is introduced to help users
-- writing and using own, new conversions. Of course this does not
-- work for security reasons in SUID binaries; in this case only the
-- system directory is considered and this normally is
-- `PREFIX/lib/gconv'. The `GCONV_PATH' environment variable is
-- examined exactly once at the first call of the `iconv_open'
-- function. Later modifications of the variable have no effect.
--
-- This function got introduced early in the X/Open Portability Guide,
-- version 2. It is supported by all commercial Unices as it is
-- required for the Unix branding. However, the quality and
-- completeness of the implementation varies widely. The function is
-- declared in `iconv.h'.
--
-- The `iconv' implementation can associate large data structure with
--the handle returned by `iconv_open'. Therefore it is crucial to free
--all the resources once all conversions are carried out and the
--conversion is not needed anymore.
--
-- - Function: int iconv_close (iconv_t CD)
-- The `iconv_close' function frees all resources associated with the
-- handle CD which must have been returned by a successful call to
-- the `iconv_open' function.
--
-- If the function call was successful the return value is 0.
-- Otherwise it is -1 and `errno' is set appropriately. Defined
-- error are:
--
-- `EBADF'
-- The conversion descriptor is invalid.
--
-- This function was introduced together with the rest of the `iconv'
-- functions in XPG2 and it is declared in `iconv.h'.
--
-- The standard defines only one actual conversion function. This has
--therefore the most general interface: it allows conversion from one
--buffer to another. Conversion from a file to a buffer, vice versa, or
--even file to file can be implemented on top of it.
--
-- - Function: size_t iconv (iconv_t CD, const char **INBUF, size_t
-- *INBYTESLEFT, char **OUTBUF, size_t *OUTBYTESLEFT)
-- The `iconv' function converts the text in the input buffer
-- according to the rules associated with the descriptor CD and
-- stores the result in the output buffer. It is possible to call the
-- function for the same text several times in a row since for
-- stateful character sets the necessary state information is kept in
-- the data structures associated with the descriptor.
--
-- The input buffer is specified by `*INBUF' and it contains
-- `*INBYTESLEFT' bytes. The extra indirection is necessary for
-- communicating the used input back to the caller (see below). It is
-- important to note that the buffer pointer is of type `char' and the
-- length is measured in bytes even if the input text is encoded in
-- wide characters.
--
-- The output buffer is specified in a similar way. `*OUTBUF' points
-- to the beginning of the buffer with at least `*OUTBYTESLEFT' bytes
-- room for the result. The buffer pointer again is of type `char'
-- and the length is measured in bytes. If OUTBUF or `*OUTBUF' is a
-- null pointer the conversion is performed but no output is
-- available.
--
-- If INBUF is a null pointer the `iconv' function performs the
-- necessary action to put the state of the conversion into the
-- initial state. This is obviously a no-op for non-stateful
-- encodings, but if the encoding has a state such a function call
-- might put some byte sequences in the output buffer which perform
-- the necessary state changes. The next call with INBUF not being a
-- null pointer then simply goes on from the initial state. It is
-- important that the programmer never makes any assumption on
-- whether the conversion has to deal with states or not. Even if
-- the input and output character sets are not stateful the
-- implementation might still have to keep states. This is due to the
-- implementation chosen for the GNU C library as it is described
-- below. Therefore an `iconv' call to reset the state should always
-- be performed if some protocol requires this for the output text.
--
-- The conversion stops for three reasons. The first is that all
-- characters from the input buffer are converted. This actually can
-- mean two things: really all bytes from the input buffer are
-- consumed or there are some bytes at the end of the buffer which
-- possibly can form a complete character but the input is
-- incomplete. The second reason for a stop is when the output
-- buffer is full. And the third reason is that the input contains
-- invalid characters.
--
-- In all these cases the buffer pointers after the last successful
-- conversion, for input and output buffer, are stored in INBUF and
-- OUTBUF and the available room in each buffer is stored in
-- INBYTESLEFT and OUTBYTESLEFT.
--
-- Since the character sets selected in the `iconv_open' call can be
-- almost arbitrary there can be situations where the input buffer
-- contains valid characters which have no identical representation
-- in the output character set. The behavior in this situation is
-- undefined. The *current* behavior of the GNU C library in this
-- situation is to return with an error immediately. This certainly
-- is not the most desirable solution. Therefore future versions
-- will provide better ones but they are not yet finished.
--
-- If all input from the input buffer is successfully converted and
-- stored in the output buffer the function returns the number of
-- conversions performed. In all other cases the return value is
-- `(size_t) -1' and `errno' is set appropriately. In this case the
-- value pointed to by INBYTESLEFT is nonzero.
--
-- `EILSEQ'
-- The conversion stopped because of an invalid byte sequence in
-- the input. After the call `*INBUF' points at the first byte
-- of the invalid byte sequence.
--
-- `E2BIG'
-- The conversion stopped because it ran out of space in the
-- output buffer.
--
-- `EINVAL'
-- The conversion stopped because of an incomplete byte sequence
-- at the end of the input buffer.
--
-- `EBADF'
-- The CD argument is invalid.
--
-- This function was introduced in the XPG2 standard and is declared
-- in the `iconv.h' header.
--
-- The definition of the `iconv' function is quite good overall. It
--provides quite flexible functionality. The only problems lie in the
--boundary cases which are incomplete byte sequences at the end of the
--input buffer and invalid input. A third problem, which is not really a
--design problem, is the way conversions are selected. The standard does
--not say anything about the legitimate names, a minimal set of available
--conversions. We will see how this negatively impacts other
--implementations, as is demonstrated below.
--
--
--File: libc.info, Node: iconv Examples, Next: Other iconv Implementations, Prev: Generic Conversion Interface, Up: Generic Charset Conversion
--
--A complete `iconv' example
----------------------------
--
-- The example below features a solution for a common problem. Given
--that one knows the internal encoding used by the system for `wchar_t'
--strings one often is in the position to read text from a file and store
--it in wide character buffers. One can do this using `mbsrtowcs' but
--then we run into the problems discussed above.
--
-- int
-- file2wcs (int fd, const char *charset, wchar_t *outbuf, size_t avail)
-- {
-- char inbuf[BUFSIZ];
-- size_t insize = 0;
-- char *wrptr = (char *) outbuf;
-- int result = 0;
-- iconv_t cd;
--
-- cd = iconv_open ("UCS4", charset);
-- if (cd == (iconv_t) -1)
-- {
-- /* Something went wrong. */
-- if (errno == EINVAL)
-- error (0, 0, "conversion from `%s' to `UCS4' no available",
-- charset);
-- else
-- perror ("iconv_open");
--
-- /* Terminate the output string. */
-- *outbuf = L'\0';
--
-- return -1;
-- }
--
-- while (avail > 0)
-- {
-- size_t nread;
-- size_t nconv;
-- char *inptr = inbuf;
--
-- /* Read more input. */
-- nread = read (fd, inbuf + insize, sizeof (inbuf) - insize);
-- if (nread == 0)
-- {
-- /* When we come here the file is completely read.
-- This still could mean there are some unused
-- characters in the `inbuf'. Put them back. */
-- if (lseek (fd, -insize, SEEK_CUR) == -1)
-- result = -1;
-- break;
-- }
-- insize += nread;
--
-- /* Do the conversion. */
-- nconv = iconv (cd, &inptr, &insize, &wrptr, &avail);
-- if (nconv == (size_t) -1)
-- {
-- /* Not everything went right. It might only be
-- an unfinished byte sequence at the end of the
-- buffer. Or it is a real problem. */
-- if (errno == EINVAL)
-- /* This is harmless. Simply move the unused
-- bytes to the beginning of the buffer so that
-- they can be used in the next round. */
-- memmove (inbuf, inptr, insize);
-- else
-- {
-- /* It is a real problem. Maybe we ran out of
-- space in the output buffer or we have invalid
-- input. In any case back the file pointer to
-- the position of the last processed byte. */
-- lseek (fd, -insize, SEEK_CUR);
-- result = -1;
-- break;
-- }
-- }
-- }
--
-- /* Terminate the output string. */
-- *((wchar_t *) wrptr) = L'\0';
--
-- if (iconv_close (cd) != 0)
-- perror ("iconv_close");
--
-- return (wchar_t *) wrptr - outbuf;
-- }
--
-- This example shows the most important aspects of using the `iconv'
--functions. It shows how successive calls to `iconv' can be used to
--convert large amounts of text. The user does not have to care about
--stateful encodings as the functions take care of everything.
--
-- An interesting point is the case where `iconv' return an error and
--`errno' is set to `EINVAL'. This is not really an error in the
--transformation. It can happen whenever the input character set
--contains byte sequences of more than one byte for some character and
--texts are not processed in one piece. In this case there is a chance
--that a multibyte sequence is cut. The caller than can simply read the
--remainder of the takes and feed the offending bytes together with new
--character from the input to `iconv' and continue the work. The
--internal state kept in the descriptor is *not* unspecified after such
--an event as it is the case with the conversion functions from the ISO C
--standard.
--
-- The example also shows the problem of using wide character strings
--with `iconv'. As explained in the description of the `iconv' function
--above the function always takes a pointer to a `char' array and the
--available space is measured in bytes. In the example the output buffer
--is a wide character buffer. Therefore we use a local variable WRPTR of
--type `char *' which is used in the `iconv' calls.
--
-- This looks rather innocent but can lead to problems on platforms
--which have tight restriction on alignment. Therefore the caller of
--`iconv' has to make sure that the pointers passed are suitable for
--access of characters from the appropriate character set. Since in the
--above case the input parameter to the function is a `wchar_t' pointer
--this is the case (unless the user violates alignment when computing the
--parameter). But in other situations, especially when writing generic
--functions where one does not know what type of character set one uses
--and therefore treats text as a sequence of bytes, it might become
--tricky.
--
--
--File: libc.info, Node: Other iconv Implementations, Next: glibc iconv Implementation, Prev: iconv Examples, Up: Generic Charset Conversion
--
--Some Details about other `iconv' Implementations
--------------------------------------------------
--
-- This is not really the place to discuss the `iconv' implementation
--of other systems but it is necessary to know a bit about them to write
--portable programs. The above mentioned problems with the specification
--of the `iconv' functions can lead to portability issues.
--
-- The first thing to notice is that due to the large number of
--character sets in use it is certainly not practical to encode the
--conversions directly in the C library. Therefore the conversion
--information must come from files outside the C library. This is
--usually done in one or both of the following ways:
--
-- * The C library contains a set of generic conversion functions which
-- can read the needed conversion tables and other information from
-- data files. These files get loaded when necessary.
--
-- This solution is problematic as it requires a great deal of effort
-- to apply to all character sets (potentially an infinite set). The
-- differences in the structure of the different character sets is so
-- large that many different variants of the table processing
-- functions must be developed. On top of this the generic nature of
-- these functions make them slower than specifically implemented
-- functions.
--
-- * The C library only contains a framework which can dynamically load
-- object files and execute the therein contained conversion
-- functions.
--
-- This solution provides much more flexibility. The C library itself
-- contains only very little code and therefore reduces the general
-- memory footprint. Also, with a documented interface between the C
-- library and the loadable modules it is possible for third parties
-- to extend the set of available conversion modules. A drawback of
-- this solution is that dynamic loading must be available.
--
-- Some implementations in commercial Unices implement a mixture of
--these these possibilities, the majority only the second solution. Using
--loadable modules moves the code out of the library itself and keeps the
--door open for extensions and improvements. But this design is also
--limiting on some platforms since not many platforms support dynamic
--loading in statically linked programs. On platforms without his
--capability it is therefore not possible to use this interface in
--statically linked programs. The GNU C library has on ELF platforms no
--problems with dynamic loading in in these situations and therefore this
--point is mood. The danger is that one gets acquainted with this and
--forgets about the restrictions on other systems.
--
-- A second thing to know about other `iconv' implementations is that
--the number of available conversions is often very limited. Some
--implementations provide in the standard release (not special
--international or developer releases) at most 100 to 200 conversion
--possibilities. This does not mean 200 different character sets are
--supported. E.g., conversions from one character set to a set of, say,
--10 others counts as 10 conversion. Together with the other direction
--this makes already 20. One can imagine the thin coverage these platform
--provide. Some Unix vendors even provide only a handful of conversions
--which renders them useless for almost all uses.
--
-- This directly leads to a third and probably the most problematic
--point. The way the `iconv' conversion functions are implemented on all
--known Unix system and the availability of the conversion functions from
--character set A to B and the conversion from B to C does *not* imply
--that the conversion from A to C is available.
--
-- This might not seem unreasonable and problematic at first but it is a
--quite big problem as one will notice shortly after hitting it. To show
--the problem we assume to write a program which has to convert from A to
--C. A call like
--
-- cd = iconv_open ("C", "A");
--
--does fail according to the assumption above. But what does the program
--do now? The conversion is really necessary and therefore simply giving
--up is no possibility.
--
-- This is a nuisance. The `iconv' function should take care of this.
--But how should the program proceed from here on? If it would try to
--convert to character set B first the two `iconv_open' calls
--
-- cd1 = iconv_open ("B", "A");
--
--and
--
-- cd2 = iconv_open ("C", "B");
--
--will succeed but how to find B?
--
-- Unfortunately, the answer is: there is no general solution. On some
--systems guessing might help. On those systems most character sets can
--convert to and from UTF8 encoded ISO 10646 or Unicode text. Beside
--this only some very system-specific methods can help. Since the
--conversion functions come from loadable modules and these modules must
--be stored somewhere in the filesystem, one *could* try to find them and
--determine from the available file which conversions are available and
--whether there is an indirect route from A to C.
--
-- This shows one of the design errors of `iconv' mentioned above. It
--should at least be possible to determine the list of available
--conversion programmatically so that if `iconv_open' says there is no
--such conversion, one could make sure this also is true for indirect
--routes.
--
-diff -Naur ../glibc-2.1.3/manual/libc.info-9 glibc-2.1.3/manual/libc.info-9
---- ../glibc-2.1.3/manual/libc.info-9 2000-01-05 19:18:25.000000000 -0800
-+++ glibc-2.1.3/manual/libc.info-9 1969-12-31 16:00:00.000000000 -0800
-@@ -1,1029 +0,0 @@
--This is Info file libc.info, produced by Makeinfo version 1.68 from the
--input file libc.texinfo.
--
--INFO-DIR-SECTION GNU libraries
--START-INFO-DIR-ENTRY
--* Libc: (libc). C library.
--END-INFO-DIR-ENTRY
--
-- This file documents the GNU C library.
--
-- This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
--Library Reference Manual', for Version 2.1 Beta.
--
-- Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
--Foundation, Inc.
--
-- Permission is granted to make and distribute verbatim copies of this
--manual provided the copyright notice and this permission notice are
--preserved on all copies.
--
-- Permission is granted to copy and distribute modified versions of
--this manual under the conditions for verbatim copying, provided also
--that the section entitled "GNU Library General Public License" is
--included exactly as in the original, and provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
-- Permission is granted to copy and distribute translations of this
--manual into another language, under the above conditions for modified
--versions, except that the text of the translation of the section
--entitled "GNU Library General Public License" must be approved for
--accuracy by the Foundation.
--
--
--File: libc.info, Node: glibc iconv Implementation, Prev: Other iconv Implementations, Up: Generic Charset Conversion
--
--The `iconv' Implementation in the GNU C library
-------------------------------------------------
--
-- After reading about the problems of `iconv' implementations in the
--last section it is certainly good to note that the implementation in
--the GNU C library has none of the problems mentioned above. What
--follows is a step-by-step analysis of the points raised above. The
--evaluation is based on the current state of the development (as of
--January 1999). The development of the `iconv' functions is not
--complete, but basic funtionality has solidified.
--
-- The GNU C library's `iconv' implementation uses shared loadable
--modules to implement the conversions. A very small number of
--conversions are built into the library itself but these are only rather
--trivial conversions.
--
-- All the benefits of loadable modules are available in the GNU C
--library implementation. This is especially appealing since the
--interface is well documented (see below) and it therefore is easy to
--write new conversion modules. The drawback of using loadable objects
--is not a problem in the GNU C library, at least on ELF systems. Since
--the library is able to load shared objects even in statically linked
--binaries this means that static linking needs not to be forbidden in
--case one wants to use `iconv'.
--
-- The second mentioned problem is the number of supported conversions.
--Currently, the GNU C library supports more than 150 character sets. The
--way the implementation is designed the number of supported conversions
--is greater than 22350 (150 times 149). If any conversion from or to a
--character set is missing it can easily be added.
--
-- Particularly impressive as it may be, this high number is due to the
--fact that the GNU C library implementation of `iconv' does not have the
--third problem mentioned above. I.e., whenever there is a conversion
--from a character set A to B and from B to C it is always possible to
--convert from A to C directly. If the `iconv_open' returns an error and
--sets `errno' to `EINVAL' this really means there is no known way,
--directly or indirectly, to perform the wanted conversion.
--
-- This is achieved by providing for each character set a conversion
--from and to UCS4 encoded ISO 10646. Using ISO 10646 as an intermediate
--representation it is possible to "triangulate", i.e., converting with
--an intermediate representation.
--
-- There is no inherent requirement to provide a conversion to
--ISO 10646 for a new character set and it is also possible to provide
--other conversions where neither source nor destination character set is
--ISO 10646. The currently existing set of conversions is simply meant to
--cover all conversions which might be of interest.
--
-- All currently available conversions use the triangulation method
--above, making conversion run unnecessarily slow. If, e.g., somebody
--often needs the conversion from ISO-2022-JP to EUC-JP, a quicker
--solution would involve direct conversion between the two character
--sets, skipping the input to ISO 10646 first. The two character sets of
--interest are much more similar to each other than to ISO 10646.
--
-- In such a situation one can easy write a new conversion and provide
--it as a better alternative. The GNU C library `iconv' implementation
--would automatically use the module implementing the conversion if it is
--specified to be more efficient.
--
--Format of `gconv-modules' files
--...............................
--
-- All information about the available conversions comes from a file
--named `gconv-modules' which can be found in any of the directories along
--the `GCONV_PATH'. The `gconv-modules' files are line-oriented text
--files, where each of the lines has one of the following formats:
--
-- * If the first non-whitespace character is a `#' the line contains
-- only comments and is ignored.
--
-- * Lines starting with `alias' define an alias name for a character
-- set. There are two more words expected on the line. The first one
-- defines the alias name and the second defines the original name of
-- the character set. The effect is that it is possible to use the
-- alias name in the FROMSET or TOSET parameters of `iconv_open' and
-- achieve the same result as when using the real character set name.
--
-- This is quite important as a character set has often many different
-- names. There is normally always an official name but this need not
-- correspond to the most popular name. Beside this many character
-- sets have special names which are somehow constructed. E.g., all
-- character sets specified by the ISO have an alias of the form
-- `ISO-IR-NNN' where NNN is the registration number. This allows
-- programs which know about the registration number to construct
-- character set names and use them in `iconv_open' calls. More on
-- the available names and aliases follows below.
--
-- * Lines starting with `module' introduce an available conversion
-- module. These lines must contain three or four more words.
--
-- The first word specifies the source character set, the second word
-- the destination character set of conversion implemented in this
-- module. The third word is the name of the loadable module. The
-- filename is constructed by appending the usual shared object
-- suffix (normally `.so') and this file is then supposed to be found
-- in the same directory the `gconv-modules' file is in. The last
-- word on the line, which is optional, is a numeric value
-- representing the cost of the conversion. If this word is missing
-- a cost of 1 is assumed. The numeric value itself does not matter
-- that much; what counts are the relative values of the sums of
-- costs for all possible conversion paths. Below is a more precise
-- description of the use of the cost value.
--
-- Returning to the example above where one has written a module to
--directly convert from ISO-2022-JP to EUC-JP and back. All what has to
--be done is to put the new module, be its name ISO2022JP-EUCJP.so, in a
--directory and add a file `gconv-modules' with the following content in
--the same directory:
--
-- module ISO-2022-JP// EUC-JP// ISO2022JP-EUCJP 1
-- module EUC-JP// ISO-2022-JP// ISO2022JP-EUCJP 1
--
-- To see why this is sufficient, it is necessary to understand how the
--conversion used by `iconv' (and described in the descriptor) is
--selected. The approach to this problem is quite simple.
--
-- At the first call of the `iconv_open' function the program reads all
--available `gconv-modules' files and builds up two tables: one
--containing all the known aliases and another which contains the
--information about the conversions and which shared object implements
--them.
--
--Finding the conversion path in `iconv'
--......................................
--
-- The set of available conversions form a directed graph with weighted
--edges. The weights on the edges are the costs specified in the
--`gconv-modules' files. The `iconv_open' function uses an algorithm
--suitable for search for the best path in such a graph and so constructs
--a list of conversions which must be performed in succession to get the
--transformation from the source to the destination character set.
--
-- Explaining why the above `gconv-modules' files allows the `iconv'
--implementation to resolve the specific ISO-2022-JP to EUC-JP conversion
--module instead of the conversion coming with the library itself is
--straighforward. Since the later conversion takes two steps (from
--ISO-2022-JP to ISO 10646 and then from ISO 10646 to EUC-JP) the cost is
--1+1 = 2. But the above `gconv-modules' file specifies that the new
--conversion modules can perform this conversion with only the cost of 1.
--
-- A mysterious piece about the `gconv-modules' file above (and also
--the file coming with the GNU C library) are the names of the character
--sets specified in the `module' lines. Why do almost all the names end
--in `//'? And this is not all: the names can actually be regular
--expressions. At this point of time this mystery should not be
--revealed, unless you have the relevant spell-casting materials: ashes
--from an original DOS 6.2 boot disk burnt in effigy, a crucifix blessed
--by St. Emacs, assorted herbal roots from Central America, sand from
--Cebu, etc. Sorry! *The part of the implementation where this is used
--is not yet finished. For now please simply follow the existing
--examples. It'll become clearer once it is. -drepper*
--
-- A last remark about the `gconv-modules' is about the names not
--ending with `//'. There often is a character set named `INTERNAL'
--mentioned. From the discussion above and the chosen name it should
--have become clear that this is the name for the representation used in
--the intermediate step of the triangulation. We have said that this is
--UCS4 but actually it is not quite right. The UCS4 specification also
--includes the specification of the byte ordering used. Since a UCS4
--value consists of four bytes a stored value is effected by byte
--ordering. The internal representation is *not* the same as UCS4 in
--case the byte ordering of the processor (or at least the running
--process) is not the same as the one required for UCS4. This is done
--for performance reasons as one does not want to perform unnecessary
--byte-swapping operations if one is not interested in actually seeing
--the result in UCS4. To avoid trouble with endianess the internal
--representation consistently is named `INTERNAL' even on big-endian
--systems where the representations are identical.
--
--`iconv' module data structures
--..............................
--
-- So far this section described how modules are located and considered
--to be used. What remains to be described is the interface of the
--modules so that one can write new ones. This section describes the
--interface as it is in use in January 1999. The interface will change
--in future a bit but hopefully only in an upward compatible way.
--
-- The definitions necessary to write new modules are publically
--available in the non-standard header `gconv.h'. The following text will
--therefore describe the definitions from this header file. But first it
--is necessary to get an overview.
--
-- From the perspective of the user of `iconv' the interface is quite
--simple: the `iconv_open' function returns a handle which can be used in
--calls to `iconv' and finally the handle is freed with a call to
--`iconv_close'. The problem is: the handle has to be able to represent
--the possibly long sequences of conversion steps and also the state of
--each conversion since the handle is all which is passed to the `iconv'
--function. Therefore the data structures are really the elements to
--understanding the implementation.
--
-- We need two different kinds of data structures. The first describes
--the conversion and the second describes the state etc. There are
--really two type definitions like this in `gconv.h'.
--
-- - Data type: struct gconv_step
-- This data structure describes one conversion a module can perform.
-- For each function in a loaded module with conversion functions
-- there is exactly one object of this type. This object is shared
-- by all users of the conversion. I.e., this object does not
-- contain any information corresponding to an actual conversion. It
-- only describes the conversion itself.
--
-- `struct gconv_loaded_object *shlib_handle'
-- `const char *modname'
-- `int counter'
-- All these elements of the structure are used internally in
-- the C library to coordinate loading and unloading the shared.
-- One must not expect any of the other elements be available
-- or initialized.
--
-- `const char *from_name'
-- `const char *to_name'
-- `from_name' and `to_name' contain the names of the source and
-- destination character sets. They can be used to identify the
-- actual conversion to be carried out since one module might
-- implement conversions for more than one character set and/or
-- direction.
--
-- `gconv_fct fct'
-- `gconv_init_fct init_fct'
-- `gconv_end_fct end_fct'
-- These elements contain pointers to the functions in the
-- loadable module. The interface will be explained below.
--
-- `int min_needed_from'
-- `int max_needed_from'
-- `int min_needed_to'
-- `int max_needed_to;'
-- These values have to be filled in the init function of the
-- module. The `min_needed_from' value specifies how many bytes
-- a character of the source character set at least needs. The
-- `max_needed_from' specifies the maximum value which also
-- includes possible shift sequences.
--
-- The `min_needed_to' and `max_needed_to' values serve the same
-- purpose but this time for the destination character set.
--
-- It is crucial that these values are accurate since otherwise
-- the conversion functions will have problems or not work at
-- all.
--
-- `int stateful'
-- This element must also be initialized by the init function.
-- It is nonzero if the source character set is stateful.
-- Otherwise it is zero.
--
-- `void *data'
-- This element can be used freely by the conversion functions
-- in the module. It can be used to communicate extra
-- information from one call to another. It need not be
-- initialized if not needed at all. If this element gets
-- assigned a pointer to dynamically allocated memory
-- (presumably in the init function) it has to be made sure that
-- the end function deallocates the memory. Otherwise the
-- application will leak memory.
--
-- It is important to be aware that this data structure is
-- shared by all users of this specification conversion and
-- therefore the `data' element must not contain data specific
-- to one specific use of the conversion function.
--
-- - Data type: struct gconv_step_data
-- This is the data structure which contains the information specific
-- to each use of the conversion functions.
--
-- `char *outbuf'
-- `char *outbufend'
-- These elements specify the output buffer for the conversion
-- step. The `outbuf' element points to the beginning of the
-- buffer and `outbufend' points to the byte following the last
-- byte in the buffer. The conversion function must not assume
-- anything about the size of the buffer but it can be safely
-- assumed the there is room for at least one complete character
-- in the output buffer.
--
-- Once the conversion is finished and the conversion is the
-- last step the `outbuf' element must be modified to point
-- after last last byte written into the buffer to signal how
-- much output is available. If this conversion step is not the
-- last one the element must not be modified. The `outbufend'
-- element must not be modified.
--
-- `int is_last'
-- This element is nonzero if this conversion step is the last
-- one. This information is necessary for the recursion. See
-- the description of the conversion function internals below.
-- This element must never be modified.
--
-- `int invocation_counter'
-- The conversion function can use this element to see how many
-- calls of the conversion function already happened. Some
-- character sets require when generating output a certain
-- prolog and by comparing this value with zero one can find out
-- whether it is the first call and therefore the prolog should
-- be emitted or not. This element must never be modified.
--
-- `int internal_use'
-- This element is another one rarely used but needed in certain
-- situations. It got assigned a nonzero value in case the
-- conversion functions are used to implement `mbsrtowcs' et.al.
-- I.e., the function is not used directly through the `iconv'
-- interface.
--
-- This sometimes makes a difference as it is expected that the
-- `iconv' functions are used to translate entire texts while the
-- `mbsrtowcs' functions are normally only used to convert single
-- strings and might be used multiple times to convert entire
-- texts.
--
-- But in this situation we would have problem complying with
-- some rules of the character set specification. Some
-- character sets require a prolog which must appear exactly
-- once for an entire text. If a number of `mbsrtowcs' calls
-- are used to convert the text only the first call must add the
-- prolog. But since there is no communication between the
-- different calls of `mbsrtowcs' the conversion functions have
-- no possibility to find this out. The situation is different
-- for sequences of `iconv' calls since the handle allows to
-- access the needed information.
--
-- This element is mostly used together with
-- `invocation_counter' in a way like this:
--
-- if (!data->internal_use && data->invocation_counter == 0)
-- /* Emit prolog. */
-- ...
--
-- This element must never be modified.
--
-- `mbstate_t *statep'
-- The `statep' element points to an object of type `mbstate_t'
-- (*note Keeping the state::.). The conversion of an stateful
-- character set must use the object pointed to by this element
-- to store information about the conversion state. The
-- `statep' element itself must never be modified.
--
-- `mbstate_t __state'
-- This element *never* must be used directly. It is only part
-- of this structure to have the needed space allocated.
--
--`iconv' module interfaces
--.........................
--
-- With the knowledge about the data structures we now can describe the
--conversion functions itself. To understand the interface a bit of
--knowledge about the functionality in the C library which loads the
--objects with the conversions is necessary.
--
-- It is often the case that one conversion is used more than once.
--I.e., there are several `iconv_open' calls for the same set of character
--sets during one program run. The `mbsrtowcs' et.al. functions in the
--GNU C library also use the `iconv' functionality which increases the
--number of uses of the same functions even more.
--
-- For this reason the modules do not get loaded exclusively for one
--conversion. Instead a module once loaded can be used by arbitrary many
--`iconv' or `mbsrtowcs' calls at the same time. The splitting of the
--information between conversion function specific information and
--conversion data makes this possible. The last section showed the two
--data structure used to do this.
--
-- This is of course also reflected in the interface and semantic of the
--functions the modules must provide. There are three functions which
--must have the following names:
--
--`gconv_init'
-- The `gconv_init' function initializes the conversion function
-- specific data structure. This very same object is shared by all
-- conversion which use this conversion and therefore no state
-- information about the conversion itself must be stored in here.
-- If a module implements more than one conversion the `gconv_init'
-- function will be called multiple times.
--
--`gconv_end'
-- The `gconv_end' function is responsible to free all resources
-- allocated by the `gconv_init' function. If there is nothing to do
-- this function can be missing. Special care must be taken if the
-- module implements more than one conversion and the `gconv_init'
-- function does not allocate the same resources for all conversions.
--
--`gconv'
-- This is the actual conversion function. It is called to convert
-- one block of text. It gets passed the conversion step information
-- initialized by `gconv_init' and the conversion data, specific to
-- this use of the conversion functions.
--
-- There are three data types defined for the three module interface
--function and these define the interface.
--
-- - Data type: int (*gconv_init_fct) (struct gconv_step *)
-- This specifies the interface of the initialization function of the
-- module. It is called exactly once for each conversion the module
-- implements.
--
-- As explained int the description of the `struct gconv_step' data
-- structure above the initialization function has to initialize
-- parts of it.
--
-- `min_needed_from'
-- `max_needed_from'
-- `min_needed_to'
-- `max_needed_to'
-- These elements must be initialized to the exact numbers of
-- the minimum and maximum number of bytes used by one character
-- in the source and destination character set respectively. If
-- the characters all have the same size the minimum and maximum
-- values are the same.
--
-- `stateful'
-- This element must be initialized to an nonzero value if the
-- source character set is stateful. Otherwise it must be zero.
--
-- If the initialization function needs to communication some
-- information to the conversion function this can happen using the
-- `data' element of the `gconv_step' structure. But since this data
-- is shared by all the conversion is must not be modified by the
-- conversion function. How this can be used is shown in the example
-- below.
--
-- #define MIN_NEEDED_FROM 1
-- #define MAX_NEEDED_FROM 4
-- #define MIN_NEEDED_TO 4
-- #define MAX_NEEDED_TO 4
--
-- int
-- gconv_init (struct gconv_step *step)
-- {
-- /* Determine which direction. */
-- struct iso2022jp_data *new_data;
-- enum direction dir = illegal_dir;
-- enum variant var = illegal_var;
-- int result;
--
-- if (__strcasecmp (step->from_name, "ISO-2022-JP//") == 0)
-- {
-- dir = from_iso2022jp;
-- var = iso2022jp;
-- }
-- else if (__strcasecmp (step->to_name, "ISO-2022-JP//") == 0)
-- {
-- dir = to_iso2022jp;
-- var = iso2022jp;
-- }
-- else if (__strcasecmp (step->from_name, "ISO-2022-JP-2//") == 0)
-- {
-- dir = from_iso2022jp;
-- var = iso2022jp2;
-- }
-- else if (__strcasecmp (step->to_name, "ISO-2022-JP-2//") == 0)
-- {
-- dir = to_iso2022jp;
-- var = iso2022jp2;
-- }
--
-- result = GCONV_NOCONV;
-- if (dir != illegal_dir)
-- {
-- new_data = (struct iso2022jp_data *)
-- malloc (sizeof (struct iso2022jp_data));
--
-- result = GCONV_NOMEM;
-- if (new_data != NULL)
-- {
-- new_data->dir = dir;
-- new_data->var = var;
-- step->data = new_data;
--
-- if (dir == from_iso2022jp)
-- {
-- step->min_needed_from = MIN_NEEDED_FROM;
-- step->max_needed_from = MAX_NEEDED_FROM;
-- step->min_needed_to = MIN_NEEDED_TO;
-- step->max_needed_to = MAX_NEEDED_TO;
-- }
-- else
-- {
-- step->min_needed_from = MIN_NEEDED_TO;
-- step->max_needed_from = MAX_NEEDED_TO;
-- step->min_needed_to = MIN_NEEDED_FROM;
-- step->max_needed_to = MAX_NEEDED_FROM + 2;
-- }
--
-- /* Yes, this is a stateful encoding. */
-- step->stateful = 1;
--
-- result = GCONV_OK;
-- }
-- }
--
-- return result;
-- }
--
-- The function first checks which conversion is wanted. The module
-- from which this function is taken implements four different
-- conversion and which one is selected can be determined by
-- comparing the names. The comparison should always be done without
-- paying attention to the case.
--
-- Then a data structure is allocated which contains the necessary
-- information about which conversion is selected. The data structure
-- `struct iso2022jp_data' is locally defined since outside the module
-- this data is not used at all. Please note that if all four
-- conversions this modules supports are requested there are four
-- data blocks.
--
-- One interesting thing is the initialization of the `min_' and
-- `max_' elements of the step data object. A single ISO-2022-JP
-- character can consist of one to four bytes. Therefore the
-- `MIN_NEEDED_FROM' and `MAX_NEEDED_FROM' macros are defined this
-- way. The output is always the `INTERNAL' character set (aka UCS4)
-- and therefore each character consists of exactly four bytes. For
-- the conversion from `INTERNAL' to ISO-2022-JP we have to take into
-- account that escape sequences might be necessary to switch the
-- character sets. Therefore the `max_needed_to' element for this
-- direction gets assigned `MAX_NEEDED_FROM + 2'. This takes into
-- account the two bytes needed for the escape sequences to single
-- the switching. The asymmetry in the maximum values for the two
-- directions can be explained easily: when reading ISO-2022-JP text
-- escape sequences can be handled alone. I.e., it is not necessary
-- to process a real character since the effect of the escape
-- sequence can be recorded in the state information. The situation
-- is different for the other direction. Since it is in general not
-- known which character comes next one cannot emit escape sequences
-- to change the state in advance. This means the escape sequences
-- which have to be emitted together with the next character.
-- Therefore one needs more room then only for the character itself.
--
-- The possible return values of the initialization function are:
--
-- `GCONV_OK'
-- The initialization succeeded
--
-- `GCONV_NOCONV'
-- The requested conversion is not supported in the module.
-- This can happen if the `gconv-modules' file has errors.
--
-- `GCONV_NOMEM'
-- Memory required to store additional information could not be
-- allocated.
--
-- The functions called before the module is unloaded is significantly
--easier. It often has nothing at all to do in which case it can be left
--out completely.
--
-- - Data type: void (*gconv_end_fct) (struct gconv_step *)
-- The task of this function is it to free all resources allocated in
-- the initialization function. Therefore only the `data' element of
-- the object pointed to by the argument is of interest. Continuing
-- the example from the initialization function, the finalization
-- function looks like this:
--
-- void
-- gconv_end (struct gconv_step *data)
-- {
-- free (data->data);
-- }
--
-- The most important function is the conversion function itself. It
--can get quite complicated for complex character sets. But since this
--is not of interest here we will only describe a possible skeleton for
--the conversion function.
--
-- - Data type: int (*gconv_fct) (struct gconv_step *, struct
-- gconv_step_data *, const char **, const char *, size_t *, int)
-- The conversion function can be called for two basic reason: to
-- convert text or to reset the state. From the description of the
-- `iconv' function it can be seen why the flushing mode is
-- necessary. What mode is selected is determined by the sixth
-- argument, an integer. If it is nonzero it means that flushing is
-- selected.
--
-- Common to both mode is where the output buffer can be found. The
-- information about this buffer is stored in the conversion step
-- data. A pointer to this is passed as the second argument to this
-- function. The description of the `struct gconv_step_data'
-- structure has more information on this.
--
-- What has to be done for flushing depends on the source character
-- set. If it is not stateful nothing has to be done. Otherwise the
-- function has to emit a byte sequence to bring the state object in
-- the initial state. Once this all happened the other conversion
-- modules in the chain of conversions have to get the same chance.
-- Whether another step follows can be determined from the `is_last'
-- element of the step data structure to which the first parameter
-- points.
--
-- The more interesting mode is when actually text has to be
-- converted. The first step in this case is to convert as much text
-- as possible from the input buffer and store the result in the
-- output buffer. The start of the input buffer is determined by the
-- third argument which is a pointer to a pointer variable
-- referencing the beginning of the buffer. The fourth argument is a
-- pointer to the byte right after the last byte in the buffer.
--
-- The conversion has to be performed according to the current state
-- if the character set is stateful. The state is stored in an
-- object pointed to by the `statep' element of the step data (second
-- argument). Once either the input buffer is empty or the output
-- buffer is full the conversion stops. At this point the pointer
-- variable referenced by the third parameter must point to the byte
-- following the last processed byte. I.e., if all of the input is
-- consumed this pointer and the fourth parameter have the same value.
--
-- What now happens depends on whether this step is the last one or
-- not. If it is the last step the only thing which has to be done
-- is to update the `outbuf' element of the step data structure to
-- point after the last written byte. This gives the caller the
-- information on how much text is available in the output buffer.
-- Beside this the variable pointed to by the fifth parameter, which
-- is of type `size_t', must be incremented by the number of
-- characters (*not bytes*) which were written in the output buffer.
-- Then the function can return.
--
-- In case the step is not the last one the later conversion
-- functions have to get a chance to do their work. Therefore the
-- appropriate conversion function has to be called. The information
-- about the functions is stored in the conversion data structures,
-- passed as the first parameter. This information and the step data
-- are stored in arrays so the next element in both cases can be
-- found by simple pointer arithmetic:
--
-- int
-- gconv (struct gconv_step *step, struct gconv_step_data *data,
-- const char **inbuf, const char *inbufend, size_t *written,
-- int do_flush)
-- {
-- struct gconv_step *next_step = step + 1;
-- struct gconv_step_data *next_data = data + 1;
-- ...
--
-- The `next_step' pointer references the next step information and
-- `next_data' the next data record. The call of the next function
-- therefore will look similar to this:
--
-- next_step->fct (next_step, next_data, &outerr, outbuf, written, 0)
--
-- But this is not yet all. Once the function call returns the
-- conversion function might have some more to do. If the return
-- value of the function is `GCONV_EMPTY_INPUT' this means there is
-- more room in the output buffer. Unless the input buffer is empty
-- the conversion functions start all over again and processes the
-- rest of the input buffer. If the return value is not
-- `GCONV_EMPTY_INPUT' something went wrong and we have to recover
-- from this.
--
-- A requirement for the conversion function is that the input buffer
-- pointer (the third argument) always points to the last character
-- which was put in the converted form in the output buffer. This is
-- trivial true after the conversion performed in the current step.
-- But if the conversion functions deeper down the stream stop
-- prematurely not all characters from the output buffer are consumed
-- and therefore the input buffer pointers must be backed of to the
-- right position.
--
-- This is easy to do if the input and output character sets have a
-- fixed width for all characters. In this situation we can compute
-- how many characters are left in the output buffer and therefore
-- can correct the input buffer pointer appropriate with a similar
-- computation. Things are getting tricky if either character set
-- has character represented with variable length byte sequences and
-- it gets even more complicated if the conversion has to take care
-- of the state. In these cases the conversion has to be performed
-- once again, from the known state before the initial conversion.
-- I.e., if necessary the state of the conversion has to be reset and
-- the conversion loop has to be executed again. The difference now
-- is that it is known how much input must be created and the
-- conversion can stop before converting the first unused character.
-- Once this is done the input buffer pointers must be updated again
-- and the function can return.
--
-- One final thing should be mentioned. If it is necessary for the
-- conversion to know whether it is the first invocation (in case a
-- prolog has to be emitted) the conversion function should just
-- before returning to the caller increment the `invocation_counter'
-- element of the step data structure. See the description of the
-- `struct gconv_step_data' structure above for more information on
-- how this can be used.
--
-- The return value must be one of the following values:
--
-- `GCONV_EMPTY_INPUT'
-- All input was consumed and there is room left in the output
-- buffer.
--
-- `GCONV_OUTPUT_FULL'
-- No more room in the output buffer. In case this is not the
-- last step this value is propagated down from the call of the
-- next conversion function in the chain.
--
-- `GCONV_INCOMPLETE_INPUT'
-- The input buffer is not entirely empty since it contains an
-- incomplete character sequence.
--
-- The following example provides a framework for a conversion
-- function. In case a new conversion has to be written the holes in
-- this implementation have to be filled and that is it.
--
-- int
-- gconv (struct gconv_step *step, struct gconv_step_data *data,
-- const char **inbuf, const char *inbufend, size_t *written,
-- int do_flush)
-- {
-- struct gconv_step *next_step = step + 1;
-- struct gconv_step_data *next_data = data + 1;
-- gconv_fct fct = next_step->fct;
-- int status;
--
-- /* If the function is called with no input this means we have
-- to reset to the initial state. The possibly partly
-- converted input is dropped. */
-- if (do_flush)
-- {
-- status = GCONV_OK;
--
-- /* Possible emit a byte sequence which put the state object
-- into the initial state. */
--
-- /* Call the steps down the chain if there are any but only
-- if we successfully emitted the escape sequence. */
-- if (status == GCONV_OK && ! data->is_last)
-- status = fct (next_step, next_data, NULL, NULL,
-- written, 1);
-- }
-- else
-- {
-- /* We preserve the initial values of the pointer variables. */
-- const char *inptr = *inbuf;
-- char *outbuf = data->outbuf;
-- char *outend = data->outbufend;
-- char *outptr;
--
-- /* This variable is used to count the number of characters
-- we actually converted. */
-- size_t converted = 0;
--
-- do
-- {
-- /* Remember the start value for this round. */
-- inptr = *inbuf;
-- /* The outbuf buffer is empty. */
-- outptr = outbuf;
--
-- /* For stateful encodings the state must be safe here. */
--
-- /* Run the conversion loop. `status' is set
-- appropriately afterwards. */
--
-- /* If this is the last step leave the loop, there is
-- nothing we can do. */
-- if (data->is_last)
-- {
-- /* Store information about how many bytes are
-- available. */
-- data->outbuf = outbuf;
--
-- /* Remember how many characters we converted. */
-- *written += converted;
--
-- break;
-- }
--
-- /* Write out all output which was produced. */
-- if (outbuf > outptr)
-- {
-- const char *outerr = data->outbuf;
-- int result;
--
-- result = fct (next_step, next_data, &outerr,
-- outbuf, written, 0);
--
-- if (result != GCONV_EMPTY_INPUT)
-- {
-- if (outerr != outbuf)
-- {
-- /* Reset the input buffer pointer. We
-- document here the complex case. */
-- size_t nstatus;
--
-- /* Reload the pointers. */
-- *inbuf = inptr;
-- outbuf = outptr;
--
-- /* Possibly reset the state. */
--
-- /* Redo the conversion, but this time
-- the end of the output buffer is at
-- `outerr'. */
-- }
--
-- /* Change the status. */
-- status = result;
-- }
-- else
-- /* All the output is consumed, we can make
-- another run if everything was ok. */
-- if (status == GCONV_FULL_OUTPUT)
-- status = GCONV_OK;
-- }
-- }
-- while (status == GCONV_OK);
--
-- /* We finished one use of this step. */
-- ++data->invocation_counter;
-- }
--
-- return status;
-- }
--
-- This information should be sufficient to write new modules. Anybody
--doing so should also take a look at the available source code in the GNU
--C library sources. It contains many examples of working and optimized
--modules.
--
--
--File: libc.info, Node: Locales, Next: Message Translation, Prev: Character Set Handling, Up: Top
--
--Locales and Internationalization
--********************************
--
-- Different countries and cultures have varying conventions for how to
--communicate. These conventions range from very simple ones, such as the
--format for representing dates and times, to very complex ones, such as
--the language spoken.
--
-- "Internationalization" of software means programming it to be able
--to adapt to the user's favorite conventions. In ISO C,
--internationalization works by means of "locales". Each locale
--specifies a collection of conventions, one convention for each purpose.
--The user chooses a set of conventions by specifying a locale (via
--environment variables).
--
-- All programs inherit the chosen locale as part of their environment.
--Provided the programs are written to obey the choice of locale, they
--will follow the conventions preferred by the user.
--
--* Menu:
--
--* Effects of Locale:: Actions affected by the choice of
-- locale.
--* Choosing Locale:: How the user specifies a locale.
--* Locale Categories:: Different purposes for which you can
-- select a locale.
--* Setting the Locale:: How a program specifies the locale
-- with library functions.
--* Standard Locales:: Locale names available on all systems.
--* Locale Information:: How to access the information for the locale.
--* Formatting Numbers:: A dedicated function to format numbers.
--
--
--File: libc.info, Node: Effects of Locale, Next: Choosing Locale, Up: Locales
--
--What Effects a Locale Has
--=========================
--
-- Each locale specifies conventions for several purposes, including the
--following:
--
-- * What multibyte character sequences are valid, and how they are
-- interpreted (*note Character Set Handling::.).
--
-- * Classification of which characters in the local character set are
-- considered alphabetic, and upper- and lower-case conversion
-- conventions (*note Character Handling::.).
--
-- * The collating sequence for the local language and character set
-- (*note Collation Functions::.).
--
-- * Formatting of numbers and currency amounts (*note General
-- Numeric::.).
--
-- * Formatting of dates and times (*note Formatting Date and Time::.).
--
-- * What language to use for output, including error messages (*note
-- Message Translation::.).
--
-- * What language to use for user answers to yes-or-no questions.
--
-- * What language to use for more complex user input. (The C library
-- doesn't yet help you implement this.)
--
-- Some aspects of adapting to the specified locale are handled
--automatically by the library subroutines. For example, all your program
--needs to do in order to use the collating sequence of the chosen locale
--is to use `strcoll' or `strxfrm' to compare strings.
--
-- Other aspects of locales are beyond the comprehension of the library.
--For example, the library can't automatically translate your program's
--output messages into other languages. The only way you can support
--output in the user's favorite language is to program this more or less
--by hand. The C library provides functions to handle translations for
--multiple languages easily.
--
-- This chapter discusses the mechanism by which you can modify the
--current locale. The effects of the current locale on specific library
--functions are discussed in more detail in the descriptions of those
--functions.
--
--
--File: libc.info, Node: Choosing Locale, Next: Locale Categories, Prev: Effects of Locale, Up: Locales
--
--Choosing a Locale
--=================
--
-- The simplest way for the user to choose a locale is to set the
--environment variable `LANG'. This specifies a single locale to use for
--all purposes. For example, a user could specify a hypothetical locale
--named `espana-castellano' to use the standard conventions of most of
--Spain.
--
-- The set of locales supported depends on the operating system you are
--using, and so do their names. We can't make any promises about what
--locales will exist, except for one standard locale called `C' or
--`POSIX'. Later we will describe how to construct locales XXX.
--
-- A user also has the option of specifying different locales for
--different purposes--in effect, choosing a mixture of multiple locales.
--
-- For example, the user might specify the locale `espana-castellano'
--for most purposes, but specify the locale `usa-english' for currency
--formatting. This might make sense if the user is a Spanish-speaking
--American, working in Spanish, but representing monetary amounts in US
--dollars.
--
-- Note that both locales `espana-castellano' and `usa-english', like
--all locales, would include conventions for all of the purposes to which
--locales apply. However, the user can choose to use each locale for a
--particular subset of those purposes.
--
--
--File: libc.info, Node: Locale Categories, Next: Setting the Locale, Prev: Choosing Locale, Up: Locales
--
--Categories of Activities that Locales Affect
--============================================
--
-- The purposes that locales serve are grouped into "categories", so
--that a user or a program can choose the locale for each category
--independently. Here is a table of categories; each name is both an
--environment variable that a user can set, and a macro name that you can
--use as an argument to `setlocale'.
--
--`LC_COLLATE'
-- This category applies to collation of strings (functions `strcoll'
-- and `strxfrm'); see *Note Collation Functions::.
--
--`LC_CTYPE'
-- This category applies to classification and conversion of
-- characters, and to multibyte and wide characters; see *Note
-- Character Handling::, and *Note Character Set Handling::.
--
--`LC_MONETARY'
-- This category applies to formatting monetary values; see *Note
-- General Numeric::.
--
--`LC_NUMERIC'
-- This category applies to formatting numeric values that are not
-- monetary; see *Note General Numeric::.
--
--`LC_TIME'
-- This category applies to formatting date and time values; see
-- *Note Formatting Date and Time::.
--
--`LC_MESSAGES'
-- This category applies to selecting the language used in the user
-- interface for message translation (*note The Uniforum approach::.;
-- *note Message catalogs a la X/Open::.).
--
--`LC_ALL'
-- This is not an environment variable; it is only a macro that you
-- can use with `setlocale' to set a single locale for all purposes.
-- Setting this environment variable overwrites all selections by the
-- other `LC_*' variables or `LANG'.
--
--`LANG'
-- If this environment variable is defined, its value specifies the
-- locale to use for all purposes except as overridden by the
-- variables above.
--
-- When developing the message translation functions it was felt that
--the functionality provided by the variables above is not sufficient.
--E.g., it should be possible to specify more than one locale name. For
--an example take a Swedish user who better speaks German than English,
--the programs messages by default are written in English. Then it
--should be possible to specify that the first choice for the language is
--Swedish, the second choice is German, and if this also fails English is
--used. This is possible with the variable `LANGUAGE'. For further
--description of this GNU extension see *Note Using gettextized
--software::.
--
-diff -Naur ../glibc-2.1.3/manual/libc.pg glibc-2.1.3/manual/libc.pg
---- ../glibc-2.1.3/manual/libc.pg 2000-01-05 19:19:29.000000000 -0800
-+++ glibc-2.1.3/manual/libc.pg 1969-12-31 16:00:00.000000000 -0800
-@@ -1,274 +0,0 @@
--\entry{gcc}{2}{\code {gcc}}
--\entry{dirent.h}{7}{\code {dirent.h}}
--\entry{fcntl.h}{7}{\code {fcntl.h}}
--\entry{grp.h}{7}{\code {grp.h}}
--\entry{limits.h}{7}{\code {limits.h}}
--\entry{pwd.h}{7}{\code {pwd.h}}
--\entry{signal.h}{7}{\code {signal.h}}
--\entry{sys/stat.h}{7}{\code {sys/stat.h}}
--\entry{sys/times.h}{7}{\code {sys/times.h}}
--\entry{termios.h}{7}{\code {termios.h}}
--\entry{-lbsd-compat}{8}{\code {-lbsd-compat}}
--\entry{bsd-compat}{8}{\code {bsd-compat}}
--\entry{errno.h}{15}{\code {errno.h}}
--\entry{errno.h}{15}{\code {errno.h}}
--\entry{errno.h}{16}{\code {errno.h}}
--\entry{errno.h}{16}{\code {errno.h}}
--\entry{stdlib.h}{32}{\code {stdlib.h}}
--\entry{stdlib.h}{34}{\code {stdlib.h}}
--\entry{stdlib.h}{34}{\code {stdlib.h}}
--\entry{stdlib.h}{35}{\code {stdlib.h}}
--\entry{stdlib.h}{36}{\code {stdlib.h}}
--\entry{malloc.h}{37}{\code {malloc.h}}
--\entry{mcheck.h}{37}{\code {mcheck.h}}
--\entry{malloc.h}{39}{\code {malloc.h}}
--\entry{malloc.h}{41}{\code {malloc.h}}
--\entry{obstack.h}{47}{\code {obstack.h}}
--\entry{stdlib.h}{57}{\code {stdlib.h}}
--\entry{ctype.h}{61}{\code {ctype.h}}
--\entry{ctype.h}{61}{\code {ctype.h}}
--\entry{ctype.h}{63}{\code {ctype.h}}
--\entry{wctype.h}{64}{\code {wctype.h}}
--\entry{wctype.h}{64}{\code {wctype.h}}
--\entry{wctype.h}{64}{\code {wctype.h}}
--\entry{wctype.h}{65}{\code {wctype.h}}
--\entry{wctype.h}{65}{\code {wctype.h}}
--\entry{wctype.h}{65}{\code {wctype.h}}
--\entry{wctype.h}{65}{\code {wctype.h}}
--\entry{wctype.h}{66}{\code {wctype.h}}
--\entry{wctype.h}{66}{\code {wctype.h}}
--\entry{wctype.h}{66}{\code {wctype.h}}
--\entry{wctype.h}{66}{\code {wctype.h}}
--\entry{wctype.h}{66}{\code {wctype.h}}
--\entry{wctype.h}{67}{\code {wctype.h}}
--\entry{wctype.h}{67}{\code {wctype.h}}
--\entry{wctype.h}{68}{\code {wctype.h}}
--\entry{wctype.h}{68}{\code {wctype.h}}
--\entry{wctype.h}{69}{\code {wctype.h}}
--\entry{wctype.h}{69}{\code {wctype.h}}
--\entry{wctype.h}{69}{\code {wctype.h}}
--\entry{string.h}{72}{\code {string.h}}
--\entry{string.h}{73}{\code {string.h}}
--\entry{string.h}{81}{\code {string.h}}
--\entry{string.h}{83}{\code {string.h}}
--\entry{string.h}{86}{\code {string.h}}
--\entry{string.h}{88}{\code {string.h}}
--\entry{argz.h}{93}{\code {argz.h}}
--\entry{envz.h}{95}{\code {envz.h}}
--\entry{wchar.h}{98}{\code {wchar.h}}
--\entry{wchar.h}{99}{\code {wchar.h}}
--\entry{limits.h}{102}{\code {limits.h}}
--\entry{stdlib.h}{102}{\code {stdlib.h}}
--\entry{wchar.h}{102}{\code {wchar.h}}
--\entry{wchar.h}{103}{\code {wchar.h}}
--\entry{wchar.h}{104}{\code {wchar.h}}
--\entry{wchar.h}{105}{\code {wchar.h}}
--\entry{wchar.h}{105}{\code {wchar.h}}
--\entry{wchar.h}{107}{\code {wchar.h}}
--\entry{wchar.h}{108}{\code {wchar.h}}
--\entry{wchar.h}{110}{\code {wchar.h}}
--\entry{wchar.h}{111}{\code {wchar.h}}
--\entry{stdlib.h}{116}{\code {stdlib.h}}
--\entry{iconv.h}{120}{\code {iconv.h}}
--\entry{iconv.h}{121}{\code {iconv.h}}
--\entry{iconv.h}{122}{\code {iconv.h}}
--\entry{gconv.h}{129}{\code {gconv.h}}
--\entry{locale.h}{143}{\code {locale.h}}
--\entry{locale.h}{146}{\code {locale.h}}
--\entry{stdlib.h}{178}{\code {stdlib.h}}
--\entry{stdlib.h}{178}{\code {stdlib.h}}
--\entry{fnmatch.h}{187}{\code {fnmatch.h}}
--\entry{stdio.h}{211}{\code {stdio.h}}
--\entry{stdio.h}{211}{\code {stdio.h}}
--\entry{stdio.h}{212}{\code {stdio.h}}
--\entry{stdio.h}{215}{\code {stdio.h}}
--\entry{stdio.h}{216}{\code {stdio.h}}
--\entry{stdio.h}{221}{\code {stdio.h}}
--\entry{stdio.h}{230}{\code {stdio.h}}
--\entry{stdio.h}{232}{\code {stdio.h}}
--\entry{printf.h}{237}{\code {printf.h}}
--\entry{printf.h}{238}{\code {printf.h}}
--\entry{stdio.h}{249}{\code {stdio.h}}
--\entry{stdio.h}{250}{\code {stdio.h}}
--\entry{stdio.h}{252}{\code {stdio.h}}
--\entry{stdio.h}{255}{\code {stdio.h}}
--\entry{stdio.h}{257}{\code {stdio.h}}
--\entry{stdio.h}{257}{\code {stdio.h}}
--\entry{stdio.h}{259}{\code {stdio.h}}
--\entry{stdio.h}{262}{\code {stdio.h}}
--\entry{unistd.h}{271}{\code {unistd.h}}
--\entry{fcntl.h}{271}{\code {fcntl.h}}
--\entry{unistd.h}{275}{\code {unistd.h}}
--\entry{stdio.h}{282}{\code {stdio.h}}
--\entry{unistd.h}{283}{\code {unistd.h}}
--\entry{sys/types.h}{289}{\code {sys/types.h}}
--\entry{fcntl.h}{305}{\code {fcntl.h}}
--\entry{unistd.h}{306}{\code {unistd.h}}
--\entry{fcntl.h}{306}{\code {fcntl.h}}
--\entry{fcntl.h}{307}{\code {fcntl.h}}
--\entry{fcntl.h}{309}{\code {fcntl.h}}
--\entry{fcntl.h}{314}{\code {fcntl.h}}
--\entry{fcntl.h}{317}{\code {fcntl.h}}
--\entry{cd}{319}{\code {cd}}
--\entry{unistd.h}{319}{\code {unistd.h}}
--\entry{dirent.h}{321}{\code {dirent.h}}
--\entry{dirent.h}{322}{\code {dirent.h}}
--\entry{dirent.h}{322}{\code {dirent.h}}
--\entry{dirent.h}{324}{\code {dirent.h}}
--\entry{unistd.h}{331}{\code {unistd.h}}
--\entry{unistd.h}{332}{\code {unistd.h}}
--\entry{unistd.h}{333}{\code {unistd.h}}
--\entry{unistd.h}{334}{\code {unistd.h}}
--\entry{stdio.h}{334}{\code {stdio.h}}
--\entry{mkdir}{335}{\code {mkdir}}
--\entry{sys/stat.h}{336}{\code {sys/stat.h}}
--\entry{ls}{336}{\code {ls}}
--\entry{sys/stat.h}{336}{\code {sys/stat.h}}
--\entry{sys/stat.h}{342}{\code {sys/stat.h}}
--\entry{chown}{343}{\code {chown}}
--\entry{chgrp}{343}{\code {chgrp}}
--\entry{unistd.h}{343}{\code {unistd.h}}
--\entry{sys/stat.h}{344}{\code {sys/stat.h}}
--\entry{umask}{346}{\code {umask}}
--\entry{sys/stat.h}{346}{\code {sys/stat.h}}
--\entry{unistd.h}{348}{\code {unistd.h}}
--\entry{unistd.h}{349}{\code {unistd.h}}
--\entry{time.h}{349}{\code {time.h}}
--\entry{utime.h}{349}{\code {utime.h}}
--\entry{sys/time.h}{350}{\code {sys/time.h}}
--\entry{sys/stat.h}{352}{\code {sys/stat.h}}
--\entry{stdio.h}{353}{\code {stdio.h}}
--\entry{unistd.h}{357}{\code {unistd.h}}
--\entry{sys/stat.h}{360}{\code {sys/stat.h}}
--\entry{sys/socket.h}{364}{\code {sys/socket.h}}
--\entry{sys/socket.h}{366}{\code {sys/socket.h}}
--\entry{sys/socket.h}{367}{\code {sys/socket.h}}
--\entry{sys/socket.h}{367}{\code {sys/socket.h}}
--\entry{sys/socket.h}{369}{\code {sys/socket.h}}
--\entry{sys/un.h}{370}{\code {sys/un.h}}
--\entry{sys/socket.h}{371}{\code {sys/socket.h}}
--\entry{netinet/in.h}{372}{\code {netinet/in.h}}
--\entry{netinet/in.h}{375}{\code {netinet/in.h}}
--\entry{arpa/inet.h}{376}{\code {arpa/inet.h}}
--\entry{/etc/hosts}{377}{\code {/etc/hosts}}
--\entry{netdb.h}{377}{\code {netdb.h}}
--\entry{netinet/in.h}{381}{\code {netinet/in.h}}
--\entry{/etc/services}{381}{\code {/etc/services}}
--\entry{netdb.h}{381}{\code {netdb.h}}
--\entry{netinet/in.h}{383}{\code {netinet/in.h}}
--\entry{/etc/protocols}{383}{\code {/etc/protocols}}
--\entry{netdb.h}{384}{\code {netdb.h}}
--\entry{sys/socket.h}{386}{\code {sys/socket.h}}
--\entry{sys/socket.h}{387}{\code {sys/socket.h}}
--\entry{sys/socket.h}{387}{\code {sys/socket.h}}
--\entry{sys/socket.h}{392}{\code {sys/socket.h}}
--\entry{sys/socket.h}{393}{\code {sys/socket.h}}
--\entry{sys/socket.h}{394}{\code {sys/socket.h}}
--\entry{sys/socket.h}{401}{\code {sys/socket.h}}
--\entry{sys/socket.h}{406}{\code {sys/socket.h}}
--\entry{sys/socket.h}{407}{\code {sys/socket.h}}
--\entry{/etc/networks}{408}{\code {/etc/networks}}
--\entry{netdb.h}{408}{\code {netdb.h}}
--\entry{unistd.h}{411}{\code {unistd.h}}
--\entry{termios.h}{413}{\code {termios.h}}
--\entry{stdlib.h}{434}{\code {stdlib.h}}
--\entry{math.h}{439}{\code {math.h}}
--\entry{complex.h}{439}{\code {complex.h}}
--\entry{stdlib.h}{451}{\code {stdlib.h}}
--\entry{stdlib.h}{452}{\code {stdlib.h}}
--\entry{math.h}{459}{\code {math.h}}
--\entry{math.h}{468}{\code {math.h}}
--\entry{stdlib.h}{468}{\code {stdlib.h}}
--\entry{math.h}{469}{\code {math.h}}
--\entry{math.h}{471}{\code {math.h}}
--\entry{complex.h}{476}{\code {complex.h}}
--\entry{complex.h}{477}{\code {complex.h}}
--\entry{stdlib.h}{478}{\code {stdlib.h}}
--\entry{stdlib.h}{480}{\code {stdlib.h}}
--\entry{stdlib.h}{482}{\code {stdlib.h}}
--\entry{time.h}{487}{\code {time.h}}
--\entry{sys/times.h}{488}{\code {sys/times.h}}
--\entry{time.h}{489}{\code {time.h}}
--\entry{sys/time.h}{490}{\code {sys/time.h}}
--\entry{time.h}{495}{\code {time.h}}
--\entry{time.h}{507}{\code {time.h}}
--\entry{/etc/localtime}{508}{\code {/etc/localtime}}
--\entry{localtime}{508}{\code {localtime}}
--\entry{/share/lib/zoneinfo}{509}{\code {/share/lib/zoneinfo}}
--\entry{zoneinfo}{509}{\code {zoneinfo}}
--\entry{sys/timex.h}{511}{\code {sys/timex.h}}
--\entry{unistd.h}{514}{\code {unistd.h}}
--\entry{sys/time.h}{514}{\code {sys/time.h}}
--\entry{sys/resource.h}{517}{\code {sys/resource.h}}
--\entry{sys/resource.h}{518}{\code {sys/resource.h}}
--\entry{sys/resource.h}{521}{\code {sys/resource.h}}
--\entry{setjmp.h}{524}{\code {setjmp.h}}
--\entry{setjmp.h}{525}{\code {setjmp.h}}
--\entry{signal.h}{529}{\code {signal.h}}
--\entry{kill}{532}{\code {kill}}
--\entry{string.h}{538}{\code {string.h}}
--\entry{stdio.h}{538}{\code {stdio.h}}
--\entry{signal.h}{538}{\code {signal.h}}
--\entry{signal.h}{540}{\code {signal.h}}
--\entry{signal.h}{543}{\code {signal.h}}
--\entry{signal.h}{556}{\code {signal.h}}
--\entry{signal.h}{557}{\code {signal.h}}
--\entry{signal.h}{561}{\code {signal.h}}
--\entry{signal.h}{562}{\code {signal.h}}
--\entry{signal.h}{565}{\code {signal.h}}
--\entry{signal.h}{572}{\code {signal.h}}
--\entry{unistd.h}{577}{\code {unistd.h}}
--\entry{argp.h}{584}{\code {argp.h}}
--\entry{stdlib.h}{610}{\code {stdlib.h}}
--\entry{stdlib.h}{614}{\code {stdlib.h}}
--\entry{stdlib.h}{616}{\code {stdlib.h}}
--\entry{unistd.h}{616}{\code {unistd.h}}
--\entry{sh}{619}{\code {sh}}
--\entry{stdlib.h}{619}{\code {stdlib.h}}
--\entry{sys/types.h}{620}{\code {sys/types.h}}
--\entry{unistd.h}{620}{\code {unistd.h}}
--\entry{unistd.h}{621}{\code {unistd.h}}
--\entry{unistd.h}{622}{\code {unistd.h}}
--\entry{sys/wait.h}{624}{\code {sys/wait.h}}
--\entry{sys/wait.h}{627}{\code {sys/wait.h}}
--\entry{sys/wait.h}{627}{\code {sys/wait.h}}
--\entry{stdio.h}{646}{\code {stdio.h}}
--\entry{unistd.h}{646}{\code {unistd.h}}
--\entry{sys/types.h}{646}{\code {sys/types.h}}
--\entry{-lbsd-compat}{647}{\code {-lbsd-compat}}
--\entry{bsd-compat}{647}{\code {bsd-compat}}
--\entry{unistd.h}{648}{\code {unistd.h}}
--\entry{sys/types.h}{648}{\code {sys/types.h}}
--\entry{unistd.h}{663}{\code {unistd.h}}
--\entry{sys/types.h}{663}{\code {sys/types.h}}
--\entry{unistd.h}{664}{\code {unistd.h}}
--\entry{sys/types.h}{664}{\code {sys/types.h}}
--\entry{unistd.h}{665}{\code {unistd.h}}
--\entry{sys/types.h}{665}{\code {sys/types.h}}
--\entry{grp.h}{666}{\code {grp.h}}
--\entry{stdio.h}{670}{\code {stdio.h}}
--\entry{unistd.h}{670}{\code {unistd.h}}
--\entry{utmp.h}{671}{\code {utmp.h}}
--\entry{utmpx.h}{676}{\code {utmpx.h}}
--\entry{utmp.h}{678}{\code {utmp.h}}
--\entry{/etc/passwd}{678}{\code {/etc/passwd}}
--\entry{pwd.h}{679}{\code {pwd.h}}
--\entry{/etc/group}{681}{\code {/etc/group}}
--\entry{grp.h}{682}{\code {grp.h}}
--\entry{hostname}{689}{\code {hostname}}
--\entry{hostid}{689}{\code {hostid}}
--\entry{unistd.h}{689}{\code {unistd.h}}
--\entry{sys/param.h}{689}{\code {sys/param.h}}
--\entry{sys/utsname.h}{690}{\code {sys/utsname.h}}
--\entry{limits.h}{697}{\code {limits.h}}
--\entry{unistd.h}{698}{\code {unistd.h}}
--\entry{limits.h}{709}{\code {limits.h}}
--\entry{unistd.h}{710}{\code {unistd.h}}
--\entry{unistd.h}{711}{\code {unistd.h}}
--\entry{assert.h}{743}{\code {assert.h}}
--\entry{stdarg.h}{746}{\code {stdarg.h}}
--\entry{stdarg.h}{748}{\code {stdarg.h}}
--\entry{varargs.h}{750}{\code {varargs.h}}
--\entry{stddef.h}{751}{\code {stddef.h}}
--\entry{limits.h}{752}{\code {limits.h}}
--\entry{float.h}{755}{\code {float.h}}
-diff -Naur ../glibc-2.1.3/manual/libc.pgs glibc-2.1.3/manual/libc.pgs
---- ../glibc-2.1.3/manual/libc.pgs 2000-01-05 19:19:03.000000000 -0800
-+++ glibc-2.1.3/manual/libc.pgs 1969-12-31 16:00:00.000000000 -0800
-@@ -1,98 +0,0 @@
--\initial {-}
--\entry {\code {-lbsd-compat}}{8, 647}
--\initial {/}
--\entry {\code {/etc/group}}{681}
--\entry {\code {/etc/hosts}}{377}
--\entry {\code {/etc/localtime}}{508}
--\entry {\code {/etc/networks}}{408}
--\entry {\code {/etc/passwd}}{678}
--\entry {\code {/etc/protocols}}{383}
--\entry {\code {/etc/services}}{381}
--\entry {\code {/share/lib/zoneinfo}}{509}
--\initial {A}
--\entry {\code {argp.h}}{584}
--\entry {\code {argz.h}}{93}
--\entry {\code {arpa/inet.h}}{376}
--\entry {\code {assert.h}}{743}
--\initial {B}
--\entry {\code {bsd-compat}}{8, 647}
--\initial {C}
--\entry {\code {cd}}{319}
--\entry {\code {chgrp}}{343}
--\entry {\code {chown}}{343}
--\entry {\code {complex.h}}{439, 476, 477}
--\entry {\code {ctype.h}}{61, 63}
--\initial {D}
--\entry {\code {dirent.h}}{7, 321, 322, 324}
--\initial {E}
--\entry {\code {envz.h}}{95}
--\entry {\code {errno.h}}{15, 16}
--\initial {F}
--\entry {\code {fcntl.h}}{7, 271, 305, 306, 307, 309, 314, 317}
--\entry {\code {float.h}}{755}
--\entry {\code {fnmatch.h}}{187}
--\initial {G}
--\entry {\code {gcc}}{2}
--\entry {\code {gconv.h}}{129}
--\entry {\code {grp.h}}{7, 666, 682}
--\initial {H}
--\entry {\code {hostid}}{689}
--\entry {\code {hostname}}{689}
--\initial {I}
--\entry {\code {iconv.h}}{120, 121, 122}
--\initial {K}
--\entry {\code {kill}}{532}
--\initial {L}
--\entry {\code {limits.h}}{7, 102, 697, 709, 752}
--\entry {\code {locale.h}}{143, 146}
--\entry {\code {localtime}}{508}
--\entry {\code {ls}}{336}
--\initial {M}
--\entry {\code {malloc.h}}{37, 39, 41}
--\entry {\code {math.h}}{439, 459, 468, 469, 471}
--\entry {\code {mcheck.h}}{37}
--\entry {\code {mkdir}}{335}
--\initial {N}
--\entry {\code {netdb.h}}{377, 381, 384, 408}
--\entry {\code {netinet/in.h}}{372, 375, 381, 383}
--\initial {O}
--\entry {\code {obstack.h}}{47}
--\initial {P}
--\entry {\code {printf.h}}{237, 238}
--\entry {\code {pwd.h}}{7, 679}
--\initial {S}
--\entry {\code {setjmp.h}}{524, 525}
--\entry {\code {sh}}{619}
--\entry {\code {signal.h}}{7, 529, 538, 540, 543, 556, 557, 561, 562, 565, 572}
--\entry {\code {stdarg.h}}{746, 748}
--\entry {\code {stddef.h}}{751}
--\entry {\code {stdio.h}}{211, 212, 215, 216, 221, 230, 232, 249, 250, 252, 255, 257, 259, 262, 282, 334, 353, 538, 646, 670}
--\entry {\code {stdlib.h}}{32, 34, 35, 36, 57, 102, 116, 178, 434, 451, 452, 468, 478, 480, 482, 610, 614, 616, 619}
--\entry {\code {string.h}}{72, 73, 81, 83, 86, 88, 538}
--\entry {\code {sys/param.h}}{689}
--\entry {\code {sys/resource.h}}{517, 518, 521}
--\entry {\code {sys/socket.h}}{364, 366, 367, 369, 371, 386, 387, 392, 393, 394, 401, 406, 407}
--\entry {\code {sys/stat.h}}{7, 336, 342, 344, 346, 352, 360}
--\entry {\code {sys/time.h}}{350, 490, 514}
--\entry {\code {sys/times.h}}{7, 488}
--\entry {\code {sys/timex.h}}{511}
--\entry {\code {sys/types.h}}{289, 620, 646, 648, 663, 664, 665}
--\entry {\code {sys/un.h}}{370}
--\entry {\code {sys/utsname.h}}{690}
--\entry {\code {sys/wait.h}}{624, 627}
--\initial {T}
--\entry {\code {termios.h}}{7, 413}
--\entry {\code {time.h}}{349, 487, 489, 495, 507}
--\initial {U}
--\entry {\code {umask}}{346}
--\entry {\code {unistd.h}}{271, 275, 283, 306, 319, 331, 332, 333, 334, 343, 348, 349, 357, 411, 514, 577, 616, 620, 621, 622, 646, 648, 663, 664, 665, 670, 689, 698, 710, 711}
--\entry {\code {utime.h}}{349}
--\entry {\code {utmp.h}}{671, 678}
--\entry {\code {utmpx.h}}{676}
--\initial {V}
--\entry {\code {varargs.h}}{750}
--\initial {W}
--\entry {\code {wchar.h}}{98, 99, 102, 103, 104, 105, 107, 108, 110, 111}
--\entry {\code {wctype.h}}{64, 65, 66, 67, 68, 69}
--\initial {Z}
--\entry {\code {zoneinfo}}{509}
-diff -Naur ../glibc-2.1.3/manual/libc.tp glibc-2.1.3/manual/libc.tp
---- ../glibc-2.1.3/manual/libc.tp 2000-01-05 19:19:29.000000000 -0800
-+++ glibc-2.1.3/manual/libc.tp 1969-12-31 16:00:00.000000000 -0800
-@@ -1,120 +0,0 @@
--\entry{enum mcheck{\_}status}{38}{\code {enum mcheck_status}}
--\entry{struct mallinfo}{41}{\code {struct mallinfo}}
--\entry{struct obstack}{47}{\code {struct obstack}}
--\entry{wctype{\_}t}{64}{\code {wctype_t}}
--\entry{wctrans{\_}t}{68}{\code {wctrans_t}}
--\entry{wchar{\_}t}{97}{\code {wchar_t}}
--\entry{wint{\_}t}{98}{\code {wint_t}}
--\entry{mbstate{\_}t}{102}{\code {mbstate_t}}
--\entry{iconv{\_}t}{119}{\code {iconv_t}}
--\entry{struct gconv{\_}step}{129}{\code {struct gconv_step}}
--\entry{struct gconv{\_}step{\_}data}{130}{\code {struct gconv_step_data}}
--\entry{struct lconv}{146}{\code {struct lconv}}
--\entry{comparison{\_}fn{\_}t}{177}{\code {comparison_fn_t}}
--\entry{struct ENTRY}{183}{\code {struct ENTRY}}
--\entry{VISIT}{185}{\code {VISIT}}
--\entry{glob{\_}t}{188}{\code {glob_t}}
--\entry{regex{\_}t}{193}{\code {regex_t}}
--\entry{regmatch{\_}t}{196}{\code {regmatch_t}}
--\entry{regoff{\_}t}{196}{\code {regoff_t}}
--\entry{wordexp{\_}t}{199}{\code {wordexp_t}}
--\entry{FILE}{211}{\code {FILE}}
--\entry{struct printf{\_}info}{238}{\code {struct printf_info}}
--\entry{printf{\_}function}{239}{\code {printf_function}}
--\entry{printf{\_}arginfo{\_}function}{240}{\code {printf_arginfo_function}}
--\entry{fpos{\_}t}{255}{\code {fpos_t}}
--\entry{fpos64{\_}t}{255}{\code {fpos64_t}}
--\entry{cookie{\_}io{\_}functions{\_}t}{263}{\code {cookie_io_functions_t}}
--\entry{cookie{\_}read{\_}function}{264}{\code {cookie_read_function}}
--\entry{cookie{\_}write{\_}function}{264}{\code {cookie_write_function}}
--\entry{cookie{\_}seek{\_}function}{264}{\code {cookie_seek_function}}
--\entry{cookie{\_}close{\_}function}{264}{\code {cookie_close_function}}
--\entry{ssize{\_}t}{275}{\code {ssize_t}}
--\entry{off{\_}t}{282}{\code {off_t}}
--\entry{off64{\_}t}{282}{\code {off64_t}}
--\entry{struct iovec}{285}{\code {struct iovec}}
--\entry{fd{\_}set}{289}{\code {fd_set}}
--\entry{struct aiocb}{293}{\code {struct aiocb}}
--\entry{struct aiocb64}{295}{\code {struct aiocb64}}
--\entry{struct aioinit}{304}{\code {struct aioinit}}
--\entry{struct flock}{314}{\code {struct flock}}
--\entry{struct dirent}{321}{\code {struct dirent}}
--\entry{DIR}{322}{\code {DIR}}
--\entry{{\_}{\_}ftw{\_}func{\_}t}{327}{\code {__ftw_func_t}}
--\entry{{\_}{\_}ftw64{\_}func{\_}t}{328}{\code {__ftw64_func_t}}
--\entry{{\_}{\_}nftw{\_}func{\_}t}{328}{\code {__nftw_func_t}}
--\entry{{\_}{\_}nftw64{\_}func{\_}t}{328}{\code {__nftw64_func_t}}
--\entry{struct FTW}{328}{\code {struct FTW}}
--\entry{struct stat}{336}{\code {struct stat}}
--\entry{struct stat64}{338}{\code {struct stat64}}
--\entry{mode{\_}t}{339}{\code {mode_t}}
--\entry{ino{\_}t}{339}{\code {ino_t}}
--\entry{ino64{\_}t}{339}{\code {ino64_t}}
--\entry{dev{\_}t}{339}{\code {dev_t}}
--\entry{nlink{\_}t}{340}{\code {nlink_t}}
--\entry{blkcnt{\_}t}{340}{\code {blkcnt_t}}
--\entry{blkcnt64{\_}t}{340}{\code {blkcnt64_t}}
--\entry{struct utimbuf}{350}{\code {struct utimbuf}}
--\entry{struct sockaddr}{366}{\code {struct sockaddr}}
--\entry{struct if{\_}nameindex}{368}{\code {struct if_nameindex}}
--\entry{struct sockaddr{\_}un}{370}{\code {struct sockaddr_un}}
--\entry{struct sockaddr{\_}in}{372}{\code {struct sockaddr_in}}
--\entry{struct sockaddr{\_}in6}{372}{\code {struct sockaddr_in6}}
--\entry{struct in{\_}addr}{375}{\code {struct in_addr}}
--\entry{struct in6{\_}addr}{375}{\code {struct in6_addr}}
--\entry{struct hostent}{377}{\code {struct hostent}}
--\entry{struct servent}{381}{\code {struct servent}}
--\entry{struct protoent}{384}{\code {struct protoent}}
--\entry{struct linger}{408}{\code {struct linger}}
--\entry{struct netent}{408}{\code {struct netent}}
--\entry{struct termios}{413}{\code {struct termios}}
--\entry{tcflag{\_}t}{414}{\code {tcflag_t}}
--\entry{cc{\_}t}{414}{\code {cc_t}}
--\entry{speed{\_}t}{424}{\code {speed_t}}
--\entry{div{\_}t}{478}{\code {div_t}}
--\entry{ldiv{\_}t}{478}{\code {ldiv_t}}
--\entry{lldiv{\_}t}{479}{\code {lldiv_t}}
--\entry{imaxdiv{\_}t}{479}{\code {imaxdiv_t}}
--\entry{clock{\_}t}{488}{\code {clock_t}}
--\entry{struct tms}{488}{\code {struct tms}}
--\entry{time{\_}t}{489}{\code {time_t}}
--\entry{struct timeval}{490}{\code {struct timeval}}
--\entry{struct timezone}{490}{\code {struct timezone}}
--\entry{struct tm}{492}{\code {struct tm}}
--\entry{struct ntptimeval}{511}{\code {struct ntptimeval}}
--\entry{struct ntptimeval}{511}{\code {struct ntptimeval}}
--\entry{struct timex}{511}{\code {struct timex}}
--\entry{struct timex}{511}{\code {struct timex}}
--\entry{struct itimerval}{514}{\code {struct itimerval}}
--\entry{struct rusage}{517}{\code {struct rusage}}
--\entry{struct rlimit}{519}{\code {struct rlimit}}
--\entry{struct rlimit64}{520}{\code {struct rlimit64}}
--\entry{jmp{\_}buf}{524}{\code {jmp_buf}}
--\entry{sigjmp{\_}buf}{525}{\code {sigjmp_buf}}
--\entry{sighandler{\_}t}{538}{\code {sighandler_t}}
--\entry{struct sigaction}{541}{\code {struct sigaction}}
--\entry{sig{\_}atomic{\_}t}{554}{\code {sig_atomic_t}}
--\entry{sigset{\_}t}{561}{\code {sigset_t}}
--\entry{struct sigaltstack}{570}{\code {struct sigaltstack}}
--\entry{struct sigstack}{571}{\code {struct sigstack}}
--\entry{struct sigvec}{572}{\code {struct sigvec}}
--\entry{struct option}{580}{\code {struct option}}
--\entry{struct argp}{585}{\code {struct argp}}
--\entry{struct argp{\_}option}{586}{\code {struct argp_option}}
--\entry{struct argp{\_}state}{592}{\code {struct argp_state}}
--\entry{struct argp{\_}child}{594}{\code {struct argp_child}}
--\entry{pid{\_}t}{620}{\code {pid_t}}
--\entry{union wait}{628}{\code {union wait}}
--\entry{uid{\_}t}{663}{\code {uid_t}}
--\entry{gid{\_}t}{663}{\code {gid_t}}
--\entry{struct exit{\_}status}{671}{\code {struct exit_status}}
--\entry{struct utmp}{671}{\code {struct utmp}}
--\entry{struct utmpx}{676}{\code {struct utmpx}}
--\entry{struct passwd}{679}{\code {struct passwd}}
--\entry{struct group}{682}{\code {struct group}}
--\entry{struct utsname}{690}{\code {struct utsname}}
--\entry{struct fstab}{691}{\code {struct fstab}}
--\entry{struct mntent}{693}{\code {struct mntent}}
--\entry{va{\_}list}{748}{\code {va_list}}
--\entry{ptrdiff{\_}t}{751}{\code {ptrdiff_t}}
--\entry{size{\_}t}{751}{\code {size_t}}
-diff -Naur ../glibc-2.1.3/manual/libc.tps glibc-2.1.3/manual/libc.tps
---- ../glibc-2.1.3/manual/libc.tps 2000-01-05 19:19:03.000000000 -0800
-+++ glibc-2.1.3/manual/libc.tps 1969-12-31 16:00:00.000000000 -0800
-@@ -1,138 +0,0 @@
--\initial {{\_}}
--\entry {\code {__ftw_func_t}}{327}
--\entry {\code {__ftw64_func_t}}{328}
--\entry {\code {__nftw_func_t}}{328}
--\entry {\code {__nftw64_func_t}}{328}
--\initial {B}
--\entry {\code {blkcnt_t}}{340}
--\entry {\code {blkcnt64_t}}{340}
--\initial {C}
--\entry {\code {cc_t}}{414}
--\entry {\code {clock_t}}{488}
--\entry {\code {comparison_fn_t}}{177}
--\entry {\code {cookie_close_function}}{264}
--\entry {\code {cookie_io_functions_t}}{263}
--\entry {\code {cookie_read_function}}{264}
--\entry {\code {cookie_seek_function}}{264}
--\entry {\code {cookie_write_function}}{264}
--\initial {D}
--\entry {\code {dev_t}}{339}
--\entry {\code {DIR}}{322}
--\entry {\code {div_t}}{478}
--\initial {E}
--\entry {\code {enum mcheck_status}}{38}
--\initial {F}
--\entry {\code {fd_set}}{289}
--\entry {\code {FILE}}{211}
--\entry {\code {fpos_t}}{255}
--\entry {\code {fpos64_t}}{255}
--\initial {G}
--\entry {\code {gid_t}}{663}
--\entry {\code {glob_t}}{188}
--\initial {I}
--\entry {\code {iconv_t}}{119}
--\entry {\code {imaxdiv_t}}{479}
--\entry {\code {ino_t}}{339}
--\entry {\code {ino64_t}}{339}
--\initial {J}
--\entry {\code {jmp_buf}}{524}
--\initial {L}
--\entry {\code {ldiv_t}}{478}
--\entry {\code {lldiv_t}}{479}
--\initial {M}
--\entry {\code {mbstate_t}}{102}
--\entry {\code {mode_t}}{339}
--\initial {N}
--\entry {\code {nlink_t}}{340}
--\initial {O}
--\entry {\code {off_t}}{282}
--\entry {\code {off64_t}}{282}
--\initial {P}
--\entry {\code {pid_t}}{620}
--\entry {\code {printf_arginfo_function}}{240}
--\entry {\code {printf_function}}{239}
--\entry {\code {ptrdiff_t}}{751}
--\initial {R}
--\entry {\code {regex_t}}{193}
--\entry {\code {regmatch_t}}{196}
--\entry {\code {regoff_t}}{196}
--\initial {S}
--\entry {\code {sig_atomic_t}}{554}
--\entry {\code {sighandler_t}}{538}
--\entry {\code {sigjmp_buf}}{525}
--\entry {\code {sigset_t}}{561}
--\entry {\code {size_t}}{751}
--\entry {\code {speed_t}}{424}
--\entry {\code {ssize_t}}{275}
--\entry {\code {struct aiocb}}{293}
--\entry {\code {struct aiocb64}}{295}
--\entry {\code {struct aioinit}}{304}
--\entry {\code {struct argp}}{585}
--\entry {\code {struct argp_child}}{594}
--\entry {\code {struct argp_option}}{586}
--\entry {\code {struct argp_state}}{592}
--\entry {\code {struct dirent}}{321}
--\entry {\code {struct ENTRY}}{183}
--\entry {\code {struct exit_status}}{671}
--\entry {\code {struct flock}}{314}
--\entry {\code {struct fstab}}{691}
--\entry {\code {struct FTW}}{328}
--\entry {\code {struct gconv_step}}{129}
--\entry {\code {struct gconv_step_data}}{130}
--\entry {\code {struct group}}{682}
--\entry {\code {struct hostent}}{377}
--\entry {\code {struct if_nameindex}}{368}
--\entry {\code {struct in_addr}}{375}
--\entry {\code {struct in6_addr}}{375}
--\entry {\code {struct iovec}}{285}
--\entry {\code {struct itimerval}}{514}
--\entry {\code {struct lconv}}{146}
--\entry {\code {struct linger}}{408}
--\entry {\code {struct mallinfo}}{41}
--\entry {\code {struct mntent}}{693}
--\entry {\code {struct netent}}{408}
--\entry {\code {struct ntptimeval}}{511}
--\entry {\code {struct obstack}}{47}
--\entry {\code {struct option}}{580}
--\entry {\code {struct passwd}}{679}
--\entry {\code {struct printf_info}}{238}
--\entry {\code {struct protoent}}{384}
--\entry {\code {struct rlimit}}{519}
--\entry {\code {struct rlimit64}}{520}
--\entry {\code {struct rusage}}{517}
--\entry {\code {struct servent}}{381}
--\entry {\code {struct sigaction}}{541}
--\entry {\code {struct sigaltstack}}{570}
--\entry {\code {struct sigstack}}{571}
--\entry {\code {struct sigvec}}{572}
--\entry {\code {struct sockaddr}}{366}
--\entry {\code {struct sockaddr_in}}{372}
--\entry {\code {struct sockaddr_in6}}{372}
--\entry {\code {struct sockaddr_un}}{370}
--\entry {\code {struct stat}}{336}
--\entry {\code {struct stat64}}{338}
--\entry {\code {struct termios}}{413}
--\entry {\code {struct timeval}}{490}
--\entry {\code {struct timex}}{511}
--\entry {\code {struct timezone}}{490}
--\entry {\code {struct tm}}{492}
--\entry {\code {struct tms}}{488}
--\entry {\code {struct utimbuf}}{350}
--\entry {\code {struct utmp}}{671}
--\entry {\code {struct utmpx}}{676}
--\entry {\code {struct utsname}}{690}
--\initial {T}
--\entry {\code {tcflag_t}}{414}
--\entry {\code {time_t}}{489}
--\initial {U}
--\entry {\code {uid_t}}{663}
--\entry {\code {union wait}}{628}
--\initial {V}
--\entry {\code {va_list}}{748}
--\entry {\code {VISIT}}{185}
--\initial {W}
--\entry {\code {wchar_t}}{97}
--\entry {\code {wctrans_t}}{68}
--\entry {\code {wctype_t}}{64}
--\entry {\code {wint_t}}{98}
--\entry {\code {wordexp_t}}{199}
-diff -Naur ../glibc-2.1.3/manual/libc.vr glibc-2.1.3/manual/libc.vr
---- ../glibc-2.1.3/manual/libc.vr 2000-01-05 19:19:29.000000000 -0800
-+++ glibc-2.1.3/manual/libc.vr 1969-12-31 16:00:00.000000000 -0800
-@@ -1,860 +0,0 @@
--\entry{{\_}POSIX{\_}SOURCE}{7}{\code {_POSIX_SOURCE}}
--\entry{{\_}POSIX{\_}C{\_}SOURCE}{8}{\code {_POSIX_C_SOURCE}}
--\entry{{\_}BSD{\_}SOURCE}{8}{\code {_BSD_SOURCE}}
--\entry{{\_}SVID{\_}SOURCE}{8}{\code {_SVID_SOURCE}}
--\entry{{\_}XOPEN{\_}SOURCE}{8}{\code {_XOPEN_SOURCE}}
--\entry{{\_}XOPEN{\_}SOURCE{\_}EXTENDED}{8}{\code {_XOPEN_SOURCE_EXTENDED}}
--\entry{{\_}LARGEFILE{\_}SOURCE}{9}{\code {_LARGEFILE_SOURCE}}
--\entry{{\_}LARGEFILE64{\_}SOURCE}{9}{\code {_LARGEFILE64_SOURCE}}
--\entry{{\_}FILE{\_}OFFSET{\_}BITS}{9}{\code {_FILE_OFFSET_BITS}}
--\entry{{\_}GNU{\_}SOURCE}{10}{\code {_GNU_SOURCE}}
--\entry{{\_}REENTRANT}{10}{\code {_REENTRANT}}
--\entry{{\_}THREAD{\_}SAFE}{10}{\code {_THREAD_SAFE}}
--\entry{errno}{15}{\code {errno}}
--\entry{EPERM}{16}{\code {EPERM}}
--\entry{ENOENT}{16}{\code {ENOENT}}
--\entry{ESRCH}{16}{\code {ESRCH}}
--\entry{EINTR}{16}{\code {EINTR}}
--\entry{EIO}{16}{\code {EIO}}
--\entry{ENXIO}{17}{\code {ENXIO}}
--\entry{E2BIG}{17}{\code {E2BIG}}
--\entry{ENOEXEC}{17}{\code {ENOEXEC}}
--\entry{EBADF}{17}{\code {EBADF}}
--\entry{ECHILD}{17}{\code {ECHILD}}
--\entry{EDEADLK}{17}{\code {EDEADLK}}
--\entry{ENOMEM}{17}{\code {ENOMEM}}
--\entry{EACCES}{17}{\code {EACCES}}
--\entry{EFAULT}{17}{\code {EFAULT}}
--\entry{ENOTBLK}{17}{\code {ENOTBLK}}
--\entry{EBUSY}{17}{\code {EBUSY}}
--\entry{EEXIST}{18}{\code {EEXIST}}
--\entry{EXDEV}{18}{\code {EXDEV}}
--\entry{ENODEV}{18}{\code {ENODEV}}
--\entry{ENOTDIR}{18}{\code {ENOTDIR}}
--\entry{EISDIR}{18}{\code {EISDIR}}
--\entry{EINVAL}{18}{\code {EINVAL}}
--\entry{EMFILE}{18}{\code {EMFILE}}
--\entry{ENFILE}{18}{\code {ENFILE}}
--\entry{ENOTTY}{18}{\code {ENOTTY}}
--\entry{ETXTBSY}{18}{\code {ETXTBSY}}
--\entry{EFBIG}{19}{\code {EFBIG}}
--\entry{ENOSPC}{19}{\code {ENOSPC}}
--\entry{ESPIPE}{19}{\code {ESPIPE}}
--\entry{EROFS}{19}{\code {EROFS}}
--\entry{EMLINK}{19}{\code {EMLINK}}
--\entry{EPIPE}{19}{\code {EPIPE}}
--\entry{EDOM}{19}{\code {EDOM}}
--\entry{ERANGE}{19}{\code {ERANGE}}
--\entry{EAGAIN}{19}{\code {EAGAIN}}
--\entry{EWOULDBLOCK}{20}{\code {EWOULDBLOCK}}
--\entry{EINPROGRESS}{20}{\code {EINPROGRESS}}
--\entry{EALREADY}{20}{\code {EALREADY}}
--\entry{ENOTSOCK}{20}{\code {ENOTSOCK}}
--\entry{EMSGSIZE}{20}{\code {EMSGSIZE}}
--\entry{EPROTOTYPE}{20}{\code {EPROTOTYPE}}
--\entry{ENOPROTOOPT}{20}{\code {ENOPROTOOPT}}
--\entry{EPROTONOSUPPORT}{20}{\code {EPROTONOSUPPORT}}
--\entry{ESOCKTNOSUPPORT}{20}{\code {ESOCKTNOSUPPORT}}
--\entry{EOPNOTSUPP}{21}{\code {EOPNOTSUPP}}
--\entry{EPFNOSUPPORT}{21}{\code {EPFNOSUPPORT}}
--\entry{EAFNOSUPPORT}{21}{\code {EAFNOSUPPORT}}
--\entry{EADDRINUSE}{21}{\code {EADDRINUSE}}
--\entry{EADDRNOTAVAIL}{21}{\code {EADDRNOTAVAIL}}
--\entry{ENETDOWN}{21}{\code {ENETDOWN}}
--\entry{ENETUNREACH}{21}{\code {ENETUNREACH}}
--\entry{ENETRESET}{21}{\code {ENETRESET}}
--\entry{ECONNABORTED}{21}{\code {ECONNABORTED}}
--\entry{ECONNRESET}{21}{\code {ECONNRESET}}
--\entry{ENOBUFS}{21}{\code {ENOBUFS}}
--\entry{EISCONN}{21}{\code {EISCONN}}
--\entry{ENOTCONN}{22}{\code {ENOTCONN}}
--\entry{EDESTADDRREQ}{22}{\code {EDESTADDRREQ}}
--\entry{ESHUTDOWN}{22}{\code {ESHUTDOWN}}
--\entry{ETOOMANYREFS}{22}{\code {ETOOMANYREFS}}
--\entry{ETIMEDOUT}{22}{\code {ETIMEDOUT}}
--\entry{ECONNREFUSED}{22}{\code {ECONNREFUSED}}
--\entry{ELOOP}{22}{\code {ELOOP}}
--\entry{ENAMETOOLONG}{22}{\code {ENAMETOOLONG}}
--\entry{EHOSTDOWN}{22}{\code {EHOSTDOWN}}
--\entry{EHOSTUNREACH}{22}{\code {EHOSTUNREACH}}
--\entry{ENOTEMPTY}{22}{\code {ENOTEMPTY}}
--\entry{EPROCLIM}{23}{\code {EPROCLIM}}
--\entry{EUSERS}{23}{\code {EUSERS}}
--\entry{EDQUOT}{23}{\code {EDQUOT}}
--\entry{ESTALE}{23}{\code {ESTALE}}
--\entry{EREMOTE}{23}{\code {EREMOTE}}
--\entry{EBADRPC}{23}{\code {EBADRPC}}
--\entry{ERPCMISMATCH}{23}{\code {ERPCMISMATCH}}
--\entry{EPROGUNAVAIL}{23}{\code {EPROGUNAVAIL}}
--\entry{EPROGMISMATCH}{23}{\code {EPROGMISMATCH}}
--\entry{EPROCUNAVAIL}{23}{\code {EPROCUNAVAIL}}
--\entry{ENOLCK}{23}{\code {ENOLCK}}
--\entry{EFTYPE}{23}{\code {EFTYPE}}
--\entry{EAUTH}{24}{\code {EAUTH}}
--\entry{ENEEDAUTH}{24}{\code {ENEEDAUTH}}
--\entry{ENOSYS}{24}{\code {ENOSYS}}
--\entry{ENOTSUP}{24}{\code {ENOTSUP}}
--\entry{EILSEQ}{24}{\code {EILSEQ}}
--\entry{EBACKGROUND}{24}{\code {EBACKGROUND}}
--\entry{EDIED}{24}{\code {EDIED}}
--\entry{ED}{24}{\code {ED}}
--\entry{EGREGIOUS}{24}{\code {EGREGIOUS}}
--\entry{EIEIO}{24}{\code {EIEIO}}
--\entry{EGRATUITOUS}{25}{\code {EGRATUITOUS}}
--\entry{EBADMSG}{25}{\code {EBADMSG}}
--\entry{EIDRM}{25}{\code {EIDRM}}
--\entry{EMULTIHOP}{25}{\code {EMULTIHOP}}
--\entry{ENODATA}{25}{\code {ENODATA}}
--\entry{ENOLINK}{25}{\code {ENOLINK}}
--\entry{ENOMSG}{25}{\code {ENOMSG}}
--\entry{ENOSR}{25}{\code {ENOSR}}
--\entry{ENOSTR}{25}{\code {ENOSTR}}
--\entry{EOVERFLOW}{25}{\code {EOVERFLOW}}
--\entry{EPROTO}{25}{\code {EPROTO}}
--\entry{ETIME}{25}{\code {ETIME}}
--\entry{ERESTART}{25}{\code {ERESTART}}
--\entry{ECHRNG}{25}{\code {ECHRNG}}
--\entry{EL2NSYNC}{25}{\code {EL2NSYNC}}
--\entry{EL3HLT}{25}{\code {EL3HLT}}
--\entry{EL3RST}{25}{\code {EL3RST}}
--\entry{ELNRNG}{25}{\code {ELNRNG}}
--\entry{EUNATCH}{25}{\code {EUNATCH}}
--\entry{ENOCSI}{25}{\code {ENOCSI}}
--\entry{EL2HLT}{25}{\code {EL2HLT}}
--\entry{EBADE}{25}{\code {EBADE}}
--\entry{EBADR}{25}{\code {EBADR}}
--\entry{EXFULL}{26}{\code {EXFULL}}
--\entry{ENOANO}{26}{\code {ENOANO}}
--\entry{EBADRQC}{26}{\code {EBADRQC}}
--\entry{EBADSLT}{26}{\code {EBADSLT}}
--\entry{EDEADLOCK}{26}{\code {EDEADLOCK}}
--\entry{EBFONT}{26}{\code {EBFONT}}
--\entry{ENONET}{26}{\code {ENONET}}
--\entry{ENOPKG}{26}{\code {ENOPKG}}
--\entry{EADV}{26}{\code {EADV}}
--\entry{ESRMNT}{26}{\code {ESRMNT}}
--\entry{ECOMM}{26}{\code {ECOMM}}
--\entry{EDOTDOT}{26}{\code {EDOTDOT}}
--\entry{ENOTUNIQ}{26}{\code {ENOTUNIQ}}
--\entry{EBADFD}{26}{\code {EBADFD}}
--\entry{EREMCHG}{26}{\code {EREMCHG}}
--\entry{ELIBACC}{26}{\code {ELIBACC}}
--\entry{ELIBBAD}{26}{\code {ELIBBAD}}
--\entry{ELIBSCN}{26}{\code {ELIBSCN}}
--\entry{ELIBMAX}{26}{\code {ELIBMAX}}
--\entry{ELIBEXEC}{26}{\code {ELIBEXEC}}
--\entry{ESTRPIPE}{26}{\code {ESTRPIPE}}
--\entry{EUCLEAN}{26}{\code {EUCLEAN}}
--\entry{ENOTNAM}{26}{\code {ENOTNAM}}
--\entry{ENAVAIL}{26}{\code {ENAVAIL}}
--\entry{EISNAM}{26}{\code {EISNAM}}
--\entry{EREMOTEIO}{26}{\code {EREMOTEIO}}
--\entry{ENOMEDIUM}{26}{\code {ENOMEDIUM}}
--\entry{EMEDIUMTYPE}{26}{\code {EMEDIUMTYPE}}
--\entry{program{\_}invocation{\_}name}{28}{\code {program_invocation_name}}
--\entry{program{\_}invocation{\_}short{\_}name}{28}{\code {program_invocation_short_name}}
--\entry{{\_}{\_}malloc{\_}hook}{39}{\code {__malloc_hook}}
--\entry{{\_}{\_}realloc{\_}hook}{39}{\code {__realloc_hook}}
--\entry{{\_}{\_}free{\_}hook}{39}{\code {__free_hook}}
--\entry{{\_}{\_}memalign{\_}hook}{39}{\code {__memalign_hook}}
--\entry{obstack{\_}alloc{\_}failed{\_}handler}{48}{\code {obstack_alloc_failed_handler}}
--\entry{WCHAR{\_}MIN}{98}{\code {WCHAR_MIN}}
--\entry{WCHAR{\_}MAX}{98}{\code {WCHAR_MAX}}
--\entry{WEOF}{98}{\code {WEOF}}
--\entry{MB{\_}LEN{\_}MAX}{102}{\code {MB_LEN_MAX}}
--\entry{MB{\_}CUR{\_}MAX}{102}{\code {MB_CUR_MAX}}
--\entry{(*gconv{\_}init{\_}fct)}{132}{\code {(*gconv_init_fct)}}
--\entry{(*gconv{\_}end{\_}fct)}{135}{\code {(*gconv_end_fct)}}
--\entry{(*gconv{\_}fct)}{135}{\code {(*gconv_fct)}}
--\entry{LC{\_}COLLATE}{142}{\code {LC_COLLATE}}
--\entry{LC{\_}CTYPE}{142}{\code {LC_CTYPE}}
--\entry{LC{\_}MONETARY}{142}{\code {LC_MONETARY}}
--\entry{LC{\_}NUMERIC}{142}{\code {LC_NUMERIC}}
--\entry{LC{\_}TIME}{142}{\code {LC_TIME}}
--\entry{LC{\_}MESSAGES}{142}{\code {LC_MESSAGES}}
--\entry{LC{\_}ALL}{143}{\code {LC_ALL}}
--\entry{LANG}{143}{\code {LANG}}
--\entry{LANGUAGE}{143}{\code {LANGUAGE}}
--\entry{ABDAY{\_}1}{150}{\code {ABDAY_1}}
--\entry{ABDAY{\_}2}{150}{\code {ABDAY_2}}
--\entry{ABDAY{\_}3}{150}{\code {ABDAY_3}}
--\entry{ABDAY{\_}4}{150}{\code {ABDAY_4}}
--\entry{ABDAY{\_}5}{150}{\code {ABDAY_5}}
--\entry{ABDAY{\_}6}{150}{\code {ABDAY_6}}
--\entry{ABDAY{\_}7}{150}{\code {ABDAY_7}}
--\entry{DAY{\_}1}{150}{\code {DAY_1}}
--\entry{DAY{\_}2}{150}{\code {DAY_2}}
--\entry{DAY{\_}3}{150}{\code {DAY_3}}
--\entry{DAY{\_}4}{150}{\code {DAY_4}}
--\entry{DAY{\_}5}{150}{\code {DAY_5}}
--\entry{DAY{\_}6}{150}{\code {DAY_6}}
--\entry{DAY{\_}7}{150}{\code {DAY_7}}
--\entry{ABMON{\_}1}{150}{\code {ABMON_1}}
--\entry{ABMON{\_}2}{150}{\code {ABMON_2}}
--\entry{ABMON{\_}3}{150}{\code {ABMON_3}}
--\entry{ABMON{\_}4}{150}{\code {ABMON_4}}
--\entry{ABMON{\_}5}{150}{\code {ABMON_5}}
--\entry{ABMON{\_}6}{150}{\code {ABMON_6}}
--\entry{ABMON{\_}7}{150}{\code {ABMON_7}}
--\entry{ABMON{\_}8}{150}{\code {ABMON_8}}
--\entry{ABMON{\_}9}{150}{\code {ABMON_9}}
--\entry{ABMON{\_}10}{150}{\code {ABMON_10}}
--\entry{ABMON{\_}11}{150}{\code {ABMON_11}}
--\entry{ABMON{\_}12}{150}{\code {ABMON_12}}
--\entry{MON{\_}1}{150}{\code {MON_1}}
--\entry{MON{\_}2}{151}{\code {MON_2}}
--\entry{MON{\_}3}{151}{\code {MON_3}}
--\entry{MON{\_}4}{151}{\code {MON_4}}
--\entry{MON{\_}5}{151}{\code {MON_5}}
--\entry{MON{\_}6}{151}{\code {MON_6}}
--\entry{MON{\_}7}{151}{\code {MON_7}}
--\entry{MON{\_}8}{151}{\code {MON_8}}
--\entry{MON{\_}9}{151}{\code {MON_9}}
--\entry{MON{\_}10}{151}{\code {MON_10}}
--\entry{MON{\_}11}{151}{\code {MON_11}}
--\entry{MON{\_}12}{151}{\code {MON_12}}
--\entry{AM{\_}STR}{151}{\code {AM_STR}}
--\entry{PM{\_}STR}{151}{\code {PM_STR}}
--\entry{D{\_}T{\_}FMT}{151}{\code {D_T_FMT}}
--\entry{D{\_}FMT}{151}{\code {D_FMT}}
--\entry{T{\_}FMT}{151}{\code {T_FMT}}
--\entry{T{\_}FMT{\_}AMPM}{151}{\code {T_FMT_AMPM}}
--\entry{ERA}{151}{\code {ERA}}
--\entry{ERA{\_}YEAR}{151}{\code {ERA_YEAR}}
--\entry{ERA{\_}D{\_}T{\_}FMT}{152}{\code {ERA_D_T_FMT}}
--\entry{ERA{\_}D{\_}FMT}{152}{\code {ERA_D_FMT}}
--\entry{ERA{\_}T{\_}FMT}{152}{\code {ERA_T_FMT}}
--\entry{ALT{\_}DIGITS}{152}{\code {ALT_DIGITS}}
--\entry{INT{\_}CURR{\_}SYMBOL}{152}{\code {INT_CURR_SYMBOL}}
--\entry{CURRENCY{\_}SYMBOL}{152}{\code {CURRENCY_SYMBOL}}
--\entry{CRNCYSTR}{152}{\code {CRNCYSTR}}
--\entry{MON{\_}DECIMAL{\_}POINT}{152}{\code {MON_DECIMAL_POINT}}
--\entry{MON{\_}THOUSANDS{\_}SEP}{152}{\code {MON_THOUSANDS_SEP}}
--\entry{MON{\_}GROUPING}{152}{\code {MON_GROUPING}}
--\entry{POSITIVE{\_}SIGN}{152}{\code {POSITIVE_SIGN}}
--\entry{NEGATIVE{\_}SIGN}{152}{\code {NEGATIVE_SIGN}}
--\entry{INT{\_}FRAC{\_}DIGITS}{152}{\code {INT_FRAC_DIGITS}}
--\entry{FRAC{\_}DIGITS}{153}{\code {FRAC_DIGITS}}
--\entry{P{\_}CS{\_}PRECEDES}{153}{\code {P_CS_PRECEDES}}
--\entry{P{\_}SEP{\_}BY{\_}SPACE}{153}{\code {P_SEP_BY_SPACE}}
--\entry{N{\_}CS{\_}PRECEDES}{153}{\code {N_CS_PRECEDES}}
--\entry{N{\_}SEP{\_}BY{\_}SPACE}{153}{\code {N_SEP_BY_SPACE}}
--\entry{P{\_}SIGN{\_}POSN}{153}{\code {P_SIGN_POSN}}
--\entry{N{\_}SIGN{\_}POSN}{153}{\code {N_SIGN_POSN}}
--\entry{DECIMAL{\_}POINT}{153}{\code {DECIMAL_POINT}}
--\entry{RADIXCHAR}{153}{\code {RADIXCHAR}}
--\entry{THOUSANDS{\_}SEP}{153}{\code {THOUSANDS_SEP}}
--\entry{THOUSEP}{153}{\code {THOUSEP}}
--\entry{GROUPING}{153}{\code {GROUPING}}
--\entry{YESEXPR}{153}{\code {YESEXPR}}
--\entry{NOEXPR}{153}{\code {NOEXPR}}
--\entry{YESSTR}{153}{\code {YESSTR}}
--\entry{NOSTR}{154}{\code {NOSTR}}
--\entry{stdin}{211}{\code {stdin}}
--\entry{stdout}{211}{\code {stdout}}
--\entry{stderr}{211}{\code {stderr}}
--\entry{FOPEN{\_}MAX}{213}{\code {FOPEN_MAX}}
--\entry{NL{\_}ARGMAX}{223}{\code {NL_ARGMAX}}
--\entry{PA{\_}FLAG{\_}MASK}{234}{\code {PA_FLAG_MASK}}
--\entry{PA{\_}INT}{234}{\code {PA_INT}}
--\entry{PA{\_}CHAR}{234}{\code {PA_CHAR}}
--\entry{PA{\_}STRING}{234}{\code {PA_STRING}}
--\entry{PA{\_}POINTER}{234}{\code {PA_POINTER}}
--\entry{PA{\_}FLOAT}{234}{\code {PA_FLOAT}}
--\entry{PA{\_}DOUBLE}{235}{\code {PA_DOUBLE}}
--\entry{PA{\_}LAST}{235}{\code {PA_LAST}}
--\entry{PA{\_}FLAG{\_}PTR}{235}{\code {PA_FLAG_PTR}}
--\entry{PA{\_}FLAG{\_}SHORT}{235}{\code {PA_FLAG_SHORT}}
--\entry{PA{\_}FLAG{\_}LONG}{235}{\code {PA_FLAG_LONG}}
--\entry{PA{\_}FLAG{\_}LONG{\_}LONG}{235}{\code {PA_FLAG_LONG_LONG}}
--\entry{PA{\_}FLAG{\_}LONG{\_}DOUBLE}{235}{\code {PA_FLAG_LONG_DOUBLE}}
--\entry{EOF}{250}{\code {EOF}}
--\entry{SEEK{\_}SET}{254}{\code {SEEK_SET}}
--\entry{SEEK{\_}CUR}{254}{\code {SEEK_CUR}}
--\entry{SEEK{\_}END}{254}{\code {SEEK_END}}
--\entry{L{\_}SET}{254}{\code {L_SET}}
--\entry{L{\_}INCR}{254}{\code {L_INCR}}
--\entry{L{\_}XTND}{254}{\code {L_XTND}}
--\entry{{\_}IOFBF}{258}{\code {_IOFBF}}
--\entry{{\_}IOLBF}{258}{\code {_IOLBF}}
--\entry{{\_}IONBF}{258}{\code {_IONBF}}
--\entry{BUFSIZ}{258}{\code {BUFSIZ}}
--\entry{MM{\_}PRINT}{264}{\code {MM_PRINT}}
--\entry{MM{\_}CONSOLE}{264}{\code {MM_CONSOLE}}
--\entry{MM{\_}HARD}{265}{\code {MM_HARD}}
--\entry{MM{\_}SOFT}{265}{\code {MM_SOFT}}
--\entry{MM{\_}FIRM}{265}{\code {MM_FIRM}}
--\entry{MM{\_}APPL}{265}{\code {MM_APPL}}
--\entry{MM{\_}UTIL}{265}{\code {MM_UTIL}}
--\entry{MM{\_}OPSYS}{265}{\code {MM_OPSYS}}
--\entry{MM{\_}RECOVER}{265}{\code {MM_RECOVER}}
--\entry{MM{\_}NRECOV}{265}{\code {MM_NRECOV}}
--\entry{MM{\_}NULLLBL}{265}{\code {MM_NULLLBL}}
--\entry{MM{\_}NULLSEV}{265}{\code {MM_NULLSEV}}
--\entry{MM{\_}NULLMC}{265}{\code {MM_NULLMC}}
--\entry{MM{\_}NULLTXT}{265}{\code {MM_NULLTXT}}
--\entry{MM{\_}NULLACT}{266}{\code {MM_NULLACT}}
--\entry{MM{\_}NULLTAG}{266}{\code {MM_NULLTAG}}
--\entry{MM{\_}NOSEV}{266}{\code {MM_NOSEV}}
--\entry{MM{\_}HALT}{266}{\code {MM_HALT}}
--\entry{MM{\_}ERROR}{266}{\code {MM_ERROR}}
--\entry{MM{\_}WARNING}{266}{\code {MM_WARNING}}
--\entry{MM{\_}INFO}{266}{\code {MM_INFO}}
--\entry{STDIN{\_}FILENO}{283}{\code {STDIN_FILENO}}
--\entry{STDOUT{\_}FILENO}{283}{\code {STDOUT_FILENO}}
--\entry{STDERR{\_}FILENO}{283}{\code {STDERR_FILENO}}
--\entry{PROT{\_}READ}{286}{\code {PROT_READ}}
--\entry{PROT{\_}WRITE}{286}{\code {PROT_WRITE}}
--\entry{PROT{\_}EXEC}{286}{\code {PROT_EXEC}}
--\entry{MAP{\_}PRIVATE}{286}{\code {MAP_PRIVATE}}
--\entry{MAP{\_}SHARED}{287}{\code {MAP_SHARED}}
--\entry{MAP{\_}FIXED}{287}{\code {MAP_FIXED}}
--\entry{MAP{\_}ANONYMOUS}{287}{\code {MAP_ANONYMOUS}}
--\entry{MAP{\_}ANON}{287}{\code {MAP_ANON}}
--\entry{MS{\_}SYNC}{288}{\code {MS_SYNC}}
--\entry{MS{\_}ASYNC}{288}{\code {MS_ASYNC}}
--\entry{FD{\_}SETSIZE}{289}{\code {FD_SETSIZE}}
--\entry{LIO{\_}READ}{294}{\code {LIO_READ}}
--\entry{LIO{\_}WRITE}{294}{\code {LIO_WRITE}}
--\entry{LIO{\_}NOP}{294}{\code {LIO_NOP}}
--\entry{F{\_}DUPFD}{306}{\code {F_DUPFD}}
--\entry{F{\_}GETFD}{307}{\code {F_GETFD}}
--\entry{F{\_}SETFD}{308}{\code {F_SETFD}}
--\entry{FD{\_}CLOEXEC}{308}{\code {FD_CLOEXEC}}
--\entry{O{\_}RDONLY}{309}{\code {O_RDONLY}}
--\entry{O{\_}WRONLY}{309}{\code {O_WRONLY}}
--\entry{O{\_}RDWR}{309}{\code {O_RDWR}}
--\entry{O{\_}READ}{309}{\code {O_READ}}
--\entry{O{\_}WRITE}{309}{\code {O_WRITE}}
--\entry{O{\_}EXEC}{310}{\code {O_EXEC}}
--\entry{O{\_}ACCMODE}{310}{\code {O_ACCMODE}}
--\entry{O{\_}CREAT}{310}{\code {O_CREAT}}
--\entry{O{\_}EXCL}{310}{\code {O_EXCL}}
--\entry{O{\_}NONBLOCK}{310}{\code {O_NONBLOCK}}
--\entry{O{\_}NOCTTY}{311}{\code {O_NOCTTY}}
--\entry{O{\_}IGNORE{\_}CTTY}{311}{\code {O_IGNORE_CTTY}}
--\entry{O{\_}NOLINK}{311}{\code {O_NOLINK}}
--\entry{O{\_}NOTRANS}{311}{\code {O_NOTRANS}}
--\entry{O{\_}TRUNC}{311}{\code {O_TRUNC}}
--\entry{O{\_}SHLOCK}{311}{\code {O_SHLOCK}}
--\entry{O{\_}EXLOCK}{312}{\code {O_EXLOCK}}
--\entry{O{\_}APPEND}{312}{\code {O_APPEND}}
--\entry{O{\_}NONBLOCK}{312}{\code {O_NONBLOCK}}
--\entry{O{\_}NDELAY}{312}{\code {O_NDELAY}}
--\entry{O{\_}ASYNC}{312}{\code {O_ASYNC}}
--\entry{O{\_}FSYNC}{312}{\code {O_FSYNC}}
--\entry{O{\_}SYNC}{312}{\code {O_SYNC}}
--\entry{O{\_}NOATIME}{313}{\code {O_NOATIME}}
--\entry{F{\_}GETFL}{313}{\code {F_GETFL}}
--\entry{F{\_}SETFL}{313}{\code {F_SETFL}}
--\entry{F{\_}GETLK}{315}{\code {F_GETLK}}
--\entry{F{\_}SETLK}{315}{\code {F_SETLK}}
--\entry{F{\_}SETLKW}{316}{\code {F_SETLKW}}
--\entry{F{\_}RDLCK}{316}{\code {F_RDLCK}}
--\entry{F{\_}WRLCK}{317}{\code {F_WRLCK}}
--\entry{F{\_}UNLCK}{317}{\code {F_UNLCK}}
--\entry{F{\_}GETOWN}{317}{\code {F_GETOWN}}
--\entry{F{\_}SETOWN}{317}{\code {F_SETOWN}}
--\entry{FTW{\_}F}{327}{\code {FTW_F}}
--\entry{FTW{\_}D}{327}{\code {FTW_D}}
--\entry{FTW{\_}NS}{327}{\code {FTW_NS}}
--\entry{FTW{\_}DNR}{327}{\code {FTW_DNR}}
--\entry{FTW{\_}SL}{327}{\code {FTW_SL}}
--\entry{FTW{\_}DP}{328}{\code {FTW_DP}}
--\entry{FTW{\_}SLN}{328}{\code {FTW_SLN}}
--\entry{FTW{\_}PHYS}{330}{\code {FTW_PHYS}}
--\entry{FTW{\_}MOUNT}{330}{\code {FTW_MOUNT}}
--\entry{FTW{\_}CHDIR}{330}{\code {FTW_CHDIR}}
--\entry{FTW{\_}DEPTH}{330}{\code {FTW_DEPTH}}
--\entry{S{\_}IFMT}{342}{\code {S_IFMT}}
--\entry{S{\_}IFDIR}{342}{\code {S_IFDIR}}
--\entry{S{\_}IFCHR}{342}{\code {S_IFCHR}}
--\entry{S{\_}IFBLK}{342}{\code {S_IFBLK}}
--\entry{S{\_}IFREG}{343}{\code {S_IFREG}}
--\entry{S{\_}IFLNK}{343}{\code {S_IFLNK}}
--\entry{S{\_}IFSOCK}{343}{\code {S_IFSOCK}}
--\entry{S{\_}IFIFO}{343}{\code {S_IFIFO}}
--\entry{S{\_}IRUSR}{344}{\code {S_IRUSR}}
--\entry{S{\_}IREAD}{344}{\code {S_IREAD}}
--\entry{S{\_}IWUSR}{344}{\code {S_IWUSR}}
--\entry{S{\_}IWRITE}{344}{\code {S_IWRITE}}
--\entry{S{\_}IXUSR}{344}{\code {S_IXUSR}}
--\entry{S{\_}IEXEC}{344}{\code {S_IEXEC}}
--\entry{S{\_}IRWXU}{344}{\code {S_IRWXU}}
--\entry{S{\_}IRGRP}{344}{\code {S_IRGRP}}
--\entry{S{\_}IWGRP}{344}{\code {S_IWGRP}}
--\entry{S{\_}IXGRP}{344}{\code {S_IXGRP}}
--\entry{S{\_}IRWXG}{344}{\code {S_IRWXG}}
--\entry{S{\_}IROTH}{345}{\code {S_IROTH}}
--\entry{S{\_}IWOTH}{345}{\code {S_IWOTH}}
--\entry{S{\_}IXOTH}{345}{\code {S_IXOTH}}
--\entry{S{\_}IRWXO}{345}{\code {S_IRWXO}}
--\entry{S{\_}ISUID}{345}{\code {S_ISUID}}
--\entry{S{\_}ISGID}{345}{\code {S_ISGID}}
--\entry{S{\_}ISVTX}{345}{\code {S_ISVTX}}
--\entry{R{\_}OK}{349}{\code {R_OK}}
--\entry{W{\_}OK}{349}{\code {W_OK}}
--\entry{X{\_}OK}{349}{\code {X_OK}}
--\entry{F{\_}OK}{349}{\code {F_OK}}
--\entry{L{\_}tmpnam}{354}{\code {L_tmpnam}}
--\entry{TMP{\_}MAX}{354}{\code {TMP_MAX}}
--\entry{P{\_}tmpdir}{355}{\code {P_tmpdir}}
--\entry{SOCK{\_}STREAM}{364}{\code {SOCK_STREAM}}
--\entry{SOCK{\_}DGRAM}{364}{\code {SOCK_DGRAM}}
--\entry{SOCK{\_}RAW}{365}{\code {SOCK_RAW}}
--\entry{AF{\_}LOCAL}{366}{\code {AF_LOCAL}}
--\entry{AF{\_}UNIX}{366}{\code {AF_UNIX}}
--\entry{AF{\_}FILE}{366}{\code {AF_FILE}}
--\entry{AF{\_}INET}{366}{\code {AF_INET}}
--\entry{AF{\_}UNSPEC}{366}{\code {AF_UNSPEC}}
--\entry{IFNAMSIZ}{368}{\code {IFNAMSIZ}}
--\entry{PF{\_}LOCAL}{369}{\code {PF_LOCAL}}
--\entry{PF{\_}UNIX}{369}{\code {PF_UNIX}}
--\entry{PF{\_}FILE}{369}{\code {PF_FILE}}
--\entry{PF{\_}INET}{371}{\code {PF_INET}}
--\entry{AF{\_}INET6}{371}{\code {AF_INET6}}
--\entry{INADDR{\_}LOOPBACK}{375}{\code {INADDR_LOOPBACK}}
--\entry{INADDR{\_}ANY}{375}{\code {INADDR_ANY}}
--\entry{INADDR{\_}BROADCAST}{375}{\code {INADDR_BROADCAST}}
--\entry{INADDR{\_}NONE}{375}{\code {INADDR_NONE}}
--\entry{in6addr{\_}loopback}{375}{\code {in6addr_loopback}}
--\entry{in6addr{\_}any}{375}{\code {in6addr_any}}
--\entry{h{\_}errno}{378}{\code {h_errno}}
--\entry{HOST{\_}NOT{\_}FOUND}{379}{\code {HOST_NOT_FOUND}}
--\entry{TRY{\_}AGAIN}{379}{\code {TRY_AGAIN}}
--\entry{NO{\_}RECOVERY}{379}{\code {NO_RECOVERY}}
--\entry{NO{\_}ADDRESS}{379}{\code {NO_ADDRESS}}
--\entry{IPPORT{\_}RESERVED}{381}{\code {IPPORT_RESERVED}}
--\entry{IPPORT{\_}USERRESERVED}{381}{\code {IPPORT_USERRESERVED}}
--\entry{PF{\_}NS}{386}{\code {PF_NS}}
--\entry{PF{\_}ISO}{386}{\code {PF_ISO}}
--\entry{PF{\_}CCITT}{386}{\code {PF_CCITT}}
--\entry{PF{\_}IMPLINK}{386}{\code {PF_IMPLINK}}
--\entry{PF{\_}ROUTE}{386}{\code {PF_ROUTE}}
--\entry{MSG{\_}OOB}{394}{\code {MSG_OOB}}
--\entry{MSG{\_}PEEK}{394}{\code {MSG_PEEK}}
--\entry{MSG{\_}DONTROUTE}{394}{\code {MSG_DONTROUTE}}
--\entry{SOL{\_}SOCKET}{407}{\code {SOL_SOCKET}}
--\entry{NCCS}{414}{\code {NCCS}}
--\entry{TCSANOW}{414}{\code {TCSANOW}}
--\entry{TCSADRAIN}{414}{\code {TCSADRAIN}}
--\entry{TCSAFLUSH}{414}{\code {TCSAFLUSH}}
--\entry{TCSASOFT}{414}{\code {TCSASOFT}}
--\entry{INPCK}{416}{\code {INPCK}}
--\entry{IGNPAR}{416}{\code {IGNPAR}}
--\entry{PARMRK}{417}{\code {PARMRK}}
--\entry{ISTRIP}{417}{\code {ISTRIP}}
--\entry{IGNBRK}{417}{\code {IGNBRK}}
--\entry{BRKINT}{417}{\code {BRKINT}}
--\entry{IGNCR}{417}{\code {IGNCR}}
--\entry{ICRNL}{417}{\code {ICRNL}}
--\entry{INLCR}{417}{\code {INLCR}}
--\entry{IXOFF}{418}{\code {IXOFF}}
--\entry{IXON}{418}{\code {IXON}}
--\entry{IXANY}{418}{\code {IXANY}}
--\entry{IMAXBEL}{418}{\code {IMAXBEL}}
--\entry{OPOST}{418}{\code {OPOST}}
--\entry{ONLCR}{419}{\code {ONLCR}}
--\entry{OXTABS}{419}{\code {OXTABS}}
--\entry{ONOEOT}{419}{\code {ONOEOT}}
--\entry{CLOCAL}{419}{\code {CLOCAL}}
--\entry{HUPCL}{419}{\code {HUPCL}}
--\entry{CREAD}{419}{\code {CREAD}}
--\entry{CSTOPB}{419}{\code {CSTOPB}}
--\entry{PARENB}{420}{\code {PARENB}}
--\entry{PARODD}{420}{\code {PARODD}}
--\entry{CSIZE}{420}{\code {CSIZE}}
--\entry{CS5}{420}{\code {CS5}}
--\entry{CS6}{420}{\code {CS6}}
--\entry{CS7}{420}{\code {CS7}}
--\entry{CS8}{420}{\code {CS8}}
--\entry{CCTS{\_}OFLOW}{420}{\code {CCTS_OFLOW}}
--\entry{CRTS{\_}IFLOW}{420}{\code {CRTS_IFLOW}}
--\entry{MDMBUF}{420}{\code {MDMBUF}}
--\entry{CIGNORE}{420}{\code {CIGNORE}}
--\entry{ICANON}{421}{\code {ICANON}}
--\entry{ECHO}{421}{\code {ECHO}}
--\entry{ECHOE}{421}{\code {ECHOE}}
--\entry{ECHOPRT}{421}{\code {ECHOPRT}}
--\entry{ECHOK}{421}{\code {ECHOK}}
--\entry{ECHOKE}{422}{\code {ECHOKE}}
--\entry{ECHONL}{422}{\code {ECHONL}}
--\entry{ECHOCTL}{422}{\code {ECHOCTL}}
--\entry{ISIG}{422}{\code {ISIG}}
--\entry{IEXTEN}{422}{\code {IEXTEN}}
--\entry{NOFLSH}{422}{\code {NOFLSH}}
--\entry{TOSTOP}{422}{\code {TOSTOP}}
--\entry{ALTWERASE}{423}{\code {ALTWERASE}}
--\entry{FLUSHO}{423}{\code {FLUSHO}}
--\entry{NOKERNINFO}{423}{\code {NOKERNINFO}}
--\entry{PENDIN}{423}{\code {PENDIN}}
--\entry{B0}{424}{\code {B0}}
--\entry{B50}{424}{\code {B50}}
--\entry{B75}{424}{\code {B75}}
--\entry{B110}{424}{\code {B110}}
--\entry{B134}{424}{\code {B134}}
--\entry{B150}{424}{\code {B150}}
--\entry{B200}{424}{\code {B200}}
--\entry{B300}{424}{\code {B300}}
--\entry{B600}{424}{\code {B600}}
--\entry{B1200}{424}{\code {B1200}}
--\entry{B1800}{424}{\code {B1800}}
--\entry{B2400}{424}{\code {B2400}}
--\entry{B4800}{424}{\code {B4800}}
--\entry{B9600}{424}{\code {B9600}}
--\entry{B19200}{424}{\code {B19200}}
--\entry{B38400}{424}{\code {B38400}}
--\entry{B57600}{424}{\code {B57600}}
--\entry{B115200}{424}{\code {B115200}}
--\entry{B230400}{424}{\code {B230400}}
--\entry{B460800}{424}{\code {B460800}}
--\entry{EXTA}{424}{\code {EXTA}}
--\entry{EXTB}{424}{\code {EXTB}}
--\entry{{\_}POSIX{\_}VDISABLE}{425}{\code {_POSIX_VDISABLE}}
--\entry{VEOF}{425}{\code {VEOF}}
--\entry{VEOL}{425}{\code {VEOL}}
--\entry{VEOL2}{425}{\code {VEOL2}}
--\entry{VERASE}{426}{\code {VERASE}}
--\entry{VWERASE}{426}{\code {VWERASE}}
--\entry{VKILL}{426}{\code {VKILL}}
--\entry{VREPRINT}{426}{\code {VREPRINT}}
--\entry{VINTR}{427}{\code {VINTR}}
--\entry{VQUIT}{427}{\code {VQUIT}}
--\entry{VSUSP}{427}{\code {VSUSP}}
--\entry{VDSUSP}{427}{\code {VDSUSP}}
--\entry{VSTART}{428}{\code {VSTART}}
--\entry{VSTOP}{428}{\code {VSTOP}}
--\entry{VLNEXT}{428}{\code {VLNEXT}}
--\entry{VDISCARD}{428}{\code {VDISCARD}}
--\entry{VSTATUS}{429}{\code {VSTATUS}}
--\entry{VMIN}{429}{\code {VMIN}}
--\entry{VTIME}{429}{\code {VTIME}}
--\entry{TCIFLUSH}{431}{\code {TCIFLUSH}}
--\entry{TCOFLUSH}{431}{\code {TCOFLUSH}}
--\entry{TCIOFLUSH}{431}{\code {TCIOFLUSH}}
--\entry{TCOOFF}{432}{\code {TCOOFF}}
--\entry{TCOON}{432}{\code {TCOON}}
--\entry{TCIOFF}{432}{\code {TCIOFF}}
--\entry{TCION}{432}{\code {TCION}}
--\entry{EBADF}{432}{\code {EBADF}}
--\entry{ENOTTY}{432}{\code {ENOTTY}}
--\entry{EINVAL}{432}{\code {EINVAL}}
--\entry{M{\_}E}{439}{\code {M_E}}
--\entry{M{\_}LOG2E}{439}{\code {M_LOG2E}}
--\entry{M{\_}LOG10E}{439}{\code {M_LOG10E}}
--\entry{M{\_}LN2}{439}{\code {M_LN2}}
--\entry{M{\_}LN10}{439}{\code {M_LN10}}
--\entry{M{\_}PI}{439}{\code {M_PI}}
--\entry{M{\_}PI{\_}2}{439}{\code {M_PI_2}}
--\entry{M{\_}PI{\_}4}{439}{\code {M_PI_4}}
--\entry{M{\_}1{\_}PI}{439}{\code {M_1_PI}}
--\entry{M{\_}2{\_}PI}{439}{\code {M_2_PI}}
--\entry{M{\_}2{\_}SQRTPI}{439}{\code {M_2_SQRTPI}}
--\entry{M{\_}SQRT2}{439}{\code {M_SQRT2}}
--\entry{M{\_}SQRT1{\_}2}{439}{\code {M_SQRT1_2}}
--\entry{PI}{440}{\code {PI}}
--\entry{FP{\_}ILOGB0}{444}{\code {FP_ILOGB0}}
--\entry{FP{\_}ILOGBNAN}{444}{\code {FP_ILOGBNAN}}
--\entry{signgam}{449}{\code {signgam}}
--\entry{RAND{\_}MAX}{452}{\code {RAND_MAX}}
--\entry{FP{\_}NAN}{459}{\code {FP_NAN}}
--\entry{FP{\_}INFINITE}{459}{\code {FP_INFINITE}}
--\entry{FP{\_}ZERO}{459}{\code {FP_ZERO}}
--\entry{FP{\_}SUBNORMAL}{460}{\code {FP_SUBNORMAL}}
--\entry{FP{\_}NORMAL}{460}{\code {FP_NORMAL}}
--\entry{INFINITY}{463}{\code {INFINITY}}
--\entry{NAN}{463}{\code {NAN}}
--\entry{FE{\_}INEXACT}{464}{\code {FE_INEXACT}}
--\entry{FE{\_}DIVBYZERO}{464}{\code {FE_DIVBYZERO}}
--\entry{FE{\_}UNDERFLOW}{464}{\code {FE_UNDERFLOW}}
--\entry{FE{\_}OVERFLOW}{464}{\code {FE_OVERFLOW}}
--\entry{FE{\_}INVALID}{464}{\code {FE_INVALID}}
--\entry{HUGE{\_}VAL}{466}{\code {HUGE_VAL}}
--\entry{HUGE{\_}VALF}{466}{\code {HUGE_VALF}}
--\entry{HUGE{\_}VALL}{466}{\code {HUGE_VALL}}
--\entry{FE{\_}TONEAREST}{466}{\code {FE_TONEAREST}}
--\entry{FE{\_}UPWARD}{466}{\code {FE_UPWARD}}
--\entry{FE{\_}DOWNWARD}{466}{\code {FE_DOWNWARD}}
--\entry{FE{\_}TOWARDZERO}{466}{\code {FE_TOWARDZERO}}
--\entry{FE{\_}DFL{\_}ENV}{468}{\code {FE_DFL_ENV}}
--\entry{FE{\_}NOMASK{\_}ENV}{468}{\code {FE_NOMASK_ENV}}
--\entry{FP{\_}FAST{\_}FMA}{476}{\code {FP_FAST_FMA}}
--\entry{{\_}Complex{\_}I}{476}{\code {_Complex_I}}
--\entry{I}{477}{\code {I}}
--\entry{CLOCKS{\_}PER{\_}SEC}{488}{\code {CLOCKS_PER_SEC}}
--\entry{CLK{\_}TCK}{488}{\code {CLK_TCK}}
--\entry{getdate{\_}err}{505}{\code {getdate_err}}
--\entry{tzname}{509}{\code {tzname}}
--\entry{timezone}{509}{\code {timezone}}
--\entry{daylight}{510}{\code {daylight}}
--\entry{RLIMIT{\_}CPU}{520}{\code {RLIMIT_CPU}}
--\entry{RLIMIT{\_}FSIZE}{520}{\code {RLIMIT_FSIZE}}
--\entry{RLIMIT{\_}DATA}{520}{\code {RLIMIT_DATA}}
--\entry{RLIMIT{\_}STACK}{520}{\code {RLIMIT_STACK}}
--\entry{RLIMIT{\_}CORE}{520}{\code {RLIMIT_CORE}}
--\entry{RLIMIT{\_}RSS}{521}{\code {RLIMIT_RSS}}
--\entry{RLIMIT{\_}NOFILE}{521}{\code {RLIMIT_NOFILE}}
--\entry{RLIMIT{\_}OFILE}{521}{\code {RLIMIT_OFILE}}
--\entry{RLIM{\_}NLIMITS}{521}{\code {RLIM_NLIMITS}}
--\entry{RLIM{\_}INFINITY}{521}{\code {RLIM_INFINITY}}
--\entry{PRIO{\_}MIN}{521}{\code {PRIO_MIN}}
--\entry{PRIO{\_}MAX}{521}{\code {PRIO_MAX}}
--\entry{PRIO{\_}PROCESS}{522}{\code {PRIO_PROCESS}}
--\entry{PRIO{\_}PGRP}{522}{\code {PRIO_PGRP}}
--\entry{PRIO{\_}USER}{522}{\code {PRIO_USER}}
--\entry{NSIG}{529}{\code {NSIG}}
--\entry{COREFILE}{530}{\code {COREFILE}}
--\entry{SIGFPE}{530}{\code {SIGFPE}}
--\entry{FPE{\_}INTOVF{\_}TRAP}{530}{\code {FPE_INTOVF_TRAP}}
--\entry{FPE{\_}INTDIV{\_}TRAP}{530}{\code {FPE_INTDIV_TRAP}}
--\entry{FPE{\_}SUBRNG{\_}TRAP}{530}{\code {FPE_SUBRNG_TRAP}}
--\entry{FPE{\_}FLTOVF{\_}TRAP}{531}{\code {FPE_FLTOVF_TRAP}}
--\entry{FPE{\_}FLTDIV{\_}TRAP}{531}{\code {FPE_FLTDIV_TRAP}}
--\entry{FPE{\_}FLTUND{\_}TRAP}{531}{\code {FPE_FLTUND_TRAP}}
--\entry{FPE{\_}DECOVF{\_}TRAP}{531}{\code {FPE_DECOVF_TRAP}}
--\entry{SIGILL}{531}{\code {SIGILL}}
--\entry{SIGSEGV}{531}{\code {SIGSEGV}}
--\entry{SIGBUS}{531}{\code {SIGBUS}}
--\entry{SIGABRT}{532}{\code {SIGABRT}}
--\entry{SIGIOT}{532}{\code {SIGIOT}}
--\entry{SIGTRAP}{532}{\code {SIGTRAP}}
--\entry{SIGEMT}{532}{\code {SIGEMT}}
--\entry{SIGSYS}{532}{\code {SIGSYS}}
--\entry{SIGTERM}{532}{\code {SIGTERM}}
--\entry{SIGINT}{532}{\code {SIGINT}}
--\entry{SIGQUIT}{533}{\code {SIGQUIT}}
--\entry{SIGKILL}{533}{\code {SIGKILL}}
--\entry{SIGHUP}{533}{\code {SIGHUP}}
--\entry{SIGALRM}{533}{\code {SIGALRM}}
--\entry{SIGVTALRM}{534}{\code {SIGVTALRM}}
--\entry{SIGPROF}{534}{\code {SIGPROF}}
--\entry{SIGIO}{534}{\code {SIGIO}}
--\entry{SIGURG}{534}{\code {SIGURG}}
--\entry{SIGPOLL}{534}{\code {SIGPOLL}}
--\entry{SIGCHLD}{534}{\code {SIGCHLD}}
--\entry{SIGCLD}{535}{\code {SIGCLD}}
--\entry{SIGCONT}{535}{\code {SIGCONT}}
--\entry{SIGSTOP}{535}{\code {SIGSTOP}}
--\entry{SIGTSTP}{535}{\code {SIGTSTP}}
--\entry{SIGTTIN}{535}{\code {SIGTTIN}}
--\entry{SIGTTOU}{535}{\code {SIGTTOU}}
--\entry{SIGPIPE}{536}{\code {SIGPIPE}}
--\entry{SIGLOST}{536}{\code {SIGLOST}}
--\entry{SIGXCPU}{536}{\code {SIGXCPU}}
--\entry{SIGXFSZ}{537}{\code {SIGXFSZ}}
--\entry{SIGUSR1}{537}{\code {SIGUSR1}}
--\entry{SIGUSR2}{537}{\code {SIGUSR2}}
--\entry{SIGWINCH}{537}{\code {SIGWINCH}}
--\entry{SIGINFO}{537}{\code {SIGINFO}}
--\entry{sys{\_}siglist}{538}{\code {sys_siglist}}
--\entry{SIG{\_}DFL}{539}{\code {SIG_DFL}}
--\entry{SIG{\_}IGN}{539}{\code {SIG_IGN}}
--\entry{SIG{\_}ERR}{540}{\code {SIG_ERR}}
--\entry{SA{\_}NOCLDSTOP}{543}{\code {SA_NOCLDSTOP}}
--\entry{SA{\_}ONSTACK}{543}{\code {SA_ONSTACK}}
--\entry{SA{\_}RESTART}{544}{\code {SA_RESTART}}
--\entry{SIG{\_}BLOCK}{562}{\code {SIG_BLOCK}}
--\entry{SIG{\_}UNBLOCK}{562}{\code {SIG_UNBLOCK}}
--\entry{SIG{\_}SETMASK}{562}{\code {SIG_SETMASK}}
--\entry{SIGSTKSZ}{570}{\code {SIGSTKSZ}}
--\entry{MINSIGSTKSZ}{570}{\code {MINSIGSTKSZ}}
--\entry{SS{\_}DISABLE}{570}{\code {SS_DISABLE}}
--\entry{SS{\_}ONSTACK}{570}{\code {SS_ONSTACK}}
--\entry{SV{\_}ONSTACK}{572}{\code {SV_ONSTACK}}
--\entry{SV{\_}INTERRUPT}{572}{\code {SV_INTERRUPT}}
--\entry{SV{\_}RESETHAND}{572}{\code {SV_RESETHAND}}
--\entry{opterr}{577}{\code {opterr}}
--\entry{optopt}{577}{\code {optopt}}
--\entry{optind}{577}{\code {optind}}
--\entry{optarg}{577}{\code {optarg}}
--\entry{argp{\_}program{\_}version}{585}{\code {argp_program_version}}
--\entry{argp{\_}program{\_}bug{\_}address}{585}{\code {argp_program_bug_address}}
--\entry{argp{\_}program{\_}version{\_}hook}{585}{\code {argp_program_version_hook}}
--\entry{argp{\_}err{\_}exit{\_}status}{585}{\code {argp_err_exit_status}}
--\entry{OPTION{\_}ARG{\_}OPTIONAL}{587}{\code {OPTION_ARG_OPTIONAL}}
--\entry{OPTION{\_}HIDDEN}{587}{\code {OPTION_HIDDEN}}
--\entry{OPTION{\_}ALIAS}{587}{\code {OPTION_ALIAS}}
--\entry{OPTION{\_}DOC}{587}{\code {OPTION_DOC}}
--\entry{OPTION{\_}NO{\_}USAGE}{588}{\code {OPTION_NO_USAGE}}
--\entry{ARGP{\_}ERR{\_}UNKNOWN}{589}{\code {ARGP_ERR_UNKNOWN}}
--\entry{ARGP{\_}KEY{\_}ARG}{589}{\code {ARGP_KEY_ARG}}
--\entry{ARGP{\_}KEY{\_}ARGS}{589}{\code {ARGP_KEY_ARGS}}
--\entry{ARGP{\_}KEY{\_}END}{590}{\code {ARGP_KEY_END}}
--\entry{ARGP{\_}KEY{\_}NO{\_}ARGS}{590}{\code {ARGP_KEY_NO_ARGS}}
--\entry{ARGP{\_}KEY{\_}INIT}{590}{\code {ARGP_KEY_INIT}}
--\entry{ARGP{\_}KEY{\_}SUCCESS}{590}{\code {ARGP_KEY_SUCCESS}}
--\entry{ARGP{\_}KEY{\_}ERROR}{590}{\code {ARGP_KEY_ERROR}}
--\entry{ARGP{\_}KEY{\_}FINI}{590}{\code {ARGP_KEY_FINI}}
--\entry{ARGP{\_}PARSE{\_}ARGV0}{594}{\code {ARGP_PARSE_ARGV0}}
--\entry{ARGP{\_}NO{\_}ERRS}{594}{\code {ARGP_NO_ERRS}}
--\entry{ARGP{\_}NO{\_}ARGS}{595}{\code {ARGP_NO_ARGS}}
--\entry{ARGP{\_}IN{\_}ORDER}{595}{\code {ARGP_IN_ORDER}}
--\entry{ARGP{\_}NO{\_}HELP}{595}{\code {ARGP_NO_HELP}}
--\entry{ARGP{\_}NO{\_}EXIT}{595}{\code {ARGP_NO_EXIT}}
--\entry{ARGP{\_}LONG{\_}ONLY}{595}{\code {ARGP_LONG_ONLY}}
--\entry{ARGP{\_}SILENT}{595}{\code {ARGP_SILENT}}
--\entry{ARGP{\_}KEY{\_}HELP{\_}PRE{\_}DOC}{596}{\code {ARGP_KEY_HELP_PRE_DOC}}
--\entry{ARGP{\_}KEY{\_}HELP{\_}POST{\_}DOC}{596}{\code {ARGP_KEY_HELP_POST_DOC}}
--\entry{ARGP{\_}KEY{\_}HELP{\_}HEADER}{596}{\code {ARGP_KEY_HELP_HEADER}}
--\entry{ARGP{\_}KEY{\_}HELP{\_}EXTRA}{596}{\code {ARGP_KEY_HELP_EXTRA}}
--\entry{ARGP{\_}KEY{\_}HELP{\_}DUP{\_}ARGS{\_}NOTE}{596}{\code {ARGP_KEY_HELP_DUP_ARGS_NOTE}}
--\entry{ARGP{\_}KEY{\_}HELP{\_}ARGS{\_}DOC}{596}{\code {ARGP_KEY_HELP_ARGS_DOC}}
--\entry{ARGP{\_}HELP{\_}USAGE}{596}{\code {ARGP_HELP_USAGE}}
--\entry{ARGP{\_}HELP{\_}SHORT{\_}USAGE}{597}{\code {ARGP_HELP_SHORT_USAGE}}
--\entry{ARGP{\_}HELP{\_}SEE}{597}{\code {ARGP_HELP_SEE}}
--\entry{ARGP{\_}HELP{\_}LONG}{597}{\code {ARGP_HELP_LONG}}
--\entry{ARGP{\_}HELP{\_}PRE{\_}DOC}{597}{\code {ARGP_HELP_PRE_DOC}}
--\entry{ARGP{\_}HELP{\_}POST{\_}DOC}{597}{\code {ARGP_HELP_POST_DOC}}
--\entry{ARGP{\_}HELP{\_}DOC}{597}{\code {ARGP_HELP_DOC}}
--\entry{ARGP{\_}HELP{\_}BUG{\_}ADDR}{597}{\code {ARGP_HELP_BUG_ADDR}}
--\entry{ARGP{\_}HELP{\_}LONG{\_}ONLY}{597}{\code {ARGP_HELP_LONG_ONLY}}
--\entry{ARGP{\_}HELP{\_}EXIT{\_}ERR}{597}{\code {ARGP_HELP_EXIT_ERR}}
--\entry{ARGP{\_}HELP{\_}EXIT{\_}OK}{597}{\code {ARGP_HELP_EXIT_OK}}
--\entry{ARGP{\_}HELP{\_}STD{\_}ERR}{597}{\code {ARGP_HELP_STD_ERR}}
--\entry{ARGP{\_}HELP{\_}STD{\_}USAGE}{597}{\code {ARGP_HELP_STD_USAGE}}
--\entry{ARGP{\_}HELP{\_}STD{\_}HELP}{597}{\code {ARGP_HELP_STD_HELP}}
--\entry{environ}{611}{\code {environ}}
--\entry{EXIT{\_}SUCCESS}{614}{\code {EXIT_SUCCESS}}
--\entry{EXIT{\_}FAILURE}{615}{\code {EXIT_FAILURE}}
--\entry{L{\_}ctermid}{646}{\code {L_ctermid}}
--\entry{aliases}{651}{\code {aliases}}
--\entry{ethers}{651}{\code {ethers}}
--\entry{group}{651}{\code {group}}
--\entry{hosts}{651}{\code {hosts}}
--\entry{netgroup}{651}{\code {netgroup}}
--\entry{networks}{651}{\code {networks}}
--\entry{protocols}{651}{\code {protocols}}
--\entry{passwd}{651}{\code {passwd}}
--\entry{rpc}{651}{\code {rpc}}
--\entry{services}{651}{\code {services}}
--\entry{shadow}{652}{\code {shadow}}
--\entry{NSS{\_}STATUS{\_}TRYAGAIN}{656}{\code {NSS_STATUS_TRYAGAIN}}
--\entry{NSS{\_}STATUS{\_}UNAVAIL}{656}{\code {NSS_STATUS_UNAVAIL}}
--\entry{NSS{\_}STATUS{\_}NOTFOUND}{656}{\code {NSS_STATUS_NOTFOUND}}
--\entry{NSS{\_}STATUS{\_}SUCCESS}{656}{\code {NSS_STATUS_SUCCESS}}
--\entry{L{\_}cuserid}{671}{\code {L_cuserid}}
--\entry{EMPTY}{672}{\code {EMPTY}}
--\entry{RUN{\_}LVL}{672}{\code {RUN_LVL}}
--\entry{BOOT{\_}TIME}{672}{\code {BOOT_TIME}}
--\entry{OLD{\_}TIME}{672}{\code {OLD_TIME}}
--\entry{NEW{\_}TIME}{672}{\code {NEW_TIME}}
--\entry{INIT{\_}PROCESS}{672}{\code {INIT_PROCESS}}
--\entry{LOGIN{\_}PROCESS}{672}{\code {LOGIN_PROCESS}}
--\entry{USER{\_}PROCESS}{672}{\code {USER_PROCESS}}
--\entry{DEAD{\_}PROCESS}{673}{\code {DEAD_PROCESS}}
--\entry{ACCOUNTING}{673}{\code {ACCOUNTING}}
--\entry{{\_}PATH{\_}UTMP}{675}{\code {_PATH_UTMP}}
--\entry{{\_}PATH{\_}WTMP}{675}{\code {_PATH_WTMP}}
--\entry{EMPTY}{676}{\code {EMPTY}}
--\entry{RUN{\_}LVL}{676}{\code {RUN_LVL}}
--\entry{BOOT{\_}TIME}{676}{\code {BOOT_TIME}}
--\entry{OLD{\_}TIME}{677}{\code {OLD_TIME}}
--\entry{NEW{\_}TIME}{677}{\code {NEW_TIME}}
--\entry{INIT{\_}PROCESS}{677}{\code {INIT_PROCESS}}
--\entry{LOGIN{\_}PROCESS}{677}{\code {LOGIN_PROCESS}}
--\entry{USER{\_}PROCESS}{677}{\code {USER_PROCESS}}
--\entry{DEAD{\_}PROCESS}{677}{\code {DEAD_PROCESS}}
--\entry{{\_}PATH{\_}FSTAB}{691}{\code {_PATH_FSTAB}}
--\entry{{\_}PATH{\_}MNTTAB}{691}{\code {_PATH_MNTTAB}}
--\entry{FSTAB}{691}{\code {FSTAB}}
--\entry{{\_}PATH{\_}MOUNTED}{691}{\code {_PATH_MOUNTED}}
--\entry{FSTAB{\_}RW}{692}{\code {FSTAB_RW}}
--\entry{FSTAB{\_}RQ}{692}{\code {FSTAB_RQ}}
--\entry{FSTAB{\_}RO}{692}{\code {FSTAB_RO}}
--\entry{FSTAB{\_}SW}{692}{\code {FSTAB_SW}}
--\entry{FSTAB{\_}XX}{692}{\code {FSTAB_XX}}
--\entry{MNTTYPE{\_}IGNORE}{694}{\code {MNTTYPE_IGNORE}}
--\entry{MNTTYPE{\_}NFS}{694}{\code {MNTTYPE_NFS}}
--\entry{MNTTYPE{\_}SWAP}{694}{\code {MNTTYPE_SWAP}}
--\entry{MNTOPT{\_}DEFAULTS}{694}{\code {MNTOPT_DEFAULTS}}
--\entry{MNTOPT{\_}RO}{694}{\code {MNTOPT_RO}}
--\entry{MNTOPT{\_}RW}{694}{\code {MNTOPT_RW}}
--\entry{MNTOPT{\_}SUID}{694}{\code {MNTOPT_SUID}}
--\entry{MNTOPT{\_}NOSUID}{695}{\code {MNTOPT_NOSUID}}
--\entry{MNTOPT{\_}NOAUTO}{695}{\code {MNTOPT_NOAUTO}}
--\entry{ARG{\_}MAX}{697}{\code {ARG_MAX}}
--\entry{CHILD{\_}MAX}{697}{\code {CHILD_MAX}}
--\entry{OPEN{\_}MAX}{697}{\code {OPEN_MAX}}
--\entry{STREAM{\_}MAX}{697}{\code {STREAM_MAX}}
--\entry{TZNAME{\_}MAX}{697}{\code {TZNAME_MAX}}
--\entry{NGROUPS{\_}MAX}{698}{\code {NGROUPS_MAX}}
--\entry{SSIZE{\_}MAX}{698}{\code {SSIZE_MAX}}
--\entry{RE{\_}DUP{\_}MAX}{698}{\code {RE_DUP_MAX}}
--\entry{{\_}POSIX{\_}JOB{\_}CONTROL}{698}{\code {_POSIX_JOB_CONTROL}}
--\entry{{\_}POSIX{\_}SAVED{\_}IDS}{698}{\code {_POSIX_SAVED_IDS}}
--\entry{{\_}POSIX2{\_}C{\_}DEV}{699}{\code {_POSIX2_C_DEV}}
--\entry{{\_}POSIX2{\_}FORT{\_}DEV}{699}{\code {_POSIX2_FORT_DEV}}
--\entry{{\_}POSIX2{\_}FORT{\_}RUN}{699}{\code {_POSIX2_FORT_RUN}}
--\entry{{\_}POSIX2{\_}LOCALEDEF}{699}{\code {_POSIX2_LOCALEDEF}}
--\entry{{\_}POSIX2{\_}SW{\_}DEV}{699}{\code {_POSIX2_SW_DEV}}
--\entry{{\_}POSIX{\_}VERSION}{699}{\code {_POSIX_VERSION}}
--\entry{{\_}POSIX2{\_}C{\_}VERSION}{700}{\code {_POSIX2_C_VERSION}}
--\entry{LINK{\_}MAX}{709}{\code {LINK_MAX}}
--\entry{MAX{\_}CANON}{709}{\code {MAX_CANON}}
--\entry{MAX{\_}INPUT}{709}{\code {MAX_INPUT}}
--\entry{NAME{\_}MAX}{710}{\code {NAME_MAX}}
--\entry{PATH{\_}MAX}{710}{\code {PATH_MAX}}
--\entry{PIPE{\_}BUF}{710}{\code {PIPE_BUF}}
--\entry{MAXNAMLEN}{710}{\code {MAXNAMLEN}}
--\entry{FILENAME{\_}MAX}{710}{\code {FILENAME_MAX}}
--\entry{{\_}POSIX{\_}CHOWN{\_}RESTRICTED}{711}{\code {_POSIX_CHOWN_RESTRICTED}}
--\entry{{\_}POSIX{\_}NO{\_}TRUNC}{711}{\code {_POSIX_NO_TRUNC}}
--\entry{{\_}POSIX{\_}VDISABLE}{711}{\code {_POSIX_VDISABLE}}
--\entry{BC{\_}BASE{\_}MAX}{713}{\code {BC_BASE_MAX}}
--\entry{BC{\_}DIM{\_}MAX}{713}{\code {BC_DIM_MAX}}
--\entry{BC{\_}SCALE{\_}MAX}{713}{\code {BC_SCALE_MAX}}
--\entry{BC{\_}STRING{\_}MAX}{713}{\code {BC_STRING_MAX}}
--\entry{COLL{\_}WEIGHTS{\_}MAX}{714}{\code {COLL_WEIGHTS_MAX}}
--\entry{EXPR{\_}NEST{\_}MAX}{714}{\code {EXPR_NEST_MAX}}
--\entry{LINE{\_}MAX}{714}{\code {LINE_MAX}}
--\entry{EQUIV{\_}CLASS{\_}MAX}{714}{\code {EQUIV_CLASS_MAX}}
--\entry{SEM{\_}VALUE{\_}MAX}{735}{\code {SEM_VALUE_MAX}}
--\entry{NDEBUG}{743}{\code {NDEBUG}}
--\entry{NULL}{750}{\code {NULL}}
--\entry{SCHAR{\_}MIN}{752}{\code {SCHAR_MIN}}
--\entry{SCHAR{\_}MAX}{752}{\code {SCHAR_MAX}}
--\entry{UCHAR{\_}MAX}{752}{\code {UCHAR_MAX}}
--\entry{CHAR{\_}MIN}{752}{\code {CHAR_MIN}}
--\entry{CHAR{\_}MAX}{753}{\code {CHAR_MAX}}
--\entry{SHRT{\_}MIN}{753}{\code {SHRT_MIN}}
--\entry{SHRT{\_}MAX}{753}{\code {SHRT_MAX}}
--\entry{USHRT{\_}MAX}{753}{\code {USHRT_MAX}}
--\entry{INT{\_}MIN}{753}{\code {INT_MIN}}
--\entry{INT{\_}MAX}{753}{\code {INT_MAX}}
--\entry{UINT{\_}MAX}{753}{\code {UINT_MAX}}
--\entry{LONG{\_}MIN}{753}{\code {LONG_MIN}}
--\entry{LONG{\_}MAX}{753}{\code {LONG_MAX}}
--\entry{ULONG{\_}MAX}{753}{\code {ULONG_MAX}}
--\entry{LONG{\_}LONG{\_}MIN}{753}{\code {LONG_LONG_MIN}}
--\entry{LONG{\_}LONG{\_}MAX}{753}{\code {LONG_LONG_MAX}}
--\entry{ULONG{\_}LONG{\_}MAX}{753}{\code {ULONG_LONG_MAX}}
--\entry{WCHAR{\_}MAX}{753}{\code {WCHAR_MAX}}
--\entry{FLT{\_}ROUNDS}{755}{\code {FLT_ROUNDS}}
--\entry{FLT{\_}RADIX}{756}{\code {FLT_RADIX}}
--\entry{FLT{\_}MANT{\_}DIG}{756}{\code {FLT_MANT_DIG}}
--\entry{DBL{\_}MANT{\_}DIG}{756}{\code {DBL_MANT_DIG}}
--\entry{LDBL{\_}MANT{\_}DIG}{756}{\code {LDBL_MANT_DIG}}
--\entry{FLT{\_}DIG}{756}{\code {FLT_DIG}}
--\entry{DBL{\_}DIG}{756}{\code {DBL_DIG}}
--\entry{LDBL{\_}DIG}{756}{\code {LDBL_DIG}}
--\entry{FLT{\_}MIN{\_}EXP}{756}{\code {FLT_MIN_EXP}}
--\entry{DBL{\_}MIN{\_}EXP}{757}{\code {DBL_MIN_EXP}}
--\entry{LDBL{\_}MIN{\_}EXP}{757}{\code {LDBL_MIN_EXP}}
--\entry{FLT{\_}MIN{\_}10{\_}EXP}{757}{\code {FLT_MIN_10_EXP}}
--\entry{DBL{\_}MIN{\_}10{\_}EXP}{757}{\code {DBL_MIN_10_EXP}}
--\entry{LDBL{\_}MIN{\_}10{\_}EXP}{757}{\code {LDBL_MIN_10_EXP}}
--\entry{FLT{\_}MAX{\_}EXP}{757}{\code {FLT_MAX_EXP}}
--\entry{DBL{\_}MAX{\_}EXP}{757}{\code {DBL_MAX_EXP}}
--\entry{LDBL{\_}MAX{\_}EXP}{757}{\code {LDBL_MAX_EXP}}
--\entry{FLT{\_}MAX{\_}10{\_}EXP}{757}{\code {FLT_MAX_10_EXP}}
--\entry{DBL{\_}MAX{\_}10{\_}EXP}{757}{\code {DBL_MAX_10_EXP}}
--\entry{LDBL{\_}MAX{\_}10{\_}EXP}{757}{\code {LDBL_MAX_10_EXP}}
--\entry{FLT{\_}MAX}{757}{\code {FLT_MAX}}
--\entry{DBL{\_}MAX}{757}{\code {DBL_MAX}}
--\entry{LDBL{\_}MAX}{757}{\code {LDBL_MAX}}
--\entry{FLT{\_}MIN}{757}{\code {FLT_MIN}}
--\entry{DBL{\_}MIN}{758}{\code {DBL_MIN}}
--\entry{LDBL{\_}MIN}{758}{\code {LDBL_MIN}}
--\entry{FLT{\_}EPSILON}{758}{\code {FLT_EPSILON}}
--\entry{DBL{\_}EPSILON}{758}{\code {DBL_EPSILON}}
--\entry{LDBL{\_}EPSILON}{758}{\code {LDBL_EPSILON}}
-diff -Naur ../glibc-2.1.3/manual/libc.vrs glibc-2.1.3/manual/libc.vrs
---- ../glibc-2.1.3/manual/libc.vrs 2000-01-05 19:19:03.000000000 -0800
-+++ glibc-2.1.3/manual/libc.vrs 1969-12-31 16:00:00.000000000 -0800
-@@ -1,869 +0,0 @@
--\initial {(}
--\entry {\code {(*gconv_end_fct)}}{135}
--\entry {\code {(*gconv_fct)}}{135}
--\entry {\code {(*gconv_init_fct)}}{132}
--\initial {{\_}}
--\entry {\code {__free_hook}}{39}
--\entry {\code {__malloc_hook}}{39}
--\entry {\code {__memalign_hook}}{39}
--\entry {\code {__realloc_hook}}{39}
--\entry {\code {_BSD_SOURCE}}{8}
--\entry {\code {_Complex_I}}{476}
--\entry {\code {_FILE_OFFSET_BITS}}{9}
--\entry {\code {_GNU_SOURCE}}{10}
--\entry {\code {_IOFBF}}{258}
--\entry {\code {_IOLBF}}{258}
--\entry {\code {_IONBF}}{258}
--\entry {\code {_LARGEFILE_SOURCE}}{9}
--\entry {\code {_LARGEFILE64_SOURCE}}{9}
--\entry {\code {_PATH_FSTAB}}{691}
--\entry {\code {_PATH_MNTTAB}}{691}
--\entry {\code {_PATH_MOUNTED}}{691}
--\entry {\code {_PATH_UTMP}}{675}
--\entry {\code {_PATH_WTMP}}{675}
--\entry {\code {_POSIX_C_SOURCE}}{8}
--\entry {\code {_POSIX_CHOWN_RESTRICTED}}{711}
--\entry {\code {_POSIX_JOB_CONTROL}}{698}
--\entry {\code {_POSIX_NO_TRUNC}}{711}
--\entry {\code {_POSIX_SAVED_IDS}}{698}
--\entry {\code {_POSIX_SOURCE}}{7}
--\entry {\code {_POSIX_VDISABLE}}{425, 711}
--\entry {\code {_POSIX_VERSION}}{699}
--\entry {\code {_POSIX2_C_DEV}}{699}
--\entry {\code {_POSIX2_C_VERSION}}{700}
--\entry {\code {_POSIX2_FORT_DEV}}{699}
--\entry {\code {_POSIX2_FORT_RUN}}{699}
--\entry {\code {_POSIX2_LOCALEDEF}}{699}
--\entry {\code {_POSIX2_SW_DEV}}{699}
--\entry {\code {_REENTRANT}}{10}
--\entry {\code {_SVID_SOURCE}}{8}
--\entry {\code {_THREAD_SAFE}}{10}
--\entry {\code {_XOPEN_SOURCE}}{8}
--\entry {\code {_XOPEN_SOURCE_EXTENDED}}{8}
--\initial {A}
--\entry {\code {ABDAY_1}}{150}
--\entry {\code {ABDAY_2}}{150}
--\entry {\code {ABDAY_3}}{150}
--\entry {\code {ABDAY_4}}{150}
--\entry {\code {ABDAY_5}}{150}
--\entry {\code {ABDAY_6}}{150}
--\entry {\code {ABDAY_7}}{150}
--\entry {\code {ABMON_1}}{150}
--\entry {\code {ABMON_10}}{150}
--\entry {\code {ABMON_11}}{150}
--\entry {\code {ABMON_12}}{150}
--\entry {\code {ABMON_2}}{150}
--\entry {\code {ABMON_3}}{150}
--\entry {\code {ABMON_4}}{150}
--\entry {\code {ABMON_5}}{150}
--\entry {\code {ABMON_6}}{150}
--\entry {\code {ABMON_7}}{150}
--\entry {\code {ABMON_8}}{150}
--\entry {\code {ABMON_9}}{150}
--\entry {\code {ACCOUNTING}}{673}
--\entry {\code {AF_FILE}}{366}
--\entry {\code {AF_INET}}{366}
--\entry {\code {AF_INET6}}{371}
--\entry {\code {AF_LOCAL}}{366}
--\entry {\code {AF_UNIX}}{366}
--\entry {\code {AF_UNSPEC}}{366}
--\entry {\code {aliases}}{651}
--\entry {\code {ALT_DIGITS}}{152}
--\entry {\code {ALTWERASE}}{423}
--\entry {\code {AM_STR}}{151}
--\entry {\code {ARG_MAX}}{697}
--\entry {\code {argp_err_exit_status}}{585}
--\entry {\code {ARGP_ERR_UNKNOWN}}{589}
--\entry {\code {ARGP_HELP_BUG_ADDR}}{597}
--\entry {\code {ARGP_HELP_DOC}}{597}
--\entry {\code {ARGP_HELP_EXIT_ERR}}{597}
--\entry {\code {ARGP_HELP_EXIT_OK}}{597}
--\entry {\code {ARGP_HELP_LONG}}{597}
--\entry {\code {ARGP_HELP_LONG_ONLY}}{597}
--\entry {\code {ARGP_HELP_POST_DOC}}{597}
--\entry {\code {ARGP_HELP_PRE_DOC}}{597}
--\entry {\code {ARGP_HELP_SEE}}{597}
--\entry {\code {ARGP_HELP_SHORT_USAGE}}{597}
--\entry {\code {ARGP_HELP_STD_ERR}}{597}
--\entry {\code {ARGP_HELP_STD_HELP}}{597}
--\entry {\code {ARGP_HELP_STD_USAGE}}{597}
--\entry {\code {ARGP_HELP_USAGE}}{596}
--\entry {\code {ARGP_IN_ORDER}}{595}
--\entry {\code {ARGP_KEY_ARG}}{589}
--\entry {\code {ARGP_KEY_ARGS}}{589}
--\entry {\code {ARGP_KEY_END}}{590}
--\entry {\code {ARGP_KEY_ERROR}}{590}
--\entry {\code {ARGP_KEY_FINI}}{590}
--\entry {\code {ARGP_KEY_HELP_ARGS_DOC}}{596}
--\entry {\code {ARGP_KEY_HELP_DUP_ARGS_NOTE}}{596}
--\entry {\code {ARGP_KEY_HELP_EXTRA}}{596}
--\entry {\code {ARGP_KEY_HELP_HEADER}}{596}
--\entry {\code {ARGP_KEY_HELP_POST_DOC}}{596}
--\entry {\code {ARGP_KEY_HELP_PRE_DOC}}{596}
--\entry {\code {ARGP_KEY_INIT}}{590}
--\entry {\code {ARGP_KEY_NO_ARGS}}{590}
--\entry {\code {ARGP_KEY_SUCCESS}}{590}
--\entry {\code {ARGP_LONG_ONLY}}{595}
--\entry {\code {ARGP_NO_ARGS}}{595}
--\entry {\code {ARGP_NO_ERRS}}{594}
--\entry {\code {ARGP_NO_EXIT}}{595}
--\entry {\code {ARGP_NO_HELP}}{595}
--\entry {\code {ARGP_PARSE_ARGV0}}{594}
--\entry {\code {argp_program_bug_address}}{585}
--\entry {\code {argp_program_version}}{585}
--\entry {\code {argp_program_version_hook}}{585}
--\entry {\code {ARGP_SILENT}}{595}
--\initial {B}
--\entry {\code {B0}}{424}
--\entry {\code {B110}}{424}
--\entry {\code {B115200}}{424}
--\entry {\code {B1200}}{424}
--\entry {\code {B134}}{424}
--\entry {\code {B150}}{424}
--\entry {\code {B1800}}{424}
--\entry {\code {B19200}}{424}
--\entry {\code {B200}}{424}
--\entry {\code {B230400}}{424}
--\entry {\code {B2400}}{424}
--\entry {\code {B300}}{424}
--\entry {\code {B38400}}{424}
--\entry {\code {B460800}}{424}
--\entry {\code {B4800}}{424}
--\entry {\code {B50}}{424}
--\entry {\code {B57600}}{424}
--\entry {\code {B600}}{424}
--\entry {\code {B75}}{424}
--\entry {\code {B9600}}{424}
--\entry {\code {BC_BASE_MAX}}{713}
--\entry {\code {BC_DIM_MAX}}{713}
--\entry {\code {BC_SCALE_MAX}}{713}
--\entry {\code {BC_STRING_MAX}}{713}
--\entry {\code {BOOT_TIME}}{672, 676}
--\entry {\code {BRKINT}}{417}
--\entry {\code {BUFSIZ}}{258}
--\initial {C}
--\entry {\code {CCTS_OFLOW}}{420}
--\entry {\code {CHAR_MAX}}{753}
--\entry {\code {CHAR_MIN}}{752}
--\entry {\code {CHILD_MAX}}{697}
--\entry {\code {CIGNORE}}{420}
--\entry {\code {CLK_TCK}}{488}
--\entry {\code {CLOCAL}}{419}
--\entry {\code {CLOCKS_PER_SEC}}{488}
--\entry {\code {COLL_WEIGHTS_MAX}}{714}
--\entry {\code {COREFILE}}{530}
--\entry {\code {CREAD}}{419}
--\entry {\code {CRNCYSTR}}{152}
--\entry {\code {CRTS_IFLOW}}{420}
--\entry {\code {CS5}}{420}
--\entry {\code {CS6}}{420}
--\entry {\code {CS7}}{420}
--\entry {\code {CS8}}{420}
--\entry {\code {CSIZE}}{420}
--\entry {\code {CSTOPB}}{419}
--\entry {\code {CURRENCY_SYMBOL}}{152}
--\initial {D}
--\entry {\code {D_FMT}}{151}
--\entry {\code {D_T_FMT}}{151}
--\entry {\code {DAY_1}}{150}
--\entry {\code {DAY_2}}{150}
--\entry {\code {DAY_3}}{150}
--\entry {\code {DAY_4}}{150}
--\entry {\code {DAY_5}}{150}
--\entry {\code {DAY_6}}{150}
--\entry {\code {DAY_7}}{150}
--\entry {\code {daylight}}{510}
--\entry {\code {DBL_DIG}}{756}
--\entry {\code {DBL_EPSILON}}{758}
--\entry {\code {DBL_MANT_DIG}}{756}
--\entry {\code {DBL_MAX}}{757}
--\entry {\code {DBL_MAX_10_EXP}}{757}
--\entry {\code {DBL_MAX_EXP}}{757}
--\entry {\code {DBL_MIN}}{758}
--\entry {\code {DBL_MIN_10_EXP}}{757}
--\entry {\code {DBL_MIN_EXP}}{757}
--\entry {\code {DEAD_PROCESS}}{673, 677}
--\entry {\code {DECIMAL_POINT}}{153}
--\initial {E}
--\entry {\code {E2BIG}}{17}
--\entry {\code {EACCES}}{17}
--\entry {\code {EADDRINUSE}}{21}
--\entry {\code {EADDRNOTAVAIL}}{21}
--\entry {\code {EADV}}{26}
--\entry {\code {EAFNOSUPPORT}}{21}
--\entry {\code {EAGAIN}}{19}
--\entry {\code {EALREADY}}{20}
--\entry {\code {EAUTH}}{24}
--\entry {\code {EBACKGROUND}}{24}
--\entry {\code {EBADE}}{25}
--\entry {\code {EBADF}}{17, 432}
--\entry {\code {EBADFD}}{26}
--\entry {\code {EBADMSG}}{25}
--\entry {\code {EBADR}}{25}
--\entry {\code {EBADRPC}}{23}
--\entry {\code {EBADRQC}}{26}
--\entry {\code {EBADSLT}}{26}
--\entry {\code {EBFONT}}{26}
--\entry {\code {EBUSY}}{17}
--\entry {\code {ECHILD}}{17}
--\entry {\code {ECHO}}{421}
--\entry {\code {ECHOCTL}}{422}
--\entry {\code {ECHOE}}{421}
--\entry {\code {ECHOK}}{421}
--\entry {\code {ECHOKE}}{422}
--\entry {\code {ECHONL}}{422}
--\entry {\code {ECHOPRT}}{421}
--\entry {\code {ECHRNG}}{25}
--\entry {\code {ECOMM}}{26}
--\entry {\code {ECONNABORTED}}{21}
--\entry {\code {ECONNREFUSED}}{22}
--\entry {\code {ECONNRESET}}{21}
--\entry {\code {ED}}{24}
--\entry {\code {EDEADLK}}{17}
--\entry {\code {EDEADLOCK}}{26}
--\entry {\code {EDESTADDRREQ}}{22}
--\entry {\code {EDIED}}{24}
--\entry {\code {EDOM}}{19}
--\entry {\code {EDOTDOT}}{26}
--\entry {\code {EDQUOT}}{23}
--\entry {\code {EEXIST}}{18}
--\entry {\code {EFAULT}}{17}
--\entry {\code {EFBIG}}{19}
--\entry {\code {EFTYPE}}{23}
--\entry {\code {EGRATUITOUS}}{25}
--\entry {\code {EGREGIOUS}}{24}
--\entry {\code {EHOSTDOWN}}{22}
--\entry {\code {EHOSTUNREACH}}{22}
--\entry {\code {EIDRM}}{25}
--\entry {\code {EIEIO}}{24}
--\entry {\code {EILSEQ}}{24}
--\entry {\code {EINPROGRESS}}{20}
--\entry {\code {EINTR}}{16}
--\entry {\code {EINVAL}}{18, 432}
--\entry {\code {EIO}}{16}
--\entry {\code {EISCONN}}{21}
--\entry {\code {EISDIR}}{18}
--\entry {\code {EISNAM}}{26}
--\entry {\code {EL2HLT}}{25}
--\entry {\code {EL2NSYNC}}{25}
--\entry {\code {EL3HLT}}{25}
--\entry {\code {EL3RST}}{25}
--\entry {\code {ELIBACC}}{26}
--\entry {\code {ELIBBAD}}{26}
--\entry {\code {ELIBEXEC}}{26}
--\entry {\code {ELIBMAX}}{26}
--\entry {\code {ELIBSCN}}{26}
--\entry {\code {ELNRNG}}{25}
--\entry {\code {ELOOP}}{22}
--\entry {\code {EMEDIUMTYPE}}{26}
--\entry {\code {EMFILE}}{18}
--\entry {\code {EMLINK}}{19}
--\entry {\code {EMPTY}}{672, 676}
--\entry {\code {EMSGSIZE}}{20}
--\entry {\code {EMULTIHOP}}{25}
--\entry {\code {ENAMETOOLONG}}{22}
--\entry {\code {ENAVAIL}}{26}
--\entry {\code {ENEEDAUTH}}{24}
--\entry {\code {ENETDOWN}}{21}
--\entry {\code {ENETRESET}}{21}
--\entry {\code {ENETUNREACH}}{21}
--\entry {\code {ENFILE}}{18}
--\entry {\code {ENOANO}}{26}
--\entry {\code {ENOBUFS}}{21}
--\entry {\code {ENOCSI}}{25}
--\entry {\code {ENODATA}}{25}
--\entry {\code {ENODEV}}{18}
--\entry {\code {ENOENT}}{16}
--\entry {\code {ENOEXEC}}{17}
--\entry {\code {ENOLCK}}{23}
--\entry {\code {ENOLINK}}{25}
--\entry {\code {ENOMEDIUM}}{26}
--\entry {\code {ENOMEM}}{17}
--\entry {\code {ENOMSG}}{25}
--\entry {\code {ENONET}}{26}
--\entry {\code {ENOPKG}}{26}
--\entry {\code {ENOPROTOOPT}}{20}
--\entry {\code {ENOSPC}}{19}
--\entry {\code {ENOSR}}{25}
--\entry {\code {ENOSTR}}{25}
--\entry {\code {ENOSYS}}{24}
--\entry {\code {ENOTBLK}}{17}
--\entry {\code {ENOTCONN}}{22}
--\entry {\code {ENOTDIR}}{18}
--\entry {\code {ENOTEMPTY}}{22}
--\entry {\code {ENOTNAM}}{26}
--\entry {\code {ENOTSOCK}}{20}
--\entry {\code {ENOTSUP}}{24}
--\entry {\code {ENOTTY}}{18, 432}
--\entry {\code {ENOTUNIQ}}{26}
--\entry {\code {environ}}{611}
--\entry {\code {ENXIO}}{17}
--\entry {\code {EOF}}{250}
--\entry {\code {EOPNOTSUPP}}{21}
--\entry {\code {EOVERFLOW}}{25}
--\entry {\code {EPERM}}{16}
--\entry {\code {EPFNOSUPPORT}}{21}
--\entry {\code {EPIPE}}{19}
--\entry {\code {EPROCLIM}}{23}
--\entry {\code {EPROCUNAVAIL}}{23}
--\entry {\code {EPROGMISMATCH}}{23}
--\entry {\code {EPROGUNAVAIL}}{23}
--\entry {\code {EPROTO}}{25}
--\entry {\code {EPROTONOSUPPORT}}{20}
--\entry {\code {EPROTOTYPE}}{20}
--\entry {\code {EQUIV_CLASS_MAX}}{714}
--\entry {\code {ERA}}{151}
--\entry {\code {ERA_D_FMT}}{152}
--\entry {\code {ERA_D_T_FMT}}{152}
--\entry {\code {ERA_T_FMT}}{152}
--\entry {\code {ERA_YEAR}}{151}
--\entry {\code {ERANGE}}{19}
--\entry {\code {EREMCHG}}{26}
--\entry {\code {EREMOTE}}{23}
--\entry {\code {EREMOTEIO}}{26}
--\entry {\code {ERESTART}}{25}
--\entry {\code {EROFS}}{19}
--\entry {\code {ERPCMISMATCH}}{23}
--\entry {\code {errno}}{15}
--\entry {\code {ESHUTDOWN}}{22}
--\entry {\code {ESOCKTNOSUPPORT}}{20}
--\entry {\code {ESPIPE}}{19}
--\entry {\code {ESRCH}}{16}
--\entry {\code {ESRMNT}}{26}
--\entry {\code {ESTALE}}{23}
--\entry {\code {ESTRPIPE}}{26}
--\entry {\code {ethers}}{651}
--\entry {\code {ETIME}}{25}
--\entry {\code {ETIMEDOUT}}{22}
--\entry {\code {ETOOMANYREFS}}{22}
--\entry {\code {ETXTBSY}}{18}
--\entry {\code {EUCLEAN}}{26}
--\entry {\code {EUNATCH}}{25}
--\entry {\code {EUSERS}}{23}
--\entry {\code {EWOULDBLOCK}}{20}
--\entry {\code {EXDEV}}{18}
--\entry {\code {EXFULL}}{26}
--\entry {\code {EXIT_FAILURE}}{615}
--\entry {\code {EXIT_SUCCESS}}{614}
--\entry {\code {EXPR_NEST_MAX}}{714}
--\entry {\code {EXTA}}{424}
--\entry {\code {EXTB}}{424}
--\initial {F}
--\entry {\code {F_DUPFD}}{306}
--\entry {\code {F_GETFD}}{307}
--\entry {\code {F_GETFL}}{313}
--\entry {\code {F_GETLK}}{315}
--\entry {\code {F_GETOWN}}{317}
--\entry {\code {F_OK}}{349}
--\entry {\code {F_RDLCK}}{316}
--\entry {\code {F_SETFD}}{308}
--\entry {\code {F_SETFL}}{313}
--\entry {\code {F_SETLK}}{315}
--\entry {\code {F_SETLKW}}{316}
--\entry {\code {F_SETOWN}}{317}
--\entry {\code {F_UNLCK}}{317}
--\entry {\code {F_WRLCK}}{317}
--\entry {\code {FD_CLOEXEC}}{308}
--\entry {\code {FD_SETSIZE}}{289}
--\entry {\code {FE_DFL_ENV}}{468}
--\entry {\code {FE_DIVBYZERO}}{464}
--\entry {\code {FE_DOWNWARD}}{466}
--\entry {\code {FE_INEXACT}}{464}
--\entry {\code {FE_INVALID}}{464}
--\entry {\code {FE_NOMASK_ENV}}{468}
--\entry {\code {FE_OVERFLOW}}{464}
--\entry {\code {FE_TONEAREST}}{466}
--\entry {\code {FE_TOWARDZERO}}{466}
--\entry {\code {FE_UNDERFLOW}}{464}
--\entry {\code {FE_UPWARD}}{466}
--\entry {\code {FILENAME_MAX}}{710}
--\entry {\code {FLT_DIG}}{756}
--\entry {\code {FLT_EPSILON}}{758}
--\entry {\code {FLT_MANT_DIG}}{756}
--\entry {\code {FLT_MAX}}{757}
--\entry {\code {FLT_MAX_10_EXP}}{757}
--\entry {\code {FLT_MAX_EXP}}{757}
--\entry {\code {FLT_MIN}}{757}
--\entry {\code {FLT_MIN_10_EXP}}{757}
--\entry {\code {FLT_MIN_EXP}}{756}
--\entry {\code {FLT_RADIX}}{756}
--\entry {\code {FLT_ROUNDS}}{755}
--\entry {\code {FLUSHO}}{423}
--\entry {\code {FOPEN_MAX}}{213}
--\entry {\code {FP_FAST_FMA}}{476}
--\entry {\code {FP_ILOGB0}}{444}
--\entry {\code {FP_ILOGBNAN}}{444}
--\entry {\code {FP_INFINITE}}{459}
--\entry {\code {FP_NAN}}{459}
--\entry {\code {FP_NORMAL}}{460}
--\entry {\code {FP_SUBNORMAL}}{460}
--\entry {\code {FP_ZERO}}{459}
--\entry {\code {FPE_DECOVF_TRAP}}{531}
--\entry {\code {FPE_FLTDIV_TRAP}}{531}
--\entry {\code {FPE_FLTOVF_TRAP}}{531}
--\entry {\code {FPE_FLTUND_TRAP}}{531}
--\entry {\code {FPE_INTDIV_TRAP}}{530}
--\entry {\code {FPE_INTOVF_TRAP}}{530}
--\entry {\code {FPE_SUBRNG_TRAP}}{530}
--\entry {\code {FRAC_DIGITS}}{153}
--\entry {\code {FSTAB}}{691}
--\entry {\code {FSTAB_RO}}{692}
--\entry {\code {FSTAB_RQ}}{692}
--\entry {\code {FSTAB_RW}}{692}
--\entry {\code {FSTAB_SW}}{692}
--\entry {\code {FSTAB_XX}}{692}
--\entry {\code {FTW_CHDIR}}{330}
--\entry {\code {FTW_D}}{327}
--\entry {\code {FTW_DEPTH}}{330}
--\entry {\code {FTW_DNR}}{327}
--\entry {\code {FTW_DP}}{328}
--\entry {\code {FTW_F}}{327}
--\entry {\code {FTW_MOUNT}}{330}
--\entry {\code {FTW_NS}}{327}
--\entry {\code {FTW_PHYS}}{330}
--\entry {\code {FTW_SL}}{327}
--\entry {\code {FTW_SLN}}{328}
--\initial {G}
--\entry {\code {getdate_err}}{505}
--\entry {\code {group}}{651}
--\entry {\code {GROUPING}}{153}
--\initial {H}
--\entry {\code {h_errno}}{378}
--\entry {\code {HOST_NOT_FOUND}}{379}
--\entry {\code {hosts}}{651}
--\entry {\code {HUGE_VAL}}{466}
--\entry {\code {HUGE_VALF}}{466}
--\entry {\code {HUGE_VALL}}{466}
--\entry {\code {HUPCL}}{419}
--\initial {I}
--\entry {\code {I}}{477}
--\entry {\code {ICANON}}{421}
--\entry {\code {ICRNL}}{417}
--\entry {\code {IEXTEN}}{422}
--\entry {\code {IFNAMSIZ}}{368}
--\entry {\code {IGNBRK}}{417}
--\entry {\code {IGNCR}}{417}
--\entry {\code {IGNPAR}}{416}
--\entry {\code {IMAXBEL}}{418}
--\entry {\code {in6addr_any}}{375}
--\entry {\code {in6addr_loopback}}{375}
--\entry {\code {INADDR_ANY}}{375}
--\entry {\code {INADDR_BROADCAST}}{375}
--\entry {\code {INADDR_LOOPBACK}}{375}
--\entry {\code {INADDR_NONE}}{375}
--\entry {\code {INFINITY}}{463}
--\entry {\code {INIT_PROCESS}}{672, 677}
--\entry {\code {INLCR}}{417}
--\entry {\code {INPCK}}{416}
--\entry {\code {INT_CURR_SYMBOL}}{152}
--\entry {\code {INT_FRAC_DIGITS}}{152}
--\entry {\code {INT_MAX}}{753}
--\entry {\code {INT_MIN}}{753}
--\entry {\code {IPPORT_RESERVED}}{381}
--\entry {\code {IPPORT_USERRESERVED}}{381}
--\entry {\code {ISIG}}{422}
--\entry {\code {ISTRIP}}{417}
--\entry {\code {IXANY}}{418}
--\entry {\code {IXOFF}}{418}
--\entry {\code {IXON}}{418}
--\initial {L}
--\entry {\code {L_ctermid}}{646}
--\entry {\code {L_cuserid}}{671}
--\entry {\code {L_INCR}}{254}
--\entry {\code {L_SET}}{254}
--\entry {\code {L_tmpnam}}{354}
--\entry {\code {L_XTND}}{254}
--\entry {\code {LANG}}{143}
--\entry {\code {LANGUAGE}}{143}
--\entry {\code {LC_ALL}}{143}
--\entry {\code {LC_COLLATE}}{142}
--\entry {\code {LC_CTYPE}}{142}
--\entry {\code {LC_MESSAGES}}{142}
--\entry {\code {LC_MONETARY}}{142}
--\entry {\code {LC_NUMERIC}}{142}
--\entry {\code {LC_TIME}}{142}
--\entry {\code {LDBL_DIG}}{756}
--\entry {\code {LDBL_EPSILON}}{758}
--\entry {\code {LDBL_MANT_DIG}}{756}
--\entry {\code {LDBL_MAX}}{757}
--\entry {\code {LDBL_MAX_10_EXP}}{757}
--\entry {\code {LDBL_MAX_EXP}}{757}
--\entry {\code {LDBL_MIN}}{758}
--\entry {\code {LDBL_MIN_10_EXP}}{757}
--\entry {\code {LDBL_MIN_EXP}}{757}
--\entry {\code {LINE_MAX}}{714}
--\entry {\code {LINK_MAX}}{709}
--\entry {\code {LIO_NOP}}{294}
--\entry {\code {LIO_READ}}{294}
--\entry {\code {LIO_WRITE}}{294}
--\entry {\code {LOGIN_PROCESS}}{672, 677}
--\entry {\code {LONG_LONG_MAX}}{753}
--\entry {\code {LONG_LONG_MIN}}{753}
--\entry {\code {LONG_MAX}}{753}
--\entry {\code {LONG_MIN}}{753}
--\initial {M}
--\entry {\code {M_1_PI}}{439}
--\entry {\code {M_2_PI}}{439}
--\entry {\code {M_2_SQRTPI}}{439}
--\entry {\code {M_E}}{439}
--\entry {\code {M_LN10}}{439}
--\entry {\code {M_LN2}}{439}
--\entry {\code {M_LOG10E}}{439}
--\entry {\code {M_LOG2E}}{439}
--\entry {\code {M_PI}}{439}
--\entry {\code {M_PI_2}}{439}
--\entry {\code {M_PI_4}}{439}
--\entry {\code {M_SQRT1_2}}{439}
--\entry {\code {M_SQRT2}}{439}
--\entry {\code {MAP_ANON}}{287}
--\entry {\code {MAP_ANONYMOUS}}{287}
--\entry {\code {MAP_FIXED}}{287}
--\entry {\code {MAP_PRIVATE}}{286}
--\entry {\code {MAP_SHARED}}{287}
--\entry {\code {MAX_CANON}}{709}
--\entry {\code {MAX_INPUT}}{709}
--\entry {\code {MAXNAMLEN}}{710}
--\entry {\code {MB_CUR_MAX}}{102}
--\entry {\code {MB_LEN_MAX}}{102}
--\entry {\code {MDMBUF}}{420}
--\entry {\code {MINSIGSTKSZ}}{570}
--\entry {\code {MM_APPL}}{265}
--\entry {\code {MM_CONSOLE}}{264}
--\entry {\code {MM_ERROR}}{266}
--\entry {\code {MM_FIRM}}{265}
--\entry {\code {MM_HALT}}{266}
--\entry {\code {MM_HARD}}{265}
--\entry {\code {MM_INFO}}{266}
--\entry {\code {MM_NOSEV}}{266}
--\entry {\code {MM_NRECOV}}{265}
--\entry {\code {MM_NULLACT}}{266}
--\entry {\code {MM_NULLLBL}}{265}
--\entry {\code {MM_NULLMC}}{265}
--\entry {\code {MM_NULLSEV}}{265}
--\entry {\code {MM_NULLTAG}}{266}
--\entry {\code {MM_NULLTXT}}{265}
--\entry {\code {MM_OPSYS}}{265}
--\entry {\code {MM_PRINT}}{264}
--\entry {\code {MM_RECOVER}}{265}
--\entry {\code {MM_SOFT}}{265}
--\entry {\code {MM_UTIL}}{265}
--\entry {\code {MM_WARNING}}{266}
--\entry {\code {MNTOPT_DEFAULTS}}{694}
--\entry {\code {MNTOPT_NOAUTO}}{695}
--\entry {\code {MNTOPT_NOSUID}}{695}
--\entry {\code {MNTOPT_RO}}{694}
--\entry {\code {MNTOPT_RW}}{694}
--\entry {\code {MNTOPT_SUID}}{694}
--\entry {\code {MNTTYPE_IGNORE}}{694}
--\entry {\code {MNTTYPE_NFS}}{694}
--\entry {\code {MNTTYPE_SWAP}}{694}
--\entry {\code {MON_1}}{150}
--\entry {\code {MON_10}}{151}
--\entry {\code {MON_11}}{151}
--\entry {\code {MON_12}}{151}
--\entry {\code {MON_2}}{151}
--\entry {\code {MON_3}}{151}
--\entry {\code {MON_4}}{151}
--\entry {\code {MON_5}}{151}
--\entry {\code {MON_6}}{151}
--\entry {\code {MON_7}}{151}
--\entry {\code {MON_8}}{151}
--\entry {\code {MON_9}}{151}
--\entry {\code {MON_DECIMAL_POINT}}{152}
--\entry {\code {MON_GROUPING}}{152}
--\entry {\code {MON_THOUSANDS_SEP}}{152}
--\entry {\code {MS_ASYNC}}{288}
--\entry {\code {MS_SYNC}}{288}
--\entry {\code {MSG_DONTROUTE}}{394}
--\entry {\code {MSG_OOB}}{394}
--\entry {\code {MSG_PEEK}}{394}
--\initial {N}
--\entry {\code {N_CS_PRECEDES}}{153}
--\entry {\code {N_SEP_BY_SPACE}}{153}
--\entry {\code {N_SIGN_POSN}}{153}
--\entry {\code {NAME_MAX}}{710}
--\entry {\code {NAN}}{463}
--\entry {\code {NCCS}}{414}
--\entry {\code {NDEBUG}}{743}
--\entry {\code {NEGATIVE_SIGN}}{152}
--\entry {\code {netgroup}}{651}
--\entry {\code {networks}}{651}
--\entry {\code {NEW_TIME}}{672, 677}
--\entry {\code {NGROUPS_MAX}}{698}
--\entry {\code {NL_ARGMAX}}{223}
--\entry {\code {NO_ADDRESS}}{379}
--\entry {\code {NO_RECOVERY}}{379}
--\entry {\code {NOEXPR}}{153}
--\entry {\code {NOFLSH}}{422}
--\entry {\code {NOKERNINFO}}{423}
--\entry {\code {NOSTR}}{154}
--\entry {\code {NSIG}}{529}
--\entry {\code {NSS_STATUS_NOTFOUND}}{656}
--\entry {\code {NSS_STATUS_SUCCESS}}{656}
--\entry {\code {NSS_STATUS_TRYAGAIN}}{656}
--\entry {\code {NSS_STATUS_UNAVAIL}}{656}
--\entry {\code {NULL}}{750}
--\initial {O}
--\entry {\code {O_ACCMODE}}{310}
--\entry {\code {O_APPEND}}{312}
--\entry {\code {O_ASYNC}}{312}
--\entry {\code {O_CREAT}}{310}
--\entry {\code {O_EXCL}}{310}
--\entry {\code {O_EXEC}}{310}
--\entry {\code {O_EXLOCK}}{312}
--\entry {\code {O_FSYNC}}{312}
--\entry {\code {O_IGNORE_CTTY}}{311}
--\entry {\code {O_NDELAY}}{312}
--\entry {\code {O_NOATIME}}{313}
--\entry {\code {O_NOCTTY}}{311}
--\entry {\code {O_NOLINK}}{311}
--\entry {\code {O_NONBLOCK}}{310, 312}
--\entry {\code {O_NOTRANS}}{311}
--\entry {\code {O_RDONLY}}{309}
--\entry {\code {O_RDWR}}{309}
--\entry {\code {O_READ}}{309}
--\entry {\code {O_SHLOCK}}{311}
--\entry {\code {O_SYNC}}{312}
--\entry {\code {O_TRUNC}}{311}
--\entry {\code {O_WRITE}}{309}
--\entry {\code {O_WRONLY}}{309}
--\entry {\code {obstack_alloc_failed_handler}}{48}
--\entry {\code {OLD_TIME}}{672, 677}
--\entry {\code {ONLCR}}{419}
--\entry {\code {ONOEOT}}{419}
--\entry {\code {OPEN_MAX}}{697}
--\entry {\code {OPOST}}{418}
--\entry {\code {optarg}}{577}
--\entry {\code {opterr}}{577}
--\entry {\code {optind}}{577}
--\entry {\code {OPTION_ALIAS}}{587}
--\entry {\code {OPTION_ARG_OPTIONAL}}{587}
--\entry {\code {OPTION_DOC}}{587}
--\entry {\code {OPTION_HIDDEN}}{587}
--\entry {\code {OPTION_NO_USAGE}}{588}
--\entry {\code {optopt}}{577}
--\entry {\code {OXTABS}}{419}
--\initial {P}
--\entry {\code {P_CS_PRECEDES}}{153}
--\entry {\code {P_SEP_BY_SPACE}}{153}
--\entry {\code {P_SIGN_POSN}}{153}
--\entry {\code {P_tmpdir}}{355}
--\entry {\code {PA_CHAR}}{234}
--\entry {\code {PA_DOUBLE}}{235}
--\entry {\code {PA_FLAG_LONG}}{235}
--\entry {\code {PA_FLAG_LONG_DOUBLE}}{235}
--\entry {\code {PA_FLAG_LONG_LONG}}{235}
--\entry {\code {PA_FLAG_MASK}}{234}
--\entry {\code {PA_FLAG_PTR}}{235}
--\entry {\code {PA_FLAG_SHORT}}{235}
--\entry {\code {PA_FLOAT}}{234}
--\entry {\code {PA_INT}}{234}
--\entry {\code {PA_LAST}}{235}
--\entry {\code {PA_POINTER}}{234}
--\entry {\code {PA_STRING}}{234}
--\entry {\code {PARENB}}{420}
--\entry {\code {PARMRK}}{417}
--\entry {\code {PARODD}}{420}
--\entry {\code {passwd}}{651}
--\entry {\code {PATH_MAX}}{710}
--\entry {\code {PENDIN}}{423}
--\entry {\code {PF_CCITT}}{386}
--\entry {\code {PF_FILE}}{369}
--\entry {\code {PF_IMPLINK}}{386}
--\entry {\code {PF_INET}}{371}
--\entry {\code {PF_ISO}}{386}
--\entry {\code {PF_LOCAL}}{369}
--\entry {\code {PF_NS}}{386}
--\entry {\code {PF_ROUTE}}{386}
--\entry {\code {PF_UNIX}}{369}
--\entry {\code {PI}}{440}
--\entry {\code {PIPE_BUF}}{710}
--\entry {\code {PM_STR}}{151}
--\entry {\code {POSITIVE_SIGN}}{152}
--\entry {\code {PRIO_MAX}}{521}
--\entry {\code {PRIO_MIN}}{521}
--\entry {\code {PRIO_PGRP}}{522}
--\entry {\code {PRIO_PROCESS}}{522}
--\entry {\code {PRIO_USER}}{522}
--\entry {\code {program_invocation_name}}{28}
--\entry {\code {program_invocation_short_name}}{28}
--\entry {\code {PROT_EXEC}}{286}
--\entry {\code {PROT_READ}}{286}
--\entry {\code {PROT_WRITE}}{286}
--\entry {\code {protocols}}{651}
--\initial {R}
--\entry {\code {R_OK}}{349}
--\entry {\code {RADIXCHAR}}{153}
--\entry {\code {RAND_MAX}}{452}
--\entry {\code {RE_DUP_MAX}}{698}
--\entry {\code {RLIM_INFINITY}}{521}
--\entry {\code {RLIM_NLIMITS}}{521}
--\entry {\code {RLIMIT_CORE}}{520}
--\entry {\code {RLIMIT_CPU}}{520}
--\entry {\code {RLIMIT_DATA}}{520}
--\entry {\code {RLIMIT_FSIZE}}{520}
--\entry {\code {RLIMIT_NOFILE}}{521}
--\entry {\code {RLIMIT_OFILE}}{521}
--\entry {\code {RLIMIT_RSS}}{521}
--\entry {\code {RLIMIT_STACK}}{520}
--\entry {\code {rpc}}{651}
--\entry {\code {RUN_LVL}}{672, 676}
--\initial {S}
--\entry {\code {S_IEXEC}}{344}
--\entry {\code {S_IFBLK}}{342}
--\entry {\code {S_IFCHR}}{342}
--\entry {\code {S_IFDIR}}{342}
--\entry {\code {S_IFIFO}}{343}
--\entry {\code {S_IFLNK}}{343}
--\entry {\code {S_IFMT}}{342}
--\entry {\code {S_IFREG}}{343}
--\entry {\code {S_IFSOCK}}{343}
--\entry {\code {S_IREAD}}{344}
--\entry {\code {S_IRGRP}}{344}
--\entry {\code {S_IROTH}}{345}
--\entry {\code {S_IRUSR}}{344}
--\entry {\code {S_IRWXG}}{344}
--\entry {\code {S_IRWXO}}{345}
--\entry {\code {S_IRWXU}}{344}
--\entry {\code {S_ISGID}}{345}
--\entry {\code {S_ISUID}}{345}
--\entry {\code {S_ISVTX}}{345}
--\entry {\code {S_IWGRP}}{344}
--\entry {\code {S_IWOTH}}{345}
--\entry {\code {S_IWRITE}}{344}
--\entry {\code {S_IWUSR}}{344}
--\entry {\code {S_IXGRP}}{344}
--\entry {\code {S_IXOTH}}{345}
--\entry {\code {S_IXUSR}}{344}
--\entry {\code {SA_NOCLDSTOP}}{543}
--\entry {\code {SA_ONSTACK}}{543}
--\entry {\code {SA_RESTART}}{544}
--\entry {\code {SCHAR_MAX}}{752}
--\entry {\code {SCHAR_MIN}}{752}
--\entry {\code {SEEK_CUR}}{254}
--\entry {\code {SEEK_END}}{254}
--\entry {\code {SEEK_SET}}{254}
--\entry {\code {SEM_VALUE_MAX}}{735}
--\entry {\code {services}}{651}
--\entry {\code {shadow}}{652}
--\entry {\code {SHRT_MAX}}{753}
--\entry {\code {SHRT_MIN}}{753}
--\entry {\code {SIG_BLOCK}}{562}
--\entry {\code {SIG_DFL}}{539}
--\entry {\code {SIG_ERR}}{540}
--\entry {\code {SIG_IGN}}{539}
--\entry {\code {SIG_SETMASK}}{562}
--\entry {\code {SIG_UNBLOCK}}{562}
--\entry {\code {SIGABRT}}{532}
--\entry {\code {SIGALRM}}{533}
--\entry {\code {SIGBUS}}{531}
--\entry {\code {SIGCHLD}}{534}
--\entry {\code {SIGCLD}}{535}
--\entry {\code {SIGCONT}}{535}
--\entry {\code {SIGEMT}}{532}
--\entry {\code {SIGFPE}}{530}
--\entry {\code {SIGHUP}}{533}
--\entry {\code {SIGILL}}{531}
--\entry {\code {SIGINFO}}{537}
--\entry {\code {SIGINT}}{532}
--\entry {\code {SIGIO}}{534}
--\entry {\code {SIGIOT}}{532}
--\entry {\code {SIGKILL}}{533}
--\entry {\code {SIGLOST}}{536}
--\entry {\code {signgam}}{449}
--\entry {\code {SIGPIPE}}{536}
--\entry {\code {SIGPOLL}}{534}
--\entry {\code {SIGPROF}}{534}
--\entry {\code {SIGQUIT}}{533}
--\entry {\code {SIGSEGV}}{531}
--\entry {\code {SIGSTKSZ}}{570}
--\entry {\code {SIGSTOP}}{535}
--\entry {\code {SIGSYS}}{532}
--\entry {\code {SIGTERM}}{532}
--\entry {\code {SIGTRAP}}{532}
--\entry {\code {SIGTSTP}}{535}
--\entry {\code {SIGTTIN}}{535}
--\entry {\code {SIGTTOU}}{535}
--\entry {\code {SIGURG}}{534}
--\entry {\code {SIGUSR1}}{537}
--\entry {\code {SIGUSR2}}{537}
--\entry {\code {SIGVTALRM}}{534}
--\entry {\code {SIGWINCH}}{537}
--\entry {\code {SIGXCPU}}{536}
--\entry {\code {SIGXFSZ}}{537}
--\entry {\code {SOCK_DGRAM}}{364}
--\entry {\code {SOCK_RAW}}{365}
--\entry {\code {SOCK_STREAM}}{364}
--\entry {\code {SOL_SOCKET}}{407}
--\entry {\code {SS_DISABLE}}{570}
--\entry {\code {SS_ONSTACK}}{570}
--\entry {\code {SSIZE_MAX}}{698}
--\entry {\code {stderr}}{211}
--\entry {\code {STDERR_FILENO}}{283}
--\entry {\code {stdin}}{211}
--\entry {\code {STDIN_FILENO}}{283}
--\entry {\code {stdout}}{211}
--\entry {\code {STDOUT_FILENO}}{283}
--\entry {\code {STREAM_MAX}}{697}
--\entry {\code {SV_INTERRUPT}}{572}
--\entry {\code {SV_ONSTACK}}{572}
--\entry {\code {SV_RESETHAND}}{572}
--\entry {\code {sys_siglist}}{538}
--\initial {T}
--\entry {\code {T_FMT}}{151}
--\entry {\code {T_FMT_AMPM}}{151}
--\entry {\code {TCIFLUSH}}{431}
--\entry {\code {TCIOFF}}{432}
--\entry {\code {TCIOFLUSH}}{431}
--\entry {\code {TCION}}{432}
--\entry {\code {TCOFLUSH}}{431}
--\entry {\code {TCOOFF}}{432}
--\entry {\code {TCOON}}{432}
--\entry {\code {TCSADRAIN}}{414}
--\entry {\code {TCSAFLUSH}}{414}
--\entry {\code {TCSANOW}}{414}
--\entry {\code {TCSASOFT}}{414}
--\entry {\code {THOUSANDS_SEP}}{153}
--\entry {\code {THOUSEP}}{153}
--\entry {\code {timezone}}{509}
--\entry {\code {TMP_MAX}}{354}
--\entry {\code {TOSTOP}}{422}
--\entry {\code {TRY_AGAIN}}{379}
--\entry {\code {tzname}}{509}
--\entry {\code {TZNAME_MAX}}{697}
--\initial {U}
--\entry {\code {UCHAR_MAX}}{752}
--\entry {\code {UINT_MAX}}{753}
--\entry {\code {ULONG_LONG_MAX}}{753}
--\entry {\code {ULONG_MAX}}{753}
--\entry {\code {USER_PROCESS}}{672, 677}
--\entry {\code {USHRT_MAX}}{753}
--\initial {V}
--\entry {\code {VDISCARD}}{428}
--\entry {\code {VDSUSP}}{427}
--\entry {\code {VEOF}}{425}
--\entry {\code {VEOL}}{425}
--\entry {\code {VEOL2}}{425}
--\entry {\code {VERASE}}{426}
--\entry {\code {VINTR}}{427}
--\entry {\code {VKILL}}{426}
--\entry {\code {VLNEXT}}{428}
--\entry {\code {VMIN}}{429}
--\entry {\code {VQUIT}}{427}
--\entry {\code {VREPRINT}}{426}
--\entry {\code {VSTART}}{428}
--\entry {\code {VSTATUS}}{429}
--\entry {\code {VSTOP}}{428}
--\entry {\code {VSUSP}}{427}
--\entry {\code {VTIME}}{429}
--\entry {\code {VWERASE}}{426}
--\initial {W}
--\entry {\code {W_OK}}{349}
--\entry {\code {WCHAR_MAX}}{98, 753}
--\entry {\code {WCHAR_MIN}}{98}
--\entry {\code {WEOF}}{98}
--\initial {X}
--\entry {\code {X_OK}}{349}
--\initial {Y}
--\entry {\code {YESEXPR}}{153}
--\entry {\code {YESSTR}}{153}
-diff -Naur ../glibc-2.1.3/manual/libcbook.texi glibc-2.1.3/manual/libcbook.texi
---- ../glibc-2.1.3/manual/libcbook.texi 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/manual/libcbook.texi 1998-02-07 12:17:00.000000000 -0800
-@@ -0,0 +1,3 @@
-+\input texinfo
-+@finalout
-+@include libc.texinfo
-diff -Naur ../glibc-2.1.3/manual/longopt.c.texi glibc-2.1.3/manual/longopt.c.texi
---- ../glibc-2.1.3/manual/longopt.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/longopt.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,94 +0,0 @@
--#include <stdio.h>
--#include <stdlib.h>
--#include <getopt.h>
--
--/* @r{Flag set by @samp{--verbose}.} */
--static int verbose_flag;
--
--int
--main (argc, argv)
-- int argc;
-- char **argv;
--@{
-- int c;
--
-- while (1)
-- @{
-- static struct option long_options[] =
-- @{
-- /* @r{These options set a flag.} */
-- @{"verbose", 0, &verbose_flag, 1@},
-- @{"brief", 0, &verbose_flag, 0@},
-- /* @r{These options don't set a flag.
-- We distinguish them by their indices.} */
-- @{"add", 1, 0, 0@},
-- @{"append", 0, 0, 0@},
-- @{"delete", 1, 0, 0@},
-- @{"create", 0, 0, 0@},
-- @{"file", 1, 0, 0@},
-- @{0, 0, 0, 0@}
-- @};
-- /* @r{@code{getopt_long} stores the option index here.} */
-- int option_index = 0;
--
-- c = getopt_long (argc, argv, "abc:d:",
-- long_options, &option_index);
--
-- /* @r{Detect the end of the options.} */
-- if (c == -1)
-- break;
--
-- switch (c)
-- @{
-- case 0:
-- /* @r{If this option set a flag, do nothing else now.} */
-- if (long_options[option_index].flag != 0)
-- break;
-- printf ("option %s", long_options[option_index].name);
-- if (optarg)
-- printf (" with arg %s", optarg);
-- printf ("\n");
-- break;
--
-- case 'a':
-- puts ("option -a\n");
-- break;
--
-- case 'b':
-- puts ("option -b\n");
-- break;
--
-- case 'c':
-- printf ("option -c with value `%s'\n", optarg);
-- break;
--
-- case 'd':
-- printf ("option -d with value `%s'\n", optarg);
-- break;
--
-- case '?':
-- /* @r{@code{getopt_long} already printed an error message.} */
-- break;
--
-- default:
-- abort ();
-- @}
-- @}
--
-- /* @r{Instead of reporting @samp{--verbose}
-- and @samp{--brief} as they are encountered,
-- we report the final status resulting from them.} */
-- if (verbose_flag)
-- puts ("verbose flag is set");
--
-- /* @r{Print any remaining command line arguments (not options).} */
-- if (optind < argc)
-- @{
-- printf ("non-option ARGV-elements: ");
-- while (optind < argc)
-- printf ("%s ", argv[optind++]);
-- putchar ('\n');
-- @}
--
-- exit (0);
--@}
-diff -Naur ../glibc-2.1.3/manual/memopen.c.texi glibc-2.1.3/manual/memopen.c.texi
---- ../glibc-2.1.3/manual/memopen.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/memopen.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,17 +0,0 @@
--#include <stdio.h>
--
--static char buffer[] = "foobar";
--
--int
--main (void)
--@{
-- int ch;
-- FILE *stream;
--
-- stream = fmemopen (buffer, strlen (buffer), "r");
-- while ((ch = fgetc (stream)) != EOF)
-- printf ("Got %c\n", ch);
-- fclose (stream);
--
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/memstrm.c.texi glibc-2.1.3/manual/memstrm.c.texi
---- ../glibc-2.1.3/manual/memstrm.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/memstrm.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,19 +0,0 @@
--#include <stdio.h>
--
--int
--main (void)
--@{
-- char *bp;
-- size_t size;
-- FILE *stream;
--
-- stream = open_memstream (&bp, &size);
-- fprintf (stream, "hello");
-- fflush (stream);
-- printf ("buf = `%s', size = %d\n", bp, size);
-- fprintf (stream, ", world");
-- fclose (stream);
-- printf ("buf = `%s', size = %d\n", bp, size);
--
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/mkfsock.c.texi glibc-2.1.3/manual/mkfsock.c.texi
---- ../glibc-2.1.3/manual/mkfsock.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/mkfsock.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,44 +0,0 @@
--#include <stddef.h>
--#include <stdio.h>
--#include <errno.h>
--#include <stdlib.h>
--#include <sys/socket.h>
--#include <sys/un.h>
--
--int
--make_named_socket (const char *filename)
--@{
-- struct sockaddr_un name;
-- int sock;
-- size_t size;
--
-- /* @r{Create the socket.} */
-- sock = socket (PF_LOCAL, SOCK_DGRAM, 0);
-- if (sock < 0)
-- @{
-- perror ("socket");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Bind a name to the socket.} */
-- name.sun_family = AF_LOCAL;
-- strncpy (name.sun_path, filename, sizeof (name.sun_path));
--
-- /* @r{The size of the address is
-- the offset of the start of the filename,
-- plus its length,
-- plus one for the terminating null byte.
-- Alternativly you can just do:
-- size = SUN_LEN (&name);
--} */
-- size = (offsetof (struct sockaddr_un, sun_path)
-- + strlen (name.sun_path) + 1);
--
-- if (bind (sock, (struct sockaddr *) &name, size) < 0)
-- @{
-- perror ("bind");
-- exit (EXIT_FAILURE);
-- @}
--
-- return sock;
--@}
-diff -Naur ../glibc-2.1.3/manual/mkisock.c.texi glibc-2.1.3/manual/mkisock.c.texi
---- ../glibc-2.1.3/manual/mkisock.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/mkisock.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,31 +0,0 @@
--#include <stdio.h>
--#include <stdlib.h>
--#include <sys/socket.h>
--#include <netinet/in.h>
--
--int
--make_socket (uint16_t port)
--@{
-- int sock;
-- struct sockaddr_in name;
--
-- /* @r{Create the socket.} */
-- sock = socket (PF_INET, SOCK_STREAM, 0);
-- if (sock < 0)
-- @{
-- perror ("socket");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Give the socket a name.} */
-- name.sin_family = AF_INET;
-- name.sin_port = htons (port);
-- name.sin_addr.s_addr = htonl (INADDR_ANY);
-- if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
-- @{
-- perror ("bind");
-- exit (EXIT_FAILURE);
-- @}
--
-- return sock;
--@}
-diff -Naur ../glibc-2.1.3/manual/pipe.c.texi glibc-2.1.3/manual/pipe.c.texi
---- ../glibc-2.1.3/manual/pipe.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/pipe.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,66 +0,0 @@
--#include <sys/types.h>
--#include <unistd.h>
--#include <stdio.h>
--#include <stdlib.h>
--
--/* @r{Read characters from the pipe and echo them to @code{stdout}.} */
--
--void
--read_from_pipe (int file)
--@{
-- FILE *stream;
-- int c;
-- stream = fdopen (file, "r");
-- while ((c = fgetc (stream)) != EOF)
-- putchar (c);
-- fclose (stream);
--@}
--
--/* @r{Write some random text to the pipe.} */
--
--void
--write_to_pipe (int file)
--@{
-- FILE *stream;
-- stream = fdopen (file, "w");
-- fprintf (stream, "hello, world!\n");
-- fprintf (stream, "goodbye, world!\n");
-- fclose (stream);
--@}
--
--int
--main (void)
--@{
-- pid_t pid;
-- int mypipe[2];
--
--@group
-- /* @r{Create the pipe.} */
-- if (pipe (mypipe))
-- @{
-- fprintf (stderr, "Pipe failed.\n");
-- return EXIT_FAILURE;
-- @}
--@end group
--
-- /* @r{Create the child process.} */
-- pid = fork ();
-- if (pid == (pid_t) 0)
-- @{
-- /* @r{This is the child process.} */
-- read_from_pipe (mypipe[0]);
-- return EXIT_SUCCESS;
-- @}
-- else if (pid < (pid_t) 0)
-- @{
-- /* @r{The fork failed.} */
-- fprintf (stderr, "Fork failed.\n");
-- return EXIT_FAILURE;
-- @}
-- else
-- @{
-- /* @r{This is the parent process.} */
-- write_to_pipe (mypipe[1]);
-- return EXIT_SUCCESS;
-- @}
--@}
-diff -Naur ../glibc-2.1.3/manual/popen.c.texi glibc-2.1.3/manual/popen.c.texi
---- ../glibc-2.1.3/manual/popen.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/popen.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,33 +0,0 @@
--#include <stdio.h>
--#include <stdlib.h>
--
--void
--write_data (FILE * stream)
--@{
-- int i;
-- for (i = 0; i < 100; i++)
-- fprintf (stream, "%d\n", i);
-- if (ferror (stream))
-- @{
-- fprintf (stderr, "Output to stream failed.\n");
-- exit (EXIT_FAILURE);
-- @}
--@}
--
--@group
--int
--main (void)
--@{
-- FILE *output;
--
-- output = popen ("more", "w");
-- if (!output)
-- @{
-- fprintf (stderr, "Could not run more.\n");
-- return EXIT_FAILURE;
-- @}
-- write_data (output);
-- pclose (output);
-- return EXIT_SUCCESS;
--@}
--@end group
-diff -Naur ../glibc-2.1.3/manual/rprintf.c.texi glibc-2.1.3/manual/rprintf.c.texi
---- ../glibc-2.1.3/manual/rprintf.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/rprintf.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,67 +0,0 @@
--#include <stdio.h>
--#include <stdlib.h>
--#include <printf.h>
--
--@group
--typedef struct
--@{
-- char *name;
--@}
--Widget;
--@end group
--
--int
--print_widget (FILE *stream,
-- const struct printf_info *info,
-- const void *const *args)
--@{
-- const Widget *w;
-- char *buffer;
-- int len;
--
-- /* @r{Format the output into a string.} */
-- w = *((const Widget **) (args[0]));
-- len = asprintf (&buffer, "<Widget %p: %s>", w, w->name);
-- if (len == -1)
-- return -1;
--
-- /* @r{Pad to the minimum field width and print to the stream.} */
-- len = fprintf (stream, "%*s",
-- (info->left ? -info->width : info->width),
-- buffer);
--
-- /* @r{Clean up and return.} */
-- free (buffer);
-- return len;
--@}
--
--
--int
--print_widget_arginfo (const struct printf_info *info, size_t n,
-- int *argtypes)
--@{
-- /* @r{We always take exactly one argument and this is a pointer to the
-- structure..} */
-- if (n > 0)
-- argtypes[0] = PA_POINTER;
-- return 1;
--@}
--
--
--int
--main (void)
--@{
-- /* @r{Make a widget to print.} */
-- Widget mywidget;
-- mywidget.name = "mywidget";
--
-- /* @r{Register the print function for widgets.} */
-- register_printf_function ('W', print_widget, print_widget_arginfo);
--
-- /* @r{Now print the widget.} */
-- printf ("|%W|\n", &mywidget);
-- printf ("|%35W|\n", &mywidget);
-- printf ("|%-35W|\n", &mywidget);
--
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/search.c.texi glibc-2.1.3/manual/search.c.texi
---- ../glibc-2.1.3/manual/search.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/search.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,93 +0,0 @@
--#include <stdlib.h>
--#include <stdio.h>
--#include <string.h>
--
--/* @r{Define an array of critters to sort.} */
--
--struct critter
-- @{
-- const char *name;
-- const char *species;
-- @};
--
--struct critter muppets[] =
-- @{
-- @{"Kermit", "frog"@},
-- @{"Piggy", "pig"@},
-- @{"Gonzo", "whatever"@},
-- @{"Fozzie", "bear"@},
-- @{"Sam", "eagle"@},
-- @{"Robin", "frog"@},
-- @{"Animal", "animal"@},
-- @{"Camilla", "chicken"@},
-- @{"Sweetums", "monster"@},
-- @{"Dr. Strangepork", "pig"@},
-- @{"Link Hogthrob", "pig"@},
-- @{"Zoot", "human"@},
-- @{"Dr. Bunsen Honeydew", "human"@},
-- @{"Beaker", "human"@},
-- @{"Swedish Chef", "human"@}
-- @};
--
--int count = sizeof (muppets) / sizeof (struct critter);
--
--
--
--/* @r{This is the comparison function used for sorting and searching.} */
--
--int
--critter_cmp (const struct critter *c1, const struct critter *c2)
--@{
-- return strcmp (c1->name, c2->name);
--@}
--
--
--/* @r{Print information about a critter.} */
--
--void
--print_critter (const struct critter *c)
--@{
-- printf ("%s, the %s\n", c->name, c->species);
--@}
--
--
--@group
--/* @r{Do the lookup into the sorted array.} */
--
--void
--find_critter (const char *name)
--@{
-- struct critter target, *result;
-- target.name = name;
-- result = bsearch (&target, muppets, count, sizeof (struct critter),
-- critter_cmp);
-- if (result)
-- print_critter (result);
-- else
-- printf ("Couldn't find %s.\n", name);
--@}
--@end group
--
--/* @r{Main program.} */
--
--int
--main (void)
--@{
-- int i;
--
-- for (i = 0; i < count; i++)
-- print_critter (&muppets[i]);
-- printf ("\n");
--
-- qsort (muppets, count, sizeof (struct critter), critter_cmp);
--
-- for (i = 0; i < count; i++)
-- print_critter (&muppets[i]);
-- printf ("\n");
--
-- find_critter ("Kermit");
-- find_critter ("Gonzo");
-- find_critter ("Janice");
--
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/select.c.texi glibc-2.1.3/manual/select.c.texi
---- ../glibc-2.1.3/manual/select.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/select.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,40 +0,0 @@
--@group
--#include <stdio.h>
--#include <unistd.h>
--#include <sys/types.h>
--#include <sys/time.h>
--@end group
--
--@group
--int
--input_timeout (int filedes, unsigned int seconds)
--@{
-- fd_set set;
-- struct timeval timeout;
--@end group
--
-- /* @r{Initialize the file descriptor set.} */
-- FD_ZERO (&set);
-- FD_SET (filedes, &set);
--
-- /* @r{Initialize the timeout data structure.} */
-- timeout.tv_sec = seconds;
-- timeout.tv_usec = 0;
--
--@group
-- /* @r{@code{select} returns 0 if timeout, 1 if input available, -1 if error.} */
-- return TEMP_FAILURE_RETRY (select (FD_SETSIZE,
-- &set, NULL, NULL,
-- &timeout));
--@}
--@end group
--
--@group
--int
--main (void)
--@{
-- fprintf (stderr, "select returned %d.\n",
-- input_timeout (STDIN_FILENO, 5));
-- return 0;
--@}
--@end group
-diff -Naur ../glibc-2.1.3/manual/setjmp.c.texi glibc-2.1.3/manual/setjmp.c.texi
---- ../glibc-2.1.3/manual/setjmp.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/setjmp.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,32 +0,0 @@
--#include <setjmp.h>
--#include <stdlib.h>
--#include <stdio.h>
--
--jmp_buf main_loop;
--
--void
--abort_to_main_loop (int status)
--@{
-- longjmp (main_loop, status);
--@}
--
--int
--main (void)
--@{
-- while (1)
-- if (setjmp (main_loop))
-- puts ("Back at main loop....");
-- else
-- do_command ();
--@}
--
--
--void
--do_command (void)
--@{
-- char buffer[128];
-- if (fgets (buffer, 128, stdin) == NULL)
-- abort_to_main_loop (-1);
-- else
-- exit (EXIT_SUCCESS);
--@}
-diff -Naur ../glibc-2.1.3/manual/sigh1.c.texi glibc-2.1.3/manual/sigh1.c.texi
---- ../glibc-2.1.3/manual/sigh1.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/sigh1.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,36 +0,0 @@
--#include <signal.h>
--#include <stdio.h>
--#include <stdlib.h>
--
--/* @r{This flag controls termination of the main loop.} */
--volatile sig_atomic_t keep_going = 1;
--
--/* @r{The signal handler just clears the flag and re-enables itself.} */
--void
--catch_alarm (int sig)
--@{
-- keep_going = 0;
-- signal (sig, catch_alarm);
--@}
--
--void
--do_stuff (void)
--@{
-- puts ("Doing stuff while waiting for alarm....");
--@}
--
--int
--main (void)
--@{
-- /* @r{Establish a handler for SIGALRM signals.} */
-- signal (SIGALRM, catch_alarm);
--
-- /* @r{Set an alarm to go off in a little while.} */
-- alarm (2);
--
-- /* @r{Check the flag once in a while to see when to quit.} */
-- while (keep_going)
-- do_stuff ();
--
-- return EXIT_SUCCESS;
--@}
-diff -Naur ../glibc-2.1.3/manual/sigusr.c.texi glibc-2.1.3/manual/sigusr.c.texi
---- ../glibc-2.1.3/manual/sigusr.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/sigusr.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,61 +0,0 @@
--@group
--#include <signal.h>
--#include <stdio.h>
--#include <sys/types.h>
--#include <unistd.h>
--@end group
--
--/* @r{When a @code{SIGUSR1} signal arrives, set this variable.} */
--volatile sig_atomic_t usr_interrupt = 0;
--
--void
--synch_signal (int sig)
--@{
-- usr_interrupt = 1;
--@}
--
--/* @r{The child process executes this function.} */
--void
--child_function (void)
--@{
-- /* @r{Perform initialization.} */
-- printf ("I'm here!!! My pid is %d.\n", (int) getpid ());
--
-- /* @r{Let parent know you're done.} */
-- kill (getppid (), SIGUSR1);
--
-- /* @r{Continue with execution.} */
-- puts ("Bye, now....");
-- exit (0);
--@}
--
--int
--main (void)
--@{
-- struct sigaction usr_action;
-- sigset_t block_mask;
-- pid_t child_id;
--
-- /* @r{Establish the signal handler.} */
-- sigfillset (&block_mask);
-- usr_action.sa_handler = synch_signal;
-- usr_action.sa_mask = block_mask;
-- usr_action.sa_flags = 0;
-- sigaction (SIGUSR1, &usr_action, NULL);
--
-- /* @r{Create the child process.} */
-- child_id = fork ();
-- if (child_id == 0)
-- child_function (); /* @r{Does not return.} */
--
--@group
-- /* @r{Busy wait for the child to send a signal.} */
-- while (!usr_interrupt)
-- ;
--@end group
--
-- /* @r{Now continue execution.} */
-- puts ("That's all, folks!");
--
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/stpcpy.c.texi glibc-2.1.3/manual/stpcpy.c.texi
---- ../glibc-2.1.3/manual/stpcpy.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/stpcpy.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,13 +0,0 @@
--#include <string.h>
--#include <stdio.h>
--
--int
--main (void)
--@{
-- char buffer[10];
-- char *to = buffer;
-- to = stpcpy (to, "foo");
-- to = stpcpy (to, "bar");
-- puts (buffer);
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/strdupa.c.texi glibc-2.1.3/manual/strdupa.c.texi
---- ../glibc-2.1.3/manual/strdupa.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/strdupa.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,19 +0,0 @@
--#include <paths.h>
--#include <string.h>
--#include <stdio.h>
--
--const char path[] = _PATH_STDPATH;
--
--int
--main (void)
--@{
-- char *wr_path = strdupa (path);
-- char *cp = strtok (wr_path, ":");
--
-- while (cp != NULL)
-- @{
-- puts (cp);
-- cp = strtok (NULL, ":");
-- @}
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/strftim.c.texi glibc-2.1.3/manual/strftim.c.texi
---- ../glibc-2.1.3/manual/strftim.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/strftim.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,31 +0,0 @@
--#include <time.h>
--#include <stdio.h>
--
--#define SIZE 256
--
--int
--main (void)
--@{
-- char buffer[SIZE];
-- time_t curtime;
-- struct tm *loctime;
--
-- /* @r{Get the current time.} */
-- curtime = time (NULL);
--
-- /* @r{Convert it to local time representation.} */
-- loctime = localtime (&curtime);
--
-- /* @r{Print out the date and time in the standard format.} */
-- fputs (asctime (loctime), stdout);
--
--@group
-- /* @r{Print it out in a nice format.} */
-- strftime (buffer, SIZE, "Today is %A, %B %d.\n", loctime);
-- fputs (buffer, stdout);
-- strftime (buffer, SIZE, "The time is %I:%M %p.\n", loctime);
-- fputs (buffer, stdout);
--
-- return 0;
--@}
--@end group
-diff -Naur ../glibc-2.1.3/manual/strncat.c.texi glibc-2.1.3/manual/strncat.c.texi
---- ../glibc-2.1.3/manual/strncat.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/strncat.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,14 +0,0 @@
--#include <string.h>
--#include <stdio.h>
--
--#define SIZE 10
--
--static char buffer[SIZE];
--
--main ()
--@{
-- strncpy (buffer, "hello", SIZE);
-- puts (buffer);
-- strncat (buffer, ", world", SIZE - strlen (buffer) - 1);
-- puts (buffer);
--@}
-diff -Naur ../glibc-2.1.3/manual/subopt.c.texi glibc-2.1.3/manual/subopt.c.texi
---- ../glibc-2.1.3/manual/subopt.c.texi 1999-07-18 18:01:09.000000000 -0700
-+++ glibc-2.1.3/manual/subopt.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,75 +0,0 @@
--#include <stdio.h>
--#include <stdlib.h>
--
--int do_all;
--const char *type;
--int read_size;
--int write_size;
--int read_only;
--
--enum
--@{
-- RO_OPTION = 0,
-- RW_OPTION,
-- READ_SIZE_OPTION,
-- WRITE_SIZE_OPTION
--@};
--
--const char *mount_opts[] =
--@{
-- [RO_OPTION] = "ro",
-- [RW_OPTION] = "rw",
-- [READ_SIZE_OPTION] = "rsize",
-- [WRITE_SIZE_OPTION] = "wsize"
--@};
--
--int
--main (int argc, char *argv[])
--@{
-- char *subopts, *value;
-- int opt;
--
-- while ((opt = getopt (argc, argv, "at:o:")) != -1)
-- switch (opt)
-- @{
-- case 'a':
-- do_all = 1;
-- break;
-- case 't':
-- type = optarg;
-- break;
-- case 'o':
-- subopts = optarg;
-- while (*subopts != '\0')
-- switch (getsubopt (&subopts, mount_opts, &value))
-- @{
-- case RO_OPTION:
-- read_only = 1;
-- break;
-- case RW_OPTION:
-- read_only = 0;
-- break;
-- case READ_SIZE_OPTION:
-- if (value == NULL)
-- abort ();
-- read_size = atoi (value);
-- break;
-- case WRITE_SIZE_OPTION:
-- if (value == NULL)
-- abort ();
-- write_size = atoi (value);
-- break;
-- default:
-- /* @r{Unknown suboption.} */
-- printf ("Unknown suboption `%s'\n", value);
-- break;
-- @}
-- break;
-- default:
-- abort ();
-- @}
--
-- /* @r{Do the real work.} */
--
-- return 0;
--@}
-diff -Naur ../glibc-2.1.3/manual/termios.c.texi glibc-2.1.3/manual/termios.c.texi
---- ../glibc-2.1.3/manual/termios.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/termios.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,60 +0,0 @@
--#include <unistd.h>
--#include <stdio.h>
--#include <stdlib.h>
--#include <termios.h>
--
--/* @r{Use this variable to remember original terminal attributes.} */
--
--struct termios saved_attributes;
--
--void
--reset_input_mode (void)
--@{
-- tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
--@}
--
--void
--set_input_mode (void)
--@{
-- struct termios tattr;
-- char *name;
--
-- /* @r{Make sure stdin is a terminal.} */
-- if (!isatty (STDIN_FILENO))
-- @{
-- fprintf (stderr, "Not a terminal.\n");
-- exit (EXIT_FAILURE);
-- @}
--
-- /* @r{Save the terminal attributes so we can restore them later.} */
-- tcgetattr (STDIN_FILENO, &saved_attributes);
-- atexit (reset_input_mode);
--
--@group
-- /* @r{Set the funny terminal modes.} */
-- tcgetattr (STDIN_FILENO, &tattr);
-- tattr.c_lflag &= ~(ICANON|ECHO); /* @r{Clear ICANON and ECHO.} */
-- tattr.c_cc[VMIN] = 1;
-- tattr.c_cc[VTIME] = 0;
-- tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
--@}
--@end group
--
--int
--main (void)
--@{
-- char c;
--
-- set_input_mode ();
--
-- while (1)
-- @{
-- read (STDIN_FILENO, &c, 1);
-- if (c == '\004') /* @r{@kbd{C-d}} */
-- break;
-- else
-- putchar (c);
-- @}
--
-- return EXIT_SUCCESS;
--@}
-diff -Naur ../glibc-2.1.3/manual/testopt.c.texi glibc-2.1.3/manual/testopt.c.texi
---- ../glibc-2.1.3/manual/testopt.c.texi 1999-07-18 18:01:08.000000000 -0700
-+++ glibc-2.1.3/manual/testopt.c.texi 1969-12-31 16:00:00.000000000 -0800
-@@ -1,51 +0,0 @@
--@group
--#include <unistd.h>
--#include <stdio.h>
--
--int
--main (int argc, char **argv)
--@{
-- int aflag = 0;
-- int bflag = 0;
-- char *cvalue = NULL;
-- int index;
-- int c;
--
-- opterr = 0;
--@end group
--
--@group
-- while ((c = getopt (argc, argv, "abc:")) != -1)
-- switch (c)
-- @{
-- case 'a':
-- aflag = 1;
-- break;
-- case 'b':
-- bflag = 1;
-- break;
-- case 'c':
-- cvalue = optarg;
-- break;
-- case '?':
-- if (isprint (optopt))
-- fprintf (stderr, "Unknown option `-%c'.\n", optopt);
-- else
-- fprintf (stderr,
-- "Unknown option character `\\x%x'.\n",
-- optopt);
-- return 1;
-- default:
-- abort ();
-- @}
--@end group
--
--@group
-- printf ("aflag = %d, bflag = %d, cvalue = %s\n",
-- aflag, bflag, cvalue);
--
-- for (index = optind; index < argc; index++)
-- printf ("Non-option argument %s\n", argv[index]);
-- return 0;
--@}
--@end group
-diff -Naur ../glibc-2.1.3/math/math_private.h glibc-2.1.3/math/math_private.h
---- ../glibc-2.1.3/math/math_private.h 1998-11-27 03:33:46.000000000 -0800
-+++ glibc-2.1.3/math/math_private.h 1998-11-30 07:01:06.000000000 -0800
-@@ -11,7 +11,7 @@
-
- /*
- * from: @(#)fdlibm.h 5.1 93/09/24
-- * $Id: math_private.h,v 1.8 1998/11/27 11:33:46 drepper Exp $
-+ * $Id: math_private.h,v 1.1.1.1 1998/11/30 15:01:06 gafton Exp $
- */
-
- #ifndef _MATH_PRIVATE_H_
-diff -Naur ../glibc-2.1.3/math/test-math.c glibc-2.1.3/math/test-math.c
---- ../glibc-2.1.3/math/test-math.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/math/test-math.c 1998-02-07 12:20:22.000000000 -0800
-@@ -0,0 +1,150 @@
-+#include <stdio.h>
-+#include <math.h>
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <string.h>
-+
-+void print_trig_stuff __P ((void));
-+
-+int
-+main (int argc, char *argv[])
-+{
-+ const char str[] = "123.456";
-+ double x,h,li,lr,a,lrr;
-+
-+ if (signbit (argc < 1 ? -0.0 : 0.0))
-+ /* I don't make this an error for now. --drepper */
-+ fputs ("\n*** Your compiler has a bug. Consider upgrading\n\n", stderr);
-+
-+ x = atof (str);
-+
-+ printf ("%g %g\n", x, pow (10.0, 3.0));
-+
-+ x = sinh(2.0);
-+
-+ printf("sinh(2.0) = %g\n", x);
-+
-+ x = sinh(3.0);
-+
-+ printf("sinh(3.0) = %g\n", x);
-+
-+ h = hypot(2.0,3.0);
-+
-+ printf("h=%g\n", h);
-+
-+ a = atan2(3.0, 2.0);
-+
-+ printf("atan2(3,2) = %g\n", a);
-+
-+ lr = pow(h,4.0);
-+
-+ printf("pow(%g,4.0) = %g\n", h, lr);
-+
-+ lrr = lr;
-+
-+ li = 4.0 * a;
-+
-+ lr = lr / exp(a*5.0);
-+
-+ printf("%g / exp(%g * 5) = %g\n", lrr, a, lr);
-+
-+ lrr = li;
-+
-+ li += 5.0 * log(h);
-+
-+ printf("%g + 5*log(%g) = %g\n", lrr, h, li);
-+
-+ printf("cos(%g) = %g, sin(%g) = %g\n", li, cos(li), li, sin(li));
-+
-+ x = drem(10.3435,6.2831852);
-+
-+ printf("drem(10.3435,6.2831852) = %g\n", x);
-+
-+ x = drem(-10.3435,6.2831852);
-+
-+ printf("drem(-10.3435,6.2831852) = %g\n", x);
-+
-+ x = drem(-10.3435,-6.2831852);
-+
-+ printf("drem(-10.3435,-6.2831852) = %g\n", x);
-+
-+ x = drem(10.3435,-6.2831852);
-+
-+ printf("drem(10.3435,-6.2831852) = %g\n", x);
-+
-+
-+ printf("x%8.6gx\n", .5);
-+ printf("x%-8.6gx\n", .5);
-+ printf("x%6.6gx\n", .5);
-+
-+ {
-+ double x = atof ("-1e-17-");
-+ printf ("%g %c= %g %s!\n",
-+ x,
-+ x == -1e-17 ? '=' : '!',
-+ -1e-17,
-+ x == -1e-17 ? "Worked" : "Failed");
-+ }
-+
-+ print_trig_stuff ();
-+
-+ return 0;
-+}
-+
-+
-+const double RAD[5] = { 0, M_PI/2, M_PI, (3*M_PI)/2, 2*M_PI };
-+
-+#define PRINT_IT_1_ARG(_func, _arg, _value) \
-+ (_value) = (_func) ((_arg)); \
-+ if (errno) { \
-+ errno = 0; \
-+ printf ("%s = ERROR %s\n", #_func, strerror (errno)); \
-+ } else \
-+ printf ("%s(%g) = %g\n", #_func, _arg, (_value)); \
-+
-+#define PRINT_IT_2_ARG(_func, _arg1, _arg2, _value) \
-+ (_value) = (_func) ((_arg1),(_arg2)); \
-+ if (errno) { \
-+ errno = 0; \
-+ printf ("%s = ERROR %s\n", #_func, strerror (errno)); \
-+ } else \
-+ printf ("%s(%g, %g) = %g\n", #_func, _arg1, _arg2, (_value)); \
-+
-+void
-+print_trig_stuff(void)
-+{
-+ double value, arg1, arg2;
-+ int i;
-+
-+ puts ("\n\nMath Test");
-+
-+ errno = 0; /* automatically reset on error condition */
-+ for (i=0; i<4; i++)
-+ {
-+ PRINT_IT_1_ARG (sin, RAD[i], value);
-+ PRINT_IT_1_ARG (cos, RAD[i], value);
-+ PRINT_IT_1_ARG (tan, RAD[i], value);
-+ PRINT_IT_1_ARG (asin, RAD[i], value);
-+ PRINT_IT_1_ARG (acos, RAD[i], value);
-+ PRINT_IT_1_ARG (atan, RAD[i], value);
-+ PRINT_IT_2_ARG (atan2, RAD[i], -RAD[i % 4], value);
-+ }
-+
-+ arg1 = 16;
-+ arg2 = 3;
-+ PRINT_IT_1_ARG (exp, arg1, value);
-+ PRINT_IT_1_ARG (log, arg1, value);
-+ PRINT_IT_1_ARG (log10, arg1, value);
-+ PRINT_IT_2_ARG (pow, arg1, arg2, value);
-+ PRINT_IT_1_ARG (sqrt, arg1, value);
-+ PRINT_IT_1_ARG (cbrt, arg1, value);
-+ PRINT_IT_2_ARG (hypot, arg1, arg2, value);
-+ PRINT_IT_1_ARG (expm1, arg1, value);
-+ PRINT_IT_1_ARG (log1p, arg1, value);
-+ PRINT_IT_1_ARG (sinh, arg1, value);
-+ PRINT_IT_1_ARG (cosh, arg1, value);
-+ PRINT_IT_1_ARG (tanh, arg1, value);
-+ PRINT_IT_1_ARG (asinh, arg1, value);
-+ PRINT_IT_1_ARG (acosh, arg1, value);
-+ PRINT_IT_1_ARG (atanh, arg1, value);
-+}
-diff -Naur ../glibc-2.1.3/misc/ioctltst.c glibc-2.1.3/misc/ioctltst.c
---- ../glibc-2.1.3/misc/ioctltst.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/misc/ioctltst.c 1998-02-07 12:20:35.000000000 -0800
-@@ -0,0 +1,55 @@
-+#include <stdio.h>
-+#include <errno.h>
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <sys/ioctl.h>
-+#include <net/if.h>
-+#include <netinet/in.h>
-+
-+/*
-+ * open a socket, get the process group information of the socket, and use the
-+ * socket to get the network interface configuration list
-+ */
-+main(int argc, char *argv[])
-+{
-+ int sock;
-+ int ioctl_result;
-+
-+ /* get a socket */
-+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-+ if (sock < 0)
-+ {
-+ perror("Cannot create socket");
-+ exit(1);
-+ }
-+
-+ /* use ioctl() to get the process group information */
-+ {
-+ int get_process_group;
-+
-+ ioctl_result = ioctl(sock, SIOCGPGRP, (char *) &get_process_group);
-+
-+ if (ioctl_result < 0)
-+ {
-+ int my_errno = errno;
-+
-+ fprintf(stderr, "errno %d ", my_errno);
-+ perror("ioctl(get process group)");
-+ }
-+ }
-+
-+ /* use ioctl() to get the interface configuration list */
-+ {
-+ static struct ifconf ifc; /* init to 0 */
-+
-+ ioctl_result = ioctl(sock, SIOCGIFCONF, (char *) &ifc);
-+
-+ if (ioctl_result < 0)
-+ {
-+ int my_errno = errno;
-+
-+ fprintf(stderr, "errno %d ", my_errno);
-+ perror("ioctl(get interface configuration list)");
-+ }
-+ }
-+}
-diff -Naur ../glibc-2.1.3/misc/nlist.h glibc-2.1.3/misc/nlist.h
---- ../glibc-2.1.3/misc/nlist.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/misc/nlist.h 1998-02-07 12:20:36.000000000 -0800
-@@ -0,0 +1,48 @@
-+/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef _NLIST_H
-+#define _NLIST_H 1
-+
-+#include <features.h>
-+
-+__BEGIN_DECLS
-+
-+/* Structure describing a symbol-table entry. */
-+struct nlist
-+{
-+ char *n_name;
-+ unsigned char n_type;
-+ char n_other;
-+ short int n_desc;
-+ unsigned long int n_value;
-+};
-+
-+#define N_NLIST_DECLARED
-+#include <a.out.h>
-+
-+
-+/* Search the executable FILE for symbols matching those in NL,
-+ which is terminated by an element with a NULL `n_un.n_name' member,
-+ and fill in the elements of NL. */
-+extern int nlist __P ((__const char *__file, struct nlist * __nl));
-+
-+
-+__END_DECLS
-+
-+#endif /* nlist.h */
-diff -Naur ../glibc-2.1.3/misc/syslog.c glibc-2.1.3/misc/syslog.c
---- ../glibc-2.1.3/misc/syslog.c 2000-02-11 15:49:57.000000000 -0800
-+++ glibc-2.1.3/misc/syslog.c 2000-02-01 14:15:08.000000000 -0800
-@@ -281,6 +281,13 @@
- __set_errno (old_errno);
- continue;
- }
-+ if (LogType == SOCK_STREAM
-+ && saved_errno == ECONNREFUSED) {
-+ /* retry with next SOCK_DGRAM: */
-+ LogType = SOCK_DGRAM;
-+ __set_errno (old_errno);
-+ continue;
-+ }
- } else
- connected = 1;
- }
-diff -Naur ../glibc-2.1.3/nis/Versions glibc-2.1.3/nis/Versions
---- ../glibc-2.1.3/nis/Versions 1998-07-28 06:50:25.000000000 -0700
-+++ glibc-2.1.3/nis/Versions 1999-12-27 08:16:06.000000000 -0800
-@@ -54,6 +54,9 @@
- __nisbind_destroy; __nisbind_next;
- readColdStartFile; writeColdStartFile;
- }
-+ GLIBC_2.1.2 {
-+ xdr_ypall;
-+ }
- }
-
- libnss_compat {
-diff -Naur ../glibc-2.1.3/nis/yp_xdr.c glibc-2.1.3/nis/yp_xdr.c
---- ../glibc-2.1.3/nis/yp_xdr.c 1998-08-18 16:25:46.000000000 -0700
-+++ glibc-2.1.3/nis/yp_xdr.c 1999-12-27 08:16:07.000000000 -0800
-@@ -28,6 +28,7 @@
- */
-
- #include <rpcsvc/yp.h>
-+#include <rpcsvc/ypclnt.h>
-
- bool_t
- xdr_ypstat (XDR *xdrs, ypstat *objp)
-@@ -298,3 +299,47 @@
- return FALSE;
- return TRUE;
- }
-+
-+bool_t
-+xdr_ypall(XDR *xdrs, struct ypall_callback *incallback)
-+{
-+ struct ypresp_key_val out;
-+ char key[YPMAXRECORD], val[YPMAXRECORD];
-+
-+ /*
-+ * Set up key/val struct to be used during the transaction.
-+ */
-+ memset(&out, 0, sizeof out);
-+ out.key.keydat_val = key;
-+ out.key.keydat_len = sizeof(key);
-+ out.val.valdat_val = val;
-+ out.val.valdat_len = sizeof(val);
-+
-+ for (;;) {
-+ bool_t more, status;
-+
-+ /* Values pending? */
-+ if (!xdr_bool(xdrs, &more))
-+ return FALSE; /* can't tell! */
-+ if (!more)
-+ return TRUE; /* no more */
-+
-+ /* Transfer key/value pair. */
-+ status = xdr_ypresp_key_val(xdrs, &out);
-+
-+ /*
-+ * If we succeeded, call the callback function.
-+ * The callback will return TRUE when it wants
-+ * no more values. If we fail, indicate the
-+ * error.
-+ */
-+ if (status) {
-+ if ((*incallback->foreach)(out.stat,
-+ (char *)out.key.keydat_val, out.key.keydat_len,
-+ (char *)out.val.valdat_val, out.val.valdat_len,
-+ incallback->data))
-+ return TRUE;
-+ } else
-+ return FALSE;
-+ }
-+}
-diff -Naur ../glibc-2.1.3/nscd/connections.c glibc-2.1.3/nscd/connections.c
---- ../glibc-2.1.3/nscd/connections.c 2000-02-22 23:02:58.000000000 -0800
-+++ glibc-2.1.3/nscd/connections.c 2000-02-18 15:52:59.000000000 -0800
-@@ -515,3 +515,17 @@
-
- nscd_run ((void *) 0);
- }
-+
-+/* Handle the HUP signal which will force a dump of the cache */
-+void
-+sighup_handler (int signum)
-+{
-+ /* Prune the password database */
-+ prune_cache (&dbs[pwddb], LONG_MAX);
-+
-+ /* Prune the group database */
-+ prune_cache (&dbs[grpdb], LONG_MAX);
-+
-+ /* Prune the host database */
-+ prune_cache (&dbs[hstdb], LONG_MAX);
-+}
-diff -Naur ../glibc-2.1.3/nscd/nscd.c glibc-2.1.3/nscd/nscd.c
---- ../glibc-2.1.3/nscd/nscd.c 1999-10-04 12:51:37.000000000 -0700
-+++ glibc-2.1.3/nscd/nscd.c 1999-12-27 07:50:23.000000000 -0800
-@@ -102,6 +102,9 @@
- options, parse_opt, NULL, doc,
- };
-
-+/* The SIGHUP handler is extern to this file */
-+extern void sighup_handler(int signum);
-+
- int
- main (int argc, char **argv)
- {
-@@ -150,12 +153,13 @@
- /* Ignore job control signals. */
- signal (SIGTTOU, SIG_IGN);
- signal (SIGTTIN, SIG_IGN);
-- signal (SIGTSTP, SIG_IGN);
-+ signal (SIGTSTP, SIG_IGN);
- }
-
- signal (SIGINT, termination_handler);
- signal (SIGQUIT, termination_handler);
- signal (SIGTERM, termination_handler);
-+ signal (SIGHUP, sighup_handler);
- signal (SIGPIPE, SIG_IGN);
-
- /* Cleanup files created by a previous `bind'. */
-diff -Naur ../glibc-2.1.3/nscd/nscd.init glibc-2.1.3/nscd/nscd.init
---- ../glibc-2.1.3/nscd/nscd.init 1999-08-17 13:04:10.000000000 -0700
-+++ glibc-2.1.3/nscd/nscd.init 2000-01-04 14:21:27.000000000 -0800
-@@ -74,7 +74,7 @@
- RETVAL=$?
- ;;
- reload)
-- killproc -HUP nscd
-+ killproc nscd -HUP
- RETVAL=$?
- ;;
- *)
-diff -Naur ../glibc-2.1.3/po/.cvsignore glibc-2.1.3/po/.cvsignore
---- ../glibc-2.1.3/po/.cvsignore 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/po/.cvsignore 2000-02-18 16:03:43.000000000 -0800
-@@ -0,0 +1 @@
-+*.mo
-diff -Naur ../glibc-2.1.3/po/cs.mo glibc-2.1.3/po/cs.mo
---- ../glibc-2.1.3/po/cs.mo 2000-01-05 19:28:54.000000000 -0800
-+++ glibc-2.1.3/po/cs.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,458 +0,0 @@
--Þ•
--[
--`
--
--m
--
--
--
--
--”
--Ã
--
--
--
--ÿ
--
--
--
--
--
--
--
--
--
--
-- 
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-11-28 09:29-0800
--PO-Revision-Date: 1999-11-09 13:01+01:00
--Last-Translator: Vladimir Michl <Vladimir.Michl@seznam.cz>
--Language-Team: Czech <cs@li.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-2
--Content-Transfer-Encoding: 8bit
--
-- [-Y cesta] vst_soubor
--
-- [vst_soubor]
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache je povolena
--%15Zd navrhovaná velikost
--%15ld sekund ¾ivotnost pozitivních záznamù
--%15ld sekund ¾ivotnost negativních záznamù
--%15ld úspìchù cache pro pozitivní záznamy
--%15ld úspìchù cache pro negativní záznamy
--%15ld neúspìchù cache pro pozitivní záznamy
--%15ld neúspìchù cache pro negativní záznamy
--%15ld%% úspì¹nost cache
--%15s zkontrolujte zmìny v /etc/%s
--
--Èlenové skupin :
--
--®ivotnost :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -p posixová_pravidla ] [ -d adresáø ] [ -L pøestupných_sekund ]
-- [ -y typ_roku ] [ soubor ... ]
--
--
--
--není mo¾ná
--
--[ VÝSTUPNÍ_SOUBOR [VSTUPNÍ_SOUBOR]...]
--
--
--
--
--
--
--
--
--
-- Toto je volné programové vybavení; podmínky pro kopírování a roz¹iøování
--naleznete ve zdrojových textech. Toto programové vybavení je zcela BEZ ZÁRUKY,
--a to i bez záruky PRODEJNOSTI nebo VHODNOSTI PRO NÌJAKÝ KONKRÉTNÍ ÚÈEL.
--
--
--
--
--
--
--
--
--
--standardního vstupu. Je-li VÝSTUPNÍ_SOUBOR -, výstup bude zapsán na standardní
--výstup.
--
--
--
---o VÝSTUPNÍ_SOUBOR VSTUPNÍ_SOUBOR
---u VSTUPNÍ_SOUBOR
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--pøipomínky k pøekladu zasílejte na adresu <cs@li.org> (èesky).
--
--(pouze anglicky), pøipomínky k pøekladu zasílejte na <cs@li.org> (èesky).
--
--
--
--
-- repertoáry znakù : %s
-- lokalizaèní soubory : %s
--%s
--
--
--¾e v¹echny kombinace tìchto názvù mohou být pou¾ity pro argumenty Z a DO.
--Jedna znaková sada mù¾e být uvedena pod vícerými názvy (pøezdívkami).
-- Nìkteré z názvù nejsou obyèejné øetìzce, ale regulární výrazy, které
--urèují mo¾né parametry programu.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d ladící úroveò serveru
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/de.mo glibc-2.1.3/po/de.mo
---- ../glibc-2.1.3/po/de.mo 2000-02-24 18:13:09.000000000 -0800
-+++ glibc-2.1.3/po/de.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,476 +0,0 @@
--Þ•
--T
--k
--
--
--
--
--‘
--
--¥
--¹
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 2000-02-16 10:39-0800
--PO-Revision-Date: 2000-02-20 09:38+01:00
--Last-Translator: Jochen Hein <jochen@jochen.org>
--Language-Team: German <de@li.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-1
--Content-Transfer-Encoding: 8-bit
--
--
--
--
--
--
--
--
--
--
--%s Cache:
--
--%15s Cache ist eingeschaltet
--%15Zd vorgeschlagene Größe
--%15ld Time to Live für positive Einträge in Sekunden
--%15ld Time to Live für negative Einträge in Sekunden
--%15ld Cache-Hits bei positiven Einträgen
--%15ld Cache-Hits bei positiven Einträgen
--%15ld Cache-Misses bei positiven Einträgen
--%15ld Cache-Misses bei negativen Einträgen
--%15ld%% Cache-Hit Verhältnis
--%15s Prüfe /etc/%s auf Änderungen
--
--Gruppen Mitglieder :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L Schaltsekunden ] [ -y Jahrestyp ] [ Dateiname ... ]
--
--
--
--
--[Ausgabedatei [Eingabedatei]...]
--
--
--
--
--
--
--
--
--
--Dies ist freie Software; in den Quellen befinden sich die Lizenzbedingungen.
--Es gibt KEINERLEI Garantie; nicht einmal für die TAUGLICHKEIT oder
--VERWENDBARKEIT FÜR EINEN ANGEGEBENEN ZWECK.
--
--
--
--
--
--
--
--
--
--- ist, wird auf die Standardausgabe geschrieben.
--
--
--
---o Ausgabedatei Eingabedatei
---u Eingabedatei
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--bedeutet nicht, daß zwischen allen Kombinationen dieser Namen als FROM
--und TO Paramter konvertiert werden kann. Eine Zeichensatzkodierung kann
--unter verschiedenen Namen aufgeführt sein (sog. Aliasnamen).
--
--Einige Namen sind keine normalen Zeichenketten sondern Reguläre Ausdrücke
--und diese passen zu einer Reihe von Namen, die als Parameter angegeben
--werden können.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d Server Debug Level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/el.mo glibc-2.1.3/po/el.mo
---- ../glibc-2.1.3/po/el.mo 1999-07-18 18:19:41.000000000 -0700
-+++ glibc-2.1.3/po/el.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,282 +0,0 @@
--Þ•
--5
--@
--F
--
--|
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
-- %s [OPTION]... [OUTPUT-FILE [INPUT-FILE]...]
--Mandatory arguments to long options are mandatory for short options too.
-- -H, --header=NAME create C header file NAME containing symbol definitions
-- -h, --help display this help and exit
-- --new do not use existing catalog, force new output file
-- -o, --output=NAME write output to file NAME
-- -V, --version output version information and exit
--If INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE
--is -, output is written to standard output.
--
-- %s [OPTION]... -o OUTPUT-FILE INPUT-FILE
-- %s [OPTION]... -u INPUT-FILE
--Mandatory arguments to long options are mandatory for short options too.
-- -f, --fold-case convert key to lower case
-- -h, --help display this help and exit
-- -o, --output=NAME write output to file NAME
-- --quiet don't print messages while building database
-- -u, --undo print content of database file, one entry a line
-- -V, --version output version information and exit
--If INPUT-FILE is -, input is read from standard input.
--
--Mandatory arguments to long options are mandatory for short options too.
-- -c, --force create output even if warning messages were issued
-- -h, --help display this help and exit
-- -f, --charmap=FILE symbolic character names defined in FILE
-- -i, --inputfile=FILE source definitions are found in FILE
-- -u, --code-set-name=NAME specify code set for mapping ISO 10646 elements
-- -v, --verbose print more messages
-- -V, --version output version information and exit
-- --posix be strictly POSIX conform
--
--System's directory for character maps: %s
-- locale files : %s
--
--Mandatory arguments to long options are mandatory for short options too.
-- -h, --help display this help and exit
-- -V, --version output version information and exit
--
-- -a, --all-locales write names of available locales
-- -m, --charmaps write names of available charmaps
--
-- -c, --category-name write names of selected categories
-- -k, --keyword-name write names of selected keywords
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-07-26 08:57-0700
--PO-Revision-Date: 1999-01-24 20:21+0000
--Last-Translator: Mavroyanopoulos Nikos <nmav@i-net.paiko.gr>
--Language-Team: Greek <S.Xenitellis@rhbnc.ac.uk>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-7
--Content-Transfer-Encoding: 8-bit
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -d êáôÜëïãïò ] [ -L äåõôåñüëåðôá áíáðÞäçóçò ] [ -y ôýðïò Ýôïõò ] [ áñ÷åßï ... ]
--
--
--êáèõóôåñÞóåé ëßãï...
--êáèõóôåñÞóåé ëßãï...
--Áõôü åßíáé åëåýèåñï ëïãéóìéêüÒ äåßôå ôïí ðçãáßï êþäéêá ãéá üñïõò áíôéãñáöÞò.
--ÄÅÍ õðÜñ÷åé åããýçóçÒ ïýôå áêüìç ãéá ËÅÉÔÏÕÑÃIÊÏÔÇÔÁÓ Þ ÊÁÔÁËËÇËÏÔÇÔÁ ÃÉÁ
--ÊÁÐÏÉÏ ÓÕÃÊÅÊÑÉÌÅÍÏ ÓÊÏÐÏ.
--
--ç õðçñåóßá
--
--
--
--
-- %s [ÅÐÉËÏÃÇ]... [ÁÑ×ÅÉÏ-ÅÎÏÄÏÕ [ÁÑ×ÅÉÏ-ÅÉÓÏÄÏÕ]...]
--Õðï÷ñåùôéêÝò ðáñÜìåôñïé óôéò ìáêñÝò åðéëïãÝò åßíáé õðï÷ñåùôéêÝò êáé ãéá ôéò
--óýíôïìåò åðéëïãÝò.
-- -H, --header=ÏÍÏÌÁ êáôáóêåõÜæåôáé Ýíá áñ÷åßï åðéêåöáëßäùí C ïíüìáôïò ÏÍÏÌÁ
-- ðåñéÝ÷ïíôáò ôïõò ïñéóìïýò ôùí óõìâüëùí
-- -h, --help åêôýðùóç áõôÞò ôçò âïÞèåéáò êáé ôåñìáôéóìüò
-- --new äåí ÷ñçóéìïðïéåßôáé õðÜñ÷ïí êáôÜëïãïò, åîáíáãêÜæåôáé íÝï áñ÷åßï åîüäïõ
-- -o, --output=ÏÍÏÌÁ ãñÜöåôáé ç Ýîïäïò óôï áñ÷åßï ÏÍÏÌÁ
-- -V, --version åêôýðùóç ðëçñïöïñéþí Ýêäïóçò êáé ôåñìáôéóìüò
--ÅÜí ôï ÁÑ×ÅÉÏ-ÅÉÓÏÄÏÕ åßíáé -, ç åßóïäïò äéáâÜæåôáé áðï ôçí êáíïíéêÞ åßóïäï.
--ÅÜí ôï ÁÑ×ÅÉÏ-ÅÎÏÄÏÕ åßíáé -, ç Ýîïäïò ãñÜöåôáé óôçí êáíïíéêÞ Ýîïäï.
--
-- %s [ÅÐÉËÏÃÇ]... -o ÁÑ×ÅÉÏ-ÅÎÏÄÏÕ ÁÑ×ÅÉÏ-ÅÉÓÏÄÏÕ
-- %s [ÅÐÉËÏÃÇ]... -u ÁÑ×ÅÉÏ-ÅÉÓÏÄÏÕ
--Õðï÷ñåùôéêÝò ðáñÜìåôñïé óôéò ìáêñÝò åðéëïãÝò åßíáé õðï÷ñåùôéêÝò êáé ãéá ôéò
--óýíôïìåò åðéëïãÝò.
-- -f, --fold-case ìåôáôñÝðåé ôï êëåéäß óå ðåæÜ ãñÜììáôá
-- -h, --help åêôýðùóç áõôÞò ôçò âïÞèåéáò êáé ôåñìáôéóìüò
-- -o, --output=ÏÍÏÌÁ ãñÜöåôáé ç Ýîïäïò óôï áñ÷åßï ÏÍÏÌÁ
-- --quiet íá ìçí åêôõðþíïíôáé ìçíýìáôá êáèþò äçìéïõñãåßôáé ç âÜóç
-- äåäïìÝíùí
-- -u, --undo åêôýðùóç ôùí ðåñéå÷ïìÝíùí ôïõ áñ÷åßïõ ôçò âÜóçò
-- äåäïìÝíùí, ìßá êáôá÷þñçóç áíÜ ãñáììÞ
-- -V, --version åêôýðùóç ðëçñïöïñéþí Ýêäïóçò êáé ôåñìáôéóìüò
--ÅÜí ôï ÁÑ×ÅÉÏ-ÅÉÓÏÄÏÕ åßíáé -, ç åßóïäïò äéáâÜæåôáé áðü ôçí êáíïíéêÞ åßóïäï.
--
--Õðï÷ñåùôéêÝò ðáñÜìåôñïé óôéò ìáêñÝò åðéëïãÝò åßíáé õðï÷ñåùôéêÝò êáé ãéá ôéò
--óýíôïìåò åðéëïãÝò.
-- -c, --force äçìéïõñãåßôáé Ýîïäïò áêüìç êáé áí ìçíýìáôá
-- ðñïåéäïðïßçóçò åêäüèçêáí
-- -h, --help åêôýðùóç áõôÞò ôçò âïÞèåéáò êáé ôåñìáôéóìüò
-- -f, --charmap=ÁÑ×ÅÉÏ óõìâïëéêÜ ïíüìáôá ÷áñáêôÞñùí ïñéóìÝíá óôï ÁÑ×ÅÉÏ
-- -i, --inputfile=ÁÑ×ÅÉÏ ïé ïñéóìïß ðçãÞò âñßóêïíôáé óôï ÁÑ×ÅÉÏ
-- -u, --code-set-name=ÏÍÏÌÁ êáèïñßæåôáé óåô êùäéêþí ãéá áíôéóôïß÷éóç
-- ôùí ISO 10646 óôïé÷åßùí
-- -v, --verbose åêôýðùóç ðåñéóóïôÝñùí ìçíõìÜôùí
-- -V, --version åêôýðùóç ðëçñïöïñéþí Ýêäïóçò êáé ôåñìáôéóìüò
-- --posix áõóôçñÞ óõìüñöùóç ìå POSIX
--
--Ï êáôÜëïãïò óõóôÞìáôïò ãéá ÷Üñôåò ÷áñáêôÞñùí: %s
-- áñ÷åßá locale: %s
--
--Õðï÷ñåùôéêÝò ðáñÜìåôñïé óôéò ìáêñÝò åðéëïãÝò åßíáé õðï÷ñåùôéêÝò êáé ãéá ôéò
--óýíôïìåò åðéëïãÝò.
-- -h, --help åêôýðùóç áõôÞò ôçò âïÞèåéáò êáé ôåñìáôéóìüò
-- -V, --version åêôýðùóç ðëçñïöïñéþí Ýêäïóçò êáé ôåñìáôéóìüò
--
-- -a, --all-locales ãñÜöïíôáé ôá ïíüìáôá ôùí äéáèÝóéìùí locales
-- -m, --charmaps ãñÜöïíôáé ôá ïíüìáôùí ôùí äéáèÝóéìùí ÷áñôþí ÷áñáêôÞñùí
--
-- -c, --category-name ãñÜöïíôáé ôá ïíüìáôùí ôùí åðéëåãìÝíùí êáôçãïñéþí
-- -k, --keyword-name ãñÜöïíôáé ôá ïíüìáôá ôùí åðéëåãìÝíùí ëÝîåùí-êëåéäéþí
--
--
--
--
--
--Üãíùóôï ÷áñáêôÞñá
--íá ÷ñçóéìïðïéçèåß áìÝóùò ìåôÜ ôï 'until time'
--
--áãíïåßôáé ç ãñáììÞ
--áãíïåßôáé ç ãñáììÞ
--
--
--êáôçãïñßá `%s' äåí åßíáé '+' ïýôå '-'
--êáôçãïñßá `%s' äåí åßíáé Ýíáò ÷áñáêôÞñáò
--óôï ðåäßï `era' óôçí êáôçãïñßá `%s'
--óôï ðåäßï `era' óôçí êáôçãïñßá `%s'
--óôï ðåäßï `era' óôçí êáôçãïñßá `%s'
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/es.mo glibc-2.1.3/po/es.mo
---- ../glibc-2.1.3/po/es.mo 1999-07-18 18:19:41.000000000 -0700
-+++ glibc-2.1.3/po/es.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,490 +0,0 @@
--Þ•
--[
--`
--
--m
--
--
--
--
--”
--È
--
--Ñ
--
--
--
--
--
--
--
--
--
--
--
--
-- 
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-11-28 09:29-0800
--PO-Revision-Date: 1998-12-12 21:19+0100
--Last-Translator: Santiago Vila Doncel <sanvila@unex.es>
--Language-Team: Spanish <es@li.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-1
--Content-Transfer-Encoding: 8-bit
--
--
--
--
--
--
--
--
--
--
--%s caché:
--
--%15s el caché está activado
--%15Zd tamaño sugerido
--%15ld segundos de vida para las entradas positivas
--%15ld segundos de vida para las entradas negativas
--%15ld aciertos de caché en las entradas positivas
--%15ld aciertos de caché en las entradas negativas
--%15ld fallos de caché en las entradas positivas
--%15ld fallos de caché en las entradas negativas
--%15ld%% tasa de aciertos de caché
--%15s compruebe /etc/%s para cambios
--
--Miembros del Grupo :
--
--Tiempo de Vida :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--de plantillas
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--ajuste de años bisiestos %s
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -d directorio ] [ -L segundos_intercalares ] [ -y tipoaño ] [ fichero ... ]
--
--
--
--
--[FICHERO-SALIDA [FICHERO-ENTRADA]...]
--
--
--
--
--
--
--
--
--
--rato ...
--un rato ...
--Esto es software libre; vea el código fuente para las condiciones de copia.
--No hay NINGUNA garantía; ni siquiera de COMERCIABILIDAD o IDONEIDAD PARA UN
--FIN DETERMINADO.
--
--
--
--
--
--
--
--
--
--de la entrada estándar. Si FICHERO-SALIDA es -, el resultado se escribe en la
--salida estándar.
--
--
--
---o FICHERO-SALIDA FICHERO-ENTRADA
---u FICHERO-ENTRADA
--
--
--
--
--también obligatorios u opcionales para las opciones cortas correspondientes.
--
--[-a|-m]
--No se puede suministrar el servicio.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- asignaciones de repertorios: %s
-- ruta de búsqueda de locales: %s
--%s
--
--
--Esto no quiere decir necesariamente que todas las combinaciones de estos
--nombres se puedan usar como parámetros FROM y TO en la línea de órdenes.
--Un determinado conjunto de caracteres puede aparecer con varios nombres
--(aliases).
--Algunos de los nombres no son cadenas normales sino expresiones regulares y
--pueden corresponderse con una variedad de nombres que pueden darse como
--parámetros al programa.
--
--
--
--
--
--
--
--
--
--
--
--de la línea anterior
--`%s'
--un carácter desconocido
--
--
--
--después
--
--
--
--actual es %d
--
--
--
--
--
--`%s' no es '+' ni '-'
--`%s' no es un único carácter
--
--campo `era' de la categoría `%s'
--campo `era' de la categoría `%s'
--campo `era' de la categoría `%s'
--
--categoría `%s'
--categoría `%s'
--categoría `%s'
--de caracteres
--
--
--
--
--categoría `%s'
--categoría `%s'
--
--
--%s
--y el objeto compartido `%s' no tiene soname
--
--%15d nivel de depuración del servidor
--
--
--
--objeto compartido `%s'
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--categoría `%s'
--categoría `%s'
--
--
--
--
--
--definición de otro elemento
--de otro elemento
--de otro símbolo
--de otro símbolo
--de símbolo en el conjunto de caracteres
--
--
--corresponde con un nombre válido en ISO 4217
--una longitud errónea
--que 127
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/fr.mo glibc-2.1.3/po/fr.mo
---- ../glibc-2.1.3/po/fr.mo 1999-08-18 18:02:29.000000000 -0700
-+++ glibc-2.1.3/po/fr.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,486 +0,0 @@
--Þ•
--[
--`
--
--m
--
--
--
--
--”
--
--Ç
--Ê
--Þ
--
--
--ê
--
--
-- 
--
--
--
--
--
--
--
--
--
--
--
--?
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-11-28 09:29-0800
--PO-Revision-Date: 1999-08-13 08:52-0500
--Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>
--Language-Team: French <traduc@traduc.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-1
--Content-Transfer-Encoding: 8-bit
--
--
--
--
--
--
--
--
--
--
--%s mémoire cache:
--
--%15s mémoire cache est activée
--%15Zd taille suggérée
--%15ld durée de vie en secondes pour les entrées positives
--%15ld durée de vie en secondes pour les entrées négatives
--%15ld succès de repérage sur les entrées positives
--%15ld succès de repérage sur les entrées négatives
--%15ld échec de repérage sur les entrées positives
--%15ld échec de repérage sur les entrées négatives
--%15ld%% taux de repérage
--%15s vérifier /etc/%s pour les changements
--
--Membres du groupe :
--
--Durée de vie :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--de délai en secondes %s
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L secondes_écoulées ] [ -y type_année ] [ fichier ... ]
--
--
--
--
--[FICHIER_DE_SORTIE [FICHIER_D_ENTRÉE]...]
--
--
--
--
--
--
--
--
--
--peut prendre un certain temps...
--peut prendre un certain temps...
--Ce logiciel est gratuit; voir les sources pour les conditions de
--reproduction. AUCUNE garantie n'est donnée; tant pour des raisons
--COMMERÇIALES que pour RÉPONDRE À UN BESOIN PARTICULIER.
--
--
--
--
--
--
--
--
--
--est -, la sortie est affichée sur la sortie standard.
--
--
--
---o FICHIER_DE_SORTIE FICHIER_D_ENTRÉE
---u FICHIER_D_ENTRÉE
--
--
--
--
--le sont aussi pour les options de forme courtes.
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--<bugs@gnu.org>.
--
--
--
--
-- de la table des répertoires: %s
-- du chemin des localisations: %s
--%s
--
--
--ne signifie pas nécessairement que toutes les combinaisons de ces noms peuvent
--être utilisées dans les paramètres FROM et TO des commandes. Un jeu de codes de
--caractères peut être affiché avec différents noms (aliases).
--Quelques uns des noms ne contiennent pas de chaînes ordinaires mais plutôt
--des expressions régulières qui concordent avec une variété de noms qui
--peuvent être passés en paramètres au programme.
--
--
--
--
--
--
--
--
--
--
--
--au temps final de la ligne précédente.
--
--
--
--juste après telle date
--
--
--
--
--
--
--
--
--catégorie `%s' n'est pas un `+' ni un `-'.
--catégorie `%s' n'est pas un caractères simple.
--
--du champ `era' de catégorie `%s'
--de catégorie `%s'
--de catégorie `%s'
--
--de catégorie `%s'.
--de catégorie `%s'
--de catégorie `%s'
--
--
--
--
--de catégorie `%s'
--
--
--
--%15d niveau serveur de déboggage
--
--
--à une définition de type `CHARMAP'.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--fusionnement n'a aucun sens.
--de catégorie `%s'.
--de catégorie `%s'
--
--
--
--
--
--provoque la duplication de la définition d'un élément.
--provoque la duplication d'autres définitions d'éléments.
--provoque la duplication d'autres définitions de symboles.
--provoque la duplication de la définition d'un symbole.
--provoque la duplication d'un nom symbolique dans le jeu de caractères.
--
--que la limite inférieure.
--
--<mb_cur_min>.
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/gl.mo glibc-2.1.3/po/gl.mo
---- ../glibc-2.1.3/po/gl.mo 2000-02-24 18:13:10.000000000 -0800
-+++ glibc-2.1.3/po/gl.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,453 +0,0 @@
--Þ•
--T
--k
--
--
--
--
--‘
--
--¥
--¹
--
--
--
--
--
--
--
--
--
--
--
--
--@
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 2000-02-16 10:39-0800
--PO-Revision-Date: 2000-02-21 10:04+0200
--Last-Translator: Jacobo Tarrio <jtarrio@iname.com>
--Language-Team: Galician <gpul-traduccion@ceu.fi.udc.es>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=iso-8859-1
--Content-Transfer-Encoding: 8bit
--
--
--
--
--
--
--
--
--
--
--%s caché:
--
--%s15s a caché está activada
--%15Zd tamaño aconsellado
--%15ld segundos de vida para as entradas positivas
--%15ld segundos de vida para as entradas negativas
--%15ld acertos de caché para entradas positivas
--%15ld acertos caché para entradas negativas
--%15ld fallos de caché para entradas positivas
--%15ld fallos de caché para entradas negativas
--%15ld%% tasa de acertos de caché
--%15s comprobe /etc/%s para ve-los cambios
--
--Membros do Grupo :
--
--Tempo de Vida :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L axuste ] [ -y tipoano ] [ ficheiro ... ]
--
--
--
--
--[FICHEIRO-SAÍDA [FICHEIRO-ENTRADA]...]
--
--
--
--
--
--
--
--
--
--Isto é software libre; vexa o código fonte polas condicións de copia. NON hai
--garantía; nin sequera de COMERCIABILIDADE ou APTITUDE PARA UN FIN DETERMINADO.
--
--
--
--
--
--
--
--
--
--Se o FICHEIRO-ENTRADA é -, a entrada lese da entrada estándar. Se o
--FICHEIRO-SAÍDA é -, a saída escríbese na saída estándar.
--
--
--
---o FICHEIRO-SAÍDA FICHEIRO-ENTRADA
---u FICHEIRO-ENTRADA
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- mapas de repertorios: %s
-- locale : %s
--%s
--
--
--significa necesariamente que tódalas combinacións deses nomes poidan ser usadas
--para os parámetros de liña de comandos DE e A. Un xogo de caracteres pode ser
--listado con distintos nomes (alias).
-- Algúns dos nomes non son cadeas normais, senón expresións regulares e
--coinciden cunha variedade de nomes que poden ser dados como parámetros do
--programa
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d nivel de depuración do servidor
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/it.mo glibc-2.1.3/po/it.mo
---- ../glibc-2.1.3/po/it.mo 2000-02-24 18:13:10.000000000 -0800
-+++ glibc-2.1.3/po/it.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,514 +0,0 @@
--Þ•
--T
--k
--
--
--
--
--‘
--
--¥
--¹
--Ñ
--
--à
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--ô
--
--
--
--
--
--
--
--
--
--
--
-->
--P
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 2000-02-16 10:39-0800
--PO-Revision-Date: 2000-02-20 22:17+01:00
--Last-Translator: Marco d'Itri <md@linux.it>
--Language-Team: Italian <it@li.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-1
--Content-Transfer-Encoding: 8-bit
--
--
--
--
--
--
--
--
--
--
--cache %s:
--
--%15s la cache è abilitata
--%15Zd dimensioni suggerite
--%15ld secondi di vita per le voci positive
--%15ld secondi di vita per le voci negative
--%15ld cache hit sulle voci positive
--%15ld cache hit sulle voci negative
--%15ld cache miss sulle voci positive
--%15ld cache miss sulle voci negative
--%15ld%% hit rate della cache
--%15s controlla i cambiamenti di /etc/%s
--
--Membri del gruppo :
--
--Tempo da vivere:
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ nomefile ... ]
--
--
--
--
--[FILE-OUTPUT [FILE-INPUT]...]
--
--
--
--
--
--
--
--
--
--Può essere una cosa lunga...
--Può essere una cosa lunga...
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--Questo è software libero; si veda il sorgente per le condizioni di copiatura.
--NON c'è alcuna garanzia; neppure di COMMERCIABILITÀ o IDONEITÀ AD UN
--PARTICOLARE SCOPO.
--
--
--
--
--
--
--
--
--NIS+ è installato?
--
--è -, l'output è scritto sullo standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--per le corrispondenti opzioni corte.
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps : %s
-- percorso di localizzazione: %s
--%s
--
--
--non significa necessariamente che tutte le combinazioni di questi nomi possono
--essere usate per i parametri di linea di comando FROM e TO. Un set di
--caratteri codificato può essere elencato con diversi nomi diversi (alias).
--Alcuni nomi non sono semplici stringhe ma espressioni regolari e corrispondono
--a una varietà di nomi che possono essere dati come parametri al programma.
--
--
--
--
--
--
--
--
--
--
--
--non è successivo al tempo finale della riga precedente
--contiene un carattere sconosciuto
--
--
--
--da usare subito dopo il tempo finale
--
--
--
--la versione attuale è %d
--
--
--
--
--
--della categoria `%s', non è né '+' né '-'
--della categoria `%s', non è un unico carattere
--
--nel campo `era' della categoria `%s'
--nel campo `era' della categoria `%s'
--nel campo `era' della categoria `%s'
--
--nel campo `era' della categoria `%s'
--nel campo `era' della categoria `%s'
--nel campo `era' della categoria `%s'
--
--
--
--nel campo `era' della categoria `%s'
--nel campo `era' della categoria `%s'
--
--
--della categoria `%s': %s
--condiviso `%s' non ha un soname
--
--%15d livello di debug del server
--
--
--
--condiviso `%s'
--
--
--
--
--
--
--
--
--
--
--
--del programma %1$s
--
--
--
--nel campo `era' della categoria `%s'
--categoria `%s'
--
--
--
--
--
--replica la definizione dell'elemento
--replica la definizione di un altro simbolo
--replica la definizione del simbolo
--replica il nome simbolico
--
--
--non deve essere la stringa vuota
--non corriposnde ad un nome ISO 4217 valido
--è di lunghezza errata
--inferiori a 127
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/ko.mo glibc-2.1.3/po/ko.mo
---- ../glibc-2.1.3/po/ko.mo 1999-07-18 18:19:41.000000000 -0700
-+++ glibc-2.1.3/po/ko.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,453 +0,0 @@
--Þ•
--[
--`
--
--m
--
--
--
--
--”
--Î
--
--
--
--
--æ
--è
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-11-28 09:29-0800
--PO-Revision-Date: 1998-12-04 06:52+0900
--Last-Translator: Changwoo Ryu <cwryu@adam.kaist.ac.kr>
--Language-Team: Korean <ko@li.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=EUC-KR
--Content-Transfer-Encoding: 8-bit
--
--
--
--
--
--
--
--
--
--
--%s ij½¬:
--
--%15s °³ÀÇ Ä³½¬ »ç¿ëÁß
--%15Zd ¸¸Å­ÀÇ ÃøÁ¤µÈ Å©±â
--%15ld Ãʵ¿¾È positive entry À¯Áö
--%15ld Ãʵ¿¾È negative entry À¯Áö
--%15ld ¹ø positive entriy¿¡ ´ëÇØ Ä³½¬ È÷Æ®
--%15ld ¹ø negative entriy¿¡ ´ëÇØ Ä³½¬ È÷Æ®
--%15ld ¹ø positive entriy¿¡ ´ëÇØ Ä³½¬ ¹Ì½º
--%15ld ¹ø negative entriy¿¡ ´ëÇØ Ä³½¬ ¹Ì½º
--%15ld%% ij½¬ È÷Æ®À²
--%15s check /etc/%s for changes
--
--±×·ì ¸â¹ö :
--
--À¯Áö ½Ã°£ :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L À±ÃÊ ] [ -y ¿¬µµÀÇÇüÅ ] [ ÆÄÀÏÀ̸§ ... ] ÀÔ´Ï´Ù
--
--
--
--
--[Ãâ·Â-ÆÄÀÏ [ÀÔ·Â-ÆÄÀÏ]...]
--
--
--
--
--
--
--
--
--
--ÀÌ ÇÁ·Î±×·¥Àº °ø°³ ¼ÒÇÁÆ®¿þ¾îÀÔ´Ï´Ù; º¹»çÁ¶°ÇÀº ¼Ò½º¸¦ ÂüÁ¶ÇϽʽÿÀ. »óÇ°¼º
--À̳ª ƯÁ¤ ¸ñÀû¿¡ ´ëÇÑ ÀûÇÕ¼ºÀ» ºñ·ÔÇÏ¿© ¾î¶°ÇÑ º¸Áõµµ ÇÏÁö ¾Ê½À´Ï´Ù.
--
--
--
--
--
--
--
--
--
--
--
--
---o Ãâ·Â-ÆÄÀÏ ÀÔ·Â-ÆÄÀÏ
---u ÀÔ·Â-ÆÄÀÏ
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- ·¹ÆÄÅ丮 Áöµµ: %s
-- ·ÎÄÉÀÏ °æ·Î : %s
--%s
--
--
--FROM°ú TO Àμö¿¡ ¿©±âÀÇ ¸ðµç ¹®Àڼ À̸§ÀÇ Á¶ÇÕÀ» »ç¿ëÇÒ ¼ö ÀÖ´Â °ÍÀº
--¾Æ´Õ´Ï´Ù. ÇÑ°³ÀÇ ¹®Àڼ ÄÚµå´Â ¸î°¡Áö ´Ù¸¥ À̸§(º°¸í)°ú ÇÔ²² ¿­°ÅµÇ¾î
--ÀÖÀ» ¼öµµ ÀÖ½À´Ï´Ù.
-- ÀÌ À̸§µéÁß ¸î°³´Â º¸Åë ¹®ÀÚ¿­ÀÌ ¾Æ´Ï¶ó Á¤±Ô½ÄÀÌ°í, ÀÌ Á¤±Ô½ÄÀº
--ÇÁ·Î±×·¥ÀÇ ÀÎÀÚ·Î ÁÖ¾îÁø ¿©·¯°¡ÁöÀÇ À̸§¿¡ ÇØ´çµË´Ï´Ù
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d ¼­¹ö µð¹ö±× ±íÀÌ
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/nl.mo glibc-2.1.3/po/nl.mo
---- ../glibc-2.1.3/po/nl.mo 1999-07-18 18:19:41.000000000 -0700
-+++ glibc-2.1.3/po/nl.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,274 +0,0 @@
--Þ•
--5
--@
--F
--
--|
--‡
--
--
--
--
--
--¦
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
-- %s [OPTION]... [OUTPUT-FILE [INPUT-FILE]...]
--Mandatory arguments to long options are mandatory for short options too.
-- -H, --header=NAME create C header file NAME containing symbol definitions
-- -h, --help display this help and exit
-- --new do not use existing catalog, force new output file
-- -o, --output=NAME write output to file NAME
-- -V, --version output version information and exit
--If INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE
--is -, output is written to standard output.
--
-- %s [OPTION]... -o OUTPUT-FILE INPUT-FILE
-- %s [OPTION]... -u INPUT-FILE
--Mandatory arguments to long options are mandatory for short options too.
-- -f, --fold-case convert key to lower case
-- -h, --help display this help and exit
-- -o, --output=NAME write output to file NAME
-- --quiet don't print messages while building databank
-- -u, --undo print content of databank file, one entry a line
-- -V, --version output version information and exit
--If INPUT-FILE is -, input is read from standard input.
--
--Mandatory arguments to long options are mandatory for short options too.
-- -c, --force create output even if warning messages were issued
-- -h, --help display this help and exit
-- -f, --charmap=FILE symbolic character names defined in FILE
-- -i, --inputfile=FILE source definitions are found in FILE
-- -u, --code-set-name=NAME specify code set for mapping ISO 10646 elements
-- -v, --verbose print more messages
-- -V, --version output version information and exit
-- --posix be strictly POSIX conform
--
--System's directory for character maps: %s
-- locale files : %s
--
--Mandatory arguments to long options are mandatory for short options too.
-- -h, --help display this help and exit
-- -V, --version output version information and exit
--
-- -a, --all-locales write names of available locales
-- -m, --charmaps write names of available charmaps
--
-- -c, --category-name write names of selected categories
-- -k, --keyword-name write names of selected keywords
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-07-26 08:57-0700
--PO-Revision-Date: 1998-12-12 15:50+0100
--Last-Translator: André van Dijk <ady@unseen.demon.nl>
--Language-Team: Dutch <nl@li.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-1
--Content-Transfer-Encoding: 8-bit
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--[ -l lokale tijd ] [ -p posixregels ] [ -d directory ]
--[ -L schrikkelseconden ] [ -y jaartype ] [ bestandsnaam ... ]
--
--
--Dit is vrije programmatuur; zie de bron-code voor copieervoorwaarden.
--Er is GEEN garantie; zelfs niet voor VERKOOPBAARHEID of GESCHIKTHEID
--VOOR EEN BEPAALD DOEL.
--
--
--
--
--
-- %s [OPTIE]... [UITVOER-BESTAND [INVOER-BESTAND]...]
--Verplichte argumenten bij lange opties zijn ook verplicht bij korte opties.
-- -H, --header=NAAM maak C header bestand NAAM met symbooldefinities
-- -h, --help toon hulp-tekst en beëindig programma
-- --new gebruik niet een bestaande catalog, maak een nieuwe
-- -o, --output=NAAM schrijf uitvoer naar bestand NAAM
-- -V, --version toon versie-informatie en beëindig programma
--Als INVOER-BESTAND is -, lees invoer uit standardinvoer. Als UITVOER-BESTAND
--is -, schrijf uitvoer naar standaarduitvoer.
--
-- %s [OPTIE]... -o UITVOER-BESTAND [INVOER-BESTAND]
-- %s [OPTIE]... -u INVOER-BESTAND
--Verplichte argument bij lange opties zijn ook verplicht bij korte opties.
-- -f, --fold-case converteer sleutel naar kleine letters
-- -h, --help toon hulp-tekst en beëindig programma
-- -o, --output=NAAM schrijf uitvoer naar bestand NAAM
-- --quiet toon geen meldingen bij aanmaken databank
-- -u, --undo toon inhoud van databank bestand, een item per regel
-- -V, --version toon versie-informatie en beëindig programma
--Als INVOER-BESTAND is -, lees invoer uit standardinvoer.
--Meld fouten via <bug-glibc@prep.ai.mit.edu>.
--
--Verplichte argumenten bij lange opties zijn ook verplicht bij korte opties.
-- -c, --force maak uitvoer zelfs als waarschuwing werden gegeven
-- -h, --help toon hulptekst en beëindig programma
-- -f, --charmap=BESTAND symbolische tekennamen gedefinieerd in BESTAND
-- -i, --inputfile=BESTAND bron definities zijn gevonden in BESTAND
-- -u, --code-set-name=NAAM specificeer codeset voor mappen ISO 10646 elementen
-- -v, --verbose toon meer meldingen
-- -V, --version toon versie-informatie en beëindig programma
-- --posix volg de POSIX afspraken
--
--Systeemmap voor tekenset: %s
-- locale bestanden: %s
--Meld fouten aan <bug-glibc@prep.ai.mit.edu>.
--
--Verplichte argumenten bij lange opties zijn ook verplicht bij korte opties.
-- -h, --help toon hulptekst en beëindig programma
-- -V, --version toon versie-informatie en beëindig programma
--
-- -a, --all-locales toon namen van beschikbare localen
-- -m, --charmaps toon namen van beschikbare tekensets
--
-- -c, --category-name toon namen van geselecteerde categorieën
-- -k, --keyword-name toon namen van geselecteerde sleutelwoorden
--Meld fouten aan <bug-glibc@prep.ai.mit.edu>.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--element definitie
--andere element definities
--andere symbool definitie
--
--korrespondeert niet met een geldige naam in ISO 4217
--`LC_MONETARY' is niet juist
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/no.mo glibc-2.1.3/po/no.mo
---- ../glibc-2.1.3/po/no.mo 1999-07-18 18:19:42.000000000 -0700
-+++ glibc-2.1.3/po/no.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,448 +0,0 @@
--Þ•
--U
--
--a
--
--
--
--
--¥
--Í
--
--Ù
--
--Ý
--æ
--è
--
--
--û
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-11-28 09:29-0800
--PO-Revision-Date: 1999-01-16 14:00+0100
--Last-Translator: Eivind Tagseth <eivindt@multinet.no>
--Language-Team: Norwegian <no@li.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-1
--Content-Transfer-Encoding: 8bit
--
--
--
--
--
--
--
--
--
--
--%s hurtigbuffer (cache):
--
--%15s hurtigbuffer er på
--%15Zd foreslått størrelse
--%15ld sekunders levetid for positive innslag
--%15ld sekunders levetid for negative innslag
--%15ld treff i hurtigbuffer for positive innslag
--%15ld treff i hurtigbuffer for negative innslag
--%15ld bom i hurtigbuffer for positive innslag
--%15ld bom i hurtigbuffer for negative innslag
--%15ld%% treffrate for hurtigbuffer
--%15s sjekk /etc/%s for endringer
--
--Gruppemedlemmer :
--
--Levetid :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L skuddsekunder ] [ -y årkontrollprogram ] [ filnavn ... ]
--
--
--
--
--[UTFIL [INNFIL]...]
--
--
--
--
--
--
--
--
--
--Dette er gratis programvare. Se kildekoden for kopieringsbetingelser.
--Programvaren har ingen garanti, ikke en gang for SALGBARHET eller EGNETHET
--TIL NOEN SPESIELL OPPGAVE.
--
--
--
--
--
--
--
--
--
--er - skrives utdata til standard ut.
--
--
--
---o UTFIL INNFIL
---u INNFIL
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--betyr ikke nødvendigvis at alle kombinasjoner av disse navnene kan bli brukt
--som FRA- og TIL-kommandolinjeparametre. Et kodet tegnsett kan være listet
--med flere forskjellige navn (alias).
-- Noen av navnene er ikke vanlige strenger men er isteden regulære uttrykk
--og de tilsvarer en variasjon av navn som kan bli gitt som parametre til
--programmet.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--ikke «+» eller «-»
--ikke ett enkelt tegn
--
--
--
--
--
--
--
--
--
--%15d debugnivå for tjener
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--elementdefinisjon
--symboldefinisjon
--symboldefinisjon
--symbolnavn i tegnsett
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/pl.mo glibc-2.1.3/po/pl.mo
---- ../glibc-2.1.3/po/pl.mo 2000-02-17 20:10:14.000000000 -0800
-+++ glibc-2.1.3/po/pl.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,458 +0,0 @@
--Þ•
--[
--`
--
--m
--
--
--
--
--”
--
--
--Ò
--
--
--
--ú
--
--ü
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-11-28 09:29-0800
--PO-Revision-Date: 1999-09-11 22:25+02:00
--Last-Translator: Pawe³ Krawczyk <kravietz@ceti.pl>
--Language-Team: Polish <pl@li.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-2
--Content-Transfer-Encoding: 8-bit
--
--
--
--
--
--
--
--
--
--
--cache %s:
--
--%15s cache jest w³±czony
--%15Zd zalecany rozmiar
--%15ld sekund czasu przez który bêd± utrzymywane wpisy pozytywne
--%15ld sekund czasu przez który bêd± utrzymywane wpisy negatywne
--%15ld trafionych wpisów pozytywnych
--%15ld trafionych wpisów negatywnych
--%15ld nietrafiownych wpisów pozytywnych
--%15ld nietrafionych wpisów negatywnych
--%15ld%% procent trafieñ
--%15s sprawd¼ zmiany w /etc/%s
--
--Cz³onkowie grupy :
--
--Czas ¿ycia :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -d katalog ] [ -L sek_przestêpne ] [ -y yearistype ]
-- [ plik ... ]
--
--
--
--
--[PLIK-WY [PLIK-WE]...]
--
--
--
--
--
--
--
--
--
--Oprogramowanie darmowe. Warunki kopiowania zamieszczone s± w kodzie ¼ród³owym.
--Nie podlega ¿adnej gwarancji, nawet gwarancji przydatno¶ci do jakiegokolwiek
--zastosowania lub sprzeda¿y.
--
--
--
--
--
--
--
--
--
--Je¶li PLIK-WE to -, dane s± czytane ze standardowego wej¶cia. Je¶li PLIK-WY
--to -, dane s± zapisywane na standardowe wyj¶cie.
--
--
--
---o PLIK-WY PLIK-WE
---u PLIK-WE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- map repertuarów : %s
-- ¶cie¿ka lokalizacji: %s
--%s
--
--
--¿e wszystkie kombinacje zestawów mog± byæ u¿ywane jako parametry OD i DO. Jeden
--zestaw znaków mo¿e znajdowaæ siê na li¶cie pod wieloma nazwami (aliasami).
-- Niektóre nazwy nie s± zwyk³ymi napisami, tylko wyra¿eniami regularnymi
--pasuj±cymi do okre¶lonego zbioru nazw. One tak¿e mog± byæ u¿ywane jako
--parametry programu.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--lub '-'
--pojedynczym znakiem
--
--
--
--
--
--
--
--
--
--%15d poziom komunikatów diagnostycznych
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/pt_BR.mo glibc-2.1.3/po/pt_BR.mo
---- ../glibc-2.1.3/po/pt_BR.mo 1999-08-18 18:02:29.000000000 -0700
-+++ glibc-2.1.3/po/pt_BR.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,448 +0,0 @@
--Þ•
--[
--`
--
--m
--
--
--
--
--”
--
--
--å
--
--
--
--
--
--
--
--
--
--
--(
--.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-11-28 09:29-0800
--PO-Revision-Date: 1999-06-29 18:07-0300
--Last-Translator: Rodrigo Parra Novo <rodarvus@conectiva.com.br>
--Language-Team: Brazilian Portuguese <ldp-br@bazar.conectiva.com.br>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-1
--Content-Transfer-Encoding: 8-bit
--
--
--
--
--
--
--
--
--
--
--cache %s:
--
--%15s cache está habilitado
--%15Zd tamanho sugerido%15ld segundos de vida para entradas positivas
--%15ld segundos de vida para entradas negativas
--%15ld hits do cache para entradas positivas
--%15ld hits do cache para entradas negativas
--%15ld%% quantidade de hits no cache
--%15s verifique o arquivo /etc/%s para mudanças
--
--Membros do Grupo :
--
--Tempo de Vida :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L segundosajuste ] [ -y tipoano ] [ nome do arquivo ... ]
--
--
--
--
--[ARQUIVO-SAÍDA [ARQUIVO-ENTRADA...]
--
--
--
--
--
--
--
--
--
--Este é um software free; leia os fontes para condicões de cópia. Não existe
--garantia; nem para comércio ou adequacão para propóstios particulares.
--
--
--
--
--
--
--
--
--
--é -, a saída é escrita para a saída padrão.
--
--
--
---o ARQUIVO-SAÍDA ARQUIVO-ENTRADA
---u ARQUIVO-ENTRADA
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- mapas de repertório: %s
-- rota de localização: %s
--%s
--
--
--conhecidos. Isto não quer dizer necessáriamente que todas as combinações
--destes nomes podem ser utilizadas nos parâmetros FROM e TO. Um conjunto
--de caracteres pode ser listado com vários nomes diferentes (apelidos).
-- Alguns destes nomes não strings simples mas sim, expressões regulares, e
--eles combinam com uma variedade de nomes que podem ser dados como parâmetrosao programa.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d nível de debug do servidor
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/sk.mo glibc-2.1.3/po/sk.mo
---- ../glibc-2.1.3/po/sk.mo 1999-07-18 18:19:42.000000000 -0700
-+++ glibc-2.1.3/po/sk.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,451 +0,0 @@
--Þ•
--Q
--
--
--n
--
--
--…
--
--†
--‡
--¢
--°
--
--
--ã
--
--
--é
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-11-28 09:29-0800
--PO-Revision-Date: 1998-12-02 22:02+01:00
--Last-Translator: Stanislav Meduna <stano@eunet.sk>
--Language-Team: Slovak <sk-i18n@rak.isternet.sk>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-2
--Content-Transfer-Encoding: 8bit
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache je povolená
--%15Zd navrhovaná veµkos»
--%15ld sekúnd ¾ivotnos» pozitívnych záznamov
--%15ld sekúnd ¾ivotnos» negatívnych záznamov
--%15ld úspechov cache pre pozitívne záznamy
--%15ld úspechov cache pre negatívne záznamy
--%15ld neúspechov cache pre pozitívne záznamy
--%15ld neúspechov cache pre negatívne záznamy
--%15ld%% úspe¹nos» cache
--%15s skontrolujte /etc/%s na zmeny
--
--Èlenovia skupín :
--
--®ivotnos» :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -d adresár ] [ -L priestupné_sekundy ] [ -y typ_roku ] [ súbor ... ]
--
--
--
--
--[ VÝSTUPNÝ_SÚBOR [VSTUPNÝ_SÚBOR]...]
--
--
--
--
--
--
--
--
--
--Toto je voµne ¹íriteµný software; pre podmienky kopírovania pozri
--zdrojový kód.Na software nie je poskytovaná ®IADNA záruka.
--
--
--
--
--
--
--
--
--
--VÝSTUPNÝ_SÚBOR -, výstup je zapísaný na ¹tandardný výstup.
--
--
--
---o VÝSTUPNÝ_SÚBOR VSTUPNÝ_SÚBOR
---u VSTUPNÝ_SÚBOR
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- mapy repertoárov: %s
-- cestu locale : %s
--%s
--
--
--¾e v¹etky kombinácie týchto názvov mô¾u by» pou¾ité pre argumenty Z a DO.
--Jedna sada znakov mô¾e by» uvedená pod viacerými názvami (aliasmi).
-- Niektoré z názvov nie sú obyèajné re»azce, ale regulárne výrazy, ktoré
--¹pecifikujú mo¾né parametre programu.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d ladiaca úroveò servera
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/sv.mo glibc-2.1.3/po/sv.mo
---- ../glibc-2.1.3/po/sv.mo 1999-07-18 18:19:42.000000000 -0700
-+++ glibc-2.1.3/po/sv.mo 1969-12-31 16:00:00.000000000 -0800
-@@ -1,456 +0,0 @@
--Þ•
--[
--`
--
--m
--
--
--
--
--”
--
--
--
--
--
--î
--
--
--
--
--
--
--
--
--
-- 
--
--
--
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache is enabled
--%15Zd suggested size
--%15ld seconds time to live for positive entries
--%15ld seconds time to live for negative entries
--%15ld cache hits on positive entries
--%15ld cache hits on negative entries
--%15ld cache misses on positive entries
--%15ld cache misses on negative entries
--%15ld%% cache hit rate
--%15s check /etc/%s for changes
--
--Group Members :
--
--Time to Live :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
--
--
--
--
--[OUTPUT-FILE [INPUT-FILE]...]
--
--
--
--
--
--
--
--
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
--
--
--
--
--
--
--
--
--is -, output is written to standard output.
--
--
--
---o OUTPUT-FILE INPUT-FILE
---u INPUT-FILE
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- repertoire maps: %s
-- locale path : %s
--%s
--
--
--not necessarily mean that all combinations of these names can be used for
--the FROM and TO command line parameters. One coded character set can be
--listed with several different names (aliases).
-- Some of the names are no plain strings but instead regular expressions and
--they match a variety of names which can be given as parameters to the
--program.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d server debug level
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--POT-Creation-Date: 1998-11-28 09:29-0800
--PO-Revision-Date: 1999-01-24 18:00 +01:00
--Last-Translator: Jan Djärv <Jan.Djarv@mbox200.swipnet.se>
--Language-Team: Swedish <sv@li.org>
--MIME-Version: 1.0
--Content-Type: text/plain; charset=ISO-8859-1
--Content-Transfer-Encoding: 8bit
--
--
--
--
--
--
--
--
--
--
--%s cache:
--
--%15s cache är påslagen
--%15Zd föreslagen storlek
--%15ld livslängd i sekunder för positiva poster
--%15ld livslängd i sekunder för negativa poster
--%15ld cache-träffar för positiva poster
--%15ld cache-träffar för negativa poster
--%15ld cache-missar för positiva poster
--%15ld cache-missar för negativa poster
--%15ld%% cache träffprocent
--%15s kontrollera /etc/%s för ändringar
--
--Guppmedlemmar :
--
--Livslängd :
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- [ -L skottsekunder ] [ -y årkontrollprogram ] [ filnamn ... ]
--
--
--
--
--[UTFIL [INFIL]...]
--
--
--
--
--
--
--
--
--
--Detta är fri programvara; se källkoden för kopieringsvillkor. Det finns
--INGEN garanti; inte ens för SÄLJBARHET eller LÄMPLIGHET FÖR NÅGOT SPECIELLT
--ÄNDAMÅL.
--
--
--
--
--
--
--
--
--
--är - så skrivs resultatet till standard ut.
--
--
--
---o UTFIL INFIL
---u INFIL
--
--
--
--
--
--[-a|-m]
--
--
--
--
--
--
--
--
--
--
--
--
--
--Rapportera fel på översättningen till <sv@li.org>.
--
--
--
--
-- repertoartabeller: %s
-- lokal-sökväg : %s
--%s
--
--
--betyder inte nödvändigtvis att alla kombinationer av dessa namn kan ges
--som FRÅN och TILL argument. En teckenuppsättning kan ha flera olika namn
--(alias).
-- En del av namnen är inte strängar utan reguljära uttryck och dessa
--matchar varianter av namn som kan ges som argument till programmet.
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--%15d servers felsökningsläge
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--elementdefinition
--symboldefinition
--namn i teckenuppsättning
--
--
--
--
--
--
-\ No newline at end of file
-diff -Naur ../glibc-2.1.3/po/sv.po glibc-2.1.3/po/sv.po
---- ../glibc-2.1.3/po/sv.po 1999-01-24 07:37:32.000000000 -0800
-+++ glibc-2.1.3/po/sv.po 1999-01-25 09:45:47.000000000 -0800
-@@ -1,7 +1,7 @@
- # GNU libc message catalog for swedish
- # Copyright © 1996, 1998 Free Software Foundation, Inc.
- # Jan Djärv <Jan.Djarv@mbox200.swipnet.se>, 1996, 1998.
--# $Revision: 1.5 $
-+# $Revision: 1.1.1.1 $
- #
- msgid ""
- msgstr ""
-diff -Naur ../glibc-2.1.3/posix/glob/ChangeLog glibc-2.1.3/posix/glob/ChangeLog
---- ../glibc-2.1.3/posix/glob/ChangeLog 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/posix/glob/ChangeLog 1998-02-07 12:24:16.000000000 -0800
-@@ -0,0 +1,23 @@
-+Sat Jul 20 21:55:31 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
-+
-+ Win32 hacks from <Rob_Tulloh@tivoli.com>.
-+ * posix/glob.c [WIN32]: Don't include <pwd.h>; don't use d_ino;
-+ use void * for my_realloc; include <malloc.h> for alloca.
-+ (glob) [WIN32]: Use "c:/users/default" for ~ if no HOME variable.
-+ * posix/fnmatch.h [WIN32]: Use prototypes even if [!__STDC__].
-+ * posix/glob.h: Likewise.
-+
-+Fri Jul 19 16:56:41 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
-+
-+ * posix/glob.h [!_AMIGA && !VMS]: Check this instead of just [!_AMIGA]
-+ for `struct stat;' forward decl.
-+
-+Sat Jun 22 10:44:09 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
-+
-+ * posix/glob.c: Include <alloca.h> only [HAVE_ALLOCA_H], not [sparc].
-+
-+Fri Jun 21 00:27:51 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
-+
-+ * posix/fnmatch.c (fnmatch): Fix \*[*?]+ case to increment name ptr
-+ only for ?s, not for *s. Fix from Chet Ramey.
-+
-diff -Naur ../glibc-2.1.3/posix/glob/Makefile.ami glibc-2.1.3/posix/glob/Makefile.ami
---- ../glibc-2.1.3/posix/glob/Makefile.ami 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/posix/glob/Makefile.ami 1998-02-07 12:24:16.000000000 -0800
-@@ -0,0 +1,69 @@
-+# Makefile for standalone distribution of libglob.a (fnmatch, glob).
-+
-+# Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
-+# This file is part of the GNU C Library.
-+
-+# This library is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU Library General Public License
-+# as published by the Free Software Foundation; either version 2 of
-+# the License, or (at your option) any later version.
-+
-+# This library is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# Library General Public License for more details.
-+
-+# You should have received a copy of the GNU Library General Public
-+# License along with the GNU C Library; see the file COPYING.LIB. If not,
-+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+# Boston, MA 02111-1307, USA.
-+
-+# Ultrix 2.2 make doesn't expand the value of VPATH.
-+VPATH = /glob/
-+# This must repeat the value, because configure will remove `VPATH = .'.
-+srcdir = /glob/
-+
-+CC = sc
-+RM = delete
-+CPPFLAGS =
-+CFLAGS =
-+
-+# Information determined by configure.
-+DEFS = Define HAVE_HEADER_STDC Define HAVE_UNISTD_H Define HAVE_STRING_H \
-+ Define HAVE_DIRENT_H
-+
-+# How to invoke ar.
-+AR = join
-+ARFLAGS = as
-+
-+# How to invoke ranlib.
-+RANLIB = ;
-+
-+.PHONY: all
-+all: glob.lib
-+
-+glob.lib : glob.o fnmatch.o
-+ $(AR) $(ARFLAGS) $@ glob.o fnmatch.o
-+ $(RANLIB) $@
-+
-+# For some reason, Unix make wants the dependencies on the source files.
-+# Otherwise it refuses to use an implicit rule!
-+# And, get this: it doesn't work to use $(srcdir)foo.c!!
-+glob.o: $(srcdir)glob.h $(srcdir)fnmatch.h glob.c
-+fnmatch.o: $(srcdir)fnmatch.h fnmatch.c
-+
-+OUTPUT_OPTION =
-+.c.o:
-+ $(CC) IDir "" \
-+ $(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION)
-+
-+.PHONY: clean realclean glob-clean glob-realclean distclean
-+clean glob-clean:
-+ -$(RM) glob.lib "#?.o" core
-+distclean glob-realclean: clean
-+ -$(RM) TAGS tags Makefile config.status config.h config.log
-+realcean: distclean
-+
-+# For inside the C library.
-+glob.tar glob.tar.Z:
-+ $(MAKE) -C .. $@
-diff -Naur ../glibc-2.1.3/posix/glob/Makefile.in glibc-2.1.3/posix/glob/Makefile.in
---- ../glibc-2.1.3/posix/glob/Makefile.in 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/posix/glob/Makefile.in 1998-02-07 12:24:16.000000000 -0800
-@@ -0,0 +1,66 @@
-+# Makefile for standalone distribution of libglob.a (fnmatch, glob).
-+
-+# Copyright (C) 1991, 92, 93, 94, 95 Free Software Foundation, Inc.
-+# This file is part of the GNU C Library.
-+
-+# This library is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU Library General Public License
-+# as published by the Free Software Foundation; either version 2 of
-+# the License, or (at your option) any later version.
-+
-+# This library is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# Library General Public License for more details.
-+
-+# You should have received a copy of the GNU Library General Public
-+# License along with this library; see the file COPYING.LIB. If
-+# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-+# Cambridge, MA 02139, USA.
-+
-+# Ultrix 2.2 make doesn't expand the value of VPATH.
-+VPATH = @srcdir@
-+# This must repeat the value, because configure will remove `VPATH = .'.
-+srcdir = @srcdir@
-+
-+CC = @CC@
-+CPPFLAGS = @CPPFLAGS@
-+CFLAGS = @CFLAGS@
-+
-+# Information determined by configure.
-+DEFS = @DEFS@
-+
-+# How to invoke ar.
-+AR = @AR@
-+ARFLAGS = rv
-+
-+# How to invoke ranlib.
-+RANLIB = @RANLIB@
-+
-+.PHONY: all
-+all: libglob.a
-+
-+libglob.a: glob.o fnmatch.o
-+ $(AR) $(ARFLAGS) $@ glob.o fnmatch.o
-+ $(RANLIB) $@
-+
-+# For some reason, Unix make wants the dependencies on the source files.
-+# Otherwise it refuses to use an implicit rule!
-+# And, get this: it doesn't work to use $(srcdir)/foo.c!!
-+glob.o: $(srcdir)/glob.h $(srcdir)/fnmatch.h glob.c
-+fnmatch.o: $(srcdir)/fnmatch.h fnmatch.c
-+
-+.c.o:
-+ $(CC) -I. -I$(srcdir) -c \
-+ $(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION)
-+
-+.PHONY: clean realclean glob-clean glob-realclean distclean
-+clean glob-clean:
-+ -rm -f libglob.a *.o core
-+distclean glob-realclean: clean
-+ -rm -f TAGS tags Makefile config.status config.h config.log
-+realcean: distclean
-+
-+# For inside the C library.
-+glob.tar glob.tar.Z:
-+ $(MAKE) -C .. $@
-diff -Naur ../glibc-2.1.3/posix/glob/SCOPTIONS glibc-2.1.3/posix/glob/SCOPTIONS
---- ../glibc-2.1.3/posix/glob/SCOPTIONS 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/posix/glob/SCOPTIONS 1998-02-07 12:24:16.000000000 -0800
-@@ -0,0 +1,13 @@
-+ERRORREXX
-+OPTIMIZE
-+NOVERSION
-+OPTIMIZERTIME
-+OPTIMIZERALIAS
-+DEFINE INCLUDEDIR="include:"
-+DEFINE LIBDIR="lib:"
-+DEFINE NO_ALLOCA
-+DEFINE NO_FLOAT
-+DEFINE NO_ARCHIVES
-+IGNORE=161
-+IGNORE=100
-+STARTUP=cres
-diff -Naur ../glibc-2.1.3/posix/glob/SMakefile glibc-2.1.3/posix/glob/SMakefile
---- ../glibc-2.1.3/posix/glob/SMakefile 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/posix/glob/SMakefile 1998-02-07 12:24:16.000000000 -0800
-@@ -0,0 +1,69 @@
-+# Makefile for standalone distribution of libglob.a (fnmatch, glob).
-+
-+# Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
-+# This file is part of the GNU C Library.
-+
-+# This library is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU Library General Public License
-+# as published by the Free Software Foundation; either version 2 of
-+# the License, or (at your option) any later version.
-+
-+# This library is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# Library General Public License for more details.
-+
-+# You should have received a copy of the GNU Library General Public
-+# License along with the GNU C Library; see the file COPYING.LIB. If not,
-+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+# Boston, MA 02111-1307, USA.
-+
-+# Ultrix 2.2 make doesn't expand the value of VPATH.
-+VPATH = /glob/
-+# This must repeat the value, because configure will remove `VPATH = .'.
-+srcdir = /glob/
-+
-+CC = sc
-+CPPFLAGS =
-+CFLAGS =
-+MAKE = smake
-+RM = delete
-+
-+# Information determined by configure.
-+DEFS = Define HAVE_HEADER_STDC Define HAVE_UNISTD_H Define HAVE_STRING_H \
-+ Define HAVE_DIRENT_H
-+
-+# How to invoke ar.
-+AR = join
-+ARFLAGS = as
-+
-+# How to invoke ranlib.
-+RANLIB = ;
-+
-+.PHONY: all
-+all: glob.lib
-+
-+glob.lib : glob.o fnmatch.o
-+ $(AR) $(ARFLAGS) $@ glob.o fnmatch.o
-+ $(RANLIB) $@
-+
-+# For some reason, Unix make wants the dependencies on the source files.
-+# Otherwise it refuses to use an implicit rule!
-+# And, get this: it doesn't work to use $(srcdir)foo.c!!
-+glob.o: $(srcdir)glob.h $(srcdir)fnmatch.h glob.c
-+fnmatch.o: $(srcdir)fnmatch.h fnmatch.c
-+
-+.c.o:
-+ $(CC) IDir "" \
-+ $(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION)
-+
-+.PHONY: clean realclean glob-clean glob-realclean distclean
-+clean glob-clean:
-+ -$(RM) -f glob.lib *.o core
-+distclean glob-realclean: clean
-+ -$(RM) -f TAGS tags Makefile config.status config.h config.log
-+realcean: distclean
-+
-+# For inside the C library.
-+glob.tar glob.tar.Z:
-+ $(MAKE) -C .. $@
-diff -Naur ../glibc-2.1.3/posix/glob/configure glibc-2.1.3/posix/glob/configure
---- ../glibc-2.1.3/posix/glob/configure 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/posix/glob/configure 1998-02-07 12:24:21.000000000 -0800
-@@ -0,0 +1,1664 @@
-+#! /bin/sh
-+
-+# Guess values for system-dependent variables and create Makefiles.
-+# Generated automatically using autoconf version 2.7
-+# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
-+#
-+# This configure script is free software; the Free Software Foundation
-+# gives unlimited permission to copy, distribute and modify it.
-+
-+# Defaults:
-+ac_help=
-+ac_default_prefix=/usr/local
-+# Any additions from configure.in:
-+
-+# Initialize some variables set by options.
-+# The variables have the same names as the options, with
-+# dashes changed to underlines.
-+build=NONE
-+cache_file=./config.cache
-+exec_prefix=NONE
-+host=NONE
-+no_create=
-+nonopt=NONE
-+no_recursion=
-+prefix=NONE
-+program_prefix=NONE
-+program_suffix=NONE
-+program_transform_name=s,x,x,
-+silent=
-+site=
-+srcdir=
-+target=NONE
-+verbose=
-+x_includes=NONE
-+x_libraries=NONE
-+bindir='${exec_prefix}/bin'
-+sbindir='${exec_prefix}/sbin'
-+libexecdir='${exec_prefix}/libexec'
-+datadir='${prefix}/share'
-+sysconfdir='${prefix}/etc'
-+sharedstatedir='${prefix}/com'
-+localstatedir='${prefix}/var'
-+libdir='${exec_prefix}/lib'
-+includedir='${prefix}/include'
-+oldincludedir='/usr/include'
-+infodir='${prefix}/info'
-+mandir='${prefix}/man'
-+
-+# Initialize some other variables.
-+subdirs=
-+MFLAGS= MAKEFLAGS=
-+
-+ac_prev=
-+for ac_option
-+do
-+
-+ # If the previous option needs an argument, assign it.
-+ if test -n "$ac_prev"; then
-+ eval "$ac_prev=\$ac_option"
-+ ac_prev=
-+ continue
-+ fi
-+
-+ case "$ac_option" in
-+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
-+ *) ac_optarg= ;;
-+ esac
-+
-+ # Accept the important Cygnus configure options, so we can diagnose typos.
-+
-+ case "$ac_option" in
-+
-+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
-+ ac_prev=bindir ;;
-+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
-+ bindir="$ac_optarg" ;;
-+
-+ -build | --build | --buil | --bui | --bu)
-+ ac_prev=build ;;
-+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
-+ build="$ac_optarg" ;;
-+
-+ -cache-file | --cache-file | --cache-fil | --cache-fi \
-+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
-+ ac_prev=cache_file ;;
-+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
-+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
-+ cache_file="$ac_optarg" ;;
-+
-+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
-+ ac_prev=datadir ;;
-+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
-+ | --da=*)
-+ datadir="$ac_optarg" ;;
-+
-+ -disable-* | --disable-*)
-+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
-+ # Reject names that are not valid shell variable names.
-+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
-+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
-+ fi
-+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
-+ eval "enable_${ac_feature}=no" ;;
-+
-+ -enable-* | --enable-*)
-+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
-+ # Reject names that are not valid shell variable names.
-+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
-+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
-+ fi
-+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
-+ case "$ac_option" in
-+ *=*) ;;
-+ *) ac_optarg=yes ;;
-+ esac
-+ eval "enable_${ac_feature}='$ac_optarg'" ;;
-+
-+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
-+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
-+ | --exec | --exe | --ex)
-+ ac_prev=exec_prefix ;;
-+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
-+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
-+ | --exec=* | --exe=* | --ex=*)
-+ exec_prefix="$ac_optarg" ;;
-+
-+ -gas | --gas | --ga | --g)
-+ # Obsolete; use --with-gas.
-+ with_gas=yes ;;
-+
-+ -help | --help | --hel | --he)
-+ # Omit some internal or obsolete options to make the list less imposing.
-+ # This message is too long to be a string in the A/UX 3.1 sh.
-+ cat << EOF
-+Usage: configure [options] [host]
-+Options: [defaults in brackets after descriptions]
-+Configuration:
-+ --cache-file=FILE cache test results in FILE
-+ --help print this message
-+ --no-create do not create output files
-+ --quiet, --silent do not print \`checking...' messages
-+ --version print the version of autoconf that created configure
-+Directory and file names:
-+ --prefix=PREFIX install architecture-independent files in PREFIX
-+ [$ac_default_prefix]
-+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
-+ [same as prefix]
-+ --bindir=DIR user executables in DIR [EPREFIX/bin]
-+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
-+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
-+ --datadir=DIR read-only architecture-independent data in DIR
-+ [PREFIX/share]
-+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
-+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
-+ [PREFIX/com]
-+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
-+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
-+ --includedir=DIR C header files in DIR [PREFIX/include]
-+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
-+ --infodir=DIR info documentation in DIR [PREFIX/info]
-+ --mandir=DIR man documentation in DIR [PREFIX/man]
-+ --srcdir=DIR find the sources in DIR [configure dir or ..]
-+ --program-prefix=PREFIX prepend PREFIX to installed program names
-+ --program-suffix=SUFFIX append SUFFIX to installed program names
-+ --program-transform-name=PROGRAM
-+ run sed PROGRAM on installed program names
-+EOF
-+ cat << EOF
-+Host type:
-+ --build=BUILD configure for building on BUILD [BUILD=HOST]
-+ --host=HOST configure for HOST [guessed]
-+ --target=TARGET configure for TARGET [TARGET=HOST]
-+Features and packages:
-+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
-+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
-+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
-+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
-+ --x-includes=DIR X include files are in DIR
-+ --x-libraries=DIR X library files are in DIR
-+EOF
-+ if test -n "$ac_help"; then
-+ echo "--enable and --with options recognized:$ac_help"
-+ fi
-+ exit 0 ;;
-+
-+ -host | --host | --hos | --ho)
-+ ac_prev=host ;;
-+ -host=* | --host=* | --hos=* | --ho=*)
-+ host="$ac_optarg" ;;
-+
-+ -includedir | --includedir | --includedi | --included | --include \
-+ | --includ | --inclu | --incl | --inc)
-+ ac_prev=includedir ;;
-+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
-+ | --includ=* | --inclu=* | --incl=* | --inc=*)
-+ includedir="$ac_optarg" ;;
-+
-+ -infodir | --infodir | --infodi | --infod | --info | --inf)
-+ ac_prev=infodir ;;
-+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
-+ infodir="$ac_optarg" ;;
-+
-+ -libdir | --libdir | --libdi | --libd)
-+ ac_prev=libdir ;;
-+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
-+ libdir="$ac_optarg" ;;
-+
-+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
-+ | --libexe | --libex | --libe)
-+ ac_prev=libexecdir ;;
-+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
-+ | --libexe=* | --libex=* | --libe=*)
-+ libexecdir="$ac_optarg" ;;
-+
-+ -localstatedir | --localstatedir | --localstatedi | --localstated \
-+ | --localstate | --localstat | --localsta | --localst \
-+ | --locals | --local | --loca | --loc | --lo)
-+ ac_prev=localstatedir ;;
-+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
-+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
-+ localstatedir="$ac_optarg" ;;
-+
-+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
-+ ac_prev=mandir ;;
-+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
-+ mandir="$ac_optarg" ;;
-+
-+ -nfp | --nfp | --nf)
-+ # Obsolete; use --without-fp.
-+ with_fp=no ;;
-+
-+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-+ | --no-cr | --no-c)
-+ no_create=yes ;;
-+
-+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
-+ no_recursion=yes ;;
-+
-+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
-+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
-+ | --oldin | --oldi | --old | --ol | --o)
-+ ac_prev=oldincludedir ;;
-+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
-+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
-+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
-+ oldincludedir="$ac_optarg" ;;
-+
-+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
-+ ac_prev=prefix ;;
-+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
-+ prefix="$ac_optarg" ;;
-+
-+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
-+ | --program-pre | --program-pr | --program-p)
-+ ac_prev=program_prefix ;;
-+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
-+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
-+ program_prefix="$ac_optarg" ;;
-+
-+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
-+ | --program-suf | --program-su | --program-s)
-+ ac_prev=program_suffix ;;
-+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
-+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
-+ program_suffix="$ac_optarg" ;;
-+
-+ -program-transform-name | --program-transform-name \
-+ | --program-transform-nam | --program-transform-na \
-+ | --program-transform-n | --program-transform- \
-+ | --program-transform | --program-transfor \
-+ | --program-transfo | --program-transf \
-+ | --program-trans | --program-tran \
-+ | --progr-tra | --program-tr | --program-t)
-+ ac_prev=program_transform_name ;;
-+ -program-transform-name=* | --program-transform-name=* \
-+ | --program-transform-nam=* | --program-transform-na=* \
-+ | --program-transform-n=* | --program-transform-=* \
-+ | --program-transform=* | --program-transfor=* \
-+ | --program-transfo=* | --program-transf=* \
-+ | --program-trans=* | --program-tran=* \
-+ | --progr-tra=* | --program-tr=* | --program-t=*)
-+ program_transform_name="$ac_optarg" ;;
-+
-+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-+ | -silent | --silent | --silen | --sile | --sil)
-+ silent=yes ;;
-+
-+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
-+ ac_prev=sbindir ;;
-+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
-+ | --sbi=* | --sb=*)
-+ sbindir="$ac_optarg" ;;
-+
-+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
-+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
-+ | --sharedst | --shareds | --shared | --share | --shar \
-+ | --sha | --sh)
-+ ac_prev=sharedstatedir ;;
-+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
-+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
-+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
-+ | --sha=* | --sh=*)
-+ sharedstatedir="$ac_optarg" ;;
-+
-+ -site | --site | --sit)
-+ ac_prev=site ;;
-+ -site=* | --site=* | --sit=*)
-+ site="$ac_optarg" ;;
-+
-+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
-+ ac_prev=srcdir ;;
-+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
-+ srcdir="$ac_optarg" ;;
-+
-+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
-+ | --syscon | --sysco | --sysc | --sys | --sy)
-+ ac_prev=sysconfdir ;;
-+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
-+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
-+ sysconfdir="$ac_optarg" ;;
-+
-+ -target | --target | --targe | --targ | --tar | --ta | --t)
-+ ac_prev=target ;;
-+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
-+ target="$ac_optarg" ;;
-+
-+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
-+ verbose=yes ;;
-+
-+ -version | --version | --versio | --versi | --vers)
-+ echo "configure generated by autoconf version 2.7"
-+ exit 0 ;;
-+
-+ -with-* | --with-*)
-+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
-+ # Reject names that are not valid shell variable names.
-+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
-+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
-+ fi
-+ ac_package=`echo $ac_package| sed 's/-/_/g'`
-+ case "$ac_option" in
-+ *=*) ;;
-+ *) ac_optarg=yes ;;
-+ esac
-+ eval "with_${ac_package}='$ac_optarg'" ;;
-+
-+ -without-* | --without-*)
-+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
-+ # Reject names that are not valid shell variable names.
-+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
-+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
-+ fi
-+ ac_package=`echo $ac_package| sed 's/-/_/g'`
-+ eval "with_${ac_package}=no" ;;
-+
-+ --x)
-+ # Obsolete; use --with-x.
-+ with_x=yes ;;
-+
-+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
-+ | --x-incl | --x-inc | --x-in | --x-i)
-+ ac_prev=x_includes ;;
-+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
-+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
-+ x_includes="$ac_optarg" ;;
-+
-+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
-+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
-+ ac_prev=x_libraries ;;
-+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
-+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
-+ x_libraries="$ac_optarg" ;;
-+
-+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
-+ ;;
-+
-+ *)
-+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
-+ echo "configure: warning: $ac_option: invalid host type" 1>&2
-+ fi
-+ if test "x$nonopt" != xNONE; then
-+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
-+ fi
-+ nonopt="$ac_option"
-+ ;;
-+
-+ esac
-+done
-+
-+if test -n "$ac_prev"; then
-+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-+fi
-+
-+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-+
-+# File descriptor usage:
-+# 0 standard input
-+# 1 file creation
-+# 2 errors and warnings
-+# 3 some systems may open it to /dev/tty
-+# 4 used on the Kubota Titan
-+# 6 checking for... messages and results
-+# 5 compiler messages saved in config.log
-+if test "$silent" = yes; then
-+ exec 6>/dev/null
-+else
-+ exec 6>&1
-+fi
-+exec 5>./config.log
-+
-+echo "\
-+This file contains any messages produced by compilers while
-+running configure, to aid debugging if configure makes a mistake.
-+" 1>&5
-+
-+# Strip out --no-create and --no-recursion so they do not pile up.
-+# Also quote any args containing shell metacharacters.
-+ac_configure_args=
-+for ac_arg
-+do
-+ case "$ac_arg" in
-+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-+ | --no-cr | --no-c) ;;
-+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
-+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
-+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
-+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
-+ esac
-+done
-+
-+# NLS nuisances.
-+# Only set LANG and LC_ALL to C if already set.
-+# These must not be set unconditionally because not all systems understand
-+# e.g. LANG=C (notably SCO).
-+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-+
-+# confdefs.h avoids OS command line length limits that DEFS can exceed.
-+rm -rf conftest* confdefs.h
-+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-+echo > confdefs.h
-+
-+# A filename unique to this package, relative to the directory that
-+# configure is in, which we can look for to find out if srcdir is correct.
-+ac_unique_file=fnmatch.c
-+
-+# Find the source files, if location was not specified.
-+if test -z "$srcdir"; then
-+ ac_srcdir_defaulted=yes
-+ # Try the directory containing this script, then its parent.
-+ ac_prog=$0
-+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
-+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
-+ srcdir=$ac_confdir
-+ if test ! -r $srcdir/$ac_unique_file; then
-+ srcdir=..
-+ fi
-+else
-+ ac_srcdir_defaulted=no
-+fi
-+if test ! -r $srcdir/$ac_unique_file; then
-+ if test "$ac_srcdir_defaulted" = yes; then
-+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
-+ else
-+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
-+ fi
-+fi
-+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-+
-+# Prefer explicitly selected file to automatically selected ones.
-+if test -z "$CONFIG_SITE"; then
-+ if test "x$prefix" != xNONE; then
-+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-+ else
-+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
-+ fi
-+fi
-+for ac_site_file in $CONFIG_SITE; do
-+ if test -r "$ac_site_file"; then
-+ echo "loading site script $ac_site_file"
-+ . "$ac_site_file"
-+ fi
-+done
-+
-+if test -r "$cache_file"; then
-+ echo "loading cache $cache_file"
-+ . $cache_file
-+else
-+ echo "creating cache $cache_file"
-+ > $cache_file
-+fi
-+
-+ac_ext=c
-+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-+ac_cpp='$CPP $CPPFLAGS'
-+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-+
-+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
-+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
-+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
-+ ac_n= ac_c='
-+' ac_t=' '
-+ else
-+ ac_n=-n ac_c= ac_t=
-+ fi
-+else
-+ ac_n= ac_c='\c' ac_t=
-+fi
-+
-+ # Extract the first word of "gcc", so it can be a program name with args.
-+set dummy gcc; ac_word=$2
-+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ if test -n "$CC"; then
-+ ac_cv_prog_CC="$CC" # Let the user override the test.
-+else
-+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-+ for ac_dir in $PATH; do
-+ test -z "$ac_dir" && ac_dir=.
-+ if test -f $ac_dir/$ac_word; then
-+ ac_cv_prog_CC="gcc"
-+ break
-+ fi
-+ done
-+ IFS="$ac_save_ifs"
-+fi
-+fi
-+CC="$ac_cv_prog_CC"
-+if test -n "$CC"; then
-+ echo "$ac_t""$CC" 1>&6
-+else
-+ echo "$ac_t""no" 1>&6
-+fi
-+
-+if test -z "$CC"; then
-+ # Extract the first word of "cc", so it can be a program name with args.
-+set dummy cc; ac_word=$2
-+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ if test -n "$CC"; then
-+ ac_cv_prog_CC="$CC" # Let the user override the test.
-+else
-+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-+ ac_prog_rejected=no
-+ for ac_dir in $PATH; do
-+ test -z "$ac_dir" && ac_dir=.
-+ if test -f $ac_dir/$ac_word; then
-+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
-+ ac_prog_rejected=yes
-+ continue
-+ fi
-+ ac_cv_prog_CC="cc"
-+ break
-+ fi
-+ done
-+ IFS="$ac_save_ifs"
-+if test $ac_prog_rejected = yes; then
-+ # We found a bogon in the path, so make sure we never use it.
-+ set dummy $ac_cv_prog_CC
-+ shift
-+ if test $# -gt 0; then
-+ # We chose a different compiler from the bogus one.
-+ # However, it has the same basename, so the bogon will be chosen
-+ # first if we set CC to just the basename; use the full file name.
-+ shift
-+ set dummy "$ac_dir/$ac_word" "$@"
-+ shift
-+ ac_cv_prog_CC="$@"
-+ fi
-+fi
-+fi
-+fi
-+CC="$ac_cv_prog_CC"
-+if test -n "$CC"; then
-+ echo "$ac_t""$CC" 1>&6
-+else
-+ echo "$ac_t""no" 1>&6
-+fi
-+
-+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-+fi
-+
-+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.c <<EOF
-+#ifdef __GNUC__
-+ yes;
-+#endif
-+EOF
-+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:601: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
-+ ac_cv_prog_gcc=yes
-+else
-+ ac_cv_prog_gcc=no
-+fi
-+fi
-+
-+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-+if test $ac_cv_prog_gcc = yes; then
-+ GCC=yes
-+ if test "${CFLAGS+set}" != set; then
-+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ echo 'void f(){}' > conftest.c
-+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
-+ ac_cv_prog_gcc_g=yes
-+else
-+ ac_cv_prog_gcc_g=no
-+fi
-+rm -f conftest*
-+
-+fi
-+
-+echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
-+ if test $ac_cv_prog_gcc_g = yes; then
-+ CFLAGS="-g -O"
-+ else
-+ CFLAGS="-O"
-+ fi
-+ fi
-+else
-+ GCC=
-+ test "${CFLAGS+set}" = set || CFLAGS="-g"
-+fi
-+
-+# Extract the first word of "ar", so it can be a program name with args.
-+set dummy ar; ac_word=$2
-+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ if test -n "$AR"; then
-+ ac_cv_prog_AR="$AR" # Let the user override the test.
-+else
-+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-+ for ac_dir in $PATH; do
-+ test -z "$ac_dir" && ac_dir=.
-+ if test -f $ac_dir/$ac_word; then
-+ ac_cv_prog_AR="ar"
-+ break
-+ fi
-+ done
-+ IFS="$ac_save_ifs"
-+ test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
-+fi
-+fi
-+AR="$ac_cv_prog_AR"
-+if test -n "$AR"; then
-+ echo "$ac_t""$AR" 1>&6
-+else
-+ echo "$ac_t""no" 1>&6
-+fi
-+
-+# Extract the first word of "ranlib", so it can be a program name with args.
-+set dummy ranlib; ac_word=$2
-+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ if test -n "$RANLIB"; then
-+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-+else
-+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-+ for ac_dir in $PATH; do
-+ test -z "$ac_dir" && ac_dir=.
-+ if test -f $ac_dir/$ac_word; then
-+ ac_cv_prog_RANLIB="ranlib"
-+ break
-+ fi
-+ done
-+ IFS="$ac_save_ifs"
-+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-+fi
-+fi
-+RANLIB="$ac_cv_prog_RANLIB"
-+if test -n "$RANLIB"; then
-+ echo "$ac_t""$RANLIB" 1>&6
-+else
-+ echo "$ac_t""no" 1>&6
-+fi
-+
-+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-+# On Suns, sometimes $CPP names a directory.
-+if test -n "$CPP" && test -d "$CPP"; then
-+ CPP=
-+fi
-+if test -z "$CPP"; then
-+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ # This must be in double quotes, not single quotes, because CPP may get
-+ # substituted into the Makefile and "${CC-cc}" will confuse make.
-+ CPP="${CC-cc} -E"
-+ # On the NeXT, cc -E runs the code through the compiler's parser,
-+ # not just through cpp.
-+ cat > conftest.$ac_ext <<EOF
-+#line 709 "configure"
-+#include "confdefs.h"
-+#include <assert.h>
-+Syntax Error
-+EOF
-+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-+{ (eval echo configure:715: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-+ac_err=`grep -v '^ *+' conftest.out`
-+if test -z "$ac_err"; then
-+ :
-+else
-+ echo "$ac_err" >&5
-+ rm -rf conftest*
-+ CPP="${CC-cc} -E -traditional-cpp"
-+ cat > conftest.$ac_ext <<EOF
-+#line 724 "configure"
-+#include "confdefs.h"
-+#include <assert.h>
-+Syntax Error
-+EOF
-+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-+{ (eval echo configure:730: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-+ac_err=`grep -v '^ *+' conftest.out`
-+if test -z "$ac_err"; then
-+ :
-+else
-+ echo "$ac_err" >&5
-+ rm -rf conftest*
-+ CPP=/lib/cpp
-+fi
-+rm -f conftest*
-+fi
-+rm -f conftest*
-+ ac_cv_prog_CPP="$CPP"
-+fi
-+ CPP="$ac_cv_prog_CPP"
-+else
-+ ac_cv_prog_CPP="$CPP"
-+fi
-+echo "$ac_t""$CPP" 1>&6
-+ echo $ac_n "checking for AIX""... $ac_c" 1>&6
-+cat > conftest.$ac_ext <<EOF
-+#line 751 "configure"
-+#include "confdefs.h"
-+#ifdef _AIX
-+ yes
-+#endif
-+
-+EOF
-+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-+ egrep "yes" >/dev/null 2>&1; then
-+ rm -rf conftest*
-+ echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF
-+#define _ALL_SOURCE 1
-+EOF
-+
-+else
-+ rm -rf conftest*
-+ echo "$ac_t""no" 1>&6
-+fi
-+rm -f conftest*
-+
-+
-+ac_safe=`echo "minix/config.h" | tr './\055' '___'`
-+echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.$ac_ext <<EOF
-+#line 778 "configure"
-+#include "confdefs.h"
-+#include <minix/config.h>
-+EOF
-+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-+{ (eval echo configure:783: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-+ac_err=`grep -v '^ *+' conftest.out`
-+if test -z "$ac_err"; then
-+ rm -rf conftest*
-+ eval "ac_cv_header_$ac_safe=yes"
-+else
-+ echo "$ac_err" >&5
-+ rm -rf conftest*
-+ eval "ac_cv_header_$ac_safe=no"
-+fi
-+rm -f conftest*
-+fi
-+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
-+ echo "$ac_t""yes" 1>&6
-+ MINIX=yes
-+else
-+ echo "$ac_t""no" 1>&6
-+MINIX=
-+fi
-+
-+if test "$MINIX" = yes; then
-+ cat >> confdefs.h <<\EOF
-+#define _POSIX_SOURCE 1
-+EOF
-+
-+ cat >> confdefs.h <<\EOF
-+#define _POSIX_1_SOURCE 2
-+EOF
-+
-+ cat >> confdefs.h <<\EOF
-+#define _MINIX 1
-+EOF
-+
-+fi
-+
-+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
-+if test -d /etc/conf/kconfig.d &&
-+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
-+then
-+ echo "$ac_t""yes" 1>&6
-+ ISC=yes # If later tests want to check for ISC.
-+ cat >> confdefs.h <<\EOF
-+#define _POSIX_SOURCE 1
-+EOF
-+
-+ if test "$GCC" = yes; then
-+ CC="$CC -posix"
-+ else
-+ CC="$CC -Xp"
-+ fi
-+else
-+ echo "$ac_t""no" 1>&6
-+ ISC=
-+fi
-+
-+echo $ac_n "checking for working const""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.$ac_ext <<EOF
-+#line 843 "configure"
-+#include "confdefs.h"
-+
-+int main() { return 0; }
-+int t() {
-+
-+/* Ultrix mips cc rejects this. */
-+typedef int charset[2]; const charset x;
-+/* SunOS 4.1.1 cc rejects this. */
-+char const *const *ccp;
-+char **p;
-+/* NEC SVR4.0.2 mips cc rejects this. */
-+struct point {int x, y;};
-+static struct point const zero = {0,0};
-+/* AIX XL C 1.02.0.0 rejects this.
-+ It does not let you subtract one const X* pointer from another in an arm
-+ of an if-expression whose if-part is not a constant expression */
-+const char *g = "string";
-+ccp = &g + (g ? g-g : 0);
-+/* HPUX 7.0 cc rejects these. */
-+++ccp;
-+p = (char**) ccp;
-+ccp = (char const *const *) p;
-+{ /* SCO 3.2v4 cc rejects this. */
-+ char *t;
-+ char const *s = 0 ? (char *) 0 : (char const *) 0;
-+
-+ *t++ = 0;
-+}
-+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
-+ int x[] = {25, 17};
-+ const int *foo = &x[0];
-+ ++foo;
-+}
-+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
-+ typedef const int *iptr;
-+ iptr p = 0;
-+ ++p;
-+}
-+{ /* AIX XL C 1.02.0.0 rejects this saying
-+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
-+ struct s { int j; const int *ap[3]; };
-+ struct s *b; b->j = 5;
-+}
-+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
-+ const int foo = 10;
-+}
-+
-+; return 0; }
-+EOF
-+if { (eval echo configure:893: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-+ rm -rf conftest*
-+ ac_cv_c_const=yes
-+else
-+ rm -rf conftest*
-+ ac_cv_c_const=no
-+fi
-+rm -f conftest*
-+
-+fi
-+
-+echo "$ac_t""$ac_cv_c_const" 1>&6
-+if test $ac_cv_c_const = no; then
-+ cat >> confdefs.h <<\EOF
-+#define const
-+EOF
-+
-+fi
-+
-+# If we cannot run a trivial program, we must be cross compiling.
-+echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ if test "$cross_compiling" = yes; then
-+ ac_cv_c_cross=yes
-+else
-+cat > conftest.$ac_ext <<EOF
-+#line 921 "configure"
-+#include "confdefs.h"
-+main(){return(0);}
-+EOF
-+{ (eval echo configure:925: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-+if test -s conftest && (./conftest; exit) 2>/dev/null; then
-+ ac_cv_c_cross=no
-+else
-+ ac_cv_c_cross=yes
-+fi
-+fi
-+rm -fr conftest*
-+fi
-+
-+echo "$ac_t""$ac_cv_c_cross" 1>&6
-+cross_compiling=$ac_cv_c_cross
-+
-+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.$ac_ext <<EOF
-+#line 943 "configure"
-+#include "confdefs.h"
-+#include <stdlib.h>
-+#include <stdarg.h>
-+#include <string.h>
-+#include <float.h>
-+EOF
-+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-+{ (eval echo configure:951: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-+ac_err=`grep -v '^ *+' conftest.out`
-+if test -z "$ac_err"; then
-+ rm -rf conftest*
-+ ac_cv_header_stdc=yes
-+else
-+ echo "$ac_err" >&5
-+ rm -rf conftest*
-+ ac_cv_header_stdc=no
-+fi
-+rm -f conftest*
-+
-+if test $ac_cv_header_stdc = yes; then
-+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-+cat > conftest.$ac_ext <<EOF
-+#line 966 "configure"
-+#include "confdefs.h"
-+#include <string.h>
-+EOF
-+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-+ egrep "memchr" >/dev/null 2>&1; then
-+ :
-+else
-+ rm -rf conftest*
-+ ac_cv_header_stdc=no
-+fi
-+rm -f conftest*
-+
-+fi
-+
-+if test $ac_cv_header_stdc = yes; then
-+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-+cat > conftest.$ac_ext <<EOF
-+#line 984 "configure"
-+#include "confdefs.h"
-+#include <stdlib.h>
-+EOF
-+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-+ egrep "free" >/dev/null 2>&1; then
-+ :
-+else
-+ rm -rf conftest*
-+ ac_cv_header_stdc=no
-+fi
-+rm -f conftest*
-+
-+fi
-+
-+if test $ac_cv_header_stdc = yes; then
-+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-+if test "$cross_compiling" = yes; then
-+ :
-+else
-+cat > conftest.$ac_ext <<EOF
-+#line 1005 "configure"
-+#include "confdefs.h"
-+#include <ctype.h>
-+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-+int main () { int i; for (i = 0; i < 256; i++)
-+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
-+exit (0); }
-+
-+EOF
-+{ (eval echo configure:1016: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-+if test -s conftest && (./conftest; exit) 2>/dev/null; then
-+ :
-+else
-+ ac_cv_header_stdc=no
-+fi
-+fi
-+rm -fr conftest*
-+fi
-+fi
-+
-+echo "$ac_t""$ac_cv_header_stdc" 1>&6
-+if test $ac_cv_header_stdc = yes; then
-+ cat >> confdefs.h <<\EOF
-+#define STDC_HEADERS 1
-+EOF
-+
-+fi
-+
-+for ac_hdr in memory.h unistd.h string.h
-+do
-+ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.$ac_ext <<EOF
-+#line 1043 "configure"
-+#include "confdefs.h"
-+#include <$ac_hdr>
-+EOF
-+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-+{ (eval echo configure:1048: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-+ac_err=`grep -v '^ *+' conftest.out`
-+if test -z "$ac_err"; then
-+ rm -rf conftest*
-+ eval "ac_cv_header_$ac_safe=yes"
-+else
-+ echo "$ac_err" >&5
-+ rm -rf conftest*
-+ eval "ac_cv_header_$ac_safe=no"
-+fi
-+rm -f conftest*
-+fi
-+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
-+ echo "$ac_t""yes" 1>&6
-+ ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
-+ cat >> confdefs.h <<EOF
-+#define $ac_tr_hdr 1
-+EOF
-+
-+else
-+ echo "$ac_t""no" 1>&6
-+fi
-+done
-+
-+ac_header_dirent=no
-+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
-+do
-+ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.$ac_ext <<EOF
-+#line 1081 "configure"
-+#include "confdefs.h"
-+#include <sys/types.h>
-+#include <$ac_hdr>
-+int main() { return 0; }
-+int t() {
-+DIR *dirp = 0;
-+; return 0; }
-+EOF
-+if { (eval echo configure:1090: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-+ rm -rf conftest*
-+ eval "ac_cv_header_dirent_$ac_safe=yes"
-+else
-+ rm -rf conftest*
-+ eval "ac_cv_header_dirent_$ac_safe=no"
-+fi
-+rm -f conftest*
-+
-+fi
-+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
-+ echo "$ac_t""yes" 1>&6
-+ ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdedfghijklmnopqrstuvwxyz./\055' 'ABCDEDFGHIJKLMNOPQRSTUVWXYZ___'`
-+ cat >> confdefs.h <<EOF
-+#define $ac_tr_hdr 1
-+EOF
-+ ac_header_dirent=$ac_hdr; break
-+else
-+ echo "$ac_t""no" 1>&6
-+fi
-+done
-+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
-+if test $ac_header_dirent = dirent.h; then
-+echo $ac_n "checking for -ldir""... $ac_c" 1>&6
-+ac_lib_var=`echo dir | tr '.-/+' '___p'`
-+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ ac_save_LIBS="$LIBS"
-+LIBS="-ldir $LIBS"
-+cat > conftest.$ac_ext <<EOF
-+#line 1121 "configure"
-+#include "confdefs.h"
-+
-+int main() { return 0; }
-+int t() {
-+opendir()
-+; return 0; }
-+EOF
-+if { (eval echo configure:1129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
-+ rm -rf conftest*
-+ eval "ac_cv_lib_$ac_lib_var=yes"
-+else
-+ rm -rf conftest*
-+ eval "ac_cv_lib_$ac_lib_var=no"
-+fi
-+rm -f conftest*
-+LIBS="$ac_save_LIBS"
-+
-+fi
-+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-+ echo "$ac_t""yes" 1>&6
-+ LIBS="$LIBS -ldir"
-+else
-+ echo "$ac_t""no" 1>&6
-+fi
-+
-+else
-+echo $ac_n "checking for -lx""... $ac_c" 1>&6
-+ac_lib_var=`echo x | tr '.-/+' '___p'`
-+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ ac_save_LIBS="$LIBS"
-+LIBS="-lx $LIBS"
-+cat > conftest.$ac_ext <<EOF
-+#line 1156 "configure"
-+#include "confdefs.h"
-+
-+int main() { return 0; }
-+int t() {
-+opendir()
-+; return 0; }
-+EOF
-+if { (eval echo configure:1164: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
-+ rm -rf conftest*
-+ eval "ac_cv_lib_$ac_lib_var=yes"
-+else
-+ rm -rf conftest*
-+ eval "ac_cv_lib_$ac_lib_var=no"
-+fi
-+rm -f conftest*
-+LIBS="$ac_save_LIBS"
-+
-+fi
-+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-+ echo "$ac_t""yes" 1>&6
-+ LIBS="$LIBS -lx"
-+else
-+ echo "$ac_t""no" 1>&6
-+fi
-+
-+fi
-+
-+echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_func_closedir_void'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ if test "$cross_compiling" = yes; then
-+ ac_cv_func_closedir_void=yes
-+else
-+cat > conftest.$ac_ext <<EOF
-+#line 1192 "configure"
-+#include "confdefs.h"
-+#include <sys/types.h>
-+#include <$ac_header_dirent>
-+int closedir(); main() { exit(closedir(opendir(".")) != 0); }
-+EOF
-+{ (eval echo configure:1198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-+if test -s conftest && (./conftest; exit) 2>/dev/null; then
-+ ac_cv_func_closedir_void=no
-+else
-+ ac_cv_func_closedir_void=yes
-+fi
-+fi
-+rm -fr conftest*
-+fi
-+
-+echo "$ac_t""$ac_cv_func_closedir_void" 1>&6
-+if test $ac_cv_func_closedir_void = yes; then
-+ cat >> confdefs.h <<\EOF
-+#define CLOSEDIR_VOID 1
-+EOF
-+
-+fi
-+
-+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
-+# for constant arguments. Useless!
-+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.$ac_ext <<EOF
-+#line 1223 "configure"
-+#include "confdefs.h"
-+#include <alloca.h>
-+int main() { return 0; }
-+int t() {
-+char *p = alloca(2 * sizeof(int));
-+; return 0; }
-+EOF
-+if { (eval echo configure:1231: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
-+ rm -rf conftest*
-+ ac_cv_header_alloca_h=yes
-+else
-+ rm -rf conftest*
-+ ac_cv_header_alloca_h=no
-+fi
-+rm -f conftest*
-+
-+fi
-+
-+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
-+if test $ac_cv_header_alloca_h = yes; then
-+ cat >> confdefs.h <<\EOF
-+#define HAVE_ALLOCA_H 1
-+EOF
-+
-+fi
-+
-+echo $ac_n "checking for alloca""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_func_alloca'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.$ac_ext <<EOF
-+#line 1255 "configure"
-+#include "confdefs.h"
-+
-+#ifdef __GNUC__
-+# define alloca __builtin_alloca
-+#else
-+# if HAVE_ALLOCA_H
-+# include <alloca.h>
-+# else
-+# ifdef _AIX
-+ #pragma alloca
-+# else
-+# ifndef alloca /* predefined by HP cc +Olibcalls */
-+char *alloca ();
-+# endif
-+# endif
-+# endif
-+#endif
-+
-+int main() { return 0; }
-+int t() {
-+char *p = (char *) alloca(1);
-+; return 0; }
-+EOF
-+if { (eval echo configure:1279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
-+ rm -rf conftest*
-+ ac_cv_func_alloca=yes
-+else
-+ rm -rf conftest*
-+ ac_cv_func_alloca=no
-+fi
-+rm -f conftest*
-+
-+fi
-+
-+echo "$ac_t""$ac_cv_func_alloca" 1>&6
-+if test $ac_cv_func_alloca = yes; then
-+ cat >> confdefs.h <<\EOF
-+#define HAVE_ALLOCA 1
-+EOF
-+
-+fi
-+
-+if test $ac_cv_func_alloca = no; then
-+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
-+ # that cause trouble. Some versions do not even contain alloca or
-+ # contain a buggy version. If you still want to use their alloca,
-+ # use ar to extract alloca.o from them instead of compiling alloca.c.
-+ ALLOCA=alloca.o
-+ cat >> confdefs.h <<\EOF
-+#define C_ALLOCA 1
-+EOF
-+
-+
-+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.$ac_ext <<EOF
-+#line 1314 "configure"
-+#include "confdefs.h"
-+#if defined(CRAY) && ! defined(CRAY2)
-+webecray
-+#else
-+wenotbecray
-+#endif
-+
-+EOF
-+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-+ egrep "webecray" >/dev/null 2>&1; then
-+ rm -rf conftest*
-+ ac_cv_os_cray=yes
-+else
-+ rm -rf conftest*
-+ ac_cv_os_cray=no
-+fi
-+rm -f conftest*
-+
-+fi
-+
-+echo "$ac_t""$ac_cv_os_cray" 1>&6
-+if test $ac_cv_os_cray = yes; then
-+for ac_func in _getb67 GETB67 getb67; do
-+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ cat > conftest.$ac_ext <<EOF
-+#line 1343 "configure"
-+#include "confdefs.h"
-+/* System header to define __stub macros and hopefully few prototypes,
-+ which can conflict with char $ac_func(); below. */
-+#include <assert.h>
-+/* Override any gcc2 internal prototype to avoid an error. */
-+char $ac_func();
-+
-+int main() { return 0; }
-+int t() {
-+
-+/* The GNU C library defines this for functions which it implements
-+ to always fail with ENOSYS. Some functions are actually named
-+ something starting with __ and the normal name is an alias. */
-+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-+choke me
-+#else
-+$ac_func();
-+#endif
-+
-+; return 0; }
-+EOF
-+if { (eval echo configure:1365: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
-+ rm -rf conftest*
-+ eval "ac_cv_func_$ac_func=yes"
-+else
-+ rm -rf conftest*
-+ eval "ac_cv_func_$ac_func=no"
-+fi
-+rm -f conftest*
-+
-+fi
-+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
-+ echo "$ac_t""yes" 1>&6
-+ cat >> confdefs.h <<EOF
-+#define CRAY_STACKSEG_END $ac_func
-+EOF
-+
-+ break
-+else
-+ echo "$ac_t""no" 1>&6
-+fi
-+
-+done
-+fi
-+
-+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ if test "$cross_compiling" = yes; then
-+ ac_cv_c_stack_direction=0
-+else
-+cat > conftest.$ac_ext <<EOF
-+#line 1397 "configure"
-+#include "confdefs.h"
-+find_stack_direction ()
-+{
-+ static char *addr = 0;
-+ auto char dummy;
-+ if (addr == 0)
-+ {
-+ addr = &dummy;
-+ return find_stack_direction ();
-+ }
-+ else
-+ return (&dummy > addr) ? 1 : -1;
-+}
-+main ()
-+{
-+ exit (find_stack_direction() < 0);
-+}
-+EOF
-+{ (eval echo configure:1416: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-+if test -s conftest && (./conftest; exit) 2>/dev/null; then
-+ ac_cv_c_stack_direction=1
-+else
-+ ac_cv_c_stack_direction=-1
-+fi
-+fi
-+rm -fr conftest*
-+fi
-+
-+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
-+cat >> confdefs.h <<EOF
-+#define STACK_DIRECTION $ac_cv_c_stack_direction
-+EOF
-+
-+fi
-+
-+echo $ac_n "checking for strcoll""... $ac_c" 1>&6
-+if eval "test \"`echo '$''{'ac_cv_func_strcoll'+set}'`\" = set"; then
-+ echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+ if test "$cross_compiling" = yes; then
-+ ac_cv_func_strcoll=no
-+else
-+cat > conftest.$ac_ext <<EOF
-+#line 1441 "configure"
-+#include "confdefs.h"
-+#include <string.h>
-+main ()
-+{
-+ exit (strcoll ("abc", "def") >= 0 ||
-+ strcoll ("ABC", "DEF") >= 0 ||
-+ strcoll ("123", "456") >= 0);
-+}
-+EOF
-+{ (eval echo configure:1451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-+if test -s conftest && (./conftest; exit) 2>/dev/null; then
-+ ac_cv_func_strcoll=yes
-+else
-+ ac_cv_func_strcoll=no
-+fi
-+fi
-+rm -fr conftest*
-+fi
-+
-+echo "$ac_t""$ac_cv_func_strcoll" 1>&6
-+if test $ac_cv_func_strcoll = yes; then
-+ cat >> confdefs.h <<\EOF
-+#define HAVE_STRCOLL 1
-+EOF
-+
-+fi
-+
-+trap '' 1 2 15
-+cat > confcache <<\EOF
-+# This file is a shell script that caches the results of configure
-+# tests run on this system so they can be shared between configure
-+# scripts and configure runs. It is not useful on other systems.
-+# If it contains results you don't want to keep, you may remove or edit it.
-+#
-+# By default, configure uses ./config.cache as the cache file,
-+# creating it if it does not exist already. You can give configure
-+# the --cache-file=FILE option to use a different cache file; that is
-+# what configure does when it calls configure scripts in
-+# subdirectories, so they share the cache.
-+# Giving --cache-file=/dev/null disables caching, for debugging configure.
-+# config.status only pays attention to the cache file if you give it the
-+# --recheck option to rerun configure.
-+#
-+EOF
-+# Ultrix sh set writes to stderr and can't be redirected directly,
-+# and sets the high bit in the cache file unless we assign to the vars.
-+(set) 2>&1 |
-+ sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
-+ >> confcache
-+if cmp -s $cache_file confcache; then
-+ :
-+else
-+ if test -w $cache_file; then
-+ echo "updating cache $cache_file"
-+ cat confcache > $cache_file
-+ else
-+ echo "not updating unwritable cache $cache_file"
-+ fi
-+fi
-+rm -f confcache
-+
-+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-+
-+test "x$prefix" = xNONE && prefix=$ac_default_prefix
-+# Let make expand exec_prefix.
-+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-+
-+# Any assignment to VPATH causes Sun make to only execute
-+# the first set of double-colon rules, so remove it if not needed.
-+# If there is a colon in the path, we need to keep it.
-+if test "x$srcdir" = x.; then
-+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
-+fi
-+
-+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-+
-+# Transform confdefs.h into DEFS.
-+# Protect against shell expansion while executing Makefile rules.
-+# Protect against Makefile macro expansion.
-+cat > conftest.defs <<\EOF
-+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
-+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
-+s%\[%\\&%g
-+s%\]%\\&%g
-+s%\$%$$%g
-+EOF
-+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
-+rm -f conftest.defs
-+
-+
-+# Without the "./", some shells look in PATH for config.status.
-+: ${CONFIG_STATUS=./config.status}
-+
-+echo creating $CONFIG_STATUS
-+rm -f $CONFIG_STATUS
-+cat > $CONFIG_STATUS <<EOF
-+#! /bin/sh
-+# Generated automatically by configure.
-+# Run this file to recreate the current configuration.
-+# This directory was configured as follows,
-+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-+#
-+# $0 $ac_configure_args
-+#
-+# Compiler output produced by configure, useful for debugging
-+# configure, is in ./config.log if it exists.
-+
-+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-+for ac_option
-+do
-+ case "\$ac_option" in
-+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
-+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
-+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-+ echo "$CONFIG_STATUS generated by autoconf version 2.7"
-+ exit 0 ;;
-+ -help | --help | --hel | --he | --h)
-+ echo "\$ac_cs_usage"; exit 0 ;;
-+ *) echo "\$ac_cs_usage"; exit 1 ;;
-+ esac
-+done
-+
-+ac_given_srcdir=$srcdir
-+
-+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-+EOF
-+cat >> $CONFIG_STATUS <<EOF
-+
-+# Protect against being on the right side of a sed subst in config.status.
-+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
-+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-+$ac_vpsub
-+$extrasub
-+s%@CFLAGS@%$CFLAGS%g
-+s%@CPPFLAGS@%$CPPFLAGS%g
-+s%@CXXFLAGS@%$CXXFLAGS%g
-+s%@DEFS@%$DEFS%g
-+s%@LDFLAGS@%$LDFLAGS%g
-+s%@LIBS@%$LIBS%g
-+s%@exec_prefix@%$exec_prefix%g
-+s%@prefix@%$prefix%g
-+s%@program_transform_name@%$program_transform_name%g
-+s%@bindir@%$bindir%g
-+s%@sbindir@%$sbindir%g
-+s%@libexecdir@%$libexecdir%g
-+s%@datadir@%$datadir%g
-+s%@sysconfdir@%$sysconfdir%g
-+s%@sharedstatedir@%$sharedstatedir%g
-+s%@localstatedir@%$localstatedir%g
-+s%@libdir@%$libdir%g
-+s%@includedir@%$includedir%g
-+s%@oldincludedir@%$oldincludedir%g
-+s%@infodir@%$infodir%g
-+s%@mandir@%$mandir%g
-+s%@CC@%$CC%g
-+s%@AR@%$AR%g
-+s%@RANLIB@%$RANLIB%g
-+s%@CPP@%$CPP%g
-+s%@ALLOCA@%$ALLOCA%g
-+
-+CEOF
-+EOF
-+cat >> $CONFIG_STATUS <<EOF
-+
-+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
-+EOF
-+cat >> $CONFIG_STATUS <<\EOF
-+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
-+ # Support "outfile[:infile]", defaulting infile="outfile.in".
-+ case "$ac_file" in
-+ *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
-+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
-+ *) ac_file_in="${ac_file}.in" ;;
-+ esac
-+
-+ # Adjust relative srcdir, etc. for subdirectories.
-+
-+ # Remove last slash and all that follows it. Not all systems have dirname.
-+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
-+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
-+ # The file is in a subdirectory.
-+ test ! -d "$ac_dir" && mkdir "$ac_dir"
-+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
-+ # A "../" for each directory in $ac_dir_suffix.
-+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
-+ else
-+ ac_dir_suffix= ac_dots=
-+ fi
-+
-+ case "$ac_given_srcdir" in
-+ .) srcdir=.
-+ if test -z "$ac_dots"; then top_srcdir=.
-+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
-+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
-+ *) # Relative path.
-+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
-+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
-+ esac
-+
-+ echo creating "$ac_file"
-+ rm -f "$ac_file"
-+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
-+ case "$ac_file" in
-+ *Makefile*) ac_comsub="1i\\
-+# $configure_input" ;;
-+ *) ac_comsub= ;;
-+ esac
-+ sed -e "$ac_comsub
-+s%@configure_input@%$configure_input%g
-+s%@srcdir@%$srcdir%g
-+s%@top_srcdir@%$top_srcdir%g
-+" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
-+fi; done
-+rm -f conftest.subs
-+
-+
-+
-+exit 0
-+EOF
-+chmod +x $CONFIG_STATUS
-+rm -fr confdefs* $ac_clean_files
-+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-+
-diff -Naur ../glibc-2.1.3/posix/glob/configure.bat glibc-2.1.3/posix/glob/configure.bat
---- ../glibc-2.1.3/posix/glob/configure.bat 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/posix/glob/configure.bat 1998-02-07 12:24:21.000000000 -0800
-@@ -0,0 +1,26 @@
-+@echo off
-+echo Configuring glob for GO32
-+rem This batch file assumes a unix-type "sed" program
-+
-+echo # Makefile generated by "configure.bat"> Makefile
-+
-+if exist config.sed del config.sed
-+
-+echo "s/@srcdir@/./ ">> config.sed
-+echo "s/@CC@/gcc/ ">> config.sed
-+echo "s/@CFLAGS@/-O2 -g/ ">> config.sed
-+echo "s/@CPPFLAGS@/-DHAVE_CONFIG_H -I../ ">> config.sed
-+echo "s/@AR@/ar/ ">> config.sed
-+echo "s/@RANLIB@/ranlib/ ">> config.sed
-+echo "s/@LDFLAGS@// ">> config.sed
-+echo "s/@DEFS@// ">> config.sed
-+echo "s/@ALLOCA@// ">> config.sed
-+echo "s/@LIBS@// ">> config.sed
-+echo "s/@LIBOBJS@// ">> config.sed
-+echo "s/^Makefile *:/_Makefile:/ ">> config.sed
-+echo "s/^config.h *:/_config.h:/ ">> config.sed
-+
-+sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
-+sed -f config2.sed Makefile.in >> Makefile
-+del config.sed
-+del config2.sed
-diff -Naur ../glibc-2.1.3/posix/glob/configure.in glibc-2.1.3/posix/glob/configure.in
---- ../glibc-2.1.3/posix/glob/configure.in 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/posix/glob/configure.in 1998-02-07 12:24:21.000000000 -0800
-@@ -0,0 +1,19 @@
-+dnl Process this file with autoconf to produce a configure script.
-+AC_INIT(fnmatch.c) dnl A distinctive file to look for in srcdir.
-+AC_PREREQ(2.1) dnl Minimum Autoconf version required.
-+AC_PROG_CC
-+AC_CHECK_PROG(AR, ar, ar, ar)
-+AC_PROG_RANLIB
-+AC_PROG_CPP dnl Later checks need this.
-+dnl These two want to come early.
-+AC_AIX
-+AC_MINIX
-+AC_ISC_POSIX
-+AC_CONST
-+AC_HEADER_STDC
-+AC_CHECK_HEADERS(memory.h unistd.h string.h)
-+AC_HEADER_DIRENT
-+AC_FUNC_CLOSEDIR_VOID
-+AC_FUNC_ALLOCA
-+AC_FUNC_STRCOLL
-+AC_OUTPUT(Makefile)
-diff -Naur ../glibc-2.1.3/posix/id.c glibc-2.1.3/posix/id.c
---- ../glibc-2.1.3/posix/id.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/posix/id.c 1999-06-30 09:00:24.000000000 -0700
-@@ -0,0 +1,176 @@
-+/* Copyright (C) 1991, 1995, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <grp.h>
-+#include <pwd.h>
-+#include <limits.h>
-+#include <sys/types.h>
-+
-+
-+static void
-+print_grpname (id, parens)
-+ gid_t id;
-+ int parens;
-+{
-+ const struct group *const g = getgrgid (id);
-+ if (g == NULL)
-+ {
-+ if (parens)
-+ return;
-+ else
-+ {
-+ fprintf (stderr, _("Couldn't find name for group %d\n"), id);
-+ exit (EXIT_FAILURE);
-+ }
-+ }
-+
-+ if (parens)
-+ printf ("(%s)", g->gr_name);
-+ else
-+ puts (g->gr_name);
-+}
-+
-+static void
-+print_pwdname (id, parens)
-+ uid_t id;
-+ int parens;
-+{
-+ const struct passwd *const p = getpwuid (id);
-+ if (p == NULL)
-+ {
-+ if (parens)
-+ return;
-+ else
-+ {
-+ fprintf (stderr, _("Couldn't find name for user %d\n"), (int) id);
-+ exit (EXIT_FAILURE);
-+ }
-+ }
-+
-+ if (parens)
-+ printf ("(%s)", p->pw_name);
-+ else
-+ puts (p->pw_name);
-+}
-+
-+int
-+main (argc, argv)
-+ int argc;
-+ char **argv;
-+{
-+ int print_gid = 1, print_uid = 1;
-+ int real = 0, name = 0;
-+ int error = 0;
-+ int c;
-+
-+ uid_t ruid = getuid (), euid = geteuid ();
-+ gid_t rgid = getgid (), egid = getegid ();
-+
-+ while ((c = getopt (argc, argv, "gurn")) != -1)
-+ switch (c)
-+ {
-+ default:
-+ error = 1;
-+ break;
-+
-+ case 'g':
-+ print_gid = 1;
-+ print_uid = 0;
-+ break;
-+
-+ case 'u':
-+ print_uid = 1;
-+ print_gid = 0;
-+ break;
-+
-+ case 'r':
-+ real = 1;
-+ break;
-+
-+ case 'n':
-+ name = 1;
-+ break;
-+ }
-+
-+ if (error || argc != optind)
-+ {
-+ fputs (_("Usage: id [-gurn]\n"), stderr);
-+ exit (EXIT_FAILURE);
-+ }
-+
-+ if (print_uid && !print_gid)
-+ {
-+ const uid_t uid = real ? ruid : euid;
-+ if (name)
-+ print_pwdname (uid, 0);
-+ else
-+ printf ("%d\n", (int) uid);
-+ }
-+ else if (print_gid && !print_uid)
-+ {
-+ const gid_t gid = real ? rgid : egid;
-+ if (name)
-+ print_grpname (gid, 0);
-+ else
-+ printf ("%d\n", (int) gid);
-+ }
-+ else
-+ {
-+#if NGROUPS_MAX > 0
-+ gid_t groups[NGROUPS_MAX];
-+ int ngroups;
-+ ngroups = getgroups (NGROUPS_MAX, groups);
-+#endif
-+
-+ printf ("uid=%d", (int) ruid);
-+ print_pwdname (ruid, 1);
-+ printf (" gid=%d", (int) rgid);
-+ print_grpname (rgid, 1);
-+ if (euid != ruid)
-+ {
-+ printf (" euid=%d", (int) euid);
-+ print_pwdname (euid, 1);
-+ }
-+ if (egid != rgid)
-+ {
-+ printf (" egid=%d", (int) egid);
-+ print_grpname (egid, 1);
-+ }
-+
-+#if NGROUPS > 0
-+ if (ngroups > 0)
-+ {
-+ size_t i;
-+ printf (" groups=%d", (int) groups[0]);
-+ print_grpname (groups[0], 1);
-+ for (i = 1; i < ngroups; ++i)
-+ {
-+ printf (", %d", (int) groups[i]);
-+ print_grpname (groups[i], 1);
-+ }
-+ }
-+#endif
-+
-+ putchar ('\n');
-+ }
-+
-+ exit (EXIT_SUCCESS);
-+}
-diff -Naur ../glibc-2.1.3/redhat/.cvsignore glibc-2.1.3/redhat/.cvsignore
---- ../glibc-2.1.3/redhat/.cvsignore 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/redhat/.cvsignore 2000-02-18 16:03:43.000000000 -0800
-@@ -0,0 +1,6 @@
-+glibc-*.tar.gz
-+glibc-2.1.spec
-+diff-CYGNUS-to-REDHAT.patch
-+build
-+root
-+
-diff -Naur ../glibc-2.1.3/redhat/ChangeLog glibc-2.1.3/redhat/ChangeLog
---- ../glibc-2.1.3/redhat/ChangeLog 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/redhat/ChangeLog 2000-02-23 17:17:37.000000000 -0800
-@@ -0,0 +1,12 @@
-+2000-02-23 Cristian Gafton <gafton@redhat.com>
-+
-+ * Makefile (install-real): New target.
-+ (install-locales-real): New.
-+ (install-locales): New.
-+ (install): Use install-locales.
-+
-+2000-01-03 Cristian Gafton <gafton@redhat.com>
-+
-+ * Makefile (archive): be more verbose about what's happening
-+
-+
-diff -Naur ../glibc-2.1.3/redhat/Makefile glibc-2.1.3/redhat/Makefile
---- ../glibc-2.1.3/redhat/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/redhat/Makefile 2000-02-23 17:16:13.000000000 -0800
-@@ -0,0 +1,81 @@
-+#
-+# Makefile for creating a source RPM out of the
-+# internal CVS tree
-+#
-+# Cristian Gafton <gafton@redhat.com>
-+# Red Hat, Inc.
-+#
-+
-+SPEC = glibc-2.1.spec
-+PROJECT = glibc
-+
-+EXTRA = diff-CYGNUS-to-REDHAT.patch glibc-2.1.spec
-+
-+VERSION=$(shell sed -n -e 's/^\#define VERSION \"\([^"]*\)\"/\1/p' < ../version.h)
-+RELEASE=$(shell awk '/Release:/ { print $$2 }' $(SPEC).in)
-+
-+CVSTAG = glibc-$(subst .,-,$(VERSION))-release-$(subst .,-,$(RELEASE))
-+CVS_ROOT = $(shell cat CVS/Root)
-+
-+# How to build stuff for testing
-+ARCH = $(shell uname -m)-redhat-linux
-+CONFIGURE = ../../configure --prefix=/usr --enable-add-ons=yes --without-cvs $(ARCH)
-+BUILD_FLAGS = -r
-+
-+all:
-+
-+$(SPEC) : $(SPEC).in
-+ sed -e "s|@@VERSION@@|$(VERSION)|g" < $< | \
-+ grep -v "^%%" > $@
-+
-+spec: $(SPEC)
-+
-+patch:
-+ -cd .. ; cvs -q diff -N -rcygnus -rHEAD > redhat/diff-CYGNUS-to-REDHAT.patch
-+
-+commit:
-+ cd .. ; cvs -q commit -m "Prepare to comit for releasing $(CVSTAG)"
-+
-+archive: clean spec commit patch
-+ @rm -f $(PROJECT)-$(VERSION).tar.gz
-+ cd .. ; cvs -q tag -F $(CVSTAG) .
-+ @rm -rf /tmp/$(PROJECT)-$(VERSION)
-+ cd /tmp; CVSROOT=$(CVS_ROOT) cvs -Q export -r$(CVSTAG) -d $(PROJECT)-$(VERSION) glibc21
-+ install -m 644 $(EXTRA) /tmp/$(PROJECT)-$(VERSION)
-+ dir=$$PWD; cd /tmp; tar czf $$dir/$(PROJECT)-$(VERSION).tar.gz $(PROJECT)-$(VERSION)
-+ @rm -rf /tmp/$(PROJECT)-$(VERSION)
-+ @echo "The archive is in $(PROJECT)-$(VERSION).tar.gz"
-+
-+clean:
-+ @rm -fv *~
-+ @rm -fv $(EXTRA)
-+ @rm -fv glibc-*.tar.gz
-+
-+build-dir:
-+ -mkdir build
-+
-+root-dir:
-+ -mkdir root
-+
-+build/config.status build/Makefile: build-dir
-+ cd build ; $(CONFIGURE)
-+
-+configure: build/config.status build/Makefile
-+
-+build: configure
-+ make $(BUILD_FLAGS) -C build
-+
-+
-+install: root-dir build-dir
-+ make install -C build install_root=$$PWD/root
-+ $(MAKE) install-locales
-+
-+install-locales:
-+ make install-locales -C ../localedata install_root=$$PWD/root objdir=$$PWD/build
-+
-+install-real: build-dir
-+ make install -C build
-+ $(MAKE) install-locales-real
-+
-+install-locales-real:
-+ make install-locales -C ../localedata objdir=$$PWD/build
-diff -Naur ../glibc-2.1.3/redhat/glibc-2.1.spec.in glibc-2.1.3/redhat/glibc-2.1.spec.in
---- ../glibc-2.1.3/redhat/glibc-2.1.spec.in 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/redhat/glibc-2.1.spec.in 2000-02-29 13:15:05.000000000 -0800
-@@ -0,0 +1,305 @@
-+Summary: The GNU libc libraries.
-+Name: glibc
-+Version: @@VERSION@@
-+Release: 15
-+Copyright: LGPL
-+Group: System Environment/Libraries
-+Source: %{name}-%{version}.tar.gz
-+# Other sources are available at:
-+# http://www.ozemail.com.au/~geoffk/glibc-crypt/glibc-crypt-2.1.tar.gz
-+# In the source tarball the file diff-CYGNUS-to-REDHAT.patch contains all
-+# diffs applied by Red Hat to the current CVS version of glibc
-+Buildroot: /var/tmp/glibc-%{PACKAGE_VERSION}-root
-+Obsoletes: zoneinfo, libc-static, libc-devel, libc-profile, libc-headers,
-+Obsoletes: linuxthreads, gencat, locale
-+Autoreq: false
-+%ifarch alpha
-+Provides: ld.so.2
-+%else
-+%endif
-+%ifarch sparc
-+Obsoletes: libc
-+%endif
-+
-+%description
-+The glibc package contains standard libraries which are used by
-+multiple programs on the system. In order to save disk space and
-+memory, as well as to make upgrading easier, common system code is
-+kept in one place and shared between programs. This particular package
-+contains the most important sets of shared libraries: the standard C
-+library and the standard math library. Without these two libraries, a
-+Linux system will not function. The glibc package also contains
-+national language (locale) support and timezone databases.
-+
-+%package devel
-+Summary: Header and object files for development using standard C libraries.
-+Group: Development/Libraries
-+Conflicts: texinfo < 3.11
-+Prereq: /sbin/install-info
-+Obsoletes: libc-debug, libc-headers, libc-devel, linuxthreads-devel
-+Obsoletes: glibc-debug
-+Prereq: kernel-headers
-+Requires: kernel-headers >= 2.2.1
-+Autoreq: true
-+
-+%description devel
-+The glibc-devel package contains the header and object files necessary
-+for developing programs which use the standard C libraries (which are
-+used by nearly all programs). If you are developing programs which
-+will use the standard C libraries, your system needs to have these
-+standard header and object files available in order to create the
-+executables.
-+
-+Install glibc-devel if you are going to develop programs which will
-+use the standard C libraries.
-+
-+%package profile
-+Summary: The GNU libc libraries, including support for gprof profiling.
-+Group: Development/Libraries
-+Obsoletes: libc-profile
-+Autoreq: true
-+
-+%description profile
-+The glibc-profile package includes the GNU libc libraries and support
-+for profiling using the gprof program. Profiling is analyzing a
-+program's functions to see how much CPU time they use and determining
-+which functions are calling other functions during execution. To use
-+gprof to profile a program, your program needs to use the GNU libc
-+libraries included in glibc-profile (instead of the standard GNU libc
-+libraries included in the glibc package).
-+
-+If you are going to use the gprof program to profile a program, you'll
-+need to install the glibc-profile program.
-+
-+%package -n nscd
-+Summary: A Name Service Caching Daemon (nscd).
-+Group: System Environment/Daemons
-+Conflicts: kernel < 2.2.0
-+Prereq: /sbin/chkconfig
-+Autoreq: true
-+
-+%description -n nscd
-+Nscd caches name service lookups and can dramatically improve
-+performance with NIS+, and may help with DNS as well. Note that you
-+can't use nscd with 2.0 kernels because of bugs in the kernel-side
-+thread support. Unfortunately, nscd happens to hit these bugs
-+particularly hard.
-+
-+Install nscd if you need a name service lookup caching daemon, and
-+you're not using a version 2.0 kernel.
-+
-+%prep
-+%setup -q
-+
-+%ifarch armv4l
-+rm -rf glibc-compat
-+%endif
-+
-+find . -type f -size 0 -o -name "*.orig" -exec rm -f {} \;
-+
-+%build
-+rm -rf build-$RPM_ARCH-linux
-+mkdir build-$RPM_ARCH-linux ; cd build-$RPM_ARCH-linux
-+%ifarch i586 i686
-+BuildFlags="-mpentium -D__USE_STRING_INLINES -fstrict-aliasing -mcpu=%{_target_cpu}"
-+%endif
-+%ifarch sparcv9
-+BuildFlags="-mv8 -mtune=ultrasparc"
-+%endif
-+CC=egcs CFLAGS="$BuildFlags -g -O3" ../configure --prefix=/usr \
-+ --enable-add-ons=yes --without-cvs \
-+ %{_target_cpu}-redhat-linux
-+make -r CFLAGS="$BuildFlags -g -O3" PARALLELMFLAGS=-s
-+
-+%install
-+rm -rf $RPM_BUILD_ROOT
-+mkdir -p $RPM_BUILD_ROOT
-+make install_root=$RPM_BUILD_ROOT install -C build-$RPM_ARCH-linux
-+cd build-$RPM_ARCH-linux && \
-+ make install_root=$RPM_BUILD_ROOT install-locales -C ../localedata objdir=`pwd` && \
-+ cd ..
-+
-+# compatibility hack: this locale has vanished from glibc, but some other
-+# programs are still using it. Normally we would handle it in the %pre
-+# section but with glibc that is simply not an option
-+mkdir -p $RPM_BUILD_ROOT/usr/share/locale/ru_RU/LC_MESSAGES
-+
-+# Remove the files we don't want to distribute
-+rm -f $RPM_BUILD_ROOT/usr/lib/libNoVersion*
-+
-+# the man pages for the linuxthreads require special attention
-+make -C linuxthreads/man
-+mkdir -p $RPM_BUILD_ROOT/usr/man/man3
-+install -m 0644 linuxthreads/man/*.3thr $RPM_BUILD_ROOT/usr/man/man3
-+gzip -9nvf $RPM_BUILD_ROOT/usr/man/man3/*
-+
-+gzip -9nvf $RPM_BUILD_ROOT/usr/info/libc*
-+
-+ln -sf libbsd-compat.a $RPM_BUILD_ROOT/usr/lib/libbsd.a
-+
-+install -m 644 redhat/nsswitch.conf $RPM_BUILD_ROOT/etc/nsswitch.conf
-+
-+# Take care of setuids
-+# -- new security review sez that this shouldn't be needed anymore
-+#chmod 755 $RPM_BUILD_ROOT/usr/libexec/pt_chown
-+
-+# This is for ncsd - in glibc 2.1
-+install -m 644 nscd/nscd.conf $RPM_BUILD_ROOT/etc
-+mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
-+install -m 755 nscd/nscd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/nscd
-+
-+# The database support
-+mkdir -p $RPM_BUILD_ROOT/var/db
-+install -m 644 nss/db-Makefile $RPM_BUILD_ROOT/var/db/Makefile
-+
-+# Strip binaries
-+strip $RPM_BUILD_ROOT/sbin/* || :
-+strip $RPM_BUILD_ROOT/usr/bin/* || :
-+strip $RPM_BUILD_ROOT/usr/sbin/* || :
-+
-+# BUILD THE FILE LIST
-+find $RPM_BUILD_ROOT -type f -or -type l |
-+ sed -e 's|.*/etc|%config &|' > rpm.filelist.in
-+for n in /usr/share /usr/include; do
-+ find ${RPM_BUILD_ROOT}${n} -type d | \
-+ grep -v '^/usr/share$' | \
-+ sed "s/^/%dir /" >> rpm.filelist.in
-+done
-+
-+# primary filelist
-+sed "s|$RPM_BUILD_ROOT||" < rpm.filelist.in |
-+ grep -v '/etc/localtime' | \
-+ grep -v '/etc/nsswitch.conf' | \
-+ sort > rpm.filelist
-+
-+grep '/usr/lib/lib.*_p\.a' < rpm.filelist > profile.filelist
-+egrep "(/usr/include)|(/usr/info)" < rpm.filelist |
-+ grep -v /usr/info/dir > devel.filelist
-+
-+mv rpm.filelist rpm.filelist.full
-+grep -v '/usr/lib/lib.*_p.a' rpm.filelist.full |
-+ egrep -v "(/usr/include)|(/usr/info)" > rpm.filelist
-+
-+grep '/usr/lib/lib.*\.a' < rpm.filelist >> devel.filelist
-+grep '/usr/lib/.*\.o' < rpm.filelist >> devel.filelist
-+grep '/usr/lib/lib.*\.so' < rpm.filelist >> devel.filelist
-+grep '/usr/man/man' < rpm.filelist >> devel.filelist
-+
-+mv rpm.filelist rpm.filelist.full
-+grep -v '/usr/lib/lib.*\.a' < rpm.filelist.full |
-+ grep -v '/usr/lib/.*\.o' |
-+ grep -v '/usr/lib/lib.*\.so'|
-+ grep -v '/usr/man/man' |
-+ grep -v 'nscd' > rpm.filelist
-+
-+# /etc/localtime - we're proud of our timezone
-+rm -f $RPM_BUILD_ROOT/etc/localtime
-+cp -f $RPM_BUILD_ROOT/usr/share/zoneinfo/US/Eastern $RPM_BUILD_ROOT/etc/localtime
-+#ln -sf ../usr/share/zoneinfo/US/Eastern $RPM_BUILD_ROOT/etc/localtime
-+
-+# the last bit: more documentation
-+rm -rf documentation
-+mkdir documentation
-+cp linuxthreads/ChangeLog documentation/ChangeLog.threads
-+cp linuxthreads/Changes documentation/Changes.threads
-+cp linuxthreads/README documentation/README.threads
-+cp linuxthreads/FAQ.html documentation/FAQ-threads.html
-+cp -r linuxthreads/Examples documentation/examples.threads
-+cp crypt/README documentation/README.crypt
-+cp db2/README documentation/README.db2
-+cp db2/mutex/README documentation/README.db2.mutex
-+cp timezone/README documentation/README.timezone
-+cp ChangeLog* documentation
-+gzip -9 documentation/ChangeLog*
-+
-+%post -p /sbin/ldconfig
-+
-+%postun -p /sbin/ldconfig
-+
-+%post devel
-+/sbin/install-info /usr/info/libc.info.gz /usr/info/dir
-+
-+%pre devel
-+# this used to be a link and it is causing nightmares now
-+if [ -L /usr/include/scsi ] ; then
-+ rm -f /usr/include/scsi
-+fi
-+
-+%preun devel
-+if [ "$1" = 0 ]; then
-+ /sbin/install-info --delete /usr/info/libc.info.gz /usr/info/dir
-+fi
-+
-+%post -n nscd
-+/sbin/chkconfig --add nscd
-+
-+%preun -n nscd
-+if [ $1 = 0 ] ; then
-+ /sbin/chkconfig --del nscd
-+fi
-+
-+%clean
-+rm -rf "$RPM_BUILD_ROOT"
-+rm -f *.filelist*
-+
-+%files -f rpm.filelist
-+%defattr(-,root,root)
-+%config(noreplace) /etc/localtime
-+%config(noreplace) /etc/nsswitch.conf
-+%doc README NEWS INSTALL FAQ BUGS NOTES PROJECTS
-+%doc documentation/* README.template README.libm
-+%doc login/README.utmpd hesiod/README.hesiod
-+%dir /var/db
-+
-+%ifnarch sparcv9 i586 i686
-+%files -f devel.filelist devel
-+%defattr(-,root,root)
-+
-+%files -f profile.filelist profile
-+%defattr(-,root,root)
-+
-+%files -n nscd
-+%defattr(-,root,root)
-+%config /etc/nscd.conf
-+/etc/rc.d/init.d/nscd
-+/usr/sbin/nscd
-+%endif
-+
-+%define date %(echo `LC_ALL="C" date +"%a %b %d %Y"`)
-+
-+%changelog
-+* %{date} Cristian Gafton <gafton@redhat.com>
-+- fix c_stubs add-on to work around various assert()s in glibc
-+- add Davem's patch for _NPROCESSORS_ONLN on Sparc
-+
-+* Fri Feb 25 2000 Cristian Gafton <gafton@redhat.com>
-+- add the c_stubs add-on
-+- sparc patch from davem
-+
-+* Thu Feb 24 2000 Cristian Gafton <gafton@redhat.com>
-+- fix locale problems on 64 bit arches
-+
-+* Tue Feb 22 2000 Cristian Gafton <gafton@redhat.com>
-+- cygnus sync up for fixes to nscd
-+
-+* Thu Feb 17 2000 Cristian Gafton <gafton@redhat.com>
-+- updated to include new China timezones
-+- sync up with the locale changes from Cygnus
-+
-+* Tue Feb 01 2000 Cristian Gafton <gafton@redhat.com>
-+- updated from cygnus branch
-+- fix syslog so that it will continuously try to fallback from SOK_DGRAM to
-+ SOCK_STREAM and backwards
-+
-+* Mon Jan 31 2000 Cristian Gafton <gafton@redhat.com>
-+- update from cygnus branch
-+- compress man pages for the linuxthreads stuff
-+
-+* Fri Jan 21 2000 Cristian Gafton <gafton@redhat.com>
-+- add Jakub's patch so we back out even more
-+
-+* Thu Jan 20 2000 Cristian Gafton <gafton@redhat.com>
-+- back out the setrlimit changes (well, sort of)
-+
-+* Mon Jan 03 2000 Cristian Gafton <gafton@redhat.com>
-+- make release from CVS server directly now
-diff -Naur ../glibc-2.1.3/redhat/nsswitch.conf glibc-2.1.3/redhat/nsswitch.conf
---- ../glibc-2.1.3/redhat/nsswitch.conf 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/redhat/nsswitch.conf 2000-01-03 17:07:08.000000000 -0800
-@@ -0,0 +1,63 @@
-+#
-+# /etc/nsswitch.conf
-+#
-+# An example Name Service Switch config file. This file should be
-+# sorted with the most-used services at the beginning.
-+#
-+# The entry '[NOTFOUND=return]' means that the search for an
-+# entry should stop if the search in the previous entry turned
-+# up nothing. Note that if the search failed due to some other reason
-+# (like no NIS server responding) then the search continues with the
-+# next entry.
-+#
-+# Legal entries are:
-+#
-+# nisplus or nis+ Use NIS+ (NIS version 3)
-+# nis or yp Use NIS (NIS version 2), also called YP
-+# dns Use DNS (Domain Name Service)
-+# files Use the local files
-+# db Use the local database (.db) files
-+# compat Use NIS on compat mode
-+# hesiod Use Hesiod for user lookups
-+# [NOTFOUND=return] Stop searching if not found so far
-+#
-+
-+# To use db, put the "db" in front of "files" for entries you want to be
-+# looked up first in the databases
-+#
-+# Example:
-+#passwd: db files nisplus nis
-+#shadow: db files nisplus nis
-+#group: db files nisplus nis
-+
-+passwd: files nisplus nis
-+shadow: files nisplus nis
-+group: files nisplus nis
-+
-+#hosts: db files nisplus nis dns
-+hosts: files nisplus nis dns
-+
-+# Example - obey only what nisplus tells us...
-+#services: nisplus [NOTFOUND=return] files
-+#networks: nisplus [NOTFOUND=return] files
-+#protocols: nisplus [NOTFOUND=return] files
-+#rpc: nisplus [NOTFOUND=return] files
-+#ethers: nisplus [NOTFOUND=return] files
-+#netmasks: nisplus [NOTFOUND=return] files
-+
-+bootparams: nisplus [NOTFOUND=return] files
-+
-+ethers: files
-+netmasks: files
-+networks: files
-+protocols: files
-+rpc: files
-+services: files
-+
-+netgroup: nisplus
-+
-+publickey: nisplus
-+
-+automount: files nisplus
-+aliases: files nisplus
-+
-diff -Naur ../glibc-2.1.3/resolv/arpa/nameser.h glibc-2.1.3/resolv/arpa/nameser.h
---- ../glibc-2.1.3/resolv/arpa/nameser.h 1999-05-12 03:23:10.000000000 -0700
-+++ glibc-2.1.3/resolv/arpa/nameser.h 1999-12-27 08:22:16.000000000 -0800
-@@ -77,7 +77,7 @@
-
- /*
- * @(#)nameser.h 8.1 (Berkeley) 6/2/93
-- * $Id: nameser.h,v 1.15 1999/05/12 10:23:10 drepper Exp $
-+ * $Id: nameser.h,v 1.2 1999/12/27 16:22:16 gafton Exp $
- */
-
- #ifndef _ARPA_NAMESER_H
-@@ -295,6 +295,11 @@
- unsigned arcount :16; /* number of resource entries */
- } HEADER;
-
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+
- /*
- * Defines for handling compressed domain names
- */
-@@ -345,6 +350,11 @@
- (cp) += INT32SZ; \
- }
-
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+
- __END_DECLS
-
- #endif /* arpa/nameser.h */
-diff -Naur ../glibc-2.1.3/resolv/gethnamaddr.c glibc-2.1.3/resolv/gethnamaddr.c
---- ../glibc-2.1.3/resolv/gethnamaddr.c 1999-10-25 15:23:46.000000000 -0700
-+++ glibc-2.1.3/resolv/gethnamaddr.c 1999-12-07 08:50:36.000000000 -0800
-@@ -55,7 +55,7 @@
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
--static char rcsid[] = "$Id: gethnamaddr.c,v 1.29.2.2 1999/10/25 22:23:46 drepper Exp $";
-+static char rcsid[] = "$Id: gethnamaddr.c,v 1.1.1.1 1999/12/07 16:50:36 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/getnetnamadr.c glibc-2.1.3/resolv/getnetnamadr.c
---- ../glibc-2.1.3/resolv/getnetnamadr.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/resolv/getnetnamadr.c 1999-06-30 09:00:50.000000000 -0700
-@@ -0,0 +1,290 @@
-+/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
-+ * Dep. Matematica Universidade de Coimbra, Portugal, Europe
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ */
-+/*
-+ * Copyright (c) 1983, 1993
-+ * The Regents of the University of California. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * This product includes software developed by the University of
-+ * California, Berkeley and its contributors.
-+ * 4. Neither the name of the University nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#if defined(LIBC_SCCS) && !defined(lint)
-+static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
-+static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
-+static char rcsid[] = "$Id: getnetnamadr.c,v 1.1.1.1 1999/06/30 16:00:50 gafton Exp $";
-+#endif /* LIBC_SCCS and not lint */
-+
-+#include <sys/types.h>
-+#include <sys/param.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <arpa/nameser.h>
-+
-+#include <stdio.h>
-+#include <netdb.h>
-+#include <resolv.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <string.h>
-+
-+#ifndef h_errno
-+extern int h_errno;
-+#endif
-+
-+#if defined(mips) && defined(SYSTYPE_BSD43) && !defined(errno)
-+extern int errno;
-+#endif
-+
-+struct netent *_getnetbyaddr __P((long net, int type));
-+struct netent *_getnetbyname __P((const char *name));
-+
-+#define BYADDR 0
-+#define BYNAME 1
-+#define MAXALIASES 35
-+
-+#if PACKETSZ > 1024
-+#define MAXPACKET PACKETSZ
-+#else
-+#define MAXPACKET 1024
-+#endif
-+
-+typedef union {
-+ HEADER hdr;
-+ u_char buf[MAXPACKET];
-+} querybuf;
-+
-+typedef union {
-+ long al;
-+ char ac;
-+} align;
-+
-+static struct netent *
-+getnetanswer(answer, anslen, net_i)
-+ querybuf *answer;
-+ int anslen;
-+ int net_i;
-+{
-+
-+ register HEADER *hp;
-+ register u_char *cp;
-+ register int n;
-+ u_char *eom;
-+ int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
-+ char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap,
-+ *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
-+static struct netent net_entry;
-+static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
-+
-+ /*
-+ * find first satisfactory answer
-+ *
-+ * answer --> +------------+ ( MESSAGE )
-+ * | Header |
-+ * +------------+
-+ * | Question | the question for the name server
-+ * +------------+
-+ * | Answer | RRs answering the question
-+ * +------------+
-+ * | Authority | RRs pointing toward an authority
-+ * | Additional | RRs holding additional information
-+ * +------------+
-+ */
-+ eom = answer->buf + anslen;
-+ hp = &answer->hdr;
-+ ancount = ntohs(hp->ancount); /* #/records in the answer section */
-+ qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
-+ bp = netbuf;
-+ buflen = sizeof(netbuf);
-+ cp = answer->buf + HFIXEDSZ;
-+ if (!qdcount) {
-+ if (hp->aa)
-+ __set_h_errno (HOST_NOT_FOUND);
-+ else
-+ __set_h_errno (TRY_AGAIN);
-+ return (NULL);
-+ }
-+ while (qdcount-- > 0)
-+ cp += __dn_skipname(cp, eom) + QFIXEDSZ;
-+ ap = net_aliases;
-+ *ap = NULL;
-+ net_entry.n_aliases = net_aliases;
-+ haveanswer = 0;
-+ while (--ancount >= 0 && cp < eom) {
-+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
-+ if ((n < 0) || !res_dnok(bp))
-+ break;
-+ cp += n;
-+ ans[0] = '\0';
-+ (void)strcpy(&ans[0], bp);
-+ GETSHORT(type, cp);
-+ GETSHORT(class, cp);
-+ cp += INT32SZ; /* TTL */
-+ GETSHORT(n, cp);
-+ if (class == C_IN && type == T_PTR) {
-+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
-+ if ((n < 0) || !res_hnok(bp)) {
-+ cp += n;
-+ return (NULL);
-+ }
-+ cp += n;
-+ *ap++ = bp;
-+ bp += strlen(bp) + 1;
-+ net_entry.n_addrtype =
-+ (class == C_IN) ? AF_INET : AF_UNSPEC;
-+ haveanswer++;
-+ }
-+ }
-+ if (haveanswer) {
-+ *ap = NULL;
-+ switch (net_i) {
-+ case BYADDR:
-+ net_entry.n_name = *net_entry.n_aliases;
-+ net_entry.n_net = 0L;
-+ break;
-+ case BYNAME:
-+ in = *net_entry.n_aliases;
-+ net_entry.n_name = &ans[0];
-+ aux2[0] = '\0';
-+ for (i = 0; i < 4; i++) {
-+ for (st = in, nchar = 0;
-+ *st != '.';
-+ st++, nchar++)
-+ ;
-+ if (nchar != 1 || *in != '0' || flag) {
-+ flag = 1;
-+ (void)strncpy(paux1,
-+ (i==0) ? in : in-1,
-+ (i==0) ?nchar : nchar+1);
-+ paux1[(i==0) ? nchar : nchar+1] = '\0';
-+ pauxt = paux2;
-+ paux2 = strcat(paux1, paux2);
-+ paux1 = pauxt;
-+ }
-+ in = ++st;
-+ }
-+ net_entry.n_net = inet_network(paux2);
-+ break;
-+ }
-+ net_entry.n_aliases++;
-+ return (&net_entry);
-+ }
-+ __set_h_errno (TRY_AGAIN);
-+ return (NULL);
-+}
-+
-+struct netent *
-+getnetbyaddr(net, net_type)
-+ register u_long net;
-+ register int net_type;
-+{
-+ unsigned int netbr[4];
-+ int nn, anslen;
-+ querybuf buf;
-+ char qbuf[MAXDNAME];
-+ u_int32_t net2; /* Changed from unsigned long --roland */
-+ struct netent *net_entry;
-+
-+ if (net_type != AF_INET)
-+ return (_getnetbyaddr(net, net_type));
-+
-+ for (nn = 4, net2 = net; net2; net2 >>= 8)
-+ netbr[--nn] = net2 & 0xff;
-+ switch (nn) {
-+ case 3: /* Class A */
-+ sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);
-+ break;
-+ case 2: /* Class B */
-+ sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);
-+ break;
-+ case 1: /* Class C */
-+ sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
-+ netbr[1]);
-+ break;
-+ case 0: /* Class D - E */
-+ sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
-+ netbr[1], netbr[0]);
-+ break;
-+ }
-+ anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
-+ if (anslen < 0) {
-+#ifdef DEBUG
-+ if (_res.options & RES_DEBUG)
-+ printf("res_query failed\n");
-+#endif
-+ if (errno == ECONNREFUSED)
-+ return (_getnetbyaddr(net, net_type));
-+ return (NULL);
-+ }
-+ net_entry = getnetanswer(&buf, anslen, BYADDR);
-+ if (net_entry) {
-+ unsigned u_net = net; /* maybe net should be unsigned ? */
-+
-+ /* Strip trailing zeros */
-+ while ((u_net & 0xff) == 0 && u_net != 0)
-+ u_net >>= 8;
-+ net_entry->n_net = u_net;
-+ return (net_entry);
-+ }
-+ return (_getnetbyaddr(net, net_type));
-+}
-+
-+struct netent *
-+getnetbyname(net)
-+ register const char *net;
-+{
-+ int anslen;
-+ querybuf buf;
-+ char qbuf[MAXDNAME];
-+ struct netent *net_entry;
-+
-+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-+ __set_h_errno (NETDB_INTERNAL);
-+ return (NULL);
-+ }
-+ strcpy(&qbuf[0], net);
-+ anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
-+ if (anslen < 0) {
-+#ifdef DEBUG
-+ if (_res.options & RES_DEBUG)
-+ printf("res_query failed\n");
-+#endif
-+ if (errno == ECONNREFUSED)
-+ return (_getnetbyname(net));
-+ return (_getnetbyname(net));
-+ }
-+ net_entry = getnetanswer(&buf, anslen, BYNAME);
-+ if (net_entry)
-+ return (net_entry);
-+ return (_getnetbyname(net));
-+}
-diff -Naur ../glibc-2.1.3/resolv/herror.c glibc-2.1.3/resolv/herror.c
---- ../glibc-2.1.3/resolv/herror.c 1998-07-16 04:00:26.000000000 -0700
-+++ glibc-2.1.3/resolv/herror.c 1999-06-30 09:00:51.000000000 -0700
-@@ -55,7 +55,7 @@
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
--static char rcsid[] = "$Id: herror.c,v 1.9 1998/07/16 11:00:26 drepper Exp $";
-+static char rcsid[] = "$Id: herror.c,v 1.1.1.1 1999/06/30 16:00:51 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/inet_addr.c glibc-2.1.3/resolv/inet_addr.c
---- ../glibc-2.1.3/resolv/inet_addr.c 1999-04-29 11:19:53.000000000 -0700
-+++ glibc-2.1.3/resolv/inet_addr.c 1999-06-30 09:00:52.000000000 -0700
-@@ -55,7 +55,7 @@
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
--static char rcsid[] = "$Id: inet_addr.c,v 1.11 1999/04/29 18:19:53 drepper Exp $";
-+static char rcsid[] = "$Id: inet_addr.c,v 1.1.1.1 1999/06/30 16:00:52 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/inet_net_ntop.c glibc-2.1.3/resolv/inet_net_ntop.c
---- ../glibc-2.1.3/resolv/inet_net_ntop.c 1996-09-26 20:24:07.000000000 -0700
-+++ glibc-2.1.3/resolv/inet_net_ntop.c 1998-02-07 12:24:30.000000000 -0800
-@@ -16,7 +16,7 @@
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
--static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.2 1996/09/27 03:24:07 drepper Exp $";
-+static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.1.1.1 1998/02/07 20:24:30 gafton Exp $";
- #endif
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/inet_net_pton.c glibc-2.1.3/resolv/inet_net_pton.c
---- ../glibc-2.1.3/resolv/inet_net_pton.c 1999-04-28 15:32:02.000000000 -0700
-+++ glibc-2.1.3/resolv/inet_net_pton.c 1999-05-07 07:36:46.000000000 -0700
-@@ -16,7 +16,7 @@
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
--static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7 1999/04/28 22:32:02 drepper Exp $";
-+static const char rcsid[] = "$Id: inet_net_pton.c,v 1.1.1.1 1999/05/07 14:36:46 gafton Exp $";
- #endif
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/inet_neta.c glibc-2.1.3/resolv/inet_neta.c
---- ../glibc-2.1.3/resolv/inet_neta.c 1997-12-03 15:11:54.000000000 -0800
-+++ glibc-2.1.3/resolv/inet_neta.c 1998-02-07 12:24:31.000000000 -0800
-@@ -16,7 +16,7 @@
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
--static const char rcsid[] = "$Id: inet_neta.c,v 1.4 1997/12/03 23:11:54 drepper Exp $";
-+static const char rcsid[] = "$Id: inet_neta.c,v 1.1.1.1 1998/02/07 20:24:31 gafton Exp $";
- #endif
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/inet_ntop.c glibc-2.1.3/resolv/inet_ntop.c
---- ../glibc-2.1.3/resolv/inet_ntop.c 1997-10-05 18:23:28.000000000 -0700
-+++ glibc-2.1.3/resolv/inet_ntop.c 1998-02-07 12:24:32.000000000 -0800
-@@ -15,7 +15,7 @@
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
--static char rcsid[] = "$Id: inet_ntop.c,v 1.5 1997/10/06 01:23:28 drepper Exp $";
-+static char rcsid[] = "$Id: inet_ntop.c,v 1.1.1.1 1998/02/07 20:24:32 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/param.h>
-diff -Naur ../glibc-2.1.3/resolv/inet_pton.c glibc-2.1.3/resolv/inet_pton.c
---- ../glibc-2.1.3/resolv/inet_pton.c 1999-04-29 09:29:36.000000000 -0700
-+++ glibc-2.1.3/resolv/inet_pton.c 1999-05-07 07:36:48.000000000 -0700
-@@ -15,7 +15,7 @@
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
--static char rcsid[] = "$Id: inet_pton.c,v 1.9 1999/04/29 16:29:36 drepper Exp $";
-+static char rcsid[] = "$Id: inet_pton.c,v 1.1.1.1 1999/05/07 14:36:48 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/param.h>
-diff -Naur ../glibc-2.1.3/resolv/nsap_addr.c glibc-2.1.3/resolv/nsap_addr.c
---- ../glibc-2.1.3/resolv/nsap_addr.c 1998-12-01 11:34:42.000000000 -0800
-+++ glibc-2.1.3/resolv/nsap_addr.c 1998-12-02 11:04:04.000000000 -0800
-@@ -16,7 +16,7 @@
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
--static char rcsid[] = "$Id: nsap_addr.c,v 1.6 1998/12/01 19:34:42 drepper Exp $";
-+static char rcsid[] = "$Id: nsap_addr.c,v 1.1.1.1 1998/12/02 19:04:04 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/res_comp.c glibc-2.1.3/resolv/res_comp.c
---- ../glibc-2.1.3/resolv/res_comp.c 1999-02-06 15:55:49.000000000 -0800
-+++ glibc-2.1.3/resolv/res_comp.c 1999-06-30 09:00:59.000000000 -0700
-@@ -55,7 +55,7 @@
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
--static char rcsid[] = "$Id: res_comp.c,v 1.16 1999/02/06 23:55:49 drepper Exp $";
-+static char rcsid[] = "$Id: res_comp.c,v 1.1.1.1 1999/06/30 16:00:59 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/res_data.c glibc-2.1.3/resolv/res_data.c
---- ../glibc-2.1.3/resolv/res_data.c 1996-08-13 20:48:55.000000000 -0700
-+++ glibc-2.1.3/resolv/res_data.c 1999-06-30 09:01:00.000000000 -0700
-@@ -54,7 +54,7 @@
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
--static char rcsid[] = "$Id: res_data.c,v 1.2 1996/08/14 03:48:55 drepper Exp $";
-+static char rcsid[] = "$Id: res_data.c,v 1.1.1.1 1999/06/30 16:01:00 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/res_debug.c glibc-2.1.3/resolv/res_debug.c
---- ../glibc-2.1.3/resolv/res_debug.c 1998-09-07 08:06:02.000000000 -0700
-+++ glibc-2.1.3/resolv/res_debug.c 1999-06-30 09:01:02.000000000 -0700
-@@ -77,7 +77,7 @@
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
--static char rcsid[] = "$Id: res_debug.c,v 1.24 1998/09/07 15:06:02 drepper Exp $";
-+static char rcsid[] = "$Id: res_debug.c,v 1.1.1.1 1999/06/30 16:01:02 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/param.h>
-diff -Naur ../glibc-2.1.3/resolv/res_init.c glibc-2.1.3/resolv/res_init.c
---- ../glibc-2.1.3/resolv/res_init.c 1999-04-28 15:34:01.000000000 -0700
-+++ glibc-2.1.3/resolv/res_init.c 1999-06-30 09:01:03.000000000 -0700
-@@ -55,7 +55,7 @@
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
--static char rcsid[] = "$Id: res_init.c,v 1.19 1999/04/28 22:34:01 drepper Exp $";
-+static char rcsid[] = "$Id: res_init.c,v 1.1.1.1 1999/06/30 16:01:03 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/res_mkquery.c glibc-2.1.3/resolv/res_mkquery.c
---- ../glibc-2.1.3/resolv/res_mkquery.c 1996-10-01 18:37:29.000000000 -0700
-+++ glibc-2.1.3/resolv/res_mkquery.c 1999-06-30 09:01:05.000000000 -0700
-@@ -55,7 +55,7 @@
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
--static char rcsid[] = "$Id: res_mkquery.c,v 1.7 1996/10/02 01:37:29 drepper Exp $";
-+static char rcsid[] = "$Id: res_mkquery.c,v 1.1.1.1 1999/06/30 16:01:05 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/res_query.c glibc-2.1.3/resolv/res_query.c
---- ../glibc-2.1.3/resolv/res_query.c 1997-05-23 08:31:34.000000000 -0700
-+++ glibc-2.1.3/resolv/res_query.c 1999-06-30 09:01:06.000000000 -0700
-@@ -55,7 +55,7 @@
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
--static char rcsid[] = "$Id: res_query.c,v 1.12 1997/05/23 15:31:34 drepper Exp $";
-+static char rcsid[] = "$Id: res_query.c,v 1.1.1.1 1999/06/30 16:01:06 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- #include <sys/types.h>
-diff -Naur ../glibc-2.1.3/resolv/res_send.c glibc-2.1.3/resolv/res_send.c
---- ../glibc-2.1.3/resolv/res_send.c 1999-08-06 20:16:16.000000000 -0700
-+++ glibc-2.1.3/resolv/res_send.c 1999-08-10 13:37:00.000000000 -0700
-@@ -51,7 +51,7 @@
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
--static char rcsid[] = "$Id: res_send.c,v 1.20.2.3 1999/08/07 03:16:16 drepper Exp $";
-+static char rcsid[] = "$Id: res_send.c,v 1.1.1.1 1999/08/10 20:37:00 gafton Exp $";
- #endif /* LIBC_SCCS and not lint */
-
- /* change this to "0"
-diff -Naur ../glibc-2.1.3/resolv/resolv.h glibc-2.1.3/resolv/resolv.h
---- ../glibc-2.1.3/resolv/resolv.h 1998-06-29 05:41:27.000000000 -0700
-+++ glibc-2.1.3/resolv/resolv.h 1999-06-30 09:01:08.000000000 -0700
-@@ -55,7 +55,7 @@
-
- /*
- * @(#)resolv.h 8.1 (Berkeley) 6/2/93
-- * $Id: resolv.h,v 1.19 1998/06/29 12:41:27 drepper Exp $
-+ * $Id: resolv.h,v 1.1.1.1 1999/06/30 16:01:08 gafton Exp $
- */
-
- #ifndef _RESOLV_H
-diff -Naur ../glibc-2.1.3/scripts/=__ify glibc-2.1.3/scripts/=__ify
---- ../glibc-2.1.3/scripts/=__ify 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/scripts/=__ify 1998-08-28 03:07:38.000000000 -0700
-@@ -0,0 +1,12 @@
-+for func in $*; do
-+ for file in `find sysdeps -name "${func}.c"`;
-+ do
-+ script=/tmp/foo$$;
-+ ( echo "%s/${func}/__&/g";
-+ echo x )>$script ;
-+ ex $file <$script ;
-+ newfile=`echo $file | sed "s/${func}/__&/"`;
-+ mv $file $newfile;
-+ echo $newfile;
-+ done
-+done
-diff -Naur ../glibc-2.1.3/scripts/mkinstalldirs glibc-2.1.3/scripts/mkinstalldirs
---- ../glibc-2.1.3/scripts/mkinstalldirs 1998-05-08 13:55:06.000000000 -0700
-+++ glibc-2.1.3/scripts/mkinstalldirs 1998-08-28 03:07:38.000000000 -0700
-@@ -4,7 +4,7 @@
- # Created: 1993-05-16
- # Public domain
-
--# $Id: mkinstalldirs,v 1.1 1998/05/08 20:55:06 drepper Exp $
-+# $Id: mkinstalldirs,v 1.1.1.1 1998/08/28 10:07:38 gafton Exp $
-
- errstatus=0
-
-diff -Naur ../glibc-2.1.3/scripts/printsources glibc-2.1.3/scripts/printsources
---- ../glibc-2.1.3/scripts/printsources 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/scripts/printsources 1998-08-28 03:07:38.000000000 -0700
-@@ -0,0 +1,29 @@
-+#! /bin/csh -f
-+
-+#
-+# Prints all the files given as arguments.
-+# Files that will fit on less than a printed page
-+# are concatenated together. Bigger ones are pr'd.
-+#
-+
-+
-+set tocat='' topr=''
-+
-+foreach file ($*)
-+ set lines=`wc -l $file | sed "s/$file//"`
-+ if ($lines > 40) then
-+ set topr=($topr $file)
-+ else
-+ set tocat=($tocat $file)
-+ endif
-+end
-+
-+
-+if ("$topr" != '') pr $topr
-+
-+if ("$tocat" != '') foreach file ($tocat)
-+ echo -n "==================== $file ======================"
-+ cat $file
-+end
-+
-+exit 0
-diff -Naur ../glibc-2.1.3/stdio-common/scanf11.c glibc-2.1.3/stdio-common/scanf11.c
---- ../glibc-2.1.3/stdio-common/scanf11.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/stdio-common/scanf11.c 1998-02-07 12:25:38.000000000 -0800
-@@ -0,0 +1,14 @@
-+/* This test comes from ISO C Corrigendum 1. */
-+#include <stdio.h>
-+
-+int
-+main (int argc, char *argv[])
-+{
-+ int d1, n1, n2, i;
-+#define NOISE 1234567
-+ int d2 = NOISE;
-+
-+ i = sscanf ("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
-+
-+ return i != 3 || d1 != 123 || n1 != 3 || n2 != 3 || d2 != NOISE;
-+}
-diff -Naur ../glibc-2.1.3/stdio-common/scanf6.c glibc-2.1.3/stdio-common/scanf6.c
---- ../glibc-2.1.3/stdio-common/scanf6.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/stdio-common/scanf6.c 1998-02-07 12:25:38.000000000 -0800
-@@ -0,0 +1,16 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+
-+int
-+main (int argc, char *argv[])
-+{
-+ int n = -1;
-+ char c = '!';
-+ int ret;
-+
-+ ret = sscanf ("0x", "%i%c", &n, &c);
-+ printf ("ret: %d, n: %d, c: %c\n", ret, n, c);
-+ if (ret != 2 || n != 0 || c != 'x')
-+ abort ();
-+ return 0;
-+}
-diff -Naur ../glibc-2.1.3/string/bits/string2.h glibc-2.1.3/string/bits/string2.h
---- ../glibc-2.1.3/string/bits/string2.h 2000-02-22 23:03:05.000000000 -0800
-+++ glibc-2.1.3/string/bits/string2.h 2000-02-23 14:48:17.000000000 -0800
-@@ -609,7 +609,7 @@
- __u = __extension__ ((void *) __u + 3);
- break;
- }
-- return &__u->__c;
-+ return (char *) &__u->__c;
- }
- # else
- # define __stpcpy_args(src) \
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_clntout.c glibc-2.1.3/sunrpc/rpc_clntout.c
---- ../glibc-2.1.3/sunrpc/rpc_clntout.c 1999-11-23 09:11:05.000000000 -0800
-+++ glibc-2.1.3/sunrpc/rpc_clntout.c 1999-12-07 08:50:37.000000000 -0800
-@@ -32,7 +32,7 @@
- * From: @(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI
- */
- char clntout_rcsid[] =
-- "$Id: rpc_clntout.c,v 1.5.2.1 1999/11/23 17:11:05 drepper Exp $";
-+ "$Id: rpc_clntout.c,v 1.1.1.1 1999/12/07 16:50:37 gafton Exp $";
-
- /*
- * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_cout.c glibc-2.1.3/sunrpc/rpc_cout.c
---- ../glibc-2.1.3/sunrpc/rpc_cout.c 1999-04-17 02:41:43.000000000 -0700
-+++ glibc-2.1.3/sunrpc/rpc_cout.c 1999-04-21 11:13:33.000000000 -0700
-@@ -32,7 +32,7 @@
- * From: @(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI
- */
- char cout_rcsid[] =
--"$Id: rpc_cout.c,v 1.10 1999/04/17 09:41:43 drepper Exp $";
-+"$Id: rpc_cout.c,v 1.1.1.1 1999/04/21 18:13:33 gafton Exp $";
-
- /*
- * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_hout.c glibc-2.1.3/sunrpc/rpc_hout.c
---- ../glibc-2.1.3/sunrpc/rpc_hout.c 1998-12-01 03:23:36.000000000 -0800
-+++ glibc-2.1.3/sunrpc/rpc_hout.c 1998-12-01 11:41:59.000000000 -0800
-@@ -32,7 +32,7 @@
- * From: @(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI
- */
- char hout_rcsid[] =
-- "$Id: rpc_hout.c,v 1.4 1998/12/01 11:23:36 drepper Exp $";
-+ "$Id: rpc_hout.c,v 1.1.1.1 1998/12/01 19:41:59 gafton Exp $";
-
- /*
- * rpc_hout.c, Header file outputter for the RPC protocol compiler
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_main.c glibc-2.1.3/sunrpc/rpc_main.c
---- ../glibc-2.1.3/sunrpc/rpc_main.c 1999-01-23 14:46:54.000000000 -0800
-+++ glibc-2.1.3/sunrpc/rpc_main.c 1999-06-30 09:03:23.000000000 -0700
-@@ -32,7 +32,7 @@
- * From @(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI;
- */
- const char main_rcsid[] =
-- "$Id: rpc_main.c,v 1.14 1999/01/23 22:46:54 drepper Exp $";
-+ "$Id: rpc_main.c,v 1.1.1.1 1999/06/30 16:03:23 gafton Exp $";
-
- /*
- * rpc_main.c, Top level of the RPC protocol compiler.
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_parse.c glibc-2.1.3/sunrpc/rpc_parse.c
---- ../glibc-2.1.3/sunrpc/rpc_parse.c 1998-02-16 09:41:53.000000000 -0800
-+++ glibc-2.1.3/sunrpc/rpc_parse.c 1998-02-20 07:54:02.000000000 -0800
-@@ -32,7 +32,7 @@
- * From: @(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI
- */
- const char parse_rcsid[] =
-- "$Id: rpc_parse.c,v 1.4 1998/02/16 17:41:53 drepper Exp $";
-+ "$Id: rpc_parse.c,v 1.1.1.1 1998/02/20 15:54:02 gafton Exp $";
-
- /*
- * rpc_parse.c, Parser for the RPC protocol compiler
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_sample.c glibc-2.1.3/sunrpc/rpc_sample.c
---- ../glibc-2.1.3/sunrpc/rpc_sample.c 1998-11-16 03:56:33.000000000 -0800
-+++ glibc-2.1.3/sunrpc/rpc_sample.c 1998-11-17 07:30:23.000000000 -0800
-@@ -32,7 +32,7 @@
- * From: @(#)rpc_sample.c 1.1 90/08/30 (C) 1987 SMI
- */
- char sample_rcsid[] =
-- "$Id: rpc_sample.c,v 1.5 1998/11/16 11:56:33 drepper Exp $";
-+ "$Id: rpc_sample.c,v 1.1.1.1 1998/11/17 15:30:23 gafton Exp $";
-
- /*
- * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_scan.c glibc-2.1.3/sunrpc/rpc_scan.c
---- ../glibc-2.1.3/sunrpc/rpc_scan.c 1998-02-16 09:41:55.000000000 -0800
-+++ glibc-2.1.3/sunrpc/rpc_scan.c 1999-06-30 09:03:25.000000000 -0700
-@@ -32,7 +32,7 @@
- * From: @(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI
- */
- char scan_rcsid[] =
-- "$Id: rpc_scan.c,v 1.6 1998/02/16 17:41:55 drepper Exp $";
-+ "$Id: rpc_scan.c,v 1.1.1.1 1999/06/30 16:03:25 gafton Exp $";
-
- /*
- * rpc_scan.c, Scanner for the RPC protocol compiler
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_svcout.c glibc-2.1.3/sunrpc/rpc_svcout.c
---- ../glibc-2.1.3/sunrpc/rpc_svcout.c 1998-12-01 03:24:21.000000000 -0800
-+++ glibc-2.1.3/sunrpc/rpc_svcout.c 1998-12-01 11:42:01.000000000 -0800
-@@ -32,7 +32,7 @@
- * From: @(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI
- */
- char svcout_rcsid[] =
-- "$Id: rpc_svcout.c,v 1.7 1998/12/01 11:24:21 drepper Exp $";
-+ "$Id: rpc_svcout.c,v 1.1.1.1 1998/12/01 19:42:01 gafton Exp $";
-
- /*
- * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_tblout.c glibc-2.1.3/sunrpc/rpc_tblout.c
---- ../glibc-2.1.3/sunrpc/rpc_tblout.c 1997-03-26 17:51:46.000000000 -0800
-+++ glibc-2.1.3/sunrpc/rpc_tblout.c 1998-02-07 12:28:22.000000000 -0800
-@@ -32,7 +32,7 @@
- * From: @(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI
- */
- char tblout_rcsid[] =
-- "$Id: rpc_tblout.c,v 1.2 1997/03/27 01:51:46 drepper Exp $";
-+ "$Id: rpc_tblout.c,v 1.1.1.1 1998/02/07 20:28:22 gafton Exp $";
-
- /*
- * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
-diff -Naur ../glibc-2.1.3/sunrpc/rpc_util.c glibc-2.1.3/sunrpc/rpc_util.c
---- ../glibc-2.1.3/sunrpc/rpc_util.c 1998-02-16 09:41:57.000000000 -0800
-+++ glibc-2.1.3/sunrpc/rpc_util.c 1998-02-20 07:54:05.000000000 -0800
-@@ -32,7 +32,7 @@
- * From: @(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI
- */
- char util_rcsid[] =
-- "$Id: rpc_util.c,v 1.6 1998/02/16 17:41:57 drepper Exp $";
-+ "$Id: rpc_util.c,v 1.1.1.1 1998/02/20 15:54:05 gafton Exp $";
-
- /*
- * rpc_util.c, Utility routines for the RPC protocol compiler
-diff -Naur ../glibc-2.1.3/sysdeps/generic/nlist.c glibc-2.1.3/sysdeps/generic/nlist.c
---- ../glibc-2.1.3/sysdeps/generic/nlist.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/sysdeps/generic/nlist.c 1998-02-07 12:29:37.000000000 -0800
-@@ -0,0 +1,43 @@
-+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <errno.h>
-+#include <nlist.h>
-+#include <stddef.h>
-+
-+/* Search the executable FILE for symbols matching those in NL,
-+ which is terminated by an element with a NULL `n_un.n_name' member,
-+ and fill in the elements of NL. */
-+int
-+nlist (file, nl)
-+ const char *file;
-+ struct nlist *nl;
-+{
-+ if (nl == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return -1;
-+ }
-+
-+ __set_errno (ENOSYS);
-+ return -1;
-+}
-+
-+
-+stub_warning (nlist)
-+#include <stub-tag.h>
-diff -Naur ../glibc-2.1.3/sysdeps/generic/paths.h glibc-2.1.3/sysdeps/generic/paths.h
---- ../glibc-2.1.3/sysdeps/generic/paths.h 1998-07-20 10:19:37.000000000 -0700
-+++ glibc-2.1.3/sysdeps/generic/paths.h 1999-12-27 08:34:12.000000000 -0800
-@@ -49,7 +49,7 @@
- #define _PATH_DEVNULL "/dev/null"
- #define _PATH_DRUM "/dev/drum"
- #define _PATH_KMEM "/dev/kmem"
--#define _PATH_MAILDIR "/var/mail"
-+#define _PATH_MAILDIR "/var/spool/mail"
- #define _PATH_LASTLOG "/var/log/lastlog"
- #define _PATH_MAN "/usr/man"
- #define _PATH_MEM "/dev/mem"
-@@ -62,10 +62,10 @@
- #define _PATH_SHADOW "/etc/shadow"
- #define _PATH_SHELLS "/etc/shells"
- #define _PATH_TTY "/dev/tty"
--#define _PATH_UNIX "/vmunix"
-+#define _PATH_UNIX "/boot/vmunix"
- #define _PATH_UTMP "/var/run/utmp"
- #define _PATH_UTMP_DB "/var/run/utmp.db"
--#define _PATH_VI "/usr/bin/vi"
-+#define _PATH_VI "/bin/vi"
- #define _PATH_WTMP "/var/log/wtmp"
-
- /* Provide trailing slash, since mostly used for building pathnames. */
-diff -Naur ../glibc-2.1.3/sysdeps/generic/varargs.h glibc-2.1.3/sysdeps/generic/varargs.h
---- ../glibc-2.1.3/sysdeps/generic/varargs.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/sysdeps/generic/varargs.h 1998-02-07 12:29:56.000000000 -0800
-@@ -0,0 +1,61 @@
-+/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#ifndef _VARARGS_H
-+
-+#define _VARARGS_H 1
-+#include <features.h>
-+
-+#ifdef __GNUC__
-+
-+#define va_alist __builtin_va_alist
-+#define va_dcl int __builtin_va_alist;
-+#define va_list char *
-+
-+#ifdef __sparc__
-+#define va_start(AP) \
-+ (__builtin_saveregs (), \
-+ AP = ((void *) &__builtin_va_alist))
-+#else
-+#define va_start(AP) AP=(char *) &__builtin_va_alist
-+#endif
-+#define va_end(AP)
-+
-+#define __va_rounded_size(TYPE) \
-+ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
-+
-+#define va_arg(AP, TYPE) \
-+ (*((TYPE *) (AP += __va_rounded_size (TYPE), \
-+ AP - __va_rounded_size (TYPE))))
-+
-+#else /* Not GCC. */
-+
-+/* Implement varargs on top of our stdarg implementation. */
-+
-+#include <stdarg.h>
-+
-+#define va_alist __va_fakearg
-+#define va_dcl int __va_fakearg;
-+
-+#undef va_start
-+#define va_start(ap) (__va_start((ap), __va_fakearg), \
-+ (ap) -= sizeof(__va_fakearg))
-+
-+#endif /* GCC. */
-+
-+#endif /* varargs.h */
-diff -Naur ../glibc-2.1.3/sysdeps/mach/sys/reboot.h glibc-2.1.3/sysdeps/mach/sys/reboot.h
---- ../glibc-2.1.3/sysdeps/mach/sys/reboot.h 1998-05-29 03:19:59.000000000 -0700
-+++ glibc-2.1.3/sysdeps/mach/sys/reboot.h 1998-07-09 11:55:57.000000000 -0700
-@@ -26,6 +26,9 @@
- /*
- * HISTORY
- * $Log: reboot.h,v $
-+ * Revision 1.1.1.1 1998/07/09 18:55:57 gafton
-+ * import from sourceware
-+ *
- * Revision 1.2 1998/05/29 10:19:59 drepper
- * Use __ASSEMBLER__ test macro not ASSEMBLER.
- *
-diff -Naur ../glibc-2.1.3/sysdeps/powerpc/test-arith.c glibc-2.1.3/sysdeps/powerpc/test-arith.c
---- ../glibc-2.1.3/sysdeps/powerpc/test-arith.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/sysdeps/powerpc/test-arith.c 1998-02-26 11:10:25.000000000 -0800
-@@ -0,0 +1,605 @@
-+/* Test floating-point arithmetic operations.
-+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+#ifndef _GNU_SOURCE
-+#define _GNU_SOURCE
-+#endif
-+#include <math.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <fenv.h>
-+#include <assert.h>
-+
-+#ifndef ESIZE
-+typedef double tocheck_t;
-+#define ESIZE 11
-+#define MSIZE 52
-+#define FUNC(x) x
-+#endif
-+
-+#define R_NEAREST 1
-+#define R_ZERO 2
-+#define R_UP 4
-+#define R_DOWN 8
-+#define R_ALL (R_NEAREST|R_ZERO|R_UP|R_DOWN)
-+static fenv_t rmodes[4];
-+static const char * const rmnames[4] =
-+{ "nearest","zero","+Inf","-Inf" };
-+
-+typedef union {
-+ tocheck_t tc;
-+ unsigned char c[sizeof(tocheck_t)];
-+} union_t;
-+
-+/* Don't try reading these in a font that doesn't distinguish
-+ O and zero. */
-+typedef enum {
-+ P_Z = 0x0, /* 00000...0 */
-+ P_000O = 0x1, /* 00011...1 */
-+ P_001Z = 0x2, /* 00100...0 */
-+ P_00O = 0x3, /* 00111...1 */
-+ P_01Z = 0x4, /* 01000...0 */
-+ P_010O = 0x5, /* 01011...1 */
-+ P_011Z = 0x6, /* 01100...0 */
-+ P_0O = 0x7, /* 01111...1 */
-+ P_1Z = 0x8, /* 10000...0 */
-+ P_100O = 0x9, /* 10011...1 */
-+ P_101Z = 0xa, /* 10100...0 */
-+ P_10O = 0xb, /* 10111...1 */
-+ P_11Z = 0xc, /* 11000...0 */
-+ P_110O = 0xd, /* 11011...1 */
-+ P_111Z = 0xe, /* 11100...0 */
-+ P_O = 0xf, /* 11111...1 */
-+ P_Z1 = 0x11, /* 000...001 */
-+ P_Z10 = 0x12, /* 000...010 */
-+ P_Z11 = 0x13, /* 000...011 */
-+ P_0O00 = 0x14, /* 011...100 */
-+ P_0O01 = 0x15, /* 011...101 */
-+ P_0O0 = 0x16, /* 011...110 */
-+ P_1Z1 = 0x19, /* 100...001 */
-+ P_1Z10 = 0x1a, /* 100...010 */
-+ P_1Z11 = 0x1b, /* 100...011 */
-+ P_O00 = 0x1c, /* 111...100 */
-+ P_O01 = 0x1d, /* 111...101 */
-+ P_O0 = 0x1e, /* 111...110 */
-+ P_R = 0x20, /* rrr...rrr */ /* ('r' means random. ) */
-+ P_Ro = 0x21, /* rrr...rrr, with odd parity. */
-+ P_0R = 0x22, /* 0rr...rrr */
-+ P_1R = 0x23, /* 1rr...rrr */
-+ P_Rno = 0x24, /* rrr...rrr, but not all ones. */
-+} pattern_t;
-+
-+static void
-+pattern_fill(pattern_t ptn, unsigned char *start, int bitoffset, int count)
-+{
-+#define bitset(count, value) \
-+ start[(count)/8] = (start[(count)/8] & ~(1 << 7-(count)%8) \
-+ | (value) << 7-(count)%8)
-+ int i;
-+
-+ if (ptn >= 0 && ptn <= 0xf)
-+ {
-+ /* Patterns between 0 and 0xF have the following format:
-+ The LSBit is used to fill the last n-3 bits of the pattern;
-+ The next 3 bits are the first 3 bits of the pattern. */
-+ for (i = 0; i < count; i++)
-+ if (i < 3)
-+ bitset((bitoffset+i), ptn >> (3-i) & 1);
-+ else
-+ bitset((bitoffset+i), ptn >> 0 & 1);
-+ }
-+ else if (ptn <= 0x1f)
-+ {
-+ /* Patterns between 0x10 and 0x1F have the following format:
-+ The two LSBits are the last two bits of the pattern;
-+ The 0x8 bit is the first bit of the pattern;
-+ The 0x4 bit is used to fill the remainder. */
-+ for (i = 0; i < count; i++)
-+ if (i == 0)
-+ bitset((bitoffset+i), ptn >> 3 & 1);
-+ else if (i >= count-2)
-+ bitset((bitoffset+i), ptn >> (count-1-i) & 1);
-+ else
-+ bitset((bitoffset+i), ptn >> 2 & 1);
-+ }
-+ else switch (ptn)
-+ {
-+ case P_0R: case P_1R:
-+ assert(count > 0);
-+ bitset(bitoffset, ptn & 1);
-+ count--;
-+ bitoffset++;
-+ case P_R:
-+ for (; count > 0; count--, bitoffset++)
-+ bitset(bitoffset, rand() & 1);
-+ break;
-+ case P_Ro:
-+ {
-+ int op = 1;
-+ assert(count > 0);
-+ for (; count > 1; count--, bitoffset++)
-+ bitset(bitoffset, op ^= (rand() & 1));
-+ bitset(bitoffset, op);
-+ break;
-+ }
-+ case P_Rno:
-+ {
-+ int op = 1;
-+ assert(count > 0);
-+ for (; count > 1; count--, bitoffset++)
-+ {
-+ int r = rand() & 1;
-+ op &= r;
-+ bitset(bitoffset, r);
-+ }
-+ bitset(bitoffset, rand() & (op ^ 1));
-+ break;
-+ }
-+
-+ default:
-+ assert(0);
-+ }
-+#undef bitset
-+}
-+
-+static tocheck_t
-+pattern(int negative, pattern_t exp, pattern_t mant)
-+{
-+ union_t result;
-+#if 0
-+ int i;
-+#endif
-+
-+ pattern_fill(negative ? P_O : P_Z, result.c, 0, 1);
-+ pattern_fill(exp, result.c, 1, ESIZE);
-+ pattern_fill(mant, result.c, ESIZE+1, MSIZE);
-+#if 0
-+ printf("neg=%d exp=%02x mant=%02x: ", negative, exp, mant);
-+ for (i = 0; i < sizeof(tocheck_t); i++)
-+ printf("%02x", result.c[i]);
-+ printf("\n");
-+#endif
-+ return result.tc;
-+}
-+
-+/* Return the closest different tocheck_t to 'x' in the direction of
-+ 'direction', or 'x' if there is no such value. Assumes 'x' is not
-+ a NaN. */
-+static tocheck_t
-+delta(tocheck_t x, int direction)
-+{
-+ union_t xx;
-+ int i;
-+
-+ xx.tc = x;
-+ if (xx.c[0] & 0x80)
-+ direction = -direction;
-+ if (direction == +1)
-+ {
-+ union_t tx;
-+ tx.tc = pattern(xx.c[0] >> 7, P_O, P_Z);
-+ if (memcmp(tx.c, xx.c, sizeof(tocheck_t)) == 0)
-+ return x;
-+ }
-+ for (i = sizeof(tocheck_t)-1; i > 0; i--)
-+ {
-+ xx.c[i] += direction;
-+ if (xx.c[i] != (direction > 0 ? 0 : 0xff))
-+ return xx.tc;
-+ }
-+ if (direction < 0 && (xx.c[0] & 0x7f) == 0)
-+ return pattern(~(xx.c[0] >> 7) & 1, P_Z, P_Z1);
-+ else
-+ {
-+ xx.c[0] += direction;
-+ return xx.tc;
-+ }
-+}
-+
-+static int nerrors = 0;
-+
-+#ifdef FE_ALL_INVALID
-+static const int all_exceptions = FE_ALL_INVALID | FE_ALL_EXCEPT;
-+#else
-+static const int all_exceptions = FE_ALL_EXCEPT;
-+#endif
-+
-+static void
-+check_result(int line, const char *rm, tocheck_t expected, tocheck_t actual)
-+{
-+ if (memcmp(&expected, &actual, sizeof(tocheck_t)) != 0)
-+ {
-+ unsigned char *ex, *ac;
-+ size_t i;
-+
-+ printf("%s:%d:round %s:result failed\n"
-+ " expected result 0x", __FILE__, line, rm);
-+ ex = (unsigned char *)&expected;
-+ ac = (unsigned char *)&actual;
-+ for (i = 0; i < sizeof(tocheck_t); i++)
-+ printf("%02x", ex[i]);
-+ printf(" got 0x");
-+ for (i = 0; i < sizeof(tocheck_t); i++)
-+ printf("%02x", ac[i]);
-+ printf("\n");
-+ nerrors++;
-+ }
-+}
-+
-+static const struct {
-+ int except;
-+ const char *name;
-+} excepts[] = {
-+#define except_entry(ex) { ex, #ex } ,
-+#ifdef FE_INEXACT
-+ except_entry(FE_INEXACT)
-+#else
-+# define FE_INEXACT 0
-+#endif
-+#ifdef FE_DIVBYZERO
-+ except_entry(FE_DIVBYZERO)
-+#else
-+# define FE_DIVBYZERO 0
-+#endif
-+#ifdef FE_UNDERFLOW
-+ except_entry(FE_UNDERFLOW)
-+#else
-+# define FE_UNDERFLOW 0
-+#endif
-+#ifdef FE_OVERFLOW
-+ except_entry(FE_OVERFLOW)
-+#else
-+# define FE_OVERFLOW 0
-+#endif
-+#ifdef FE_INVALID
-+ except_entry(FE_INVALID)
-+#else
-+# define FE_INVALID 0
-+#endif
-+#ifdef FE_INVALID_SNAN
-+ except_entry(FE_INVALID_SNAN)
-+#else
-+# define FE_INVALID_SNAN FE_INVALID
-+#endif
-+#ifdef FE_INVALID_ISI
-+ except_entry(FE_INVALID_ISI)
-+#else
-+# define FE_INVALID_ISI FE_INVALID
-+#endif
-+#ifdef FE_INVALID_IDI
-+ except_entry(FE_INVALID_IDI)
-+#else
-+# define FE_INVALID_IDI FE_INVALID
-+#endif
-+#ifdef FE_INVALID_ZDZ
-+ except_entry(FE_INVALID_ZDZ)
-+#else
-+# define FE_INVALID_ZDZ FE_INVALID
-+#endif
-+#ifdef FE_INVALID_COMPARE
-+ except_entry(FE_INVALID_COMPARE)
-+#else
-+# define FE_INVALID_COMPARE FE_INVALID
-+#endif
-+#ifdef FE_INVALID_SOFTWARE
-+ except_entry(FE_INVALID_SOFTWARE)
-+#else
-+# define FE_INVALID_SOFTWARE FE_INVALID
-+#endif
-+#ifdef FE_INVALID_SQRT
-+ except_entry(FE_INVALID_SQRT)
-+#else
-+# define FE_INVALID_SQRT FE_INVALID
-+#endif
-+#ifdef FE_INVALID_INTEGER_CONVERSION
-+ except_entry(FE_INVALID_INTEGER_CONVERSION)
-+#else
-+# define FE_INVALID_INTEGER_CONVERSION FE_INVALID
-+#endif
-+};
-+
-+static int excepts_missing = 0;
-+
-+static void
-+check_excepts(int line, const char *rm, int expected, int actual)
-+{
-+ if (expected & excepts_missing)
-+ expected = expected & ~excepts_missing | FE_INVALID_SNAN;
-+ if ((expected & all_exceptions) != actual)
-+ {
-+ size_t i;
-+ printf("%s:%d:round %s:exceptions failed\n"
-+ " expected exceptions ", __FILE__, line,rm);
-+ for (i = 0; i < sizeof(excepts)/sizeof(excepts[0]); i++)
-+ if (expected & excepts[i].except)
-+ printf("%s ",excepts[i].name);
-+ if ((expected & all_exceptions) == 0)
-+ printf("- ");
-+ printf("got");
-+ for (i = 0; i < sizeof(excepts)/sizeof(excepts[0]); i++)
-+ if (actual & excepts[i].except)
-+ printf(" %s",excepts[i].name);
-+ if ((actual & all_exceptions) == 0)
-+ printf("- ");
-+ printf(".\n");
-+ nerrors++;
-+ }
-+}
-+
-+typedef enum {
-+ B_ADD, B_SUB, B_MUL, B_DIV, B_NEG, B_ABS, B_SQRT
-+} op_t;
-+typedef struct {
-+ int line;
-+ op_t op;
-+ int a_sgn;
-+ pattern_t a_exp, a_mant;
-+ int b_sgn;
-+ pattern_t b_exp, b_mant;
-+ int rmode;
-+ int excepts;
-+ int x_sgn;
-+ pattern_t x_exp, x_mant;
-+} optest_t;
-+static const optest_t optests[] = {
-+ /* Additions of zero. */
-+ {__LINE__,B_ADD, 0,P_Z,P_Z, 0,P_Z,P_Z, R_ALL,0, 0,P_Z,P_Z },
-+ {__LINE__,B_ADD, 1,P_Z,P_Z, 0,P_Z,P_Z, R_ALL & ~R_DOWN,0, 0,P_Z,P_Z },
-+ {__LINE__,B_ADD, 1,P_Z,P_Z, 0,P_Z,P_Z, R_DOWN,0, 1,P_Z,P_Z },
-+ {__LINE__,B_ADD, 1,P_Z,P_Z, 1,P_Z,P_Z, R_ALL,0, 1,P_Z,P_Z },
-+
-+ /* Additions with NaN. */
-+ {__LINE__,B_ADD, 0,P_O,P_101Z, 0,P_Z,P_Z, R_ALL,0, 0,P_O,P_101Z },
-+ {__LINE__,B_ADD, 0,P_O,P_01Z, 0,P_Z,P_Z, R_ALL,
-+ FE_INVALID | FE_INVALID_SNAN, 0,P_O,P_11Z },
-+ {__LINE__,B_ADD, 0,P_O,P_Z, 0,P_O,P_0O, R_ALL,
-+ FE_INVALID | FE_INVALID_SNAN, 0,P_O,P_O },
-+ {__LINE__,B_ADD, 0,P_Z,P_Z, 0,P_O,P_11Z, R_ALL,0, 0,P_O,P_11Z },
-+ {__LINE__,B_ADD, 0,P_O,P_001Z, 0,P_O,P_001Z, R_ALL,
-+ FE_INVALID | FE_INVALID_SNAN, 0,P_O,P_101Z },
-+ {__LINE__,B_ADD, 0,P_O,P_1Z, 0,P_Z,P_Z, R_ALL,0, 0,P_O,P_1Z },
-+ {__LINE__,B_ADD, 0,P_0O,P_Z, 0,P_O,P_10O, R_ALL,0, 0,P_O,P_10O },
-+
-+ /* Additions with infinity. */
-+ {__LINE__,B_ADD, 0,P_O,P_Z, 0,P_Z,P_Z, R_ALL,0, 0,P_O,P_Z },
-+ {__LINE__,B_ADD, 0,P_O,P_Z, 1,P_Z,P_Z, R_ALL,0, 0,P_O,P_Z },
-+ {__LINE__,B_ADD, 1,P_O,P_Z, 0,P_Z,P_Z, R_ALL,0, 1,P_O,P_Z },
-+ {__LINE__,B_ADD, 1,P_O,P_Z, 1,P_Z,P_Z, R_ALL,0, 1,P_O,P_Z },
-+ {__LINE__,B_ADD, 0,P_O,P_Z, 0,P_O,P_Z, R_ALL,0, 0,P_O,P_Z },
-+ {__LINE__,B_ADD, 1,P_O,P_Z, 1,P_O,P_Z, R_ALL,0, 1,P_O,P_Z },
-+ {__LINE__,B_ADD, 0,P_O,P_Z, 1,P_O,P_Z, R_ALL,
-+ FE_INVALID | FE_INVALID_ISI, 0,P_O,P_1Z },
-+ {__LINE__,B_ADD, 1,P_O,P_Z, 0,P_O,P_Z, R_ALL,
-+ FE_INVALID | FE_INVALID_ISI, 0,P_O,P_1Z },
-+ {__LINE__,B_ADD, 0,P_O,P_Z, 0,P_0O,P_Z, R_ALL,0, 0,P_O,P_Z },
-+ {__LINE__,B_ADD, 1,P_O,P_Z, 0,P_0O,P_Z, R_ALL,0, 1,P_O,P_Z },
-+ {__LINE__,B_ADD, 0,P_O,P_Z, 1,P_0O,P_Z, R_ALL,0, 0,P_O,P_Z },
-+ {__LINE__,B_ADD, 1,P_O,P_Z, 1,P_0O,P_Z, R_ALL,0, 1,P_O,P_Z },
-+
-+ /* Overflow (and zero). */
-+ {__LINE__,B_ADD, 0,P_O0,P_Z, 0,P_O0,P_Z, R_NEAREST | R_UP,
-+ FE_INEXACT | FE_OVERFLOW, 0,P_O,P_Z },
-+ {__LINE__,B_ADD, 0,P_O0,P_Z, 0,P_O0,P_Z, R_ZERO | R_DOWN,
-+ FE_INEXACT | FE_OVERFLOW, 0,P_O0,P_O },
-+ {__LINE__,B_ADD, 1,P_O0,P_Z, 1,P_O0,P_Z, R_NEAREST | R_DOWN,
-+ FE_INEXACT | FE_OVERFLOW, 1,P_O,P_Z },
-+ {__LINE__,B_ADD, 1,P_O0,P_Z, 1,P_O0,P_Z, R_ZERO | R_UP,
-+ FE_INEXACT | FE_OVERFLOW, 1,P_O0,P_O },
-+ {__LINE__,B_ADD, 0,P_O0,P_Z, 1,P_O0,P_Z, R_ALL & ~R_DOWN,
-+ 0, 0,P_Z,P_Z },
-+ {__LINE__,B_ADD, 0,P_O0,P_Z, 1,P_O0,P_Z, R_DOWN,
-+ 0, 1,P_Z,P_Z },
-+
-+ /* Negation. */
-+ {__LINE__,B_NEG, 0,P_Z,P_Z, 0,0,0, R_ALL, 0, 1,P_Z,P_Z },
-+ {__LINE__,B_NEG, 1,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
-+ {__LINE__,B_NEG, 0,P_O,P_Z, 0,0,0, R_ALL, 0, 1,P_O,P_Z },
-+ {__LINE__,B_NEG, 1,P_O,P_Z, 0,0,0, R_ALL, 0, 0,P_O,P_Z },
-+ {__LINE__,B_NEG, 0,P_O,P_1Z, 0,0,0, R_ALL, 0, 1,P_O,P_1Z },
-+ {__LINE__,B_NEG, 1,P_O,P_1Z, 0,0,0, R_ALL, 0, 0,P_O,P_1Z },
-+ {__LINE__,B_NEG, 0,P_O,P_01Z, 0,0,0, R_ALL, 0, 1,P_O,P_01Z },
-+ {__LINE__,B_NEG, 1,P_O,P_01Z, 0,0,0, R_ALL, 0, 0,P_O,P_01Z },
-+ {__LINE__,B_NEG, 0,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 1,P_1Z,P_1Z1 },
-+ {__LINE__,B_NEG, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
-+ {__LINE__,B_NEG, 0,P_Z,P_Z1, 0,0,0, R_ALL, 0, 1,P_Z,P_Z1 },
-+ {__LINE__,B_NEG, 1,P_Z,P_Z1, 0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
-+
-+ /* Absolute value. */
-+ {__LINE__,B_ABS, 0,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
-+ {__LINE__,B_ABS, 1,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
-+ {__LINE__,B_ABS, 0,P_O,P_Z, 0,0,0, R_ALL, 0, 0,P_O,P_Z },
-+ {__LINE__,B_ABS, 1,P_O,P_Z, 0,0,0, R_ALL, 0, 0,P_O,P_Z },
-+ {__LINE__,B_ABS, 0,P_O,P_1Z, 0,0,0, R_ALL, 0, 0,P_O,P_1Z },
-+ {__LINE__,B_ABS, 1,P_O,P_1Z, 0,0,0, R_ALL, 0, 0,P_O,P_1Z },
-+ {__LINE__,B_ABS, 0,P_O,P_01Z, 0,0,0, R_ALL, 0, 0,P_O,P_01Z },
-+ {__LINE__,B_ABS, 1,P_O,P_01Z, 0,0,0, R_ALL, 0, 0,P_O,P_01Z },
-+ {__LINE__,B_ABS, 0,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
-+ {__LINE__,B_ABS, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
-+ {__LINE__,B_ABS, 0,P_Z,P_Z1, 0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
-+ {__LINE__,B_ABS, 1,P_Z,P_Z1, 0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
-+
-+ /* Square root. */
-+ {__LINE__,B_SQRT, 0,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
-+ {__LINE__,B_SQRT, 1,P_Z,P_Z, 0,0,0, R_ALL, 0, 1,P_Z,P_Z },
-+ {__LINE__,B_SQRT, 0,P_O,P_1Z, 0,0,0, R_ALL, 0, 0,P_O,P_1Z },
-+ {__LINE__,B_SQRT, 1,P_O,P_1Z, 0,0,0, R_ALL, 0, 1,P_O,P_1Z },
-+ {__LINE__,B_SQRT, 0,P_O,P_01Z, 0,0,0, R_ALL,
-+ FE_INVALID | FE_INVALID_SNAN, 0,P_O,P_11Z },
-+ {__LINE__,B_SQRT, 1,P_O,P_01Z, 0,0,0, R_ALL,
-+ FE_INVALID | FE_INVALID_SNAN, 1,P_O,P_11Z },
-+
-+ {__LINE__,B_SQRT, 0,P_O,P_Z, 0,0,0, R_ALL, 0, 0,P_O,P_Z },
-+ {__LINE__,B_SQRT, 0,P_0O,P_Z, 0,0,0, R_ALL, 0, 0,P_0O,P_Z },
-+
-+ {__LINE__,B_SQRT, 1,P_O,P_Z, 0,0,0, R_ALL,
-+ FE_INVALID | FE_INVALID_SQRT, 0,P_O,P_1Z },
-+ {__LINE__,B_SQRT, 1,P_1Z,P_1Z1, 0,0,0, R_ALL,
-+ FE_INVALID | FE_INVALID_SQRT, 0,P_O,P_1Z },
-+ {__LINE__,B_SQRT, 1,P_Z,P_Z1, 0,0,0, R_ALL,
-+ FE_INVALID | FE_INVALID_SQRT, 0,P_O,P_1Z },
-+
-+};
-+
-+static void
-+check_op(void)
-+{
-+ size_t i;
-+ int j;
-+ tocheck_t r, a, b, x;
-+ int raised;
-+
-+ for (i = 0; i < sizeof(optests)/sizeof(optests[0]); i++)
-+ {
-+ a = pattern(optests[i].a_sgn, optests[i].a_exp,
-+ optests[i].a_mant);
-+ b = pattern(optests[i].b_sgn, optests[i].b_exp,
-+ optests[i].b_mant);
-+ x = pattern(optests[i].x_sgn, optests[i].x_exp,
-+ optests[i].x_mant);
-+ for (j = 0; j < 4; j++)
-+ if (optests[i].rmode & 1<<j)
-+ {
-+ fesetenv(rmodes+j);
-+ switch (optests[i].op)
-+ {
-+ case B_ADD: r = a + b; break;
-+ case B_SUB: r = a - b; break;
-+ case B_MUL: r = a * b; break;
-+ case B_DIV: r = a / b; break;
-+ case B_NEG: r = -a; break;
-+ case B_ABS: r = FUNC(fabs)(a); break;
-+ case B_SQRT: r = FUNC(sqrt)(a); break;
-+ }
-+ raised = fetestexcept(all_exceptions);
-+ check_result(optests[i].line,rmnames[j],x,r);
-+ check_excepts(optests[i].line,rmnames[j],
-+ optests[i].excepts,raised);
-+ }
-+ }
-+}
-+
-+static void
-+fail_xr(int line, const char *rm, tocheck_t x, tocheck_t r, tocheck_t xx,
-+ int xflag)
-+{
-+ size_t i;
-+ unsigned char *cx, *cr, *cxx;
-+
-+ printf("%s:%d:round %s:fail\n with x=0x", __FILE__, line,rm);
-+ cx = (unsigned char *)&x;
-+ cr = (unsigned char *)&r;
-+ cxx = (unsigned char *)&xx;
-+ for (i = 0; i < sizeof(tocheck_t); i++)
-+ printf("%02x", cx[i]);
-+ printf(" r=0x");
-+ for (i = 0; i < sizeof(tocheck_t); i++)
-+ printf("%02x", cr[i]);
-+ printf(" xx=0x");
-+ for (i = 0; i < sizeof(tocheck_t); i++)
-+ printf("%02x", cxx[i]);
-+ printf(" inexact=%d\n", xflag != 0);
-+ nerrors++;
-+}
-+
-+static void
-+check_sqrt(tocheck_t a)
-+{
-+ int j;
-+ tocheck_t r0, r1, r2, x0, x1, x2;
-+ int raised = 0;
-+ int ok;
-+
-+ for (j = 0; j < 4; j++)
-+ {
-+ int excepts;
-+
-+ fesetenv(rmodes+j);
-+ r1 = FUNC(sqrt)(a);
-+ excepts = fetestexcept(all_exceptions);
-+ fesetenv(FE_DFL_ENV);
-+ raised |= excepts & ~FE_INEXACT;
-+ x1 = r1 * r1 - a;
-+ if (excepts & FE_INEXACT)
-+ {
-+ r0 = delta(r1,-1); r2 = delta(r1,1);
-+ switch (1 << j)
-+ {
-+ case R_NEAREST:
-+ x0 = r0 * r0 - a; x2 = r2 * r2 - a;
-+ ok = fabs(x0) >= fabs(x1) && fabs(x1) <= fabs(x2);
-+ break;
-+ case R_ZERO: case R_DOWN:
-+ x2 = r2 * r2 - a;
-+ ok = x1 <= 0 && x2 >= 0;
-+ break;
-+ case R_UP:
-+ x0 = r0 * r0 - a;
-+ ok = x1 >= 0 && x0 <= 0;
-+ break;
-+ default:
-+ assert(0);
-+ }
-+ }
-+ else
-+ ok = x1 == 0;
-+ if (!ok)
-+ fail_xr(__LINE__,rmnames[j],a,r1,x1,excepts&FE_INEXACT);
-+ }
-+ check_excepts(__LINE__,"all",0,raised);
-+}
-+
-+int main(int argc, char **argv)
-+{
-+ int i;
-+
-+ _LIB_VERSION = _IEEE_;
-+
-+ /* Set up environments for rounding modes. */
-+ fesetenv(FE_DFL_ENV);
-+ fesetround(FE_TONEAREST);
-+ fegetenv(rmodes+0);
-+ fesetround(FE_TOWARDZERO);
-+ fegetenv(rmodes+1);
-+ fesetround(FE_UPWARD);
-+ fegetenv(rmodes+2);
-+ fesetround(FE_DOWNWARD);
-+ fegetenv(rmodes+3);
-+
-+#if defined(FE_INVALID_SOFTWARE) || defined(FE_INVALID_SQRT)
-+ /* There's this really stupid feature of the 601... */
-+ fesetenv(FE_DFL_ENV);
-+ feraiseexcept(FE_INVALID_SOFTWARE);
-+ if (!fetestexcept(FE_INVALID_SOFTWARE))
-+ excepts_missing |= FE_INVALID_SOFTWARE;
-+ fesetenv(FE_DFL_ENV);
-+ feraiseexcept(FE_INVALID_SQRT);
-+ if (!fetestexcept(FE_INVALID_SQRT))
-+ excepts_missing |= FE_INVALID_SQRT;
-+#endif
-+
-+ check_op();
-+ for (i = 0; i < 100000; i++)
-+ check_sqrt(pattern(0, P_Rno, P_R));
-+ for (i = 0; i < 100; i++)
-+ check_sqrt(pattern(0, P_Z, P_R));
-+ check_sqrt(pattern(0,P_Z,P_Z1));
-+
-+ printf("%d errors.\n", nerrors);
-+ return nerrors == 0 ? 0 : 1;
-+}
-diff -Naur ../glibc-2.1.3/sysdeps/powerpc/test-arithf.c glibc-2.1.3/sysdeps/powerpc/test-arithf.c
---- ../glibc-2.1.3/sysdeps/powerpc/test-arithf.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/sysdeps/powerpc/test-arithf.c 1998-02-07 12:36:26.000000000 -0800
-@@ -0,0 +1,6 @@
-+typedef float tocheck_t;
-+#define ESIZE 8
-+#define MSIZE 23
-+#define FUNC(x) x##f
-+
-+#include "test-arith.c"
-diff -Naur ../glibc-2.1.3/sysdeps/unix/bsd/osf/=dirstream.h glibc-2.1.3/sysdeps/unix/bsd/osf/=dirstream.h
---- ../glibc-2.1.3/sysdeps/unix/bsd/osf/=dirstream.h 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/sysdeps/unix/bsd/osf/=dirstream.h 1998-02-07 12:37:25.000000000 -0800
-@@ -0,0 +1,44 @@
-+/* Copyright (C) 1993 Free Software Foundation, Inc.
-+ Contributed by Brendan Kehoe (brendan@zen.org).
-+
-+The GNU C Library is free software; you can redistribute it and/or
-+modify it under the terms of the GNU Library General Public License as
-+published by the Free Software Foundation; either version 2 of the
-+License, or (at your option) any later version.
-+
-+The GNU C Library is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+Library General Public License for more details.
-+
-+You should have received a copy of the GNU Library General Public
-+License along with the GNU C Library; see the file COPYING.LIB. If
-+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-+Cambridge, MA 02139, USA. */
-+
-+#ifndef _DIRSTREAM_H
-+
-+#define _DIRSTREAM_H 1
-+
-+#define __need_size_t
-+#include <stddef.h>
-+
-+/* Directory stream type. */
-+
-+typedef struct
-+ {
-+ int __fd; /* File descriptor. */
-+
-+ size_t __offset; /* Current offset into the block. */
-+ size_t __size; /* Total valid data in the block. */
-+ char *__data; /* Directory block. */
-+
-+ int __allocation; /* Space allocated for the block. */
-+
-+ int __data_len; /* Size of __data. */
-+ long __dd_seek; /* OSF/1 magic cookie returned by getdents. */
-+ void *dd_lock; /* Used by OSF/1 for inter-thread locking. */
-+
-+ } DIR;
-+
-+#endif /* dirstream.h */
-diff -Naur ../glibc-2.1.3/sysdeps/unix/nlist.c glibc-2.1.3/sysdeps/unix/nlist.c
---- ../glibc-2.1.3/sysdeps/unix/nlist.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/sysdeps/unix/nlist.c 1998-02-07 12:37:11.000000000 -0800
-@@ -0,0 +1,91 @@
-+/* Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <errno.h>
-+#include <a.out.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+
-+/* Search the executable FILE for symbols matching those in NL,
-+ which is terminated by an element with a NULL `n_un.n_name' member,
-+ and fill in the elements of NL. */
-+int
-+nlist (const char *file, struct nlist *nl)
-+{
-+ FILE *f;
-+ struct exec header;
-+ size_t nsymbols;
-+ struct nlist *symbols;
-+ unsigned long int string_table_size;
-+ char *string_table;
-+ register size_t i;
-+
-+ if (nl == NULL)
-+ {
-+ __set_errno (EINVAL);
-+ return -1;
-+ }
-+
-+ f = fopen (file, "r");
-+ if (f == NULL)
-+ return -1;
-+
-+ if (fread ((void *) &header, sizeof (header), 1, f) != 1)
-+ goto lose;
-+
-+ if (fseek (f, N_SYMOFF (header), SEEK_SET) != 0)
-+ goto lose;
-+
-+ symbols = (struct nlist *) __alloca (header.a_syms);
-+ nsymbols = header.a_syms / sizeof (symbols[0]);
-+
-+ if (fread ((void *) symbols, sizeof (symbols[0]), nsymbols, f) != nsymbols)
-+ goto lose;
-+
-+ if (fread ((void *) &string_table_size, sizeof (string_table_size), 1, f)
-+ != 1)
-+ goto lose;
-+ string_table_size -= sizeof (string_table_size);
-+
-+ string_table = (char *) __alloca (string_table_size);
-+ if (fread ((void *) string_table, string_table_size, 1, f) != 1)
-+ goto lose;
-+
-+ for (i = 0; i < nsymbols; ++i)
-+ {
-+ register struct nlist *nlp;
-+ for (nlp = nl; nlp->n_un.n_name != NULL; ++nlp)
-+ if (!strcmp (nlp->n_un.n_name,
-+ &string_table[symbols[i].n_un.n_strx -
-+ sizeof (string_table_size)]))
-+ {
-+ char *const name = nlp->n_un.n_name;
-+ *nlp = symbols[i];
-+ nlp->n_un.n_name = name;
-+ }
-+ }
-+
-+ (void) fclose (f);
-+ return 0;
-+
-+ lose:;
-+ (void) fclose (f);
-+ return -1;
-+}
-diff -Naur ../glibc-2.1.3/sysdeps/unix/sysv/linux/alpha/bits/types.h glibc-2.1.3/sysdeps/unix/sysv/linux/alpha/bits/types.h
---- ../glibc-2.1.3/sysdeps/unix/sysv/linux/alpha/bits/types.h 1999-12-21 15:52:15.000000000 -0800
-+++ glibc-2.1.3/sysdeps/unix/sysv/linux/alpha/bits/types.h 2000-01-21 10:20:54.000000000 -0800
-@@ -57,8 +57,8 @@
- typedef __int64_t __loff_t; /* Type of file sizes and offsets. */
- typedef __int32_t __pid_t; /* Type of process identifications. */
- typedef __int64_t __ssize_t; /* Type of a byte count, or error. */
--typedef __uint64_t __rlim_t; /* Type of resource counts. */
--typedef __uint64_t __rlim64_t; /* "" (LFS) */
-+typedef __int64_t __rlim_t; /* Type of resource counts. */
-+typedef __int64_t __rlim64_t; /* "" (LFS) */
- typedef __uint32_t __blkcnt_t; /* Type to count nr disk blocks. */
- typedef __uint64_t __blkcnt64_t; /* "" (LFS) */
- typedef __int32_t __fsblkcnt_t; /* Type to count file system blocks. */
-diff -Naur ../glibc-2.1.3/sysdeps/unix/sysv/linux/bits/types.h glibc-2.1.3/sysdeps/unix/sysv/linux/bits/types.h
---- ../glibc-2.1.3/sysdeps/unix/sysv/linux/bits/types.h 1999-12-21 15:52:16.000000000 -0800
-+++ glibc-2.1.3/sysdeps/unix/sysv/linux/bits/types.h 2000-01-21 10:20:54.000000000 -0800
-@@ -68,8 +68,8 @@
- typedef __quad_t __loff_t; /* Type of file sizes and offsets. */
- typedef int __pid_t; /* Type of process identifications. */
- typedef int __ssize_t; /* Type of a byte count, or error. */
--typedef __u_long __rlim_t; /* Type of resource counts. */
--typedef __u_quad_t __rlim64_t; /* Type of resource counts (LFS). */
-+typedef long int __rlim_t; /* Type of resource counts. */
-+typedef __quad_t __rlim64_t; /* Type of resource counts (LFS). */
- typedef __u_int __id_t; /* General type for ID. */
-
- typedef struct
-diff -Naur ../glibc-2.1.3/sysdeps/unix/sysv/linux/i386/bits/resource.h glibc-2.1.3/sysdeps/unix/sysv/linux/i386/bits/resource.h
---- ../glibc-2.1.3/sysdeps/unix/sysv/linux/i386/bits/resource.h 2000-01-25 20:09:30.000000000 -0800
-+++ glibc-2.1.3/sysdeps/unix/sysv/linux/i386/bits/resource.h 1969-12-31 16:00:00.000000000 -0800
-@@ -1,205 +0,0 @@
--/* Bit values & structures for resource limits. Linux version.
-- Copyright (C) 1994, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
-- This file is part of the GNU C Library.
--
-- The GNU C Library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Library General Public License as
-- published by the Free Software Foundation; either version 2 of the
-- License, or (at your option) any later version.
--
-- The GNU C Library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Library General Public License for more details.
--
-- You should have received a copy of the GNU Library General Public
-- License along with the GNU C Library; see the file COPYING.LIB. If not,
-- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-- Boston, MA 02111-1307, USA. */
--
--#ifndef _SYS_RESOURCE_H
--# error "Never use <bits/resource.h> directly; include <sys/resource.h> instead."
--#endif
--
--#include <bits/types.h>
--
--/* Transmute defines to enumerations. The macro re-definitions are
-- necessary because some programs want to test for operating system
-- features with #ifdef RUSAGE_SELF. In ISO C the reflexive
-- definition is a no-op. */
--
--/* Kinds of resource limit. */
--enum __rlimit_resource
--{
-- /* Per-process CPU limit, in seconds. */
-- RLIMIT_CPU = 0,
--#define RLIMIT_CPU RLIMIT_CPU
--
-- /* Largest file that can be created, in bytes. */
-- RLIMIT_FSIZE = 1,
--#define RLIMIT_FSIZE RLIMIT_FSIZE
--
-- /* Maximum size of data segment, in bytes. */
-- RLIMIT_DATA = 2,
--#define RLIMIT_DATA RLIMIT_DATA
--
-- /* Maximum size of stack segment, in bytes. */
-- RLIMIT_STACK = 3,
--#define RLIMIT_STACK RLIMIT_STACK
--
-- /* Largest core file that can be created, in bytes. */
-- RLIMIT_CORE = 4,
--#define RLIMIT_CORE RLIMIT_CORE
--
-- /* Largest resident set size, in bytes.
-- This affects swapping; processes that are exceeding their
-- resident set size will be more likely to have physical memory
-- taken from them. */
-- RLIMIT_RSS = 5,
--#define RLIMIT_RSS RLIMIT_RSS
--
-- /* Number of open files. */
-- RLIMIT_NOFILE = 7,
-- RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */
--#define RLIMIT_NOFILE RLIMIT_NOFILE
--#define RLIMIT_OFILE RLIMIT_OFILE
--
-- /* Address space limit. */
-- RLIMIT_AS = 9,
--#define RLIMIT_AS RLIMIT_AS
--
-- /* Number of processes. */
-- RLIMIT_NPROC = 6,
--#define RLIMIT_NPROC RLIMIT_NPROC
--
-- /* Locked-in-memory address space. */
-- RLIMIT_MEMLOCK = 8,
--#define RLIMIT_MEMLOCK RLIMIT_MEMLOCK
--
-- RLIMIT_NLIMITS = 10,
-- RLIM_NLIMITS = RLIMIT_NLIMITS
--#define RLIMIT_NLIMITS RLIMIT_NLIMITS
--#define RLIM_NLIMITS RLIM_NLIMITS
--};
--
--/* Value to indicate that there is no limit. */
--#ifndef __USE_FILE_OFFSET64
--# define RLIM_INFINITY ((long int) (~0UL >> 1))
--#else
--# define RLIM_INFINITY 0x7fffffffffffffffLL
--#endif
--
--#ifdef __USE_LARGEFILE64
--# define RLIM64_INFINITY 0x7fffffffffffffffLL
--#endif
--
--/* We can represent all limits. */
--#define RLIM_SAVED_MAX RLIM_INFINITY
--#define RLIM_SAVED_CUR RLIM_INFINITY
--
--
--/* Type for resource quantity measurement. */
--#ifndef __USE_FILE_OFFSET64
--typedef __rlim_t rlim_t;
--#else
--typedef __rlim64_t rlim_t;
--#endif
--#ifdef __USE_LARGEFILE64
--typedef __rlim64_t rlim64_t;
--#endif
--
--struct rlimit
-- {
-- /* The current (soft) limit. */
-- rlim_t rlim_cur;
-- /* The hard limit. */
-- rlim_t rlim_max;
-- };
--
--#ifdef __USE_LARGEFILE64
--struct rlimit64
-- {
-- /* The current (soft) limit. */
-- rlim64_t rlim_cur;
-- /* The hard limit. */
-- rlim64_t rlim_max;
-- };
--#endif
--
--/* Whose usage statistics do you want? */
--enum __rusage_who
--{
-- /* The calling process. */
-- RUSAGE_SELF = 0,
--#define RUSAGE_SELF RUSAGE_SELF
--
-- /* All of its terminated child processes. */
-- RUSAGE_CHILDREN = -1,
--#define RUSAGE_CHILDREN RUSAGE_CHILDREN
--
-- /* Both. */
-- RUSAGE_BOTH = -2
--#define RUSAGE_BOTH RUSAGE_BOTH
--};
--
--#define __need_timeval
--#include <bits/time.h> /* For `struct timeval'. */
--
--/* Structure which says how much of each resource has been used. */
--struct rusage
-- {
-- /* Total amount of user time used. */
-- struct timeval ru_utime;
-- /* Total amount of system time used. */
-- struct timeval ru_stime;
-- /* Maximum resident set size (in kilobytes). */
-- long int ru_maxrss;
-- /* Amount of sharing of text segment memory
-- with other processes (kilobyte-seconds). */
-- long int ru_ixrss;
-- /* Amount of data segment memory used (kilobyte-seconds). */
-- long int ru_idrss;
-- /* Amount of stack memory used (kilobyte-seconds). */
-- long int ru_isrss;
-- /* Number of soft page faults (i.e. those serviced by reclaiming
-- a page from the list of pages awaiting reallocation. */
-- long int ru_minflt;
-- /* Number of hard page faults (i.e. those that required I/O). */
-- long int ru_majflt;
-- /* Number of times a process was swapped out of physical memory. */
-- long int ru_nswap;
-- /* Number of input operations via the file system. Note: This
-- and `ru_oublock' do not include operations with the cache. */
-- long int ru_inblock;
-- /* Number of output operations via the file system. */
-- long int ru_oublock;
-- /* Number of IPC messages sent. */
-- long int ru_msgsnd;
-- /* Number of IPC messages received. */
-- long int ru_msgrcv;
-- /* Number of signals delivered. */
-- long int ru_nsignals;
-- /* Number of voluntary context switches, i.e. because the process
-- gave up the process before it had to (usually to wait for some
-- resource to be available). */
-- long int ru_nvcsw;
-- /* Number of involuntary context switches, i.e. a higher priority process
-- became runnable or the current process used up its time slice. */
-- long int ru_nivcsw;
-- };
--
--/* Priority limits. */
--#define PRIO_MIN -20 /* Minimum priority a process can have. */
--#define PRIO_MAX 20 /* Maximum priority a process can have. */
--
--/* The type of the WHICH argument to `getpriority' and `setpriority',
-- indicating what flavor of entity the WHO argument specifies. */
--enum __priority_which
--{
-- PRIO_PROCESS = 0, /* WHO is a process ID. */
--#define PRIO_PROCESS PRIO_PROCESS
-- PRIO_PGRP = 1, /* WHO is a process group ID. */
--#define PRIO_PGRP PRIO_PGRP
-- PRIO_USER = 2 /* WHO is a user ID. */
--#define PRIO_USER PRIO_USER
--};
-diff -Naur ../glibc-2.1.3/sysdeps/unix/sysv/linux/mips/bits/types.h glibc-2.1.3/sysdeps/unix/sysv/linux/mips/bits/types.h
---- ../glibc-2.1.3/sysdeps/unix/sysv/linux/mips/bits/types.h 1999-12-21 15:52:18.000000000 -0800
-+++ glibc-2.1.3/sysdeps/unix/sysv/linux/mips/bits/types.h 2000-01-21 10:20:54.000000000 -0800
-@@ -68,8 +68,8 @@
- typedef __quad_t __loff_t; /* Type of file sizes and offsets. */
- typedef int __pid_t; /* Type of process identifications. */
- typedef int __ssize_t; /* Type of a byte count, or error. */
--typedef __u_long __rlim_t; /* Type of resource counts. */
--typedef __u_quad_t __rlim64_t; /* Type of resource counts (LFS). */
-+typedef long int __rlim_t; /* Type of resource counts. */
-+typedef __quad_t __rlim64_t; /* Type of resource counts (LFS). */
- typedef __u_int __id_t; /* General type for ID. */
-
- typedef struct
-diff -Naur ../glibc-2.1.3/sysdeps/unix/sysv/linux/paths.h glibc-2.1.3/sysdeps/unix/sysv/linux/paths.h
---- ../glibc-2.1.3/sysdeps/unix/sysv/linux/paths.h 1998-08-12 10:05:51.000000000 -0700
-+++ glibc-2.1.3/sysdeps/unix/sysv/linux/paths.h 1999-12-27 08:34:12.000000000 -0800
-@@ -51,7 +51,7 @@
- #define _PATH_KLOG "/proc/kmsg"
- #define _PATH_KMEM "/dev/kmem"
- #define _PATH_LASTLOG "/var/log/lastlog"
--#define _PATH_MAILDIR "/var/mail"
-+#define _PATH_MAILDIR "/var/spool/mail"
- #define _PATH_MAN "/usr/man"
- #define _PATH_MEM "/dev/mem"
- #define _PATH_MNTTAB "/etc/fstab"
-@@ -63,9 +63,9 @@
- #define _PATH_SHADOW "/etc/shadow"
- #define _PATH_SHELLS "/etc/shells"
- #define _PATH_TTY "/dev/tty"
--#define _PATH_UNIX "/vmlinux"
-+#define _PATH_UNIX "/boot/vmlinux"
- #define _PATH_UTMP "/var/run/utmp"
--#define _PATH_VI "/usr/bin/vi"
-+#define _PATH_VI "/bin/vi"
- #define _PATH_WTMP "/var/log/wtmp"
-
- /* Provide trailing slash, since mostly used for building pathnames. */
-diff -Naur ../glibc-2.1.3/sysdeps/unix/sysv/linux/sparc/bits/types.h glibc-2.1.3/sysdeps/unix/sysv/linux/sparc/bits/types.h
---- ../glibc-2.1.3/sysdeps/unix/sysv/linux/sparc/bits/types.h 1999-12-21 15:52:19.000000000 -0800
-+++ glibc-2.1.3/sysdeps/unix/sysv/linux/sparc/bits/types.h 2000-01-21 10:20:54.000000000 -0800
-@@ -85,8 +85,8 @@
- #else
- typedef int __ssize_t; /* Type of a byte count, or error. */
- #endif
--typedef __u_long __rlim_t; /* Type of resource counts. */
--typedef __u_quad_t __rlim64_t; /* Type of resource counts (LFS). */
-+typedef long int __rlim_t; /* Type of resource counts. */
-+typedef __quad_t __rlim64_t; /* Type of resource counts (LFS). */
- typedef __u_int __id_t; /* General type for IDs. */
-
- typedef struct
-diff -Naur ../glibc-2.1.3/sysdeps/unix/sysv/linux/sparc/getsysstats.c glibc-2.1.3/sysdeps/unix/sysv/linux/sparc/getsysstats.c
---- ../glibc-2.1.3/sysdeps/unix/sysv/linux/sparc/getsysstats.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/sysdeps/unix/sysv/linux/sparc/getsysstats.c 2000-02-29 13:25:59.000000000 -0800
-@@ -0,0 +1,55 @@
-+/* Determine various system internal values, Linux/Sparc version.
-+ Copyright (C) 1999 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Andreas Schwab <schwab@suse.de> and
-+ Jakub Jelinek <jj@ultra.linux.cz>
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+
-+/* We need to define a special parser for /proc/cpuinfo. */
-+#define GET_NPROCS_PARSER(FP, BUFFER, RESULT) \
-+ do \
-+ { \
-+ (RESULT) = 0; \
-+ /* Find the line that contains the information about the number of \
-+ active cpus. We don't have to fear extremely long lines since \
-+ the kernel will not generate them. 8192 bytes are really \
-+ enough. */ \
-+ while (fgets_unlocked (BUFFER, sizeof (BUFFER), FP) != NULL) \
-+ if (sscanf (BUFFER, "ncpus active : %d", &(RESULT)) == 1) \
-+ break; \
-+ } \
-+ while (0)
-+
-+
-+/* On the Sparc we can distinguish between the number of configured and
-+ active cpus. */
-+#define GET_NPROCS_CONF_PARSER(FP, BUFFER, RESULT) \
-+ do \
-+ { \
-+ (RESULT) = 0; \
-+ /* Find the line that contains the information about the number of \
-+ probed cpus. We don't have to fear extremely long lines since \
-+ the kernel will not generate them. 8192 bytes are really \
-+ enough. */ \
-+ while (fgets_unlocked ((BUFFER), sizeof (BUFFER), (FP)) != NULL) \
-+ if (sscanf (buffer, "ncpus probed : %d", &(RESULT)) == 1) \
-+ break; \
-+ } \
-+ while (0)
-+
-+#include <sysdeps/unix/sysv/linux/getsysstats.c>
-diff -Naur ../glibc-2.1.3/sysdeps/unix/sysv/linux/sys/quota.h glibc-2.1.3/sysdeps/unix/sysv/linux/sys/quota.h
---- ../glibc-2.1.3/sysdeps/unix/sysv/linux/sys/quota.h 1998-10-05 06:40:12.000000000 -0700
-+++ glibc-2.1.3/sysdeps/unix/sysv/linux/sys/quota.h 1999-06-30 09:20:26.000000000 -0700
-@@ -35,7 +35,7 @@
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
-- * Version: $Id: quota.h,v 1.5 1998/10/05 13:40:12 drepper Exp $
-+ * Version: $Id: quota.h,v 1.1.1.1 1999/06/30 16:20:26 gafton Exp $
- */
-
- #ifndef _SYS_QUOTA_H
-diff -Naur ../glibc-2.1.3/time/ap.c glibc-2.1.3/time/ap.c
---- ../glibc-2.1.3/time/ap.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/time/ap.c 1998-02-07 12:39:22.000000000 -0800
-@@ -0,0 +1,45 @@
-+/* Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <time.h>
-+#include <malloc.h>
-+#include <mcheck.h>
-+
-+/* Prints the time in the form "hh:mm ?M", where ? is A or P.
-+ A simple test for strftime(). */
-+int
-+main (int argc, char *argv[])
-+{
-+ char buf[20];
-+ time_t t;
-+
-+ mcheck (NULL);
-+
-+ if (argc != 1)
-+ fprintf (stderr, "Usage: %s\n", argv[0]);
-+
-+ t = time ((time_t *) NULL);
-+ if (strftime (buf, sizeof (buf), "%I:%M %p", localtime (&t)) == 0)
-+ exit (EXIT_FAILURE);
-+
-+ puts (buf);
-+
-+ return EXIT_SUCCESS;
-+}
-diff -Naur ../glibc-2.1.3/time/date.c glibc-2.1.3/time/date.c
---- ../glibc-2.1.3/time/date.c 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/time/date.c 1998-02-07 12:39:31.000000000 -0800
-@@ -0,0 +1,49 @@
-+/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Library General Public License as
-+ published by the Free Software Foundation; either version 2 of the
-+ License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Library General Public License for more details.
-+
-+ You should have received a copy of the GNU Library General Public
-+ License along with the GNU C Library; see the file COPYING.LIB. If not,
-+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+#include <stddef.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <time.h>
-+
-+
-+/* Prints the date in the form "Day Mon dd hh:mm:ss ZZZ yyyy\n".
-+ A simple test for localtime and strftime. */
-+int
-+main (argc, argv)
-+ int argc;
-+ char **argv;
-+{
-+ time_t t = time (NULL);
-+ struct tm *tp = localtime (&t);
-+ char good = tp != NULL;
-+
-+ if (good)
-+ {
-+ char buf[BUFSIZ];
-+ good = strftime (buf, sizeof (buf), "%a %b %d %X %Z %Y", tp);
-+ if (good)
-+ puts (buf);
-+ else
-+ perror ("strftime");
-+ }
-+ else
-+ perror ("localtime");
-+
-+ return good ? EXIT_SUCCESS : EXIT_FAILURE;
-+}
-diff -Naur ../glibc-2.1.3/timezone/Makefile glibc-2.1.3/timezone/Makefile
---- ../glibc-2.1.3/timezone/Makefile 1999-05-05 04:32:09.000000000 -0700
-+++ glibc-2.1.3/timezone/Makefile 2000-02-14 15:34:01.000000000 -0800
-@@ -33,7 +33,7 @@
- tzbases := africa antarctica asia australasia europe northamerica \
- southamerica etcetera factory systemv \
- solar87 solar88 solar89
--tzlinks := backward
-+tzlinks := backward aliases
- tzfiles := $(tzbases) $(tzlinks)
- # pacificnew doesn't compile; if it is to be used, it should be included in
- # northamerica.
-diff -Naur ../glibc-2.1.3/timezone/aliases glibc-2.1.3/timezone/aliases
---- ../glibc-2.1.3/timezone/aliases 1969-12-31 16:00:00.000000000 -0800
-+++ glibc-2.1.3/timezone/aliases 2000-02-14 15:34:01.000000000 -0800
-@@ -0,0 +1,10 @@
-+# $Id: aliases,v 1.2 2000/02/14 23:34:01 gafton Exp $
-+
-+# this file contains timezone aliases people might care about. We do not
-+# add them to the backward file because we want to be able to clearly
-+# identify the ones that are not official timezones. It is better to
-+# maintain this list separately, because it is for the benefit of the user
-+# config tools only.
-+
-+Link Asia/Shanghai China/Shanghai
-+Link Asia/Shanghai China/Beijing