| This is |
| /usr/local/google/home/jnewlin/src/uclibc/buildroot/output/build/glibc-2.19/build/manual/libc.info, |
| produced by makeinfo version 4.13 from libc.texinfo. |
| |
| 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 |
| |
| 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." |
| |
| |
| File: libc.info, Node: Getopt Long Option Example, Prev: Getopt Long Options, Up: Getopt |
| |
| 25.2.4 Example of Parsing Long Options with `getopt_long' |
| --------------------------------------------------------- |
| |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <getopt.h> |
| |
| /* Flag set by `--verbose'. */ |
| static int verbose_flag; |
| |
| int |
| main (int argc, char **argv) |
| { |
| int c; |
| |
| while (1) |
| { |
| static struct option long_options[] = |
| { |
| /* These options set a flag. */ |
| {"verbose", no_argument, &verbose_flag, 1}, |
| {"brief", no_argument, &verbose_flag, 0}, |
| /* These options don't set a flag. |
| We distinguish them by their indices. */ |
| {"add", no_argument, 0, 'a'}, |
| {"append", no_argument, 0, 'b'}, |
| {"delete", required_argument, 0, 'd'}, |
| {"create", required_argument, 0, 'c'}, |
| {"file", required_argument, 0, 'f'}, |
| {0, 0, 0, 0} |
| }; |
| /* `getopt_long' stores the option index here. */ |
| int option_index = 0; |
| |
| c = getopt_long (argc, argv, "abc:d:f:", |
| long_options, &option_index); |
| |
| /* Detect the end of the options. */ |
| if (c == -1) |
| break; |
| |
| switch (c) |
| { |
| case 0: |
| /* If this option set a flag, do nothing else now. */ |
| if (long_options[option_index].flag != 0) |
| break; |
| printf ("option %s", long_options[option_index].name); |
| if (optarg) |
| printf (" with arg %s", optarg); |
| printf ("\n"); |
| break; |
| |
| case 'a': |
| puts ("option -a\n"); |
| break; |
| |
| case 'b': |
| puts ("option -b\n"); |
| break; |
| |
| case 'c': |
| printf ("option -c with value `%s'\n", optarg); |
| break; |
| |
| case 'd': |
| printf ("option -d with value `%s'\n", optarg); |
| break; |
| |
| case 'f': |
| printf ("option -f with value `%s'\n", optarg); |
| break; |
| |
| case '?': |
| /* `getopt_long' already printed an error message. */ |
| break; |
| |
| default: |
| abort (); |
| } |
| } |
| |
| /* Instead of reporting `--verbose' |
| and `--brief' as they are encountered, |
| we report the final status resulting from them. */ |
| if (verbose_flag) |
| puts ("verbose flag is set"); |
| |
| /* Print any remaining command line arguments (not options). */ |
| if (optind < argc) |
| { |
| printf ("non-option ARGV-elements: "); |
| while (optind < argc) |
| printf ("%s ", argv[optind++]); |
| putchar ('\n'); |
| } |
| |
| exit (0); |
| } |
| |
| |
| File: libc.info, Node: Argp, Next: Suboptions, Prev: Getopt, Up: Parsing Program Arguments |
| |
| 25.3 Parsing Program Options with Argp |
| ====================================== |
| |
| "Argp" is an interface for parsing unix-style argument vectors. *Note |
| Program Arguments::. |
| |
| Argp provides features unavailable in the more commonly used |
| `getopt' interface. These features include automatically producing |
| output in response to the `--help' and `--version' options, as |
| described in the GNU coding standards. Using argp makes it less likely |
| that programmers will neglect to implement these additional options or |
| keep them up to date. |
| |
| Argp also provides the ability to merge several independently defined |
| option parsers into one, mediating conflicts between them and making the |
| result appear seamless. A library can export an argp option parser that |
| user programs might employ in conjunction with their own option parsers, |
| resulting in less work for the user programs. Some programs may use |
| only argument parsers exported by libraries, thereby achieving |
| consistent and efficient option-parsing for abstractions implemented by |
| the libraries. |
| |
| The header file `<argp.h>' should be included to use argp. |
| |
| 25.3.1 The `argp_parse' Function |
| -------------------------------- |
| |
| The main interface to argp is the `argp_parse' function. In many |
| cases, calling `argp_parse' is the only argument-parsing code needed in |
| `main'. *Note Program Arguments::. |
| |
| -- Function: error_t argp_parse (const struct argp *ARGP, int ARGC, |
| char **ARGV, unsigned FLAGS, int *ARG_INDEX, void *INPUT) |
| Preliminary: | MT-Unsafe race:argpbuf locale env | AS-Unsafe heap |
| i18n lock corrupt | AC-Unsafe mem lock corrupt | *Note POSIX |
| Safety Concepts::. |
| |
| The `argp_parse' function parses the arguments in ARGV, of length |
| ARGC, using the argp parser ARGP. *Note Argp Parsers::. Passing |
| a null pointer for ARGP is the same as using a `struct argp' |
| containing all zeros. |
| |
| FLAGS is a set of flag bits that modify the parsing behavior. |
| *Note Argp Flags::. INPUT is passed through to the argp parser |
| ARGP, and has meaning defined by ARGP. A typical usage is to pass |
| a pointer to a structure which is used for specifying parameters |
| to the parser and passing back the results. |
| |
| Unless the `ARGP_NO_EXIT' or `ARGP_NO_HELP' flags are included in |
| FLAGS, calling `argp_parse' may result in the program exiting. |
| This behavior is true if an error is detected, or when an unknown |
| option is encountered. *Note Program Termination::. |
| |
| If ARG_INDEX is non-null, the index of the first unparsed option |
| in ARGV is returned as a value. |
| |
| The return value is zero for successful parsing, or an error code |
| (*note Error Codes::) if an error is detected. Different argp |
| parsers may return arbitrary error codes, but the standard error |
| codes are: `ENOMEM' if a memory allocation error occurred, or |
| `EINVAL' if an unknown option or option argument is encountered. |
| |
| * Menu: |
| |
| * Globals: Argp Global Variables. Global argp parameters. |
| * Parsers: Argp Parsers. Defining parsers for use with `argp_parse'. |
| * Flags: Argp Flags. Flags that modify the behavior of `argp_parse'. |
| * Help: Argp Help. Printing help messages when not parsing. |
| * Examples: Argp Examples. Simple examples of programs using argp. |
| * Customization: Argp User Customization. |
| Users may control the `--help' output format. |
| |
| |
| File: libc.info, Node: Argp Global Variables, Next: Argp Parsers, Up: Argp |
| |
| 25.3.2 Argp Global Variables |
| ---------------------------- |
| |
| These variables make it easy for user programs to implement the |
| `--version' option and provide a bug-reporting address in the `--help' |
| output. These are implemented in argp by default. |
| |
| -- Variable: const char * argp_program_version |
| If defined or set by the user program to a non-zero value, then a |
| `--version' option is added when parsing with `argp_parse', which |
| will print the `--version' string followed by a newline and exit. |
| The exception to this is if the `ARGP_NO_EXIT' flag is used. |
| |
| -- Variable: const char * argp_program_bug_address |
| If defined or set by the user program to a non-zero value, |
| `argp_program_bug_address' should point to a string that will be |
| printed at the end of the standard output for the `--help' option, |
| embedded in a sentence that says `Report bugs to ADDRESS.'. |
| |
| -- Variable: argp_program_version_hook |
| If defined or set by the user program to a non-zero value, a |
| `--version' option is added when parsing with `arg_parse', which |
| prints the program version and exits with a status of zero. This |
| is not the case if the `ARGP_NO_HELP' flag is used. If the |
| `ARGP_NO_EXIT' flag is set, the exit behavior of the program is |
| suppressed or modified, as when the argp parser is going to be |
| used by other programs. |
| |
| It should point to a function with this type of signature: |
| |
| void PRINT-VERSION (FILE *STREAM, struct argp_state *STATE) |
| |
| *Note Argp Parsing State::, for an explanation of STATE. |
| |
| This variable takes precedence over `argp_program_version', and is |
| useful if a program has version information not easily expressed |
| in a simple string. |
| |
| -- Variable: error_t argp_err_exit_status |
| This is the exit status used when argp exits due to a parsing |
| error. If not defined or set by the user program, this defaults |
| to: `EX_USAGE' from `<sysexits.h>'. |
| |
| |
| File: libc.info, Node: Argp Parsers, Next: Argp Flags, Prev: Argp Global Variables, Up: Argp |
| |
| 25.3.3 Specifying Argp Parsers |
| ------------------------------ |
| |
| The first argument to the `argp_parse' function is a pointer to a |
| `struct argp', which is known as an "argp parser": |
| |
| -- Data Type: struct argp |
| This structure specifies how to parse a given set of options and |
| arguments, perhaps in conjunction with other argp parsers. It has |
| the following fields: |
| |
| `const struct argp_option *options' |
| A pointer to a vector of `argp_option' structures specifying |
| which options this argp parser understands; it may be zero if |
| there are no options at all. *Note Argp Option Vectors::. |
| |
| `argp_parser_t parser' |
| A pointer to a function that defines actions for this parser; |
| it is called for each option parsed, and at other |
| well-defined points in the parsing process. A value of zero |
| is the same as a pointer to a function that always returns |
| `ARGP_ERR_UNKNOWN'. *Note Argp Parser Functions::. |
| |
| `const char *args_doc' |
| If non-zero, a string describing what non-option arguments |
| are called by this parser. This is only used to print the |
| `Usage:' message. If it contains newlines, the strings |
| separated by them are considered alternative usage patterns |
| and printed on separate lines. Lines after the first are |
| prefixed by ` or: ' instead of `Usage:'. |
| |
| `const char *doc' |
| If non-zero, a string containing extra text to be printed |
| before and after the options in a long help message, with the |
| two sections separated by a vertical tab (`'\v'', `'\013'') |
| character. By convention, the documentation before the |
| options is just a short string explaining what the program |
| does. Documentation printed after the options describe |
| behavior in more detail. |
| |
| `const struct argp_child *children' |
| A pointer to a vector of `argp_children' structures. This |
| pointer specifies which additional argp parsers should be |
| combined with this one. *Note Argp Children::. |
| |
| `char *(*help_filter)(int KEY, const char *TEXT, void *INPUT)' |
| If non-zero, a pointer to a function that filters the output |
| of help messages. *Note Argp Help Filtering::. |
| |
| `const char *argp_domain' |
| If non-zero, the strings used in the argp library are |
| translated using the domain described by this string. If |
| zero, the current default domain is used. |
| |
| |
| Of the above group, `options', `parser', `args_doc', and the `doc' |
| fields are usually all that are needed. If an argp parser is defined |
| as an initialized C variable, only the fields used need be specified in |
| the initializer. The rest will default to zero due to the way C |
| structure initialization works. This design is exploited in most argp |
| structures; the most-used fields are grouped near the beginning, the |
| unused fields left unspecified. |
| |
| * Menu: |
| |
| * Options: Argp Option Vectors. Specifying options in an argp parser. |
| * Argp Parser Functions:: Defining actions for an argp parser. |
| * Children: Argp Children. Combining multiple argp parsers. |
| * Help Filtering: Argp Help Filtering. Customizing help output for an argp parser. |
| |
| |
| File: libc.info, Node: Argp Option Vectors, Next: Argp Parser Functions, Prev: Argp Parsers, Up: Argp Parsers |
| |
| 25.3.4 Specifying Options in an Argp Parser |
| ------------------------------------------- |
| |
| The `options' field in a `struct argp' points to a vector of `struct |
| argp_option' structures, each of which specifies an option that the |
| argp parser supports. Multiple entries may be used for a single option |
| provided it has multiple names. This should be terminated by an entry |
| with zero in all fields. Note that when using an initialized C array |
| for options, writing `{ 0 }' is enough to achieve this. |
| |
| -- Data Type: struct argp_option |
| This structure specifies a single option that an argp parser |
| understands, as well as how to parse and document that option. It |
| has the following fields: |
| |
| `const char *name' |
| The long name for this option, corresponding to the long |
| option `--NAME'; this field may be zero if this option _only_ |
| has a short name. To specify multiple names for an option, |
| additional entries may follow this one, with the |
| `OPTION_ALIAS' flag set. *Note Argp Option Flags::. |
| |
| `int key' |
| The integer key provided by the current option to the option |
| parser. If KEY has a value that is a printable ASCII |
| character (i.e., `isascii (KEY)' is true), it _also_ |
| specifies a short option `-CHAR', where CHAR is the ASCII |
| character with the code KEY. |
| |
| `const char *arg' |
| If non-zero, this is the name of an argument associated with |
| this option, which must be provided (e.g., with the |
| `--NAME=VALUE' or `-CHAR VALUE' syntaxes), unless the |
| `OPTION_ARG_OPTIONAL' flag (*note Argp Option Flags::) is |
| set, in which case it _may_ be provided. |
| |
| `int flags' |
| Flags associated with this option, some of which are referred |
| to above. *Note Argp Option Flags::. |
| |
| `const char *doc' |
| A documentation string for this option, for printing in help |
| messages. |
| |
| If both the `name' and `key' fields are zero, this string |
| will be printed tabbed left from the normal option column, |
| making it useful as a group header. This will be the first |
| thing printed in its group. In this usage, it's conventional |
| to end the string with a `:' character. |
| |
| `int group' |
| Group identity for this option. |
| |
| In a long help message, options are sorted alphabetically |
| within each group, and the groups presented in the order 0, |
| 1, 2, ..., N, -M, ..., -2, -1. |
| |
| Every entry in an options array with this field 0 will |
| inherit the group number of the previous entry, or zero if |
| it's the first one. If it's a group header with `name' and |
| `key' fields both zero, the previous entry + 1 is the |
| default. Automagic options such as `--help' are put into |
| group -1. |
| |
| Note that because of C structure initialization rules, this |
| field often need not be specified, because 0 is the correct |
| value. |
| |
| * Menu: |
| |
| * Flags: Argp Option Flags. Flags for options. |
| |
| |
| File: libc.info, Node: Argp Option Flags, Up: Argp Option Vectors |
| |
| 25.3.4.1 Flags for Argp Options |
| ............................... |
| |
| The following flags may be or'd together in the `flags' field of a |
| `struct argp_option'. These flags control various aspects of how that |
| option is parsed or displayed in help messages: |
| |
| `OPTION_ARG_OPTIONAL' |
| The argument associated with this option is optional. |
| |
| `OPTION_HIDDEN' |
| This option isn't displayed in any help messages. |
| |
| `OPTION_ALIAS' |
| This option is an alias for the closest previous non-alias option. |
| This means that it will be displayed in the same help entry, and |
| will inherit fields other than `name' and `key' from the option |
| being aliased. |
| |
| `OPTION_DOC' |
| This option isn't actually an option and should be ignored by the |
| actual option parser. It is an arbitrary section of documentation |
| that should be displayed in much the same manner as the options. |
| This is known as a "documentation option". |
| |
| If this flag is set, then the option `name' field is displayed |
| unmodified (e.g., no `--' prefix is added) at the left-margin where |
| a _short_ option would normally be displayed, and this |
| documentation string is left in it's usual place. For purposes of |
| sorting, any leading whitespace and punctuation is ignored, unless |
| the first non-whitespace character is `-'. This entry is displayed |
| after all options, after `OPTION_DOC' entries with a leading `-', |
| in the same group. |
| |
| `OPTION_NO_USAGE' |
| This option shouldn't be included in `long' usage messages, but |
| should still be included in other help messages. This is intended |
| for options that are completely documented in an argp's `args_doc' |
| field. *Note Argp Parsers::. Including this option in the |
| generic usage list would be redundant, and should be avoided. |
| |
| For instance, if `args_doc' is `"FOO BAR\n-x BLAH"', and the `-x' |
| option's purpose is to distinguish these two cases, `-x' should |
| probably be marked `OPTION_NO_USAGE'. |
| |
| |
| File: libc.info, Node: Argp Parser Functions, Next: Argp Children, Prev: Argp Option Vectors, Up: Argp Parsers |
| |
| 25.3.5 Argp Parser Functions |
| ---------------------------- |
| |
| The function pointed to by the `parser' field in a `struct argp' (*note |
| Argp Parsers::) defines what actions take place in response to each |
| option or argument parsed. It is also used as a hook, allowing a |
| parser to perform tasks at certain other points during parsing. |
| |
| Argp parser functions have the following type signature: |
| |
| error_t PARSER (int KEY, char *ARG, struct argp_state *STATE) |
| |
| where the arguments are as follows: |
| |
| KEY |
| For each option that is parsed, PARSER is called with a value of |
| KEY from that option's `key' field in the option vector. *Note |
| Argp Option Vectors::. PARSER is also called at other times with |
| special reserved keys, such as `ARGP_KEY_ARG' for non-option |
| arguments. *Note Argp Special Keys::. |
| |
| ARG |
| If KEY is an option, ARG is its given value. This defaults to |
| zero if no value is specified. Only options that have a non-zero |
| `arg' field can ever have a value. These must _always_ have a |
| value unless the `OPTION_ARG_OPTIONAL' flag is specified. If the |
| input being parsed specifies a value for an option that doesn't |
| allow one, an error results before PARSER ever gets called. |
| |
| If KEY is `ARGP_KEY_ARG', ARG is a non-option argument. Other |
| special keys always have a zero ARG. |
| |
| STATE |
| STATE points to a `struct argp_state', containing useful |
| information about the current parsing state for use by PARSER. |
| *Note Argp Parsing State::. |
| |
| When PARSER is called, it should perform whatever action is |
| appropriate for KEY, and return `0' for success, `ARGP_ERR_UNKNOWN' if |
| the value of KEY is not handled by this parser function, or a unix |
| error code if a real error occurred. *Note Error Codes::. |
| |
| -- Macro: int ARGP_ERR_UNKNOWN |
| Argp parser functions should return `ARGP_ERR_UNKNOWN' for any KEY |
| value they do not recognize, or for non-option arguments (`KEY == |
| ARGP_KEY_ARG') that they are not equipped to handle. |
| |
| A typical parser function uses a switch statement on KEY: |
| |
| error_t |
| parse_opt (int key, char *arg, struct argp_state *state) |
| { |
| switch (key) |
| { |
| case OPTION_KEY: |
| ACTION |
| break; |
| ... |
| default: |
| return ARGP_ERR_UNKNOWN; |
| } |
| return 0; |
| } |
| |
| * Menu: |
| |
| * Keys: Argp Special Keys. Special values for the KEY argument. |
| * State: Argp Parsing State. What the STATE argument refers to. |
| * Functions: Argp Helper Functions. Functions to help during argp parsing. |
| |
| |
| File: libc.info, Node: Argp Special Keys, Next: Argp Parsing State, Up: Argp Parser Functions |
| |
| 25.3.5.1 Special Keys for Argp Parser Functions |
| ............................................... |
| |
| In addition to key values corresponding to user options, the KEY |
| argument to argp parser functions may have a number of other special |
| values. In the following example ARG and STATE refer to parser |
| function arguments. *Note Argp Parser Functions::. |
| |
| `ARGP_KEY_ARG' |
| This is not an option at all, but rather a command line argument, |
| whose value is pointed to by ARG. |
| |
| When there are multiple parser functions in play due to argp |
| parsers being combined, it's impossible to know which one will |
| handle a specific argument. Each is called until one returns 0 or |
| an error other than `ARGP_ERR_UNKNOWN'; if an argument is not |
| handled, `argp_parse' immediately returns success, without parsing |
| any more arguments. |
| |
| Once a parser function returns success for this key, that fact is |
| recorded, and the `ARGP_KEY_NO_ARGS' case won't be used. |
| _However_, if while processing the argument a parser function |
| decrements the `next' field of its STATE argument, the option |
| won't be considered processed; this is to allow you to actually |
| modify the argument, perhaps into an option, and have it processed |
| again. |
| |
| `ARGP_KEY_ARGS' |
| If a parser function returns `ARGP_ERR_UNKNOWN' for |
| `ARGP_KEY_ARG', it is immediately called again with the key |
| `ARGP_KEY_ARGS', which has a similar meaning, but is slightly more |
| convenient for consuming all remaining arguments. ARG is 0, and |
| the tail of the argument vector may be found at `STATE->argv + |
| STATE->next'. If success is returned for this key, and |
| `STATE->next' is unchanged, all remaining arguments are considered |
| to have been consumed. Otherwise, the amount by which |
| `STATE->next' has been adjusted indicates how many were used. |
| Here's an example that uses both, for different args: |
| |
| ... |
| case ARGP_KEY_ARG: |
| if (STATE->arg_num == 0) |
| /* First argument */ |
| first_arg = ARG; |
| else |
| /* Let the next case parse it. */ |
| return ARGP_KEY_UNKNOWN; |
| break; |
| case ARGP_KEY_ARGS: |
| remaining_args = STATE->argv + STATE->next; |
| num_remaining_args = STATE->argc - STATE->next; |
| break; |
| |
| `ARGP_KEY_END' |
| This indicates that there are no more command line arguments. |
| Parser functions are called in a different order, children first. |
| This allows each parser to clean up its state for the parent. |
| |
| `ARGP_KEY_NO_ARGS' |
| Because it's common to do some special processing if there aren't |
| any non-option args, parser functions are called with this key if |
| they didn't successfully process any non-option arguments. This |
| is called just before `ARGP_KEY_END', where more general validity |
| checks on previously parsed arguments take place. |
| |
| `ARGP_KEY_INIT' |
| This is passed in before any parsing is done. Afterwards, the |
| values of each element of the `child_input' field of STATE, if |
| any, are copied to each child's state to be the initial value of |
| the `input' when _their_ parsers are called. |
| |
| `ARGP_KEY_SUCCESS' |
| Passed in when parsing has successfully been completed, even if |
| arguments remain. |
| |
| `ARGP_KEY_ERROR' |
| Passed in if an error has occurred and parsing is terminated. In |
| this case a call with a key of `ARGP_KEY_SUCCESS' is never made. |
| |
| `ARGP_KEY_FINI' |
| The final key ever seen by any parser, even after |
| `ARGP_KEY_SUCCESS' and `ARGP_KEY_ERROR'. Any resources allocated |
| by `ARGP_KEY_INIT' may be freed here. At times, certain resources |
| allocated are to be returned to the caller after a successful |
| parse. In that case, those particular resources can be freed in |
| the `ARGP_KEY_ERROR' case. |
| |
| In all cases, `ARGP_KEY_INIT' is the first key seen by parser |
| functions, and `ARGP_KEY_FINI' the last, unless an error was returned |
| by the parser for `ARGP_KEY_INIT'. Other keys can occur in one the |
| following orders. OPT refers to an arbitrary option key: |
| |
| OPT... `ARGP_KEY_NO_ARGS' `ARGP_KEY_END' `ARGP_KEY_SUCCESS' |
| The arguments being parsed did not contain any non-option |
| arguments. |
| |
| ( OPT | `ARGP_KEY_ARG' )... `ARGP_KEY_END' `ARGP_KEY_SUCCESS' |
| All non-option arguments were successfully handled by a parser |
| function. There may be multiple parser functions if multiple argp |
| parsers were combined. |
| |
| ( OPT | `ARGP_KEY_ARG' )... `ARGP_KEY_SUCCESS' |
| Some non-option argument went unrecognized. |
| |
| This occurs when every parser function returns `ARGP_KEY_UNKNOWN' |
| for an argument, in which case parsing stops at that argument if |
| ARG_INDEX is a null pointer. Otherwise an error occurs. |
| |
| In all cases, if a non-null value for ARG_INDEX gets passed to |
| `argp_parse', the index of the first unparsed command-line argument is |
| passed back in that value. |
| |
| If an error occurs and is either detected by argp or because a parser |
| function returned an error value, each parser is called with |
| `ARGP_KEY_ERROR'. No further calls are made, except the final call |
| with `ARGP_KEY_FINI'. |
| |
| |
| File: libc.info, Node: Argp Parsing State, Next: Argp Helper Functions, Prev: Argp Special Keys, Up: Argp Parser Functions |
| |
| 25.3.5.2 Argp Parsing State |
| ........................... |
| |
| The third argument to argp parser functions (*note Argp Parser |
| Functions::) is a pointer to a `struct argp_state', which contains |
| information about the state of the option parsing. |
| |
| -- Data Type: struct argp_state |
| This structure has the following fields, which may be modified as |
| noted: |
| |
| `const struct argp *const root_argp' |
| The top level argp parser being parsed. Note that this is |
| often _not_ the same `struct argp' passed into `argp_parse' by |
| the invoking program. *Note Argp::. It is an internal argp |
| parser that contains options implemented by `argp_parse' |
| itself, such as `--help'. |
| |
| `int argc' |
| `char **argv' |
| The argument vector being parsed. This may be modified. |
| |
| `int next' |
| The index in `argv' of the next argument to be parsed. This |
| may be modified. |
| |
| One way to consume all remaining arguments in the input is to |
| set `STATE->next = STATE->argc', perhaps after recording the |
| value of the `next' field to find the consumed arguments. The |
| current option can be re-parsed immediately by decrementing |
| this field, then modifying `STATE->argv[STATE->next]' to |
| reflect the option that should be reexamined. |
| |
| `unsigned flags' |
| The flags supplied to `argp_parse'. These may be modified, |
| although some flags may only take effect when `argp_parse' is |
| first invoked. *Note Argp Flags::. |
| |
| `unsigned arg_num' |
| While calling a parsing function with the KEY argument |
| `ARGP_KEY_ARG', this represents the number of the current arg, |
| starting at 0. It is incremented after each `ARGP_KEY_ARG' |
| call returns. At all other times, this is the number of |
| `ARGP_KEY_ARG' arguments that have been processed. |
| |
| `int quoted' |
| If non-zero, the index in `argv' of the first argument |
| following a special `--' argument. This prevents anything |
| that follows from being interpreted as an option. It is only |
| set after argument parsing has proceeded past this point. |
| |
| `void *input' |
| An arbitrary pointer passed in from the caller of |
| `argp_parse', in the INPUT argument. |
| |
| `void **child_inputs' |
| These are values that will be passed to child parsers. This |
| vector will be the same length as the number of children in |
| the current parser. Each child parser will be given the |
| value of `STATE->child_inputs[I]' as _its_ `STATE->input' |
| field, where I is the index of the child in the this parser's |
| `children' field. *Note Argp Children::. |
| |
| `void *hook' |
| For the parser function's use. Initialized to 0, but |
| otherwise ignored by argp. |
| |
| `char *name' |
| The name used when printing messages. This is initialized to |
| `argv[0]', or `program_invocation_name' if `argv[0]' is |
| unavailable. |
| |
| `FILE *err_stream' |
| `FILE *out_stream' |
| The stdio streams used when argp prints. Error messages are |
| printed to `err_stream', all other output, such as `--help' |
| output) to `out_stream'. These are initialized to `stderr' |
| and `stdout' respectively. *Note Standard Streams::. |
| |
| `void *pstate' |
| Private, for use by the argp implementation. |
| |
| |
| File: libc.info, Node: Argp Helper Functions, Prev: Argp Parsing State, Up: Argp Parser Functions |
| |
| 25.3.5.3 Functions For Use in Argp Parsers |
| .......................................... |
| |
| Argp provides a number of functions available to the user of argp |
| (*note Argp Parser Functions::), mostly for producing error messages. |
| These take as their first argument the STATE argument to the parser |
| function. *Note Argp Parsing State::. |
| |
| -- Function: void argp_usage (const struct argp_state *STATE) |
| Preliminary: | MT-Unsafe race:argpbuf env locale | AS-Unsafe heap |
| i18n corrupt | AC-Unsafe mem corrupt lock | *Note POSIX Safety |
| Concepts::. |
| |
| Outputs the standard usage message for the argp parser referred to |
| by STATE to `STATE->err_stream' and terminate the program with |
| `exit (argp_err_exit_status)'. *Note Argp Global Variables::. |
| |
| -- Function: void argp_error (const struct argp_state *STATE, const |
| char *FMT, ...) |
| Preliminary: | MT-Unsafe race:argpbuf env locale | AS-Unsafe heap |
| i18n corrupt | AC-Unsafe mem corrupt lock | *Note POSIX Safety |
| Concepts::. |
| |
| Prints the printf format string FMT and following args, preceded |
| by the program name and `:', and followed by a `Try ... --help' |
| message, and terminates the program with an exit status of |
| `argp_err_exit_status'. *Note Argp Global Variables::. |
| |
| -- Function: void argp_failure (const struct argp_state *STATE, int |
| STATUS, int ERRNUM, const char *FMT, ...) |
| Preliminary: | MT-Safe | AS-Unsafe corrupt heap | AC-Unsafe lock |
| corrupt mem | *Note POSIX Safety Concepts::. |
| |
| Similar to the standard gnu error-reporting function `error', this |
| prints the program name and `:', the printf format string FMT, and |
| the appropriate following args. If it is non-zero, the standard |
| unix error text for ERRNUM is printed. If STATUS is non-zero, it |
| terminates the program with that value as its exit status. |
| |
| The difference between `argp_failure' and `argp_error' is that |
| `argp_error' is for _parsing errors_, whereas `argp_failure' is |
| for other problems that occur during parsing but don't reflect a |
| syntactic problem with the input, such as illegal values for |
| options, bad phase of the moon, etc. |
| |
| -- Function: void argp_state_help (const struct argp_state *STATE, |
| FILE *STREAM, unsigned FLAGS) |
| Preliminary: | MT-Unsafe race:argpbuf env locale | AS-Unsafe heap |
| i18n corrupt | AC-Unsafe mem corrupt lock | *Note POSIX Safety |
| Concepts::. |
| |
| Outputs a help message for the argp parser referred to by STATE, |
| to STREAM. The FLAGS argument determines what sort of help |
| message is produced. *Note Argp Help Flags::. |
| |
| Error output is sent to `STATE->err_stream', and the program name |
| printed is `STATE->name'. |
| |
| The output or program termination behavior of these functions may be |
| suppressed if the `ARGP_NO_EXIT' or `ARGP_NO_ERRS' flags are passed to |
| `argp_parse'. *Note Argp Flags::. |
| |
| This behavior is useful if an argp parser is exported for use by |
| other programs (e.g., by a library), and may be used in a context where |
| it is not desirable to terminate the program in response to parsing |
| errors. In argp parsers intended for such general use, and for the |
| case where the program _doesn't_ terminate, calls to any of these |
| functions should be followed by code that returns the appropriate error |
| code: |
| |
| if (BAD ARGUMENT SYNTAX) |
| { |
| argp_usage (STATE); |
| return EINVAL; |
| } |
| |
| If a parser function will _only_ be used when `ARGP_NO_EXIT' is not |
| set, the return may be omitted. |
| |
| |
| File: libc.info, Node: Argp Children, Next: Argp Help Filtering, Prev: Argp Parser Functions, Up: Argp Parsers |
| |
| 25.3.6 Combining Multiple Argp Parsers |
| -------------------------------------- |
| |
| The `children' field in a `struct argp' enables other argp parsers to |
| be combined with the referencing one for the parsing of a single set of |
| arguments. This field should point to a vector of `struct argp_child', |
| which is terminated by an entry having a value of zero in the `argp' |
| field. |
| |
| Where conflicts between combined parsers arise, as when two specify |
| an option with the same name, the parser conflicts are resolved in |
| favor of the parent argp parser(s), or the earlier of the argp parsers |
| in the list of children. |
| |
| -- Data Type: struct argp_child |
| An entry in the list of subsidiary argp parsers pointed to by the |
| `children' field in a `struct argp'. The fields are as follows: |
| |
| `const struct argp *argp' |
| The child argp parser, or zero to end of the list. |
| |
| `int flags' |
| Flags for this child. |
| |
| `const char *header' |
| If non-zero, this is an optional header to be printed within |
| help output before the child options. As a side-effect, a |
| non-zero value forces the child options to be grouped |
| together. To achieve this effect without actually printing a |
| header string, use a value of `""'. As with header strings |
| specified in an option entry, the conventional value of the |
| last character is `:'. *Note Argp Option Vectors::. |
| |
| `int group' |
| This is where the child options are grouped relative to the |
| other `consolidated' options in the parent argp parser. The |
| values are the same as the `group' field in `struct |
| argp_option'. *Note Argp Option Vectors::. All |
| child-groupings follow parent options at a particular group |
| level. If both this field and `header' are zero, then the |
| child's options aren't grouped together, they are merged with |
| parent options at the parent option group level. |
| |
| |
| |
| File: libc.info, Node: Argp Flags, Next: Argp Help, Prev: Argp Parsers, Up: Argp |
| |
| 25.3.7 Flags for `argp_parse' |
| ----------------------------- |
| |
| The default behavior of `argp_parse' is designed to be convenient for |
| the most common case of parsing program command line argument. To |
| modify these defaults, the following flags may be or'd together in the |
| FLAGS argument to `argp_parse': |
| |
| `ARGP_PARSE_ARGV0' |
| Don't ignore the first element of the ARGV argument to |
| `argp_parse'. Unless `ARGP_NO_ERRS' is set, the first element of |
| the argument vector is skipped for option parsing purposes, as it |
| corresponds to the program name in a command line. |
| |
| `ARGP_NO_ERRS' |
| Don't print error messages for unknown options to `stderr'; unless |
| this flag is set, `ARGP_PARSE_ARGV0' is ignored, as `argv[0]' is |
| used as the program name in the error messages. This flag implies |
| `ARGP_NO_EXIT'. This is based on the assumption that silent |
| exiting upon errors is bad behavior. |
| |
| `ARGP_NO_ARGS' |
| Don't parse any non-option args. Normally these are parsed by |
| calling the parse functions with a key of `ARGP_KEY_ARG', the |
| actual argument being the value. This flag needn't normally be |
| set, as the default behavior is to stop parsing as soon as an |
| argument fails to be parsed. *Note Argp Parser Functions::. |
| |
| `ARGP_IN_ORDER' |
| Parse options and arguments in the same order they occur on the |
| command line. Normally they're rearranged so that all options |
| come first. |
| |
| `ARGP_NO_HELP' |
| Don't provide the standard long option `--help', which ordinarily |
| causes usage and option help information to be output to `stdout' |
| and `exit (0)'. |
| |
| `ARGP_NO_EXIT' |
| Don't exit on errors, although they may still result in error |
| messages. |
| |
| `ARGP_LONG_ONLY' |
| Use the gnu getopt `long-only' rules for parsing arguments. This |
| allows long-options to be recognized with only a single `-' (i.e., |
| `-help'). This results in a less useful interface, and its use is |
| discouraged as it conflicts with the way most GNU programs work as |
| well as the GNU coding standards. |
| |
| `ARGP_SILENT' |
| Turns off any message-printing/exiting options, specifically |
| `ARGP_NO_EXIT', `ARGP_NO_ERRS', and `ARGP_NO_HELP'. |
| |
| |
| File: libc.info, Node: Argp Help Filtering, Prev: Argp Children, Up: Argp Parsers |
| |
| 25.3.8 Customizing Argp Help Output |
| ----------------------------------- |
| |
| The `help_filter' field in a `struct argp' is a pointer to a function |
| that filters the text of help messages before displaying them. They |
| have a function signature like: |
| |
| char *HELP-FILTER (int KEY, const char *TEXT, void *INPUT) |
| |
| Where KEY is either a key from an option, in which case TEXT is that |
| option's help text. *Note Argp Option Vectors::. Alternately, one of |
| the special keys with names beginning with `ARGP_KEY_HELP_' might be |
| used, describing which other help text TEXT will contain. *Note Argp |
| Help Filter Keys::. |
| |
| The function should return either TEXT if it remains as-is, or a |
| replacement string allocated using `malloc'. This will be either be |
| freed by argp or zero, which prints nothing. The value of TEXT is |
| supplied _after_ any translation has been done, so if any of the |
| replacement text needs translation, it will be done by the filter |
| function. INPUT is either the input supplied to `argp_parse' or it is |
| zero, if `argp_help' was called directly by the user. |
| |
| * Menu: |
| |
| * Keys: Argp Help Filter Keys. Special KEY values for help filter functions. |
| |
| |
| File: libc.info, Node: Argp Help Filter Keys, Up: Argp Help Filtering |
| |
| 25.3.8.1 Special Keys for Argp Help Filter Functions |
| .................................................... |
| |
| The following special values may be passed to an argp help filter |
| function as the first argument in addition to key values for user |
| options. They specify which help text the TEXT argument contains: |
| |
| `ARGP_KEY_HELP_PRE_DOC' |
| The help text preceding options. |
| |
| `ARGP_KEY_HELP_POST_DOC' |
| The help text following options. |
| |
| `ARGP_KEY_HELP_HEADER' |
| The option header string. |
| |
| `ARGP_KEY_HELP_EXTRA' |
| This is used after all other documentation; TEXT is zero for this |
| key. |
| |
| `ARGP_KEY_HELP_DUP_ARGS_NOTE' |
| The explanatory note printed when duplicate option arguments have |
| been suppressed. |
| |
| `ARGP_KEY_HELP_ARGS_DOC' |
| The argument doc string; formally the `args_doc' field from the |
| argp parser. *Note Argp Parsers::. |
| |
| |
| File: libc.info, Node: Argp Help, Next: Argp Examples, Prev: Argp Flags, Up: Argp |
| |
| 25.3.9 The `argp_help' Function |
| ------------------------------- |
| |
| Normally programs using argp need not be written with particular |
| printing argument-usage-type help messages in mind as the standard |
| `--help' option is handled automatically by argp. Typical error cases |
| can be handled using `argp_usage' and `argp_error'. *Note Argp Helper |
| Functions::. However, if it's desirable to print a help message in |
| some context other than parsing the program options, argp offers the |
| `argp_help' interface. |
| |
| -- Function: void argp_help (const struct argp *ARGP, FILE *STREAM, |
| unsigned FLAGS, char *NAME) |
| Preliminary: | MT-Unsafe race:argpbuf env locale | AS-Unsafe heap |
| i18n corrupt | AC-Unsafe mem corrupt lock | *Note POSIX Safety |
| Concepts::. |
| |
| This outputs a help message for the argp parser ARGP to STREAM. |
| The type of messages printed will be determined by FLAGS. |
| |
| Any options such as `--help' that are implemented automatically by |
| argp itself will _not_ be present in the help output; for this |
| reason it is best to use `argp_state_help' if calling from within |
| an argp parser function. *Note Argp Helper Functions::. |
| |
| * Menu: |
| |
| * Flags: Argp Help Flags. Specifying what sort of help message to print. |
| |
| |
| File: libc.info, Node: Argp Help Flags, Up: Argp Help |
| |
| 25.3.10 Flags for the `argp_help' Function |
| ------------------------------------------ |
| |
| When calling `argp_help' (*note Argp Help::) or `argp_state_help' |
| (*note Argp Helper Functions::) the exact output is determined by the |
| FLAGS argument. This should consist of any of the following flags, |
| or'd together: |
| |
| `ARGP_HELP_USAGE' |
| A unix `Usage:' message that explicitly lists all options. |
| |
| `ARGP_HELP_SHORT_USAGE' |
| A unix `Usage:' message that displays an appropriate placeholder to |
| indicate where the options go; useful for showing the non-option |
| argument syntax. |
| |
| `ARGP_HELP_SEE' |
| A `Try ... for more help' message; `...' contains the program name |
| and `--help'. |
| |
| `ARGP_HELP_LONG' |
| A verbose option help message that gives each option available |
| along with its documentation string. |
| |
| `ARGP_HELP_PRE_DOC' |
| The part of the argp parser doc string preceding the verbose |
| option help. |
| |
| `ARGP_HELP_POST_DOC' |
| The part of the argp parser doc string that following the verbose |
| option help. |
| |
| `ARGP_HELP_DOC' |
| `(ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)' |
| |
| `ARGP_HELP_BUG_ADDR' |
| A message that prints where to report bugs for this program, if the |
| `argp_program_bug_address' variable contains this information. |
| |
| `ARGP_HELP_LONG_ONLY' |
| This will modify any output to reflect the `ARGP_LONG_ONLY' mode. |
| |
| The following flags are only understood when used with |
| `argp_state_help'. They control whether the function returns after |
| printing its output, or terminates the program: |
| |
| `ARGP_HELP_EXIT_ERR' |
| This will terminate the program with `exit (argp_err_exit_status)'. |
| |
| `ARGP_HELP_EXIT_OK' |
| This will terminate the program with `exit (0)'. |
| |
| The following flags are combinations of the basic flags for printing |
| standard messages: |
| |
| `ARGP_HELP_STD_ERR' |
| Assuming that an error message for a parsing error has printed, |
| this prints a message on how to get help, and terminates the |
| program with an error. |
| |
| `ARGP_HELP_STD_USAGE' |
| This prints a standard usage message and terminates the program |
| with an error. This is used when no other specific error messages |
| are appropriate or available. |
| |
| `ARGP_HELP_STD_HELP' |
| This prints the standard response for a `--help' option, and |
| terminates the program successfully. |
| |
| |
| File: libc.info, Node: Argp Examples, Next: Argp User Customization, Prev: Argp Help, Up: Argp |
| |
| 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 |
| |
| |
| File: libc.info, Node: Netgroup Database, Prev: Database Example, Up: Users and Groups |
| |
| 29.16 Netgroup Database |
| ======================= |
| |
| * Menu: |
| |
| * Netgroup Data:: Data in the Netgroup database and where |
| it comes from. |
| * Lookup Netgroup:: How to look for a particular netgroup. |
| * Netgroup Membership:: How to test for netgroup membership. |
| |
| |
| File: libc.info, Node: Netgroup Data, Next: Lookup Netgroup, Up: Netgroup Database |
| |
| 29.16.1 Netgroup Data |
| --------------------- |
| |
| Sometimes it is useful to group users according to other criteria |
| (*note Group Database::). E.g., it is useful to associate a certain |
| group of users with a certain machine. On the other hand grouping of |
| host names is not supported so far. |
| |
| In Sun Microsystems SunOS appeared a new kind of database, the |
| netgroup database. It allows grouping hosts, users, and domains |
| freely, giving them individual names. To be more concrete, a netgroup |
| is a list of triples consisting of a host name, a user name, and a |
| domain name where any of the entries can be a wildcard entry matching |
| all inputs. A last possibility is that names of other netgroups can |
| also be given in the list specifying a netgroup. So one can construct |
| arbitrary hierarchies without loops. |
| |
| Sun's implementation allows netgroups only for the `nis' or |
| `nisplus' service, *note Services in the NSS configuration::. The |
| implementation in the GNU C Library has no such restriction. An entry |
| in either of the input services must have the following form: |
| |
| GROUPNAME ( GROUPNAME | `('HOSTNAME`,'USERNAME`,'`domainname'`)' )+ |
| |
| Any of the fields in the triple can be empty which means anything |
| matches. While describing the functions we will see that the opposite |
| case is useful as well. I.e., there may be entries which will not |
| match any input. For entries like this, a name consisting of the single |
| character `-' shall be used. |
| |
| |
| File: libc.info, Node: Lookup Netgroup, Next: Netgroup Membership, Prev: Netgroup Data, Up: Netgroup Database |
| |
| 29.16.2 Looking up one Netgroup |
| ------------------------------- |
| |
| The lookup functions for netgroups are a bit different to all other |
| system database handling functions. Since a single netgroup can contain |
| many entries a two-step process is needed. First a single netgroup is |
| selected and then one can iterate over all entries in this netgroup. |
| These functions are declared in `netdb.h'. |
| |
| -- Function: int setnetgrent (const char *NETGROUP) |
| Preliminary: | MT-Unsafe race:netgrent locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| A call to this function initializes the internal state of the |
| library to allow following calls of the `getnetgrent' to iterate |
| over all entries in the netgroup with name NETGROUP. |
| |
| When the call is successful (i.e., when a netgroup with this name |
| exists) the return value is `1'. When the return value is `0' no |
| netgroup of this name is known or some other error occurred. |
| |
| It is important to remember that there is only one single state for |
| iterating the netgroups. Even if the programmer uses the |
| `getnetgrent_r' function the result is not really reentrant since |
| always only one single netgroup at a time can be processed. If the |
| program needs to process more than one netgroup simultaneously she must |
| protect this by using external locking. This problem was introduced in |
| the original netgroups implementation in SunOS and since we must stay |
| compatible it is not possible to change this. |
| |
| Some other functions also use the netgroups state. Currently these |
| are the `innetgr' function and parts of the implementation of the |
| `compat' service part of the NSS implementation. |
| |
| -- Function: int getnetgrent (char **HOSTP, char **USERP, char |
| **DOMAINP) |
| Preliminary: | MT-Unsafe race:netgrent race:netgrentbuf locale | |
| AS-Unsafe dlopen plugin heap lock | AC-Unsafe corrupt lock fd mem |
| | *Note POSIX Safety Concepts::. |
| |
| This function returns the next unprocessed entry of the currently |
| selected netgroup. The string pointers, in which addresses are |
| passed in the arguments HOSTP, USERP, and DOMAINP, will contain |
| after a successful call pointers to appropriate strings. If the |
| string in the next entry is empty the pointer has the value `NULL'. |
| The returned string pointers are only valid if none of the netgroup |
| related functions are called. |
| |
| The return value is `1' if the next entry was successfully read. A |
| value of `0' means no further entries exist or internal errors |
| occurred. |
| |
| -- Function: int getnetgrent_r (char **HOSTP, char **USERP, char |
| **DOMAINP, char *BUFFER, size_t BUFLEN) |
| Preliminary: | MT-Unsafe race:netgrent locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| This function is similar to `getnetgrent' with only one exception: |
| the strings the three string pointers HOSTP, USERP, and DOMAINP |
| point to, are placed in the buffer of BUFLEN bytes starting at |
| BUFFER. This means the returned values are valid even after other |
| netgroup related functions are called. |
| |
| The return value is `1' if the next entry was successfully read and |
| the buffer contains enough room to place the strings in it. `0' is |
| returned in case no more entries are found, the buffer is too |
| small, or internal errors occurred. |
| |
| This function is a GNU extension. The original implementation in |
| the SunOS libc does not provide this function. |
| |
| -- Function: void endnetgrent (void) |
| Preliminary: | MT-Unsafe race:netgrent | AS-Unsafe dlopen plugin |
| heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX Safety |
| Concepts::. |
| |
| This function frees all buffers which were allocated to process |
| the last selected netgroup. As a result all string pointers |
| returned by calls to `getnetgrent' are invalid afterwards. |
| |
| |
| File: libc.info, Node: Netgroup Membership, Prev: Lookup Netgroup, Up: Netgroup Database |
| |
| 29.16.3 Testing for Netgroup Membership |
| --------------------------------------- |
| |
| It is often not necessary to scan the whole netgroup since often the |
| only interesting question is whether a given entry is part of the |
| selected netgroup. |
| |
| -- Function: int innetgr (const char *NETGROUP, const char *HOST, |
| const char *USER, const char *DOMAIN) |
| Preliminary: | MT-Unsafe race:netgrent locale | AS-Unsafe dlopen |
| plugin heap lock | AC-Unsafe corrupt lock fd mem | *Note POSIX |
| Safety Concepts::. |
| |
| This function tests whether the triple specified by the parameters |
| HOSTP, USERP, and DOMAINP is part of the netgroup NETGROUP. Using |
| this function has the advantage that |
| |
| 1. no other netgroup function can use the global netgroup state |
| since internal locking is used and |
| |
| 2. the function is implemented more efficiently than successive |
| calls to the other `set'/`get'/`endnetgrent' functions. |
| |
| Any of the pointers HOSTP, USERP, and DOMAINP can be `NULL' which |
| means any value is accepted in this position. This is also true |
| for the name `-' which should not match any other string otherwise. |
| |
| The return value is `1' if an entry matching the given triple is |
| found in the netgroup. The return value is `0' if the netgroup |
| itself is not found, the netgroup does not contain the triple or |
| internal errors occurred. |
| |
| |
| File: libc.info, Node: System Management, Next: System Configuration, Prev: Users and Groups, Up: Top |
| |
| 30 System Management |
| ******************** |
| |
| This chapter describes facilities for controlling the system that |
| underlies a process (including the operating system and hardware) and |
| for getting information about it. Anyone can generally use the |
| informational facilities, but usually only a properly privileged process |
| can make changes. |
| |
| * Menu: |
| |
| * Host Identification:: Determining the name of the machine. |
| * Platform Type:: Determining operating system and basic |
| machine type |
| * Filesystem Handling:: Controlling/querying mounts |
| * System Parameters:: Getting and setting various system parameters |
| |
| To get information on parameters of the system that are built into |
| the system, such as the maximum length of a filename, *note System |
| Configuration::. |
| |
| |
| File: libc.info, Node: Host Identification, Next: Platform Type, Up: System Management |
| |
| 30.1 Host Identification |
| ======================== |
| |
| This section explains how to identify the particular system on which |
| your program is running. First, let's review the various ways computer |
| systems are named, which is a little complicated because of the history |
| of the development of the Internet. |
| |
| Every Unix system (also known as a host) has a host name, whether |
| it's connected to a network or not. In its simplest form, as used |
| before computer networks were an issue, it's just a word like `chicken'. |
| |
| But any system attached to the Internet or any network like it |
| conforms to a more rigorous naming convention as part of the Domain |
| Name System (DNS). In DNS, every host name is composed of two parts: |
| |
| 1. hostname |
| |
| 2. domain name |
| |
| You will note that "hostname" looks a lot like "host name", but is |
| not the same thing, and that people often incorrectly refer to entire |
| host names as "domain names." |
| |
| In DNS, the full host name is properly called the FQDN (Fully |
| Qualified Domain Name) and consists of the hostname, then a period, |
| then the domain name. The domain name itself usually has multiple |
| components separated by periods. So for example, a system's hostname |
| may be `chicken' and its domain name might be `ai.mit.edu', so its FQDN |
| (which is its host name) is `chicken.ai.mit.edu'. |
| |
| Adding to the confusion, though, is that DNS is not the only name |
| space in which a computer needs to be known. Another name space is the |
| NIS (aka YP) name space. For NIS purposes, there is another domain |
| name, which is called the NIS domain name or the YP domain name. It |
| need not have anything to do with the DNS domain name. |
| |
| Confusing things even more is the fact that in DNS, it is possible |
| for multiple FQDNs to refer to the same system. However, there is |
| always exactly one of them that is the true host name, and it is called |
| the canonical FQDN. |
| |
| In some contexts, the host name is called a "node name." |
| |
| For more information on DNS host naming, see *note Host Names::. |
| |
| Prototypes for these functions appear in `unistd.h'. |
| |
| The programs `hostname', `hostid', and `domainname' work by calling |
| these functions. |
| |
| -- Function: int gethostname (char *NAME, size_t SIZE) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| This function returns the host name of the system on which it is |
| called, in the array NAME. The SIZE argument specifies the size of |
| this array, in bytes. Note that this is _not_ the DNS hostname. |
| If the system participates in DNS, this is the FQDN (see above). |
| |
| The return value is `0' on success and `-1' on failure. In the |
| GNU C Library, `gethostname' fails if SIZE is not large enough; |
| then you can try again with a larger array. The following `errno' |
| error condition is defined for this function: |
| |
| `ENAMETOOLONG' |
| The SIZE argument is less than the size of the host name plus |
| one. |
| |
| On some systems, there is a symbol for the maximum possible host |
| name length: `MAXHOSTNAMELEN'. It is defined in `sys/param.h'. |
| But you can't count on this to exist, so it is cleaner to handle |
| failure and try again. |
| |
| `gethostname' stores the beginning of the host name in NAME even |
| if the host name won't entirely fit. For some purposes, a |
| truncated host name is good enough. If it is, you can ignore the |
| error code. |
| |
| -- Function: int sethostname (const char *NAME, size_t LENGTH) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| The `sethostname' function sets the host name of the system that |
| calls it to NAME, a string with length LENGTH. Only privileged |
| processes are permitted to do this. |
| |
| Usually `sethostname' gets called just once, at system boot time. |
| Often, the program that calls it sets it to the value it finds in |
| the file `/etc/hostname'. |
| |
| Be sure to set the host name to the full host name, not just the |
| DNS hostname (see above). |
| |
| The return value is `0' on success and `-1' on failure. The |
| following `errno' error condition is defined for this function: |
| |
| `EPERM' |
| This process cannot set the host name because it is not |
| privileged. |
| |
| -- Function: int getdomainnname (char *NAME, size_t LENGTH) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| `getdomainname' returns the NIS (aka YP) domain name of the system |
| on which it is called. Note that this is not the more popular DNS |
| domain name. Get that with `gethostname'. |
| |
| The specifics of this function are analogous to `gethostname', |
| above. |
| |
| |
| -- Function: int setdomainname (const char *NAME, size_t LENGTH) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| `getdomainname' sets the NIS (aka YP) domain name of the system on |
| which it is called. Note that this is not the more popular DNS |
| domain name. Set that with `sethostname'. |
| |
| The specifics of this function are analogous to `sethostname', |
| above. |
| |
| |
| -- Function: long int gethostid (void) |
| Preliminary: | MT-Safe hostid env locale | AS-Unsafe dlopen plugin |
| corrupt heap lock | AC-Unsafe lock corrupt mem fd | *Note POSIX |
| Safety Concepts::. |
| |
| This function returns the "host ID" of the machine the program is |
| running on. By convention, this is usually the primary Internet |
| IP address of that machine, converted to a `long int'. However, |
| on some systems it is a meaningless but unique number which is |
| hard-coded for each machine. |
| |
| This is not widely used. It arose in BSD 4.2, but was dropped in |
| BSD 4.4. It is not required by POSIX. |
| |
| The proper way to query the IP address is to use `gethostbyname' |
| on the results of `gethostname'. For more information on IP |
| addresses, *Note Host Addresses::. |
| |
| -- Function: int sethostid (long int ID) |
| Preliminary: | MT-Unsafe const:hostid | AS-Unsafe | AC-Unsafe |
| corrupt fd | *Note POSIX Safety Concepts::. |
| |
| The `sethostid' function sets the "host ID" of the host machine to |
| ID. Only privileged processes are permitted to do this. Usually |
| it happens just once, at system boot time. |
| |
| The proper way to establish the primary IP address of a system is |
| to configure the IP address resolver to associate that IP address |
| with the system's host name as returned by `gethostname'. For |
| example, put a record for the system in `/etc/hosts'. |
| |
| See `gethostid' above for more information on host ids. |
| |
| The return value is `0' on success and `-1' on failure. The |
| following `errno' error conditions are defined for this function: |
| |
| `EPERM' |
| This process cannot set the host name because it is not |
| privileged. |
| |
| `ENOSYS' |
| The operating system does not support setting the host ID. |
| On some systems, the host ID is a meaningless but unique |
| number hard-coded for each machine. |
| |
| |
| File: libc.info, Node: Platform Type, Next: Filesystem Handling, Prev: Host Identification, Up: System Management |
| |
| 30.2 Platform Type Identification |
| ================================= |
| |
| You can use the `uname' function to find out some information about the |
| type of computer your program is running on. This function and the |
| associated data type are declared in the header file `sys/utsname.h'. |
| |
| As a bonus, `uname' also gives some information identifying the |
| particular system your program is running on. This is the same |
| information which you can get with functions targeted to this purpose |
| described in *note Host Identification::. |
| |
| -- Data Type: struct utsname |
| The `utsname' structure is used to hold information returned by |
| the `uname' function. It has the following members: |
| |
| `char sysname[]' |
| This is the name of the operating system in use. |
| |
| `char release[]' |
| This is the current release level of the operating system |
| implementation. |
| |
| `char version[]' |
| This is the current version level within the release of the |
| operating system. |
| |
| `char machine[]' |
| This is a description of the type of hardware that is in use. |
| |
| Some systems provide a mechanism to interrogate the kernel |
| directly for this information. On systems without such a |
| mechanism, the GNU C Library fills in this field based on the |
| configuration name that was specified when building and |
| installing the library. |
| |
| GNU uses a three-part name to describe a system |
| configuration; the three parts are CPU, MANUFACTURER and |
| SYSTEM-TYPE, and they are separated with dashes. Any |
| possible combination of three names is potentially |
| meaningful, but most such combinations are meaningless in |
| practice and even the meaningful ones are not necessarily |
| supported by any particular GNU program. |
| |
| Since the value in `machine' is supposed to describe just the |
| hardware, it consists of the first two parts of the |
| configuration name: `CPU-MANUFACTURER'. For example, it |
| might be one of these: |
| |
| `"sparc-sun"', `"i386-ANYTHING"', `"m68k-hp"', |
| `"m68k-sony"', `"m68k-sun"', `"mips-dec"' |
| |
| `char nodename[]' |
| This is the host name of this particular computer. In the |
| GNU C Library, the value is the same as that returned by |
| `gethostname'; see *note Host Identification::. |
| |
| gethostname() is implemented with a call to uname(). |
| |
| `char domainname[]' |
| This is the NIS or YP domain name. It is the same value |
| returned by `getdomainname'; see *note Host Identification::. |
| This element is a relatively recent invention and use of it |
| is not as portable as use of the rest of the structure. |
| |
| |
| -- Function: int uname (struct utsname *INFO) |
| Preliminary: | MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety |
| Concepts::. |
| |
| The `uname' function fills in the structure pointed to by INFO |
| with information about the operating system and host machine. A |
| non-negative value indicates that the data was successfully stored. |
| |
| `-1' as the value indicates an error. The only error possible is |
| `EFAULT', which we normally don't mention as it is always a |
| possibility. |
| |
| |
| File: libc.info, Node: Filesystem Handling, Next: System Parameters, Prev: Platform Type, Up: System Management |
| |
| 30.3 Controlling and Querying Mounts |
| ==================================== |
| |
| All files are in filesystems, and before you can access any file, its |
| filesystem must be mounted. Because of Unix's concept of _Everything |
| is a file_, mounting of filesystems is central to doing almost |
| anything. This section explains how to find out what filesystems are |
| currently mounted and what filesystems are available for mounting, and |
| how to change what is mounted. |
| |
| The classic filesystem is the contents of a disk drive. The concept |
| is considerably more abstract, though, and lots of things other than |
| disk drives can be mounted. |
| |
| Some block devices don't correspond to traditional devices like disk |
| drives. For example, a loop device is a block device whose driver uses |
| a regular file in another filesystem as its medium. So if that regular |
| file contains appropriate data for a filesystem, you can by mounting the |
| loop device essentially mount a regular file. |
| |
| Some filesystems aren't based on a device of any kind. The "proc" |
| filesystem, for example, contains files whose data is made up by the |
| filesystem driver on the fly whenever you ask for it. And when you |
| write to it, the data you write causes changes in the system. No data |
| gets stored. |
| |
| * Menu: |
| |
| * Mount Information:: What is or could be mounted? |
| * Mount-Unmount-Remount:: Controlling what is mounted and how |
| |
| |
| File: libc.info, Node: Mount Information, Next: Mount-Unmount-Remount, Up: Filesystem Handling |
| |
| 30.3.1 Mount Information |
| ------------------------ |
| |
| For some programs it is desirable and necessary to access information |
| about whether a certain filesystem is mounted and, if it is, where, or |
| simply to get lists of all the available filesystems. The GNU C Library |
| provides some functions to retrieve this information portably. |
| |
| Traditionally Unix systems have a file named `/etc/fstab' which |
| describes all possibly mounted filesystems. The `mount' program uses |
| this file to mount at startup time of the system all the necessary |
| filesystems. The information about all the filesystems actually |
| mounted is normally kept in a file named either `/var/run/mtab' or |
| `/etc/mtab'. Both files share the same syntax and it is crucial that |
| this syntax is followed all the time. Therefore it is best to never |
| directly write the files. The functions described in this section can |
| do this and they also provide the functionality to convert the external |
| textual representation to the internal representation. |
| |
| Note that the `fstab' and `mtab' files are maintained on a system by |
| _convention_. It is possible for the files not to exist or not to be |
| consistent with what is really mounted or available to mount, if the |
| system's administration policy allows it. But programs that mount and |
| unmount filesystems typically maintain and use these files as described |
| herein. |
| |
| The filenames given above should never be used directly. The |
| portable way to handle these file is to use the macro `_PATH_FSTAB', |
| defined in `fstab.h', or `_PATH_MNTTAB', defined in `mntent.h' and |
| `paths.h', for `fstab'; and the macro `_PATH_MOUNTED', also defined in |
| `mntent.h' and `paths.h', for `mtab'. There are also two alternate |
| macro names `FSTAB', `MNTTAB', and `MOUNTED' defined but these names |
| are deprecated and kept only for backward compatibility. The names |
| `_PATH_MNTTAB' and `_PATH_MOUNTED' should always be used. |
| |
| * Menu: |
| |
| * fstab:: The `fstab' file |
| * mtab:: The `mtab' file |
| * Other Mount Information:: Other (non-libc) sources of mount information |
| |