### Install the GNU C Library with make install Source: https://sourceware.org/glibc/manual/latest/html_node/Running-make-install.html Run 'make install' to build and install the library, headers, and Info files. It is recommended to compile everything first and to shut down to single-user mode before installing as the primary C library. ```shell make install ``` -------------------------------- ### Build, check, and install the GNU C Library in order Source: https://sourceware.org/glibc/manual/latest/html_node/Running-make-install.html The steps must be done in this order: build, optionally check, switch include directories, then install. Not moving the directory before install results in an unusable mixture of header files from both libraries. ```shell make ``` ```shell make check ``` ```shell make install ``` -------------------------------- ### Include headers for select example Source: https://sourceware.org/glibc/manual/latest/html_node/Waiting-for-I_002fO.html Required header files for the select example, including _GNU_SOURCE for TEMP_FAILURE_RETRY. ```c #define _GNU_SOURCE 1 #include #include #include #include #include ``` -------------------------------- ### Minimal gettext usage example Source: https://sourceware.org/glibc/manual/latest/html_node/Using-gettextized-software.html Example program that sets the locale, sets the default domain to 'test-package', binds that domain to /usr/local/share/locale, and prints a translated message. At program start the default domain is 'messages' and the default locale is 'C'. Correct functioning relies on LC_MESSAGES for catalog lookup and LC_CTYPE for character set conversion. ```c { setlocale (LC_ALL, ""); textdomain ("test-package"); bindtextdomain ("test-package", "/usr/local/share/locale"); puts (gettext ("Hello, world!")); } ``` -------------------------------- ### Include headers and define SHELL for process creation example Source: https://sourceware.org/glibc/manual/latest/html_node/Process-Creation-Example.html Includes required headers and defines the shell program path used by the example. ```c #include #include #include #include #include /* Execute the command using this shell program. */ #define SHELL "/bin/sh" ``` -------------------------------- ### Install the GNU C Library with DESTDIR Source: https://sourceware.org/glibc/manual/latest/html_node/Running-make-install.html Set DESTDIR on the command line for 'make install' to prepend a path to all installation paths. Useful for chroot environments or binary distributions. The directory must be an absolute file name. ```shell make install DESTDIR=/path/to/root ``` -------------------------------- ### Example /etc/tunables.conf entries Source: https://sourceware.org/glibc/manual/latest/html_node/System_002dwide-Tunables.html Shows the format for setting tunables in /etc/tunables.conf, one per line, using the glibc.malloc.trim_threshold and glibc.malloc.check examples. ```plaintext glibc.malloc.trim_threshold=128 glibc.malloc.check=3 ``` -------------------------------- ### Include headers for scandir example Source: https://sourceware.org/glibc/manual/latest/html_node/Simple-Directory-Lister-Mark-II.html Includes the standard I/O and directory entry headers required for the scandir example. ```c #include #include ``` -------------------------------- ### Install all locales into the locale archive with make localedata/install-locales Source: https://sourceware.org/glibc/manual/latest/html_node/Running-make-install.html Run from the build directory to install all supported locales into the locale archive. ```shell make localedata/install-locales ``` -------------------------------- ### Example: Using Fast Growth Functions Source: https://sourceware.org/glibc/manual/latest/html_node/Extra-Fast-Growing.html Example C code demonstrating how to use obstack_room and obstack_1grow_fast to efficiently add a string to an obstack, checking for room only when necessary. ```APIDOC ## Example: add_string function ### Description This example shows how to use obstack_room and obstack_1grow_fast to add a string to an obstack efficiently. It checks for available room and falls back to the slow function when needed. ### Code ```c void add_string (struct obstack *obstack, const char *ptr, int len) { while (len > 0) { int room = obstack_room (obstack); if (room == 0) { /* Not enough room. Add one character slowly, which may copy to a new chunk and make room. */ obstack_1grow (obstack, *ptr++); len--; } else { if (room > len) room = len; /* Add fast as much as we have room for. */ len -= room; while (room-- > 0) obstack_1grow_fast (obstack, *ptr++); } } } ``` ``` -------------------------------- ### openlog, syslog, and closelog example Source: https://sourceware.org/glibc/manual/latest/html_node/Syslog-Example.html Example code showing how to use setlogmask, openlog, syslog, and closelog to send log messages to the system logger. ```APIDOC ## openlog, syslog, and closelog example ### Description This example demonstrates the use of `openlog`, `syslog`, and `closelog` functions to send log messages to the system logger. It also shows how to use `setlogmask` to filter out messages below a certain priority. ### Functions Used - `setlogmask` - `openlog` - `syslog` - `closelog` ### Example Code ```c #include setlogmask (LOG_UPTO (LOG_NOTICE)); openlog ("exampleprog", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); syslog (LOG_NOTICE, "Program started by User %d", getuid ()); syslog (LOG_INFO, "A tree falls in a forest"); closelog (); ``` ### Explanation - `setlogmask` sets the log priority mask to `LOG_UPTO(LOG_NOTICE)`, which discards messages with priority `LOG_DEBUG` and `LOG_INFO`. - `openlog` opens a connection to the system logger with the program name "exampleprog", options `LOG_CONS | LOG_PID | LOG_NDELAY`, and facility `LOG_LOCAL1`. - The first `syslog` call sends a `LOG_NOTICE` message, which is allowed by the mask. - The second `syslog` call sends a `LOG_INFO` message, which is discarded because it is below the mask threshold. - `closelog` closes the connection to the system logger. ``` -------------------------------- ### Install all locales as files with make localedata/install-locale-files Source: https://sourceware.org/glibc/manual/latest/html_node/Running-make-install.html Installs all locales as files in the default configured locale installation directory (derived from '--prefix' or --localedir). ```shell make localedata/install-locale-files ``` -------------------------------- ### Sample output of the time functions example Source: https://sourceware.org/glibc/manual/latest/html_node/Time-Functions-Example.html This is the output produced by the example program. It shows the current date and time in the simple format, followed by the English format lines. ```text 2024-06-09 13:50:06 Today is Sunday, June 09. The time is 01:50 PM. ``` -------------------------------- ### Example: Using _unlocked functions with explicit locking Source: https://sourceware.org/glibc/manual/latest/html_node/Streams-and-Threads.html Example code demonstrating how to use flockfile and putc_unlocked to avoid implicit locking overhead in a loop. ```APIDOC ## Example: Using _unlocked functions with explicit locking ### Description Demonstrates using `flockfile` and `putc_unlocked` to avoid implicit locking in a loop. ### Code ```c void foo (FILE *fp, char *buf) { flockfile (fp); while (*buf != '/') putc_unlocked (*buf++, fp); funlockfile (fp); } ``` ``` -------------------------------- ### Example catalog path for LANGUAGE=de Source: https://sourceware.org/glibc/manual/latest/html_node/Using-gettextized-software.html Shows the message catalog file that gettext will try to use when the user sets LANGUAGE to 'de' in the environment, given the bindtextdomain directory and domain from the example. ```text /usr/local/share/locale/de/LC_MESSAGES/test-package.mo ``` -------------------------------- ### strrchr example Source: https://sourceware.org/glibc/manual/latest/html_node/Search-Functions.html Example of strrchr searching backwards from the end of the string for the last occurrence of 'l', returning a pointer to the substring starting at that character. ```c strrchr ("hello, world", 'l') ⇒ "ld" ``` -------------------------------- ### Example invocations and output of testopt Source: https://sourceware.org/glibc/manual/latest/html_node/Example-of-Getopt.html Sample command lines and their corresponding output for the testopt program, demonstrating how getopt handles various option combinations, including combined options, options with arguments, and non-option arguments. ```shell % testopt aflag = 0, bflag = 0, cvalue = (null) ``` ```shell % testopt -a -b aflag = 1, bflag = 1, cvalue = (null) ``` ```shell % testopt -ab aflag = 1, bflag = 1, cvalue = (null) ``` ```shell % testopt -c foo aflag = 0, bflag = 0, cvalue = foo ``` ```shell % testopt -cfoo aflag = 0, bflag = 0, cvalue = foo ``` ```shell % testopt arg1 aflag = 0, bflag = 0, cvalue = (null) Non-option argument arg1 ``` ```shell % testopt -a arg1 aflag = 1, bflag = 0, cvalue = (null) Non-option argument arg1 ``` ```shell % testopt -c foo arg1 aflag = 0, bflag = 0, cvalue = foo Non-option argument arg1 ``` ```shell % testopt -a -- -b aflag = 1, bflag = 0, cvalue = (null) Non-option argument -b ``` ```shell % testopt -a - aflag = 1, bflag = 0, cvalue = (null) Non-option argument - ``` -------------------------------- ### Using strlen to get pointer to null byte Source: https://sourceware.org/glibc/manual/latest/html_node/Search-Functions.html A common but not optimal way to get a pointer to the terminating null byte of a string by adding the string length to the start pointer. ```c s += strlen (s); ``` -------------------------------- ### waitpid (SIGCHLD handler example) Source: https://sourceware.org/glibc/manual/latest/html_node/Process-Completion.html Example of using 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. ```APIDOC ## waitpid (SIGCHLD handler example) ### Description Example of using `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. ### Function Signature `pid_t waitpid (pid_t pid, int *status-ptr, int options)` ### Parameters - **pid** (pid_t) - The process ID to wait for. Use `WAIT_ANY` to wait for any child process. - **status-ptr** (int *) - Pointer to an integer where the status information will be stored. - **options** (int) - Options for the wait operation. Use `WNOHANG` to return immediately if no child has terminated. ### Return Value Returns the process ID of the child whose state changed, 0 if using `WNOHANG` and no child has terminated, or -1 on error. ### Example Code ```c 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; } ``` ``` -------------------------------- ### Install handler with sa_mask to block signals Source: https://sourceware.org/glibc/manual/latest/html_node/Blocking-for-Handler.html This example installs a handler for SIGTSTP using sigaction, setting sa_mask to block SIGINT and SIGQUIT during handler execution. It uses sigemptyset and sigaddset to build the mask. The handler function catch_stop is declared but not defined here. ```c #include #include void catch_stop (); void install_handler (void) { struct sigaction setup_action; sigset_t block_mask; sigemptyset (&block_mask); /* Block other terminal-generated signals while handler runs. */ sigaddset (&block_mask, SIGINT); sigaddset (&block_mask, SIGQUIT); setup_action.sa_handler = catch_stop; setup_action.sa_mask = block_mask; setup_action.sa_flags = 0; sigaction (SIGTSTP, &setup_action, NULL); } ``` -------------------------------- ### Example /etc/nsswitch.conf configuration Source: https://sourceware.org/glibc/manual/latest/html_node/NSS-Configuration-File.html Shows a typical NSS configuration file with entries for passwd, shadow, group, hosts, networks, ethers, protocols, rpc, and services databases. The first column is the database name, and the rest of the line specifies the lookup process, including service specifications and optional reactions. ```plaintext # /etc/nsswitch.conf # # Name Service Switch configuration file. # passwd: db files shadow: files group: db files hosts: files dns networks: files ethers: db files protocols: db files rpc: db files services: db files ``` -------------------------------- ### strchr example: find first occurrence of a character Source: https://sourceware.org/glibc/manual/latest/html_node/Search-Functions.html Shows the return value of strchr when searching for a character that exists and one that does not. The first call returns a pointer to the substring starting at the match; the second returns NULL. ```c strchr ("hello, world", 'l') ⇒ "llo, world" strchr ("hello, world", '?') ⇒ NULL ``` -------------------------------- ### Limit CPU affinity with sched_getaffinity and sched_setaffinity Source: https://sourceware.org/glibc/manual/latest/html_node/CPU-Affinity.html Example C code that limits the number of CPUs a process runs on. It uses getcpu to get the current CPU, get_nprocs_conf to get the number of configured processors, and CPU_ALLOC/CPU_ALLOC_SIZE to allocate a CPU set. It then clears CPUs from the set if the current CPU count exceeds half of the configured processors, and applies the new affinity with sched_setaffinity. Error handling and CPU selection logic are omitted. ```c #define _GNU_SOURCE #include #include #include void limit_cpus (void) { unsigned int mycpu; size_t nproc, cssz, cpu; cpu_set_t *cs; getcpu (&mycpu, NULL); nproc = get_nprocs_conf (); cssz = CPU_ALLOC_SIZE (nproc); cs = CPU_ALLOC (nproc); sched_getaffinity (0, cssz, cs); if (CPU_COUNT_S (cssz, cs) > nproc / 2) { for (cpu = nproc / 2; cpu < nproc; cpu ++) if (cpu != mycpu) CPU_CLR_S (cpu, cssz, cs); sched_setaffinity (0, cssz, cs); } CPU_FREE (cs); } ``` -------------------------------- ### gconv_init implementation for ISO-2022-JP module Source: https://sourceware.org/glibc/manual/latest/html_node/glibc-iconv-Implementation.html Example initialization function for an iconv module supporting ISO-2022-JP and ISO-2022-JP-2 conversions. It determines the conversion direction by comparing names case-insensitively, allocates a data structure, sets min/max needed byte counts (with MAX_NEEDED_TO = MAX_NEEDED_FROM + 2 for the to direction to account for escape sequences), marks the step as stateful, and returns __GCONV_OK, __GCONV_NOCONV, or __GCONV_NOMEM. ```c #define MIN_NEEDED_FROM 1 #define MAX_NEEDED_FROM 4 #define MIN_NEEDED_TO 4 #define MAX_NEEDED_TO 4 int gconv_init (struct __gconv_step *step) { /* Determine which direction. */ struct iso2022jp_data *new_data; enum direction dir = illegal_dir; enum variant var = illegal_var; int result; if (__strcasecmp (step->__from_name, "ISO-2022-JP//") == 0) { dir = from_iso2022jp; var = iso2022jp; } else if (__strcasecmp (step->__to_name, "ISO-2022-JP//") == 0) { dir = to_iso2022jp; var = iso2022jp; } else if (__strcasecmp (step->__from_name, "ISO-2022-JP-2//") == 0) { dir = from_iso2022jp; var = iso2022jp2; } else if (__strcasecmp (step->__to_name, "ISO-2022-JP-2//") == 0) { dir = to_iso2022jp; var = iso2022jp2; } result = __GCONV_NOCONV; if (dir != illegal_dir) { new_data = (struct iso2022jp_data *) malloc (sizeof (struct iso2022jp_data)); result = __GCONV_NOMEM; if (new_data != NULL) { new_data->dir = dir; new_data->var = var; step->__data = new_data; if (dir == from_iso2022jp) { step->__min_needed_from = MIN_NEEDED_FROM; step->__max_needed_from = MAX_NEEDED_FROM; step->__min_needed_to = MIN_NEEDED_TO; step->__max_needed_to = MAX_NEEDED_TO; } else { step->__min_needed_from = MIN_NEEDED_TO; step->__max_needed_from = MAX_NEEDED_TO; step->__min_needed_to = MIN_NEEDED_FROM; step->__max_needed_to = MAX_NEEDED_FROM + 2; } /* Yes, this is a stateful encoding. */ step->__stateful = 1; result = __GCONV_OK; } } return result; } ``` -------------------------------- ### Shared file position with duplicated descriptors Source: https://sourceware.org/glibc/manual/latest/html_node/File-Position-Primitive.html This example shows that descriptors made by duplication share a common file position. Altering the position of one duplicate affects all, so reading from d1 and d2 after lseek reads consecutive blocks starting at the 1024th character. ```c { int d1, d2, d3; char buf1[4], buf2[4]; d1 = open ("foo", O_RDONLY); d2 = dup (d1); d3 = dup (d2); lseek (d3, 1024, SEEK_SET); read (d1, buf1, 4); read (d2, buf2, 4); } ``` -------------------------------- ### Using GNU basename to get program name Source: https://sourceware.org/glibc/manual/latest/html_node/Finding-Tokens-in-a-String.html Example of using the GNU basename function to obtain the last component of a path, here the program name from argv[0]. It does not modify the argument and respects trailing slashes. The prototype is in string.h, but including libgen.h overrides it with the XPG version. ```c #include int main (int argc, char *argv[]) { char *prog = basename (argv[0]); if (argc < 2) { fprintf (stderr, "Usage %s \n", prog); exit (1); } ... } ``` -------------------------------- ### getsubopt example for mount program Source: https://sourceware.org/glibc/manual/latest/html_node/Suboptions-Example.html This C program demonstrates parsing suboptions with getsubopt. It defines an option table for mount suboptions (ro, rw, rsize, wsize) and processes them in a switch statement. It uses getopt to handle -a, -t, and -o options, and for -o it iterates over suboptions, setting flags and sizes, and printing an error for unknown suboptions. ```c #include #include #include 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, (char * const *) 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; } ``` -------------------------------- ### C program using time, localtime, and strftime Source: https://sourceware.org/glibc/manual/latest/html_node/Time-Functions-Example.html This example program gets the current time with time(), converts it to local time with localtime(), and formats it with strftime() in two ways. It prints the date and time in a locale-independent format and then in a more descriptive English format. The program returns 1 if localtime() fails. ```c #include #include int main (void) { /* This buffer is big enough that the strftime calls below cannot possibly exhaust it. */ char buf[256]; /* Get the current time. */ time_t curtime = time (NULL); /* Convert it to local time representation. */ struct tm *lt = localtime (&curtime); if (!lt) return 1; /* Print the date and time in a simple format that is independent of locale. */ strftime (buf, sizeof buf, "%Y-%m-%d %H:%M:%S", lt); puts (buf); ``` ```c /* Print it in a nicer English format. */ strftime (buf, sizeof buf, "Today is %A, %B %d.", lt); puts (buf); strftime (buf, sizeof buf, "The time is %I:%M %p.", lt); puts (buf); return 0; } ``` -------------------------------- ### printf example with %d, %s, and %% conversions Source: https://sourceware.org/glibc/manual/latest/html_node/Formatted-Output-Basics.html Shows how to use printf with a template string containing conversion specifications. The example prints a filename and a percentage value, using %s for a string, %d for an integer, and %% for a literal percent sign. The output is shown as a separate block. ```c int pct = 37; char filename[] = "foo.txt"; printf ("Processing of `%s' is %d%% finished.\nPlease be patient.\n", filename, pct); ``` ```text Processing of `foo.txt' is 37% finished. Please be patient. ``` -------------------------------- ### Read all supplementary group IDs with getgroups Source: https://sourceware.org/glibc/manual/latest/html_node/Reading-Persona.html This example shows how to use getgroups to read all supplementary group IDs. It first calls getgroups with count zero to get the total number, then allocates an array and calls getgroups again to fill it. If the second call fails, it frees the allocated memory and returns NULL. ```c 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; } ``` -------------------------------- ### Complete Argp example program with multiple options and structured help Source: https://sourceware.org/glibc/manual/latest/html_node/Argp-Example-4.html This is the full C source code for the Argp example program 'argp-ex4'. It demonstrates advanced Argp features: headers in the options vector, a two-part documentation string (doc) separated by a vertical-tab character, handling of optional arguments (--repeat), and the ARGP_KEY_NO_ARGS key. The program accepts a required ARG1 and optional STRING... arguments, and supports options like --verbose, --quiet, --silent, --output, --repeat, and --abort. ```c /* 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 #include #include const char *argp_program_version = "argp-ex4 1.0"; const char *argp_program_bug_address = ""; /* 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; ``` -------------------------------- ### Signal-based mtrace/muntrace enable/disable example Source: https://sourceware.org/glibc/manual/latest/html_node/Tips-for-the-Memory-Debugger.html Use this C program to toggle memory allocation tracing at runtime via SIGUSR1 and SIGUSR2 signals. It requires including and , and the program must be started with MALLOC_TRACE set in the environment. The output will not show allocations before the first signal, but memory leaks will still be detected. ```c #include #include static void enable (int sig) { mtrace (); signal (SIGUSR1, enable); } static void disable (int sig) { muntrace (); signal (SIGUSR2, disable); } int main (int argc, char *argv[]) { ... signal (SIGUSR1, enable); signal (SIGUSR2, disable); ... } ``` -------------------------------- ### Signal handler setup using raise to reproduce default SIGTSTP behavior Source: https://sourceware.org/glibc/manual/latest/html_node/Signaling-Yourself.html This example shows how to use raise to reproduce the default behavior of a trapped signal. The tstp_handler resets the SIGTSTP action to default, performs cleanup, and then calls raise(SIGTSTP) to resend the signal. The cont_handler restores the handler when the process is continued. ```c #include /* When a stop signal arrives, set the action back to the default and then resend the signal after doing cleanup actions. */ void tstp_handler (int sig) { signal (SIGTSTP, SIG_DFL); /* Do cleanup actions here. */ ... raise (SIGTSTP); } /* When the process is continued again, restore the signal handler. */ void cont_handler (int sig) { signal (SIGCONT, cont_handler); signal (SIGTSTP, tstp_handler); } ``` ```c /* Enable both handlers during program initialization. */ int main (void) { signal (SIGCONT, cont_handler); signal (SIGTSTP, tstp_handler); ... } ``` -------------------------------- ### Initialize signal mask for SIGALRM Source: https://sourceware.org/glibc/manual/latest/html_node/Testing-for-Delivery.html Sets up a signal set containing SIGALRM using sigemptyset and sigaddset. This is the first part of the example, preparing the mask used later in the main loop. ```c /* This variable is set by the SIGALRM signal handler. */ volatile sig_atomic_t flag = 0; int main (void) { sigset_t block_alarm; ... /* Initialize the signal mask. */ sigemptyset (&block_alarm); sigaddset (&block_alarm, SIGALRM); ``` -------------------------------- ### Install a locale into the locale archive with localedef Source: https://sourceware.org/glibc/manual/latest/html_node/Running-make-install.html Installs the German locale de_DE with UTF-8 encoding into the locale archive. The locale archive is generally installed as /usr/lib/locale/locale-archive and is beneficial when installing sixty or more locales. ```shell localedef -i de_DE -f UTF-8 de_DE ``` -------------------------------- ### readlink_malloc: read symbolic link with dynamic buffer Source: https://sourceware.org/glibc/manual/latest/html_node/Symbolic-Links.html Example function that reads the target of a symbolic link using readlink, growing the buffer as needed. It returns a null-terminated string (the buffer is allocated with xreallocarray and the link content is not null-terminated by readlink, but the function returns the buffer as is). The function returns NULL on error. The buffer size starts at 50 and doubles each iteration. ```c char * readlink_malloc (const char *filename) { size_t size = 50; char *buffer = NULL; while (1) { buffer = xreallocarray (buffer, size, 2); size *= 2; ssize_t nchars = readlink (filename, buffer, size); if (nchars < 0) { free (buffer); return NULL; } if (nchars < size) return buffer; } } ``` -------------------------------- ### Mount and remount filesystem with mount() Source: https://sourceware.org/glibc/manual/latest/html_node/Mount_002dUnmount_002dRemount.html Example of using mount() to mount a CD-ROM with read-only and nosuid options, and to remount an existing filesystem with the MS_REMOUNT flag. ```c #include mount("/dev/hdb", "/cdrom", "iso9660", MS_MGC_VAL | MS_RDONLY | MS_NOSUID, ""); mount("/dev/hda2", "/mnt", "", MS_MGC_VAL | MS_REMOUNT, ""); ``` -------------------------------- ### Install a single locale without the archive using localedef --no-archive Source: https://sourceware.org/glibc/manual/latest/html_node/Running-make-install.html Installs just the one locale as a file in its self-named directory (e.g., /usr/lib/locale/en_US.utf8). Use this when installing only one or two locales. ```shell localedef --no-archive -i de_DE -f UTF-8 de_DE ``` -------------------------------- ### select Source: https://sourceware.org/glibc/manual/latest/html_node/Library-Summary.html Waits for I/O readiness on multiple file descriptors. ```APIDOC ## select ### Description Waits for I/O readiness on multiple file descriptors. ### Function Signature `int select (int nfds, fd_set *read-fds, fd_set *write-fds, fd_set *except-fds, struct timeval *timeout)` ### Header `sys/select.h` ### Standard POSIX.1 ### Parameters - **nfds** (int) - The highest-numbered file descriptor in any set plus one. - **read-fds** (fd_set *) - Set of descriptors to watch for readability. - **write-fds** (fd_set *) - Set of descriptors to watch for writability. - **except-fds** (fd_set *) - Set of descriptors to watch for exceptions. - **timeout** (struct timeval *) - Maximum time to wait, or NULL for blocking. ### Return Value Returns the number of ready descriptors, 0 on timeout, or -1 on error. ``` -------------------------------- ### Argp example #3: program with options and arguments Source: https://sourceware.org/glibc/manual/latest/html_node/Argp-Example-3.html Complete C program demonstrating Argp with user options and arguments. It defines options like --verbose, --quiet, --silent (alias), and --output, and uses a structure to communicate between main and parse_opt. The parser handles non-option arguments and returns errors appropriately. ```c /* 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 #include const char *argp_program_version = "argp-ex3 1.0"; const char *argp_program_bug_address = ""; /* 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; ``` -------------------------------- ### sum_ints_from_string example Source: https://sourceware.org/glibc/manual/latest/html_node/Parsing-of-Integers.html Example function that parses a string as a sequence of integers and returns their sum, using strtol. ```APIDOC ## sum_ints_from_string ### Description Parses a string as a sequence of integers and returns the sum of them. Uses strtol to parse each integer, skipping whitespace, and handles overflow by printing a message. ### Function Signature `int sum_ints_from_string (char *string)` ### Parameters - **string** (char *) - Required - The string to parse. ### Return Value Returns the sum of all integers parsed from the string. ### Example Code ```c int sum_ints_from_string (char *string) { int sum = 0; while (1) { char *tail; int next; /* Skip whitespace by hand, to detect the end. */ while (isspace (*string)) string++; if (*string == 0) break; /* There is more nonwhitespace, */ /* so it ought to be another number. */ errno = 0; /* Parse it. */ next = strtol (string, &tail, 0); /* Add it in, if not overflow. */ if (errno) printf ("Overflow\n"); else sum += next; /* Advance past it. */ string = tail; } return sum; } ``` ``` -------------------------------- ### execle Source: https://sourceware.org/glibc/manual/latest/html_node/Library-Summary.html Executes a file with a list of arguments and an environment. ```APIDOC ## execle ### Description Executes a file with a list of arguments and an environment. ### Function Signature `int execle (const char *filename, const char *arg0, …, char *const env[])` ### Header unistd.h (POSIX.1) ### Parameters - **filename** (const char *) - The file to execute. - **arg0** (const char *) - The first argument. - **…** - Additional arguments, terminated by NULL. - **env** (char *const[]) - The environment array. ### Return Value - **int** - Returns -1 on error. ``` -------------------------------- ### vfprintf example Source: https://sourceware.org/glibc/manual/latest/html_node/Variable-Arguments-Output.html Example showing how to use vfprintf to print error messages to stderr with a program name prefix. ```APIDOC ## Example: Using vfprintf ### Description This example defines an eprintf function that prints error messages to stderr with a prefix indicating the program name. ### Code ```c #include #include void eprintf (const char *template, ...) { va_list ap; extern char *program_invocation_short_name; fprintf (stderr, "%s: ", program_invocation_short_name); va_start (ap, template); vfprintf (stderr, template, ap); va_end (ap); } ``` ### Usage Example ```c eprintf ("file `%s' does not exist\n", filename); ``` ### GCC Format Attribute To enable compile-time checking of format strings, declare the function with the format attribute: ```c void eprintf (const char *template, ...) __attribute__ ((format (printf, 1, 2))); ``` ``` -------------------------------- ### Output of printf extension example Source: https://sourceware.org/glibc/manual/latest/html_node/Printf-Extension-Example.html Shows the expected output of the program, demonstrating the effect of width and left-justification. ```text || | | | | ``` -------------------------------- ### Calling eprintf Source: https://sourceware.org/glibc/manual/latest/html_node/Variable-Arguments-Output.html Shows a sample call to eprintf with a format string and a filename argument. ```c eprintf ("file `%s' does not exist\n", filename); ```