Dies ist die Info-Datei libc.info, hergestellt von Makeinfo Version
1.68 aus der Eingabe-Datei 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.07 DRAFT, last updated 4 Oct 1996, of `The GNU C
Library Reference Manual', for Version 2.00 Beta.

   Copyright (C) 1993, '94, '95, '96, '97 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: 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 set-user-ID 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 set-user-ID 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
saved 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>
     
     
     /* Save 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 = setuid (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 = setuid (ruid);
     #else
       status = setreuid (euid, ruid);
     #endif
       if (status < 0) {
         fprintf (stderr, "Couldn't set uid.\n");
         exit (status);
         }
     }
     
     /* Main program. */
     
     int
     main (void)
     {
       /* Save 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 original
effective 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.

   * Be cautious about using the `system' and `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.

   * 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 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::.).

   The `getlogin' function is declared in `unistd.h', while `cuserid'
and `L_cuserid' are declared in `stdio.h'.

 - Fonction: 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'.

 - Fonction: 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 it is already removed in 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; *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 Database,  Next: Group Database,  Prev: Who Logged In,  Up: Users and Groups

User Database
=============

   This section describes all about 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.

* Menü:

* 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,  Prev: User Database,  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'.

 - Fonction: 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.

 - Fonction: 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 is returns
     information about the user whose user ID is UID.  But the result
     is not placed in a static buffer.  Instead the user supplied
     structure pointed to by RESULT_BUF is filled with the information.
     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 the return value is `0' the pointer returned in RESULT points
     to the record which contains the wanted data (i.e., RESULT
     contains the value RESULT_BUF).  In case the return value is non
     null there is no user in the data base with user ID UID or the
     buffer BUFFER is too small to contain all the needed information.
     In the later case the global ERRNO variable is set to `ERANGE'.

 - Fonction: 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 value indicates there is no user named NAME.

 - Fonction: 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.  But the result
     is not placed in a static buffer.  Instead the user supplied
     structure pointed to by RESULT_BUF is filled with the information.
     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 the return value is `0' the pointer returned in RESULT points
     to the record which contains the wanted data (i.e., RESULT
     contains the value RESULT_BUF).  In case the return value is non
     null there is no user in the data base with user name NAME or the
     buffer BUFFER is too small to contain all the needed information.
     In the later case the global ERRNO variable is set to `ERANGE'.


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.

 - Fonction: 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.

     This stream must correspond to a file in the same format as the
     standard password database file.  This function comes from System
     V.

 - Fonction: 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.

     This stream must correspond to a file in the same format as the
     standard password database file.

     If the function returns null RESULT points to the structure with
     the wanted data (normally this is in RESULT_BUF).  If errors
     occurred the return value is non-null and RESULT contains a null
     pointer.

   The way to scan all the entries in the user database is with
`setpwent', `getpwent', and `endpwent'.

 - Fonction: void setpwent (void)
     This function initializes a stream which `getpwent' and
     `getpwent_r' use to read the user database.

 - Fonction: 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 in case no further entry is available.

 - Fonction: 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'.  But in contrast
     to the `getpwent' function this function is reentrant since the
     result is placed in the user supplied structure pointed to by
     RESULT_BUF.  Additional data, normally the strings pointed to by
     the elements of the result structure, are placed in the additional
     buffer or length BUFLEN starting at BUFFER.

     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.

 - Fonction: 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
--------------------

 - Fonction: 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: Netgroup Database,  Prev: User Database,  Up: Users and Groups

Group Database
==============

   This section describes all about 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.

* Menü:

* 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,  Prev: Group Database,  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'.

 - Fonction: 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.

 - Fonction: 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 is returns
     information about the group whose group ID is GID.  But the result
     is not placed in a static buffer.  Instead the user supplied
     structure pointed to by RESULT_BUF is filled with the information.
     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 the return value is `0' the pointer returned in RESULT points
     to the record which contains the wanted data (i.e., RESULT
     contains the value RESULT_BUF).  If the return value is non-zero
     there is no group in the data base with group ID GID or the buffer
     BUFFER is too small to contain all the needed information.  In the
     later case the global ERRNO variable is set to `ERANGE'.

 - Fonction: 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.

 - Fonction: 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.  But the
     result is not placed in a static buffer.  Instead the user
     supplied structure pointed to by RESULT_BUF is filled with the
     information.  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 the return value is `0' the pointer returned in RESULT points
     to the record which contains the wanted data (i.e., RESULT
     contains the value RESULT_BUF).  If the return value is non-zero
     there is no group in the data base with group name NAME or the
     buffer BUFFER is too small to contain all the needed information.
     In the later case the global ERRNO variable is set to `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.

 - Fonction: 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 rewritten 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.

 - Fonction: 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'.

 - Fonction: 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'.

 - Fonction: 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 rewritten on subsequent
     calls to `getgrent'.  You must copy the contents of the structure
     if you wish to save the information.

 - Fonction: 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'.  But in contrast
     to the `getgrent' function this function is reentrant since the
     result is placed in the user supplied structure pointed to by
     RESULT_BUF.  Additional data, normally the strings pointed to by
     the elements of the result structure, are placed in the additional
     buffer or length BUFLEN starting at BUFFER.

     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.

 - Fonction: void endgrent (void)
     This function closes the internal stream used by `getgrent' or
     `getgrent_r'.


File: libc.info,  Node: Netgroup Database,  Next: Database Example,  Prev: Group Database,  Up: Users and Groups

Netgroup Database
=================

* Menü:

* 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,  Prev: Netgroup Database,  Up: Netgroup Database

Netgroup Data
-------------

   Sometimes it is useful group users according to other criterias like
the ones used in the *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'.

 - Fonction: 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.

 - Fonction: 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.

 - Fonction: 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.

 - Fonction: 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.

 - Fonction: 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: Database Example,  Prev: Netgroup 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: 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.

* Menü:

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


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.

 - Fonction: 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.

 - Fonction: 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.

 - Fonction: 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.

 - Fonction: 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,  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"'

 - Fonction: 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: System Configuration,  Next: Language Features,  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::.).

* Menü:

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

