| This is libc.info, produced by makeinfo version 5.2 from libc.texinfo. |
| |
| This file documents the GNU C Library. |
| |
| This is 'The GNU C Library Reference Manual', for version 2.19 |
| (Buildroot). |
| |
| Copyright (C) 1993-2014 Free Software Foundation, Inc. |
| |
| Permission is granted to copy, distribute and/or modify this document |
| under the terms of the GNU Free Documentation License, Version 1.3 or |
| any later version published by the Free Software Foundation; with the |
| Invariant Sections being "Free Software Needs Free Documentation" and |
| "GNU Lesser General Public License", the Front-Cover texts being "A GNU |
| Manual", and with the Back-Cover Texts as in (a) below. A copy of the |
| license is included in the section entitled "GNU Free Documentation |
| License". |
| |
| (a) The FSF's Back-Cover Text is: "You have the freedom to copy and |
| modify this GNU manual. Buying copies from the FSF supports it in |
| developing GNU and promoting software freedom." |
| INFO-DIR-SECTION Software libraries |
| START-INFO-DIR-ENTRY |
| * Libc: (libc). C library. |
| END-INFO-DIR-ENTRY |
| |
| INFO-DIR-SECTION GNU C library functions and macros |
| START-INFO-DIR-ENTRY |
| * 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)Processor Time. |
| * CLOCAL: (libc)Control Modes. |
| * CLOCKS_PER_SEC: (libc)CPU Time. |
| * COLL_WEIGHTS_MAX: (libc)Utility Limits. |
| * CPU_CLR: (libc)CPU Affinity. |
| * CPU_ISSET: (libc)CPU Affinity. |
| * CPU_SET: (libc)CPU Affinity. |
| * CPU_SETSIZE: (libc)CPU Affinity. |
| * CPU_ZERO: (libc)CPU Affinity. |
| * 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. |
| * ECANCELED: (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. |
| * EHWPOISON: (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. |
| * EKEYEXPIRED: (libc)Error Codes. |
| * EKEYREJECTED: (libc)Error Codes. |
| * EKEYREVOKED: (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. |
| * ENOKEY: (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. |
| * ENOTRECOVERABLE: (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. |
| * EOWNERDEAD: (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. |
| * ERFKILL: (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. |
| * MAXSYMLINKS: (libc)Symbolic Links. |
| * 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_INET6: (libc)Internet Namespace. |
| * 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. |
| * S_TYPEISMQ: (libc)Testing File Type. |
| * S_TYPEISSEM: (libc)Testing File Type. |
| * S_TYPEISSHM: (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)EOF and Errors. |
| * 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. |
| * __fbufsize: (libc)Controlling Buffering. |
| * __flbf: (libc)Controlling Buffering. |
| * __fpending: (libc)Controlling Buffering. |
| * __fpurge: (libc)Flushing Buffers. |
| * __freadable: (libc)Opening Streams. |
| * __freading: (libc)Opening Streams. |
| * __fsetlocking: (libc)Streams and Threads. |
| * __fwritable: (libc)Opening Streams. |
| * __fwriting: (libc)Opening Streams. |
| * __gconv_end_fct: (libc)glibc iconv Implementation. |
| * __gconv_fct: (libc)glibc iconv Implementation. |
| * __gconv_init_fct: (libc)glibc iconv Implementation. |
| * __ppc_get_timebase: (libc)PowerPC. |
| * __ppc_get_timebase_freq: (libc)PowerPC. |
| * __ppc_mdoio: (libc)PowerPC. |
| * __ppc_mdoom: (libc)PowerPC. |
| * __ppc_set_ppr_low: (libc)PowerPC. |
| * __ppc_set_ppr_med: (libc)PowerPC. |
| * __ppc_set_ppr_med_low: (libc)PowerPC. |
| * __ppc_yield: (libc)PowerPC. |
| * __va_copy: (libc)Argument Macros. |
| * _exit: (libc)Termination Internals. |
| * _flushlbf: (libc)Flushing Buffers. |
| * _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)mtab. |
| * addseverity: (libc)Adding Severity Classes. |
| * adjtime: (libc)High-Resolution Calendar. |
| * adjtimex: (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. |
| * aligned_alloc: (libc)Aligned Memory Blocks. |
| * 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 Calendar Time. |
| * asctime_r: (libc)Formatting Calendar 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. |
| * backtrace: (libc)Backtraces. |
| * backtrace_symbols: (libc)Backtraces. |
| * backtrace_symbols_fd: (libc)Backtraces. |
| * basename: (libc)Finding Tokens in a String. |
| * basename: (libc)Finding Tokens in a String. |
| * bcmp: (libc)String/Array Comparison. |
| * bcopy: (libc)Copying and Concatenation. |
| * bind: (libc)Setting Address. |
| * bind_textdomain_codeset: (libc)Charset conversion in gettext. |
| * bindtextdomain: (libc)Locating gettext catalog. |
| * brk: (libc)Resizing the Data Segment. |
| * 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. |
| * canonicalize_file_name: (libc)Symbolic Links. |
| * 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)Error Recovery. |
| * clearerr_unlocked: (libc)Error Recovery. |
| * clock: (libc)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. |
| * closelog: (libc)closelog. |
| * 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 Calendar Time. |
| * ctime_r: (libc)Formatting Calendar Time. |
| * cuserid: (libc)Who Logged In. |
| * dcgettext: (libc)Translation with gettext. |
| * dcngettext: (libc)Advanced gettext functions. |
| * des_setparity: (libc)DES Encryption. |
| * dgettext: (libc)Translation with gettext. |
| * difftime: (libc)Elapsed Time. |
| * dirfd: (libc)Opening a Directory. |
| * dirname: (libc)Finding Tokens in a String. |
| * div: (libc)Integer Division. |
| * dngettext: (libc)Advanced gettext functions. |
| * 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)fstab. |
| * endgrent: (libc)Scanning All Groups. |
| * endhostent: (libc)Host Names. |
| * endmntent: (libc)mtab. |
| * 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. |
| * err: (libc)Error Messages. |
| * errno: (libc)Checking for Errors. |
| * error: (libc)Error Messages. |
| * error_at_line: (libc)Error Messages. |
| * errx: (libc)Error Messages. |
| * 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. |
| * fchdir: (libc)Working Directory. |
| * fchmod: (libc)Setting Permissions. |
| * fchown: (libc)File Owner. |
| * 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. |
| * fdopendir: (libc)Opening a Directory. |
| * feclearexcept: (libc)Status bit operations. |
| * fedisableexcept: (libc)Control Functions. |
| * feenableexcept: (libc)Control Functions. |
| * fegetenv: (libc)Control Functions. |
| * fegetexcept: (libc)Control Functions. |
| * fegetexceptflag: (libc)Status bit operations. |
| * fegetround: (libc)Rounding. |
| * feholdexcept: (libc)Control Functions. |
| * feof: (libc)EOF and Errors. |
| * feof_unlocked: (libc)EOF and Errors. |
| * feraiseexcept: (libc)Status bit operations. |
| * ferror: (libc)EOF and Errors. |
| * ferror_unlocked: (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. |
| * fflush_unlocked: (libc)Flushing Buffers. |
| * fgetc: (libc)Character Input. |
| * fgetc_unlocked: (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. |
| * fgets_unlocked: (libc)Line Input. |
| * fgetwc: (libc)Character Input. |
| * fgetwc_unlocked: (libc)Character Input. |
| * fgetws: (libc)Line Input. |
| * fgetws_unlocked: (libc)Line Input. |
| * fileno: (libc)Descriptors and Streams. |
| * fileno_unlocked: (libc)Descriptors and Streams. |
| * finite: (libc)Floating Point Classes. |
| * finitef: (libc)Floating Point Classes. |
| * finitel: (libc)Floating Point Classes. |
| * flockfile: (libc)Streams and Threads. |
| * 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. |
| * fputc_unlocked: (libc)Simple Output. |
| * fputs: (libc)Simple Output. |
| * fputs_unlocked: (libc)Simple Output. |
| * fputwc: (libc)Simple Output. |
| * fputwc_unlocked: (libc)Simple Output. |
| * fputws: (libc)Simple Output. |
| * fputws_unlocked: (libc)Simple Output. |
| * fread: (libc)Block Input/Output. |
| * fread_unlocked: (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)File Size. |
| * ftruncate: (libc)File Size. |
| * ftrylockfile: (libc)Streams and Threads. |
| * ftw64: (libc)Working with Directory Trees. |
| * ftw: (libc)Working with Directory Trees. |
| * funlockfile: (libc)Streams and Threads. |
| * futimes: (libc)File Times. |
| * fwide: (libc)Streams and I18N. |
| * fwprintf: (libc)Formatted Output Functions. |
| * fwrite: (libc)Block Input/Output. |
| * fwrite_unlocked: (libc)Block Input/Output. |
| * fwscanf: (libc)Formatted Input Functions. |
| * gamma: (libc)Special Functions. |
| * gammaf: (libc)Special Functions. |
| * gammal: (libc)Special Functions. |
| * gcvt: (libc)System V Number Conversion. |
| * get_avphys_pages: (libc)Query Memory Parameters. |
| * get_current_dir_name: (libc)Working Directory. |
| * get_nprocs: (libc)Processor Resources. |
| * get_nprocs_conf: (libc)Processor Resources. |
| * get_phys_pages: (libc)Query Memory Parameters. |
| * getauxval: (libc)Auxiliary Vector. |
| * getc: (libc)Character Input. |
| * getc_unlocked: (libc)Character Input. |
| * getchar: (libc)Character Input. |
| * getchar_unlocked: (libc)Character Input. |
| * getcontext: (libc)System V contexts. |
| * getcwd: (libc)Working Directory. |
| * getdate: (libc)General Time String Parsing. |
| * getdate_r: (libc)General Time String Parsing. |
| * getdelim: (libc)Line Input. |
| * getdomainnname: (libc)Host Identification. |
| * getegid: (libc)Reading Persona. |
| * getenv: (libc)Environment Access. |
| * geteuid: (libc)Reading Persona. |
| * getfsent: (libc)fstab. |
| * getfsfile: (libc)fstab. |
| * getfsspec: (libc)fstab. |
| * 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. |
| * getgrouplist: (libc)Setting Groups. |
| * 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. |
| * getloadavg: (libc)Processor Resources. |
| * getlogin: (libc)Who Logged In. |
| * getmntent: (libc)mtab. |
| * getmntent_r: (libc)mtab. |
| * 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. |
| * getopt_long_only: (libc)Getopt Long Options. |
| * getpagesize: (libc)Query Memory Parameters. |
| * getpass: (libc)getpass. |
| * getpeername: (libc)Who is Connected. |
| * getpgid: (libc)Process Group Functions. |
| * getpgrp: (libc)Process Group Functions. |
| * getpid: (libc)Process Identification. |
| * getppid: (libc)Process Identification. |
| * getpriority: (libc)Traditional Scheduling Functions. |
| * 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. |
| * getutmp: (libc)XPG Functions. |
| * getutmpx: (libc)XPG Functions. |
| * getutxent: (libc)XPG Functions. |
| * getutxid: (libc)XPG Functions. |
| * getutxline: (libc)XPG Functions. |
| * getw: (libc)Character Input. |
| * getwc: (libc)Character Input. |
| * getwc_unlocked: (libc)Character Input. |
| * getwchar: (libc)Character Input. |
| * getwchar_unlocked: (libc)Character Input. |
| * getwd: (libc)Working Directory. |
| * glob64: (libc)Calling Glob. |
| * glob: (libc)Calling Glob. |
| * globfree64: (libc)More Flags for Globbing. |
| * globfree: (libc)More Flags for Globbing. |
| * gmtime: (libc)Broken-down Time. |
| * gmtime_r: (libc)Broken-down Time. |
| * grantpt: (libc)Allocation. |
| * gsignal: (libc)Signaling Yourself. |
| * gtty: (libc)BSD Terminal Modes. |
| * hasmntopt: (libc)mtab. |
| * 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. |
| * initgroups: (libc)Setting Groups. |
| * initstate: (libc)BSD Random. |
| * initstate_r: (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. |
| * issignaling: (libc)Floating Point Classes. |
| * 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. |
| * logbf: (libc)Exponents and Logarithms. |
| * logbl: (libc)Exponents and Logarithms. |
| * 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. |
| * lutimes: (libc)File Times. |
| * madvise: (libc)Memory-mapped I/O. |
| * makecontext: (libc)System V contexts. |
| * 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. |
| * memfrob: (libc)Trivial Encryption. |
| * memmem: (libc)Search Functions. |
| * memmove: (libc)Copying and Concatenation. |
| * mempcpy: (libc)Copying and Concatenation. |
| * memrchr: (libc)Search Functions. |
| * memset: (libc)Copying and Concatenation. |
| * mkdir: (libc)Creating Directories. |
| * mkdtemp: (libc)Temporary Files. |
| * mkfifo: (libc)FIFO Special Files. |
| * mknod: (libc)Making Special Files. |
| * mkstemp: (libc)Temporary Files. |
| * mktemp: (libc)Temporary Files. |
| * mktime: (libc)Broken-down Time. |
| * mlock: (libc)Page Lock Functions. |
| * mlockall: (libc)Page Lock Functions. |
| * mmap64: (libc)Memory-mapped I/O. |
| * mmap: (libc)Memory-mapped I/O. |
| * modf: (libc)Rounding Functions. |
| * modff: (libc)Rounding Functions. |
| * modfl: (libc)Rounding Functions. |
| * mount: (libc)Mount-Unmount-Remount. |
| * 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. |
| * munlock: (libc)Page Lock Functions. |
| * munlockall: (libc)Page Lock Functions. |
| * 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 with Directory Trees. |
| * nftw: (libc)Working with Directory Trees. |
| * ngettext: (libc)Advanced gettext functions. |
| * nice: (libc)Traditional Scheduling Functions. |
| * 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)High Accuracy Clock. |
| * ntp_gettime: (libc)High Accuracy Clock. |
| * 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. |
| * opendir: (libc)Opening a Directory. |
| * openlog: (libc)openlog. |
| * 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. |
| * posix_memalign: (libc)Aligned Memory Blocks. |
| * 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_getattr_default_np: (libc)Default Thread Attributes. |
| * pthread_getspecific: (libc)Thread-specific Data. |
| * pthread_key_create: (libc)Thread-specific Data. |
| * pthread_key_delete: (libc)Thread-specific Data. |
| * pthread_setattr_default_np: (libc)Default Thread Attributes. |
| * pthread_setspecific: (libc)Thread-specific Data. |
| * ptsname: (libc)Allocation. |
| * ptsname_r: (libc)Allocation. |
| * putc: (libc)Simple Output. |
| * putc_unlocked: (libc)Simple Output. |
| * putchar: (libc)Simple Output. |
| * putchar_unlocked: (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. |
| * putwc: (libc)Simple Output. |
| * putwc_unlocked: (libc)Simple Output. |
| * putwchar: (libc)Simple Output. |
| * putwchar_unlocked: (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. |
| * random_r: (libc)BSD Random. |
| * rawmemchr: (libc)Search Functions. |
| * read: (libc)I/O Primitives. |
| * readdir64: (libc)Reading/Closing Directory. |
| * readdir64_r: (libc)Reading/Closing Directory. |
| * readdir: (libc)Reading/Closing Directory. |
| * readdir_r: (libc)Reading/Closing Directory. |
| * readlink: (libc)Symbolic Links. |
| * readv: (libc)Scatter-Gather. |
| * realloc: (libc)Changing Block Size. |
| * realpath: (libc)Symbolic Links. |
| * 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. |
| * rpmatch: (libc)Yes-or-No Questions. |
| * sbrk: (libc)Resizing the Data Segment. |
| * 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. |
| * sched_get_priority_max: (libc)Basic Scheduling Functions. |
| * sched_get_priority_min: (libc)Basic Scheduling Functions. |
| * sched_getaffinity: (libc)CPU Affinity. |
| * sched_getparam: (libc)Basic Scheduling Functions. |
| * sched_getscheduler: (libc)Basic Scheduling Functions. |
| * sched_rr_get_interval: (libc)Basic Scheduling Functions. |
| * sched_setaffinity: (libc)CPU Affinity. |
| * sched_setparam: (libc)Basic Scheduling Functions. |
| * sched_setscheduler: (libc)Basic Scheduling Functions. |
| * sched_yield: (libc)Basic Scheduling Functions. |
| * secure_getenv: (libc)Environment Access. |
| * seed48: (libc)SVID Random. |
| * seed48_r: (libc)SVID Random. |
| * seekdir: (libc)Random Access Directory. |
| * select: (libc)Waiting for I/O. |
| * send: (libc)Sending Data. |
| * sendmsg: (libc)Receiving Datagrams. |
| * sendto: (libc)Sending Datagrams. |
| * setbuf: (libc)Controlling Buffering. |
| * setbuffer: (libc)Controlling Buffering. |
| * setcontext: (libc)System V contexts. |
| * setdomainname: (libc)Host Identification. |
| * setegid: (libc)Setting Groups. |
| * setenv: (libc)Environment Access. |
| * seteuid: (libc)Setting User ID. |
| * setfsent: (libc)fstab. |
| * 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. |
| * setlogmask: (libc)setlogmask. |
| * setmntent: (libc)mtab. |
| * setnetent: (libc)Networks Database. |
| * setnetgrent: (libc)Lookup Netgroup. |
| * setpgid: (libc)Process Group Functions. |
| * setpgrp: (libc)Process Group Functions. |
| * setpriority: (libc)Traditional Scheduling Functions. |
| * 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. |
| * setstate_r: (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. |
| * shm_open: (libc)Memory-mapped I/O. |
| * shm_unlink: (libc)Memory-mapped I/O. |
| * 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. |
| * 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. |
| * srandom_r: (libc)BSD Random. |
| * sscanf: (libc)Formatted Input Functions. |
| * ssignal: (libc)Basic Signal Handling. |
| * stat64: (libc)Reading Attributes. |
| * stat: (libc)Reading Attributes. |
| * stime: (libc)Simple Calendar Time. |
| * stpcpy: (libc)Copying and Concatenation. |
| * stpncpy: (libc)Copying and Concatenation. |
| * strcasecmp: (libc)String/Array Comparison. |
| * strcasestr: (libc)Search Functions. |
| * strcat: (libc)Copying and Concatenation. |
| * strchr: (libc)Search Functions. |
| * strchrnul: (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. |
| * strfry: (libc)strfry. |
| * strftime: (libc)Formatting Calendar 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. |
| * strtoimax: (libc)Parsing of Integers. |
| * 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. |
| * strtoumax: (libc)Parsing of Integers. |
| * strtouq: (libc)Parsing of Integers. |
| * strverscmp: (libc)String/Array Comparison. |
| * strxfrm: (libc)Collation Functions. |
| * stty: (libc)BSD Terminal Modes. |
| * swapcontext: (libc)System V contexts. |
| * swprintf: (libc)Formatted Output Functions. |
| * swscanf: (libc)Formatted Input Functions. |
| * symlink: (libc)Symbolic Links. |
| * sync: (libc)Synchronizing I/O. |
| * syscall: (libc)System Calls. |
| * sysconf: (libc)Sysconf Definition. |
| * sysctl: (libc)System Parameters. |
| * syslog: (libc)syslog; vsyslog. |
| * 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. |
| * timegm: (libc)Broken-down Time. |
| * timelocal: (libc)Broken-down Time. |
| * times: (libc)Processor 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)File Size. |
| * truncate: (libc)File Size. |
| * 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. |
| * ulimit: (libc)Limits on Resources. |
| * umask: (libc)Setting Permissions. |
| * umount2: (libc)Mount-Unmount-Remount. |
| * umount: (libc)Mount-Unmount-Remount. |
| * uname: (libc)Platform Type. |
| * ungetc: (libc)How Unread. |
| * ungetwc: (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. |
| * utmpxname: (libc)XPG Functions. |
| * va_arg: (libc)Argument Macros. |
| * va_copy: (libc)Argument Macros. |
| * va_end: (libc)Argument Macros. |
| * va_start: (libc)Argument Macros. |
| * valloc: (libc)Aligned Memory Blocks. |
| * vasprintf: (libc)Variable Arguments Output. |
| * verr: (libc)Error Messages. |
| * verrx: (libc)Error Messages. |
| * 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. |
| * vfwprintf: (libc)Variable Arguments Output. |
| * vfwscanf: (libc)Variable Arguments Input. |
| * vlimit: (libc)Limits on Resources. |
| * 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. |
| * vswprintf: (libc)Variable Arguments Output. |
| * vswscanf: (libc)Variable Arguments Input. |
| * vsyslog: (libc)syslog; vsyslog. |
| * vtimes: (libc)Resource Usage. |
| * vwarn: (libc)Error Messages. |
| * vwarnx: (libc)Error Messages. |
| * vwprintf: (libc)Variable Arguments Output. |
| * vwscanf: (libc)Variable Arguments Input. |
| * wait3: (libc)BSD Wait Functions. |
| * wait4: (libc)Process Completion. |
| * wait: (libc)Process Completion. |
| * waitpid: (libc)Process Completion. |
| * warn: (libc)Error Messages. |
| * warnx: (libc)Error Messages. |
| * wcpcpy: (libc)Copying and Concatenation. |
| * wcpncpy: (libc)Copying and Concatenation. |
| * wcrtomb: (libc)Converting a Character. |
| * wcscasecmp: (libc)String/Array Comparison. |
| * wcscat: (libc)Copying and Concatenation. |
| * wcschr: (libc)Search Functions. |
| * wcschrnul: (libc)Search Functions. |
| * wcscmp: (libc)String/Array Comparison. |
| * wcscoll: (libc)Collation Functions. |
| * wcscpy: (libc)Copying and Concatenation. |
| * wcscspn: (libc)Search Functions. |
| * wcsdup: (libc)Copying and Concatenation. |
| * wcsftime: (libc)Formatting Calendar Time. |
| * wcslen: (libc)String Length. |
| * wcsncasecmp: (libc)String/Array Comparison. |
| * wcsncat: (libc)Copying and Concatenation. |
| * wcsncmp: (libc)String/Array Comparison. |
| * wcsncpy: (libc)Copying and Concatenation. |
| * wcsnlen: (libc)String Length. |
| * wcsnrtombs: (libc)Converting Strings. |
| * wcspbrk: (libc)Search Functions. |
| * wcsrchr: (libc)Search Functions. |
| * wcsrtombs: (libc)Converting Strings. |
| * wcsspn: (libc)Search Functions. |
| * wcsstr: (libc)Search Functions. |
| * wcstod: (libc)Parsing of Floats. |
| * wcstof: (libc)Parsing of Floats. |
| * wcstoimax: (libc)Parsing of Integers. |
| * wcstok: (libc)Finding Tokens in a String. |
| * wcstol: (libc)Parsing of Integers. |
| * wcstold: (libc)Parsing of Floats. |
| * wcstoll: (libc)Parsing of Integers. |
| * wcstombs: (libc)Non-reentrant String Conversion. |
| * wcstoq: (libc)Parsing of Integers. |
| * wcstoul: (libc)Parsing of Integers. |
| * wcstoull: (libc)Parsing of Integers. |
| * wcstoumax: (libc)Parsing of Integers. |
| * wcstouq: (libc)Parsing of Integers. |
| * wcswcs: (libc)Search Functions. |
| * wcsxfrm: (libc)Collation Functions. |
| * wctob: (libc)Converting a Character. |
| * wctomb: (libc)Non-reentrant Character Conversion. |
| * wctrans: (libc)Wide Character Case Conversion. |
| * wctype: (libc)Classification of Wide Characters. |
| * wmemchr: (libc)Search Functions. |
| * wmemcmp: (libc)String/Array Comparison. |
| * wmemcpy: (libc)Copying and Concatenation. |
| * wmemmove: (libc)Copying and Concatenation. |
| * wmempcpy: (libc)Copying and Concatenation. |
| * wmemset: (libc)Copying and Concatenation. |
| * wordexp: (libc)Calling Wordexp. |
| * wordfree: (libc)Calling Wordexp. |
| * wprintf: (libc)Formatted Output Functions. |
| * write: (libc)I/O Primitives. |
| * writev: (libc)Scatter-Gather. |
| * wscanf: (libc)Formatted Input Functions. |
| * 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 |
| |
| |
| File: libc.info, Node: Argp Examples, Next: Argp User Customization, Prev: Argp Help, Up: Argp |
| |
| 25.3.11 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 |
| |
| 25.3.11.1 A Minimal Program Using Argp |
| ...................................... |
| |
| This is perhaps the smallest program possible that uses argp. It won't |
| do much except give an error messages and exit when there are any |
| arguments, and prints a rather pointless message for '--help'. |
| |
| |
| /* 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 <stdlib.h> |
| #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 |
| |
| 25.3.11.2 A Program Using Argp with Only Default Options |
| ........................................................ |
| |
| This program doesn't use any options or arguments, it uses argp to be |
| compliant with the GNU standard command line format. |
| |
| In addition to giving no arguments and implementing a '--help' |
| option, this example has a '--version' option, which 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 normally used, but they are |
| not in this small program. There are also two global variables that |
| argp can use defined here, 'argp_program_version' and |
| 'argp_program_bug_address'. They are considered global variables |
| because they will almost always be constant for a given program, even if |
| they use different argument parsers for various tasks. |
| |
| |
| /* 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). */ |
| |
| #include <stdlib.h> |
| #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 argument 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 |
| |
| 25.3.11.3 A Program Using Argp with User Options |
| ................................................ |
| |
| This program uses the same features as example 2, adding user options |
| and arguments. |
| |
| We now use the first four fields in 'argp' (*note Argp Parsers::) and |
| specify '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::. It 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. |
| |
| |
| /* 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 arguments 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 <stdlib.h> |
| #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 |
| |
| 25.3.11.4 A Program Using Multiple Combined Argp Parsers |
| ........................................................ |
| |
| This program uses the same features as example 3, but has more options, |
| and presents more structure in the '--help' output. It also illustrates |
| how you can 'steal' the remainder of the input arguments past a certain |
| point for programs that accept a list of items. It also illustrates the |
| 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 help output, two features are used: _headers_ and a |
| two part option string. The _headers_ are entries in the options |
| vector. *Note Argp Option Vectors::. The first four fields are zero. |
| The two part documentation string are 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 a short string stating what the program does, and |
| after any options it 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. |
| In addition, documentation strings are passed to the 'gettext' function, |
| for possible translation into the current locale. |
| |
| |
| /* 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 documentation 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); |
| } |
| |
| |
| File: libc.info, Node: Argp User Customization, Prev: Argp Examples, Up: Argp |
| |
| 25.3.12 Argp User Customization |
| ------------------------------- |
| |
| The 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 of tokens. Whitespace is ignored: |
| |
| 'dup-args' |
| 'no-dup-args' |
| These turn "duplicate-argument-mode" on or off. In duplicate |
| argument mode, if an option that accepts an argument has multiple |
| names, the argument is shown for each name. Otherwise, it is only |
| shown for the first long option. A note is subsequently printed so |
| the user knows that it applies to other names as well. The default |
| is 'no-dup-args', which is less consistent, but prettier. |
| |
| 'dup-args-note' |
| 'no-dup-args-note' |
| These will enable or disable the note informing the user of |
| suppressed option argument duplication. The default is |
| 'dup-args-note'. |
| |
| 'short-opt-col=N' |
| This prints the first short option in column N. The default is 2. |
| |
| 'long-opt-col=N' |
| This prints the first long option in column N. The default is 6. |
| |
| 'doc-opt-col=N' |
| This prints 'documentation options' (*note Argp Option Flags::) in |
| column N. The default is 2. |
| |
| 'opt-doc-col=N' |
| This prints the documentation for options starting in column N. |
| The default is 29. |
| |
| 'header-col=N' |
| This will indent the group headers that document groups of options |
| to column N. The default is 1. |
| |
| 'usage-indent=N' |
| This will indent continuation lines in 'Usage:' messages to column |
| N. The default is 12. |
| |
| 'rmargin=N' |
| This will word wrap help output at or before column N. The default |
| is 79. |
| |
| |
| File: libc.info, Node: Suboptions, Next: Suboptions Example, Prev: Argp, Up: Parsing Program Arguments |
| |
| 25.3.12.1 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, char *const *TOKENS, char |
| **VALUEP) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 |
| |
| 25.3.13 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> |
| #include <unistd.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, |
| THE_END |
| }; |
| |
| const char *mount_opts[] = |
| { |
| [RO_OPTION] = "ro", |
| [RW_OPTION] = "rw", |
| [READ_SIZE_OPTION] = "rsize", |
| [WRITE_SIZE_OPTION] = "wsize", |
| [THE_END] = NULL |
| }; |
| |
| 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: Auxiliary Vector, Prev: Program Arguments, Up: Program Basics |
| |
| 25.4 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 |
| |
| 25.4.1 Environment Access |
| ------------------------- |
| |
| The value of an environment variable can be accessed with the 'getenv' |
| function. This is declared in the header file 'stdlib.h'. |
| |
| Libraries should use 'secure_getenv' instead of 'getenv', so that |
| they do not accidentally use untrusted environment variables. |
| Modifications of environment variables are not allowed in multi-threaded |
| programs. The 'getenv' and 'secure_getenv' functions can be safely used |
| in multi-threaded programs. |
| |
| -- Function: char * getenv (const char *NAME) |
| Preliminary: | MT-Safe env | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 C 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: char * secure_getenv (const char *NAME) |
| Preliminary: | MT-Safe env | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| This function is similar to 'getenv', but it returns a null pointer |
| if the environment is untrusted. This happens when the program |
| file has SUID or SGID bits set. General-purpose libraries should |
| always prefer this function over 'getenv' to avoid vulnerabilities |
| if the library is referenced from a SUID/SGID program. |
| |
| This function is a GNU extension. |
| |
| -- Function: int putenv (char *STRING) |
| Preliminary: | MT-Unsafe const:env | AS-Unsafe heap lock | |
| AC-Unsafe corrupt lock mem | *Note POSIX Safety Concepts::. |
| |
| 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. |
| |
| If the function is successful it returns '0'. Otherwise the return |
| value is nonzero and 'errno' is set to indicate the error. |
| |
| The difference to the 'setenv' function is that the exact string |
| given as the parameter STRING is put into the environment. If the |
| user should change the string after the 'putenv' call this will |
| reflect automatically in the environment. This also requires that |
| STRING not be an automatic variable whose scope is left before the |
| variable is removed from the environment. The same applies of |
| course to dynamically allocated variables which are freed later. |
| |
| 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) |
| Preliminary: | MT-Unsafe const:env | AS-Unsafe heap lock | |
| AC-Unsafe corrupt lock mem | *Note POSIX Safety Concepts::. |
| |
| 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. To do this a new string is created and the strings |
| NAME and VALUE are copied. 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. |
| |
| If the function is successful it returns '0'. Otherwise the |
| environment is unchanged and the return value is '-1' and 'errno' |
| is set. |
| |
| This function was originally part of the BSD library but is now |
| part of the Unix standard. |
| |
| -- Function: int unsetenv (const char *NAME) |
| Preliminary: | MT-Unsafe const:env | AS-Unsafe lock | AC-Unsafe |
| lock | *Note POSIX Safety Concepts::. |
| |
| 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. |
| |
| The function return '-1' if NAME is a null pointer, points to an |
| empty string, or points to a string containing a '=' character. It |
| returns '0' if the call succeeded. |
| |
| This function was originally part of the BSD library but is now |
| part of the Unix standard. The BSD version had no return value, |
| though. |
| |
| 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) |
| Preliminary: | MT-Unsafe const:env | AS-Unsafe heap lock | |
| AC-Unsafe lock mem | *Note POSIX Safety Concepts::. |
| |
| 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 GNU systems, 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 |
| |
| 25.4.2 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 program; 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: Auxiliary Vector, Next: System Calls, Prev: Environment Variables, Up: Program Basics |
| |
| 25.5 Auxiliary Vector |
| ===================== |
| |
| When a program is executed, it receives information from the operating |
| system about the environment in which it is operating. The form of this |
| information is a table of key-value pairs, where the keys are from the |
| set of 'AT_' values in 'elf.h'. Some of the data is provided by the |
| kernel for libc consumption, and may be obtained by ordinary interfaces, |
| such as 'sysconf'. However, on a platform-by-platform basis there may |
| be information that is not available any other way. |
| |
| 25.5.1 Definition of 'getauxval' |
| -------------------------------- |
| |
| -- Function: unsigned long int getauxval (unsigned long int TYPE) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| This function is used to inquire about the entries in the auxiliary |
| vector. The TYPE argument should be one of the 'AT_' symbols |
| defined in 'elf.h'. If a matching entry is found, the value is |
| returned; if the entry is not found, zero is returned and 'errno' |
| is set to 'ENOENT'. |
| |
| For some platforms, the key 'AT_HWCAP' is the easiest way to inquire |
| about any instruction set extensions available at runtime. In this |
| case, there will (of necessity) be a platform-specific set of 'HWCAP_' |
| values masked together that describe the capabilities of the cpu on |
| which the program is being executed. |
| |
| |
| File: libc.info, Node: System Calls, Next: Program Termination, Prev: Auxiliary Vector, Up: Program Basics |
| |
| 25.6 System Calls |
| ================= |
| |
| A system call is a request for service that a program makes of the |
| kernel. The service is generally something that only the kernel has the |
| privilege to do, such as doing I/O. Programmers don't normally need to |
| be concerned with system calls because there are functions in the GNU C |
| Library to do virtually everything that system calls do. These |
| functions work by making system calls themselves. For example, there is |
| a system call that changes the permissions of a file, but you don't need |
| to know about it because you can just use the GNU C Library's 'chmod' |
| function. |
| |
| System calls are sometimes called kernel calls. |
| |
| However, there are times when you want to make a system call |
| explicitly, and for that, the GNU C Library provides the 'syscall' |
| function. 'syscall' is harder to use and less portable than functions |
| like 'chmod', but easier and more portable than coding the system call |
| in assembler instructions. |
| |
| 'syscall' is most useful when you are working with a system call |
| which is special to your system or is newer than the GNU C Library you |
| are using. 'syscall' is implemented in an entirely generic way; the |
| function does not know anything about what a particular system call does |
| or even if it is valid. |
| |
| The description of 'syscall' in this section assumes a certain |
| protocol for system calls on the various platforms on which the GNU C |
| Library runs. That protocol is not defined by any strong authority, but |
| we won't describe it here either because anyone who is coding 'syscall' |
| probably won't accept anything less than kernel and C library source |
| code as a specification of the interface between them anyway. |
| |
| 'syscall' is declared in 'unistd.h'. |
| |
| -- Function: long int syscall (long int SYSNO, ...) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 'syscall' performs a generic system call. |
| |
| SYSNO is the system call number. Each kind of system call is |
| identified by a number. Macros for all the possible system call |
| numbers are defined in 'sys/syscall.h' |
| |
| The remaining arguments are the arguments for the system call, in |
| order, and their meanings depend on the kind of system call. Each |
| kind of system call has a definite number of arguments, from zero |
| to five. If you code more arguments than the system call takes, |
| the extra ones to the right are ignored. |
| |
| The return value is the return value from the system call, unless |
| the system call failed. In that case, 'syscall' returns '-1' and |
| sets 'errno' to an error code that the system call returned. Note |
| that system calls do not return '-1' when they succeed. |
| |
| If you specify an invalid SYSNO, 'syscall' returns '-1' with |
| 'errno' = 'ENOSYS'. |
| |
| Example: |
| |
| |
| #include <unistd.h> |
| #include <sys/syscall.h> |
| #include <errno.h> |
| |
| ... |
| |
| int rc; |
| |
| rc = syscall(SYS_chmod, "/etc/passwd", 0444); |
| |
| if (rc == -1) |
| fprintf(stderr, "chmod failed, errno = %d\n", errno); |
| |
| |
| This, if all the compatibility stars are aligned, is equivalent to |
| the following preferable code: |
| |
| |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <errno.h> |
| |
| ... |
| |
| int rc; |
| |
| rc = chmod("/etc/passwd", 0444); |
| if (rc == -1) |
| fprintf(stderr, "chmod failed, errno = %d\n", errno); |
| |
| |
| |
| File: libc.info, Node: Program Termination, Prev: System Calls, Up: Program Basics |
| |
| 25.7 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 |
| |
| 25.7.1 Normal Termination |
| ------------------------- |
| |
| A process terminates normally when its program signals it is done by |
| calling '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) |
| Preliminary: | MT-Unsafe race:exit | AS-Unsafe corrupt | AC-Unsafe |
| corrupt lock | *Note POSIX Safety Concepts::. |
| |
| The 'exit' function tells the system that the program is done, |
| which causes it to terminate the process. |
| |
| STATUS is the program's exit status, which becomes part of the |
| process' termination 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 |
| |
| 25.7.2 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. |
| |
| Don't confuse a program's exit status with a process' termination |
| status. There are lots of ways a process can terminate besides having |
| its program finish. In the event that the process termination _is_ |
| caused by program termination (i.e., 'exit'), though, the program's exit |
| status becomes part of the process' termination status. |
| |
| |
| File: libc.info, Node: Cleanups on Exit, Next: Aborting a Program, Prev: Exit Status, Up: Program Termination |
| |
| 25.7.3 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)) |
| Preliminary: | MT-Safe | AS-Unsafe heap lock | AC-Unsafe lock mem | |
| *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Unsafe heap lock | AC-Unsafe lock mem | |
| *Note POSIX Safety Concepts::. |
| |
| 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 |
| |
| 25.7.4 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) |
| Preliminary: | MT-Safe | AS-Unsafe corrupt | AC-Unsafe lock corrupt |
| | *Note POSIX Safety Concepts::. |
| |
| 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 |
| |
| 25.7.5 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 C99 and is declared in |
| 'stdlib.h'. |
| |
| When a process terminates for any reason--either because the program |
| terminates, or 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::. |
| |
| * A process exit status is saved to be reported back to the parent |
| process via 'wait' or 'waitpid'; see *note Process Completion::. |
| If the program exited, this status includes as its low-order 8 bits |
| the program exit status. |
| |
| * 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: Program Basics, Up: Top |
| |
| 26 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 |
| |
| 26.1 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) |
| Preliminary: | MT-Safe | AS-Unsafe plugin heap lock | AC-Unsafe |
| lock mem | *Note POSIX Safety Concepts::. |
| |
| 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 return value of zero |
| indicates that no command processor is available. |
| |
| This function is a cancellation 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 cancellation 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 |
| |
| 26.2 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 |
| |
| 26.3 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 C Library, this is an 'int'. |
| |
| -- Function: pid_t getpid (void) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| The 'getpid' function returns the process ID of the current |
| process. |
| |
| -- Function: pid_t getppid (void) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 |
| |
| 26.4 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) |
| Preliminary: | MT-Safe | AS-Unsafe plugin | AC-Unsafe lock | *Note |
| POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Unsafe plugin | AC-Unsafe lock | *Note |
| POSIX Safety Concepts::. |
| |
| 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 |
| |
| 26.5 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. |
| |
| To see the effects of 'exec' from the point of view of the called |
| program, see *note Program Basics::. |
| |
| 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[]) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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, ...) |
| Preliminary: | MT-Safe | AS-Unsafe heap | AC-Unsafe mem | *Note |
| POSIX Safety Concepts::. |
| |
| 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[]) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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[]) |
| Preliminary: | MT-Safe | AS-Unsafe heap | AC-Unsafe mem | *Note |
| POSIX Safety Concepts::. |
| |
| 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[]) |
| Preliminary: | MT-Safe env | AS-Unsafe heap | AC-Unsafe mem | *Note |
| POSIX Safety Concepts::. |
| |
| 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, ...) |
| Preliminary: | MT-Safe env | AS-Unsafe heap | AC-Unsafe mem | *Note |
| POSIX Safety Concepts::. |
| |
| 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::. On |
| GNU/Hurd systems, 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. GNU/Hurd systems |
| have 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::. On GNU/Hurd systems, 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::). |
| |
| |
| File: libc.info, Node: Process Completion, Next: Process Completion Status, Prev: Executing a File, Up: Processes |
| |
| 26.6 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 cancellation 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 cancellation 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 cancellation 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 cancellation handlers. |
| |
| -- Function: pid_t wait4 (pid_t PID, int *STATUS-PTR, int OPTIONS, |
| struct rusage *USAGE) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 |
| |
| 26.7 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| This macro returns a nonzero value if the child process terminated |
| normally with 'exit' or '_exit'. |
| |
| -- Macro: int WEXITSTATUS (int STATUS) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| This macro returns a nonzero value if the child process terminated |
| and produced a core dump. |
| |
| -- Macro: int WIFSTOPPED (int STATUS) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| This macro returns a nonzero value if the child process is stopped. |
| |
| -- Macro: int WSTOPSIG (int STATUS) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 |
| |
| 26.8 BSD Process Wait Functions |
| =============================== |
| |
| The GNU C 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 |
| |
| 26.9 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 |
| |
| 27 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 |
| |
| 27.1 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 |
| |
| 27.2 Job Control is Optional |
| ============================ |
| |
| Not all operating systems support job control. GNU systems do support |
| job control, but if you are using the GNU C 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 |
| |
| 27.3 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 |
| |
| 27.4 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 |
| |
| 27.5 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 |
| |
| 27.6 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 |
| |
| 27.6.1 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 |
| |
| 27.6.2 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 |
| |
| 27.6.3 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 |
| |
| 27.6.4 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 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 |
| |
| 27.6.5 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 |
| |
| 27.6.6 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 |
| |
| 27.6.7 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 |
| |
| 27.7 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 |
| |
| 27.7.1 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 C 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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::. |
| |
| |
| File: libc.info, Node: Process Group Functions, Next: Terminal Access Functions, Prev: Identifying the Terminal, Up: Functions for Job Control |
| |
| 27.7.2 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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. |
| |
| -- Function: pid_t getpgrp (void) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| The 'getpgrp' function returns the process group ID of the calling |
| process. |
| |
| -- Function: int getpgid (pid_t PID) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| The 'getpgid' function 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 |
| |
| 27.7.3 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| This function is used to obtain the process group ID of the session |
| for which the 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 is not the controlling terminal. |
| |
| |
| File: libc.info, Node: Name Service Switch, Next: Users and Groups, Prev: Job Control, Up: Top |
| |
| 28 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. |
| |
| 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. The 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 |
| |
| 28.1 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 the 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 |
| |
| 28.2 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 |
| |
| 28.2.1 Services in the NSS configuration File |
| --------------------------------------------- |
| |
| The above example file mentions five different services: 'files', 'db', |
| 'dns', '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 |
| |
| 28.2.2 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 |
| |
| 28.2.3 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 definitive. |
| |
| 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 |
| |
| 28.3 NSS Module Internals |
| ========================= |
| |
| Now it is time to describe what 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 |
| |
| 28.3.1 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 themselves. This is _not_ true at the moment, though. |
| However, the 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 this information is duplicated. The answer |
| is that we want to make it possible 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 don't tell this to anybody. |
| |
| |
| File: libc.info, Node: NSS Modules Interface, Prev: NSS Module Names, Up: NSS Module Internals |
| |
| 28.3.2 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 of the 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 explained 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 |
| data 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 |
| |
| 28.4 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 |
| |
| 28.4.1 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 the 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 programs (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 |
| |
| 28.4.2 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 much more we can say 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 there 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 honor 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 Management, Prev: Name Service Switch, Up: Top |
| |
| 29 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 |
| |
| 29.1 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 |
| |
| 29.2 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 |
| |
| 29.3 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 |
| |
| 29.4 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 |
| |
| 29.5 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 C 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 C Library, this is an alias for 'unsigned int'. |
| |
| -- Function: uid_t getuid (void) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| The 'getuid' function returns the real user ID of the process. |
| |
| -- Function: gid_t getgid (void) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| The 'getgid' function returns the real group ID of the process. |
| |
| -- Function: uid_t geteuid (void) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| The 'geteuid' function returns the effective user ID of the |
| process. |
| |
| -- Function: gid_t getegid (void) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| The 'getegid' function returns the effective group ID of the |
| process. |
| |
| -- Function: int getgroups (int COUNT, gid_t *GROUPS) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 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 |
| |
| 29.6 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) |
| Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock | *Note |
| POSIX Safety Concepts::. |
| |
| This function sets the effective user ID of a process to NEWEUID, |
| 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 NEWEUID 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) |
| Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock | *Note |
| POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock | *Note |
| POSIX Safety Concepts::. |
| |
| 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. |
| |
| |
| File: libc.info, Node: Setting Groups, Next: Enable/Disable Setuid, Prev: Setting User ID, Up: Users and Groups |
| |
| 29.7 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) |
| Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock | *Note |
| POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock | *Note |
| POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock | *Note |
| POSIX Safety Concepts::. |
| |
| 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, const gid_t *GROUPS) |
| Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock | *Note |
| POSIX Safety Concepts::. |
| |
| 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 GROUP) |
| Preliminary: | MT-Safe locale | AS-Unsafe dlopen plugin heap lock | |
| AC-Unsafe corrupt mem fd lock | *Note POSIX Safety Concepts::. |
| |
| The 'initgroups' function sets the process's supplementary group |
| IDs to be the normal default for the user name USER. The group |
| GROUP is automatically included. |
| |
| 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'. |
| |
| If you are interested in the groups a particular user belongs to, but |
| do not want to change the process's supplementary group IDs, you can use |
| 'getgrouplist'. To use 'getgrouplist', your programs should include the |
| header file 'grp.h'. |
| |
| -- Function: int getgrouplist (const char *USER, gid_t GROUP, gid_t |
| *GROUPS, int *NGROUPS) |
| Preliminary: | MT-Safe locale | AS-Unsafe dlopen plugin heap lock | |
| AC-Unsafe corrupt mem fd lock | *Note POSIX Safety Concepts::. |
| |
| The 'getgrouplist' function scans the group database for all the |
| groups USER belongs to. Up to *NGROUPS group IDs corresponding to |
| these groups are stored in the array GROUPS; the return value from |
| the function is the number of group IDs actually stored. If |
| *NGROUPS is smaller than the total number of groups found, then |
| 'getgrouplist' returns a value of '-1' and stores the actual number |
| of groups in *NGROUPS. The group GROUP is automatically included |
| in the list of groups returned by 'getgrouplist'. |
| |
| Here's how to use 'getgrouplist' to read all supplementary groups |
| for USER: |
| |
| gid_t * |
| supplementary_groups (char *user) |
| { |
| int ngroups = 16; |
| gid_t *groups |
| = (gid_t *) xmalloc (ngroups * sizeof (gid_t)); |
| struct passwd *pw = getpwnam (user); |
| |
| if (pw == NULL) |
| return NULL; |
| |
| if (getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups) < 0) |
| { |
| groups = xrealloc (ngroups * sizeof (gid_t)); |
| getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups); |
| } |
| return groups; |
| } |
| |
| |
| File: libc.info, Node: Enable/Disable Setuid, Next: Setuid Program Example, Prev: Setting Groups, Up: Users and Groups |
| |
| 29.8 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 |
| seteuid (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 |
| |
| 29.9 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 |
| |
| 29.10 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 |
| |
| 29.11 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) |
| Preliminary: | MT-Unsafe race:getlogin race:utent sig:ALRM timer |
| locale | AS-Unsafe dlopen plugin heap lock | AC-Unsafe corrupt lock |
| fd mem | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe locale | AS-Unsafe dlopen plugin heap lock | |
| AC-Unsafe corrupt lock fd mem | *Note POSIX Safety Concepts::. |
| |
| 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 |
| |
| 29.12 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 |
| |
| 29.12.1 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 GNU systems 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) |
| Preliminary: | MT-Unsafe race:utent | AS-Unsafe lock | AC-Unsafe |
| lock fd | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe init race:utent race:utentbuf sig:ALRM |
| timer | AS-Unsafe heap lock | AC-Unsafe lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:utent | AS-Unsafe lock | AC-Unsafe |
| lock fd | *Note POSIX Safety Concepts::. |
| |
| This function closes the user accounting database. |
| |
| -- Function: struct utmp * getutid (const struct utmp *ID) |
| Preliminary: | MT-Unsafe init race:utent sig:ALRM timer | AS-Unsafe |
| lock heap | AC-Unsafe lock mem fd | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe init race:utent sig:ALRM timer | AS-Unsafe |
| heap lock | AC-Unsafe lock fd mem | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:utent sig:ALRM timer | AS-Unsafe lock |
| | AC-Unsafe lock fd | *Note POSIX Safety Concepts::. |
| |
| 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 returned for the request is overwritten by 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) |
| Preliminary: | MT-Unsafe race:utent sig:ALRM timer | AS-Unsafe lock |
| | AC-Unsafe lock fd | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:utent sig:ALRM timer | AS-Unsafe lock |
| | AC-Unsafe lock fd | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:utent sig:ALRM timer | AS-Unsafe lock |
| | AC-Unsafe lock fd | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:utent | AS-Unsafe lock heap | |
| AC-Unsafe lock mem | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe sig:ALRM timer | AS-Unsafe | AC-Unsafe fd |
| | *Note POSIX Safety Concepts::. |
| |
| 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 C Library, 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 |
| |
| 29.12.2 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. |
| In the GNU C Library, '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, in the GNU C Library, 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) |
| Preliminary: | MT-Unsafe race:utent | AS-Unsafe lock | AC-Unsafe |
| lock fd | *Note POSIX Safety Concepts::. |
| |
| This function is similar to 'setutent'. In the GNU C Library it is |
| simply an alias for 'setutent'. |
| |
| -- Function: struct utmpx * getutxent (void) |
| Preliminary: | MT-Unsafe init race:utent sig:ALRM timer | AS-Unsafe |
| heap lock | AC-Unsafe lock fd mem | *Note POSIX Safety Concepts::. |
| |
| The 'getutxent' function is similar to 'getutent', but returns a |
| pointer to a 'struct utmpx' instead of 'struct utmp'. In the GNU C |
| Library it simply is an alias for 'getutent'. |
| |
| -- Function: void endutxent (void) |
| Preliminary: | MT-Unsafe race:utent | AS-Unsafe lock | AC-Unsafe |
| lock | *Note POSIX Safety Concepts::. |
| |
| This function is similar to 'endutent'. In the GNU C Library it is |
| simply an alias for 'endutent'. |
| |
| -- Function: struct utmpx * getutxid (const struct utmpx *ID) |
| Preliminary: | MT-Unsafe init race:utent sig:ALRM timer | AS-Unsafe |
| lock heap | AC-Unsafe lock mem fd | *Note POSIX Safety Concepts::. |
| |
| This function is similar to 'getutid', but uses 'struct utmpx' |
| instead of 'struct utmp'. In the GNU C Library it is simply an |
| alias for 'getutid'. |
| |
| -- Function: struct utmpx * getutxline (const struct utmpx *LINE) |
| Preliminary: | MT-Unsafe init race:utent sig:ALRM timer | AS-Unsafe |
| heap lock | AC-Unsafe lock fd mem | *Note POSIX Safety Concepts::. |
| |
| This function is similar to 'getutid', but uses 'struct utmpx' |
| instead of 'struct utmp'. In the GNU C Library it is simply an |
| alias for 'getutline'. |
| |
| -- Function: struct utmpx * pututxline (const struct utmpx *UTMP) |
| Preliminary: | MT-Unsafe race:utent sig:ALRM timer | AS-Unsafe lock |
| | AC-Unsafe lock fd | *Note POSIX Safety Concepts::. |
| |
| The 'pututxline' function is functionally identical to 'pututline', |
| but uses 'struct utmpx' instead of 'struct utmp'. In the GNU C |
| Library, 'pututxline' is simply an alias for 'pututline'. |
| |
| -- Function: int utmpxname (const char *FILE) |
| Preliminary: | MT-Unsafe race:utent | AS-Unsafe lock heap | |
| AC-Unsafe lock mem | *Note POSIX Safety Concepts::. |
| |
| The 'utmpxname' function is functionally identical to 'utmpname'. |
| In the GNU C Library, 'utmpxname' is simply an alias for |
| 'utmpname'. |
| |
| You can translate between a traditional 'struct utmp' and an XPG |
| 'struct utmpx' with the following functions. In the GNU C Library, |
| these functions are merely copies, since the two structures are |
| identical. |
| |
| -- Function: int getutmp (const struct utmpx *UTMPX, struct utmp *UTMP) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 'getutmp' copies the information, insofar as the structures are |
| compatible, from UTMPX to UTMP. |
| |
| -- Function: int getutmpx (const struct utmp *UTMP, struct utmpx |
| *UTMPX) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| 'getutmpx' copies the information, insofar as the structures are |
| compatible, from UTMP to UTMPX. |
| |
| |
| File: libc.info, Node: Logging In and Out, Prev: XPG Functions, Up: User Accounting Database |
| |
| 29.12.3 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) |
| Preliminary: | MT-Unsafe race:ttyname | AS-Unsafe heap lock | |
| AC-Unsafe lock fd mem | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:utent sig:ALRM timer | AS-Unsafe lock |
| heap | AC-Unsafe lock corrupt fd mem | *Note POSIX Safety |
| Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:utent sig:ALRM timer | AS-Unsafe lock |
| heap | AC-Unsafe lock fd mem | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe sig:ALRM timer | AS-Unsafe | AC-Unsafe fd |
| | *Note POSIX Safety Concepts::. |
| |
| 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 |
| |
| 29.13 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 |
| |
| 29.13.1 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 |
| |
| 29.13.2 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) |
| Preliminary: | MT-Unsafe race:pwuid locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe locale | AS-Unsafe dlopen plugin heap lock | |
| AC-Unsafe corrupt lock fd mem | *Note POSIX Safety Concepts::. |
| |
| 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 |
| occurred, 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) |
| Preliminary: | MT-Unsafe race:pwnam locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe locale | AS-Unsafe dlopen plugin heap lock | |
| AC-Unsafe corrupt lock fd mem | *Note POSIX Safety Concepts::. |
| |
| 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 |
| |
| 29.13.3 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) |
| Preliminary: | MT-Unsafe race:fpwent | AS-Unsafe corrupt lock | |
| AC-Unsafe corrupt lock | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Unsafe corrupt | AC-Unsafe corrupt lock |
| | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:pwent locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| This function initializes a stream which 'getpwent' and |
| 'getpwent_r' use to read the user database. |
| |
| -- Function: struct passwd * getpwent (void) |
| Preliminary: | MT-Unsafe race:pwent race:pwentbuf locale | |
| AS-Unsafe dlopen plugin heap lock | AC-Unsafe corrupt lock fd mem | |
| *Note POSIX Safety Concepts::. |
| |
| 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, |
| size_t BUFLEN, struct passwd **RESULT) |
| Preliminary: | MT-Unsafe race:pwent locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:pwent locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| 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 |
| |
| 29.13.4 Writing a User Entry |
| ---------------------------- |
| |
| -- Function: int putpwent (const struct passwd *P, FILE *STREAM) |
| Preliminary: | MT-Safe locale | AS-Unsafe corrupt | AC-Unsafe lock |
| corrupt | *Note POSIX Safety Concepts::. |
| |
| 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 group and user ID fields are left empty if the group or user |
| name starts with a - or +. |
| |
| The function 'putpwent' is declared in 'pwd.h'. |
| |
| |
| File: libc.info, Node: Group Database, Next: Database Example, Prev: User Database, Up: Users and Groups |
| |
| 29.14 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 |
| |
| 29.14.1 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 |
| |
| 29.14.2 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) |
| Preliminary: | MT-Unsafe race:grgid locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe locale | AS-Unsafe dlopen plugin heap lock | |
| AC-Unsafe corrupt lock fd mem | *Note POSIX Safety Concepts::. |
| |
| 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 occurred, 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) |
| Preliminary: | MT-Unsafe race:grnam locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe locale | AS-Unsafe dlopen plugin heap lock | |
| AC-Unsafe corrupt lock fd mem | *Note POSIX Safety Concepts::. |
| |
| 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 |
| |
| 29.14.3 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) |
| Preliminary: | MT-Unsafe race:fgrent | AS-Unsafe corrupt lock | |
| AC-Unsafe corrupt lock | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Safe | AS-Unsafe corrupt | AC-Unsafe corrupt lock |
| | *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:grent locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:grent race:grentbuf locale | |
| AS-Unsafe dlopen plugin heap lock | AC-Unsafe corrupt lock fd mem | |
| *Note POSIX Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:grent locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| 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) |
| Preliminary: | MT-Unsafe race:grent locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| This function closes the internal stream used by 'getgrent' or |
| 'getgrent_r'. |
| |
| |
| File: libc.info, Node: Database Example, Next: Netgroup Database, Prev: Group Database, Up: Users and Groups |
| |
| 29.15 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 |
| |