### pthread_getattr_np(3) C Example: Get Thread Guard Size, Stack Address, and Stack Size Source: https://manpages.debian.org/unstable/manpages-dev/pthread_getattr_np This C code example demonstrates the usage of pthread_getattr_np(). It creates a thread and then uses pthread_getattr_np() to retrieve and display its guard size, stack address, and stack size attributes. The example shows how command-line arguments can influence these attributes. ```c /* Example program demonstrating pthread_getattr_np() */ #include #include #include #include void *thread_func(void *arg) { pthread_t self = pthread_self(); pthread_attr_t attr; int ret; /* Initialize attribute object */ ret = pthread_getattr_np(self, &attr); if (ret != 0) { fprintf(stderr, "pthread_getattr_np failed: %d\n", ret); return NULL; } size_t guard_size; size_t stack_size; void *stack_addr; pthread_attr_getguardsize(&attr, &guard_size); pthread_attr_getstack(&attr, &stack_addr, &stack_size); printf("Attributes of created thread:\n"); printf(" Guard size = %zu bytes\n", guard_size); printf(" Stack address = %p (EOS = %p)\n", stack_addr, (char *)stack_addr + stack_size); printf(" Stack size = 0x%zx (%zu) bytes\n", stack_size, stack_size); /* Destroy attribute object */ pthread_attr_destroy(&attr); return NULL; } int main(int argc, char *argv[]) { pthread_t tid; pthread_attr_t attr; int ret; /* Initialize attribute object with default values */ pthread_attr_init(&attr); // Parse command line arguments for guard size, stack size, etc. (simplified) // For brevity, actual parsing of -g, -s, -a is omitted here. // The provided man page examples show how to set these. printf("Thread attributes object after initializations:\n"); size_t guard_size_init; size_t stack_size_init; void *stack_addr_init; pthread_attr_getguardsize(&attr, &guard_size_init); pthread_attr_getstack(&attr, &stack_addr_init, &stack_size_init); printf(" Guard size = %zu bytes\n", guard_size_init); printf(" Stack address = %p\n", stack_addr_init); printf(" Stack size = 0x%zx (%zu) bytes\n", stack_size_init, stack_size_init); /* Create the thread */ ret = pthread_create(&tid, &attr, thread_func, NULL); if (ret != 0) { fprintf(stderr, "pthread_create failed: %d\n", ret); return 1; } /* Wait for the thread to complete */ pthread_join(tid, NULL); /* Destroy attribute object */ pthread_attr_destroy(&attr); return 0; } ``` -------------------------------- ### Examples and Related Functions Source: https://manpages.debian.org/unstable/manpages-dev/recvfrom.2.en Provides an example of using recvfrom() and lists related system calls and functions for further reference. ```APIDOC ## Examples and Related Functions ### Description This section provides a usage example for a socket function and lists related system calls and functions for comprehensive understanding. ### Examples An example of the use of **recvfrom**() is shown in getaddrinfo(3). ### See Also fcntl(2), getsockopt(2), read(2), recvmmsg(2), select(2), shutdown(2), socket(2), cmsg(3), sockatmark(3), ip(7), ipv6(7), socket(7), tcp(7), udp(7), unix(7) ``` -------------------------------- ### io_setup System Call Source: https://manpages.debian.org/unstable/manpages-dev/io_setup This section details the raw Linux system call interface for creating an asynchronous I/O context. ```APIDOC ## io_setup System Call ### Description Creates an asynchronous I/O context suitable for concurrently processing a specified number of operations. The context handle must not point to an existing AIO context and should be initialized to 0 before the call. Upon success, the handle is filled with the resulting context ID. ### Method System Call (raw Linux interface) ### Endpoint N/A (System Call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None #### Arguments - **nr_events** (unsigned int *) - Required - The number of events the context should support. - **ctx_idp** (aio_context_t **) - Required - A pointer to a variable that will be filled with the resulting AIO context handle. Must be initialized to 0 and not point to an existing context. ### Request Example ```c #include long io_setup(unsigned int *nr_events, aio_context_t **ctx_idp); ``` ### Response #### Success Response (0) - **Return Value** (long) - 0 on success. #### Failure Response - **Return Value** (long) - -1 on error, with `errno` set to indicate the error. See ERRORS section. #### Error Codes - **EAGAIN**: `nr_events` exceeds the limit defined in `/proc/sys/fs/aio-max-nr`. - **EFAULT**: Invalid pointer passed for `ctx_idp`. - **EINVAL**: `ctx_idp` is not initialized, or `nr_events` exceeds internal limits (must be > 0). - **ENOMEM**: Insufficient kernel resources available. - **ENOSYS**: `io_setup` is not implemented on this architecture. ### Versions - Linux 2.5 ### See Also io_cancel(2), io_destroy(2), io_getevents(2), io_submit(2), aio(7) ### Note This describes the raw system call. The `libaio` library provides a wrapper function with a different type for `ctx_idp` (_io_context_t *) and a different error reporting convention (returns negated error numbers). ``` -------------------------------- ### fgets() Function Usage Example (Secure) Source: https://manpages.debian.org/unstable/manpages-dev/gets This is a secure example of using fgets() in C to read input from standard input (stdin). It specifies the buffer, the maximum number of characters to read (to prevent overflows), and the input stream. This is the preferred method over gets(). ```c char buffer[100]; if (fgets(buffer, sizeof(buffer), stdin) != NULL) { // Process the input in buffer } ``` -------------------------------- ### C Example: Get or set arbitrary baud rate on a serial port Source: https://manpages.debian.org/unstable/manpages-dev/TCSETA This C code provides a practical example of how to get or set an arbitrary baud rate on a serial port using ioctl calls and the termios2 structure. It includes error handling for file opening and ioctl operations, and checks for the availability of the BOTHER flag and TCGETS2 ioctl. The example demonstrates opening a device in non-blocking mode and retrieving or setting terminal settings. ```c /* SPDX-License-Identifier: GPL-2.0-or-later */ #include #include #include #include #include #include int main(int argc, char *argv[]) { #if !defined BOTHER fprintf(stderr, "BOTHER is unsupported\n"); /* Program may fallback to TCGETS/TCSETS with Bnnn constants */ exit(EXIT_FAILURE); #else /* Declare tio structure, its type depends on supported ioctl */ # if defined TCGETS2 struct termios2 tio; # else struct termios tio; # endif int fd, rc; if (argc != 2 && argc != 3 && argc != 4) { fprintf(stderr, "Usage: %s device [output [input] ]\n", argv[0]); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDWR | O_NONBLOCK | O_NOCTTY); if (fd < 0) { perror("open"); exit(EXIT_FAILURE); } /* Get the current serial port settings via supported ioctl */ # if defined TCGETS2 rc = ioctl(fd, TCGETS2, &tio); # else rc = ioctl(fd, TCGETS, &tio); ``` -------------------------------- ### Tail Queue Initialization and Example Operations (C) Source: https://manpages.debian.org/unstable/manpages-dev/LIST_INIT A complete C example demonstrating the declaration, initialization, insertion (head, tail, after, before), removal, and traversal (forward and reverse) of elements in a tail queue. ```c #include // Assuming TAILQ_HEAD, TAILQ_ENTRY, etc. are defined elsewhere TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); struct tailhead *headp; // Tail queue head. struct entry { // ... other fields TAILQ_ENTRY(entry) entries; // Tail queue. // ... other fields } *n1, *n2, *n3, *np; // Initialize the queue. TAILQ_INIT(&head); n1 = malloc(sizeof(struct entry)); // Insert at the head. TAILQ_INSERT_HEAD(&head, n1, entries); n1 = malloc(sizeof(struct entry)); // Insert at the tail. TAILQ_INSERT_TAIL(&head, n1, entries); n2 = malloc(sizeof(struct entry)); // Insert after. TAILQ_INSERT_AFTER(&head, n1, n2, entries); n3 = malloc(sizeof(struct entry)); // Insert before. TAILQ_INSERT_BEFORE(n2, n3, entries); TAILQ_REMOVE(&head, n2, entries); // Deletion. free(n2); // Forward traversal. TAILQ_FOREACH(np, &head, entries) np-> ... // Reverse traversal. TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) np-> ... // TailQ Deletion (iterative). while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1); } // Faster TailQ Deletion (iterative). TAILQ_INIT(&head); // Re-initialize for this example n1 = TAILQ_FIRST(&head); while (n1 != NULL) { n2 = TAILQ_NEXT(n1, entries); free(n1); n1 = n2; } TAILQ_INIT(&head); ``` -------------------------------- ### Include Header for io_setup Source: https://manpages.debian.org/unstable/manpages-dev/io_setup This code snippet shows the necessary header file to include for using the io_setup system call and its associated types. ```c #include ``` -------------------------------- ### RPC Function Prototypes Source: https://manpages.debian.org/unstable/manpages-dev/getrpcbynumber Provides the function prototypes for accessing RPC program entries. Includes functions to get an entry, get by name, get by number, set the starting point, and close the database connection. ```c struct rpcent *getrpcent(void); struct rpcent *getrpcbyname(const char **_name_); struct rpcent *getrpcbynumber(int *_number_); void setrpcent(int *_stayopen_); void endrpcent(void); ``` -------------------------------- ### rtime(3) C Example: Get Remote Machine Time Source: https://manpages.debian.org/unstable/manpages-dev/rtime.3.en This C code example demonstrates how to use the rtime function to retrieve the time from a remote machine named 'linux'. It includes necessary headers for network operations, time manipulation, and error handling. The example shows how to set up the sockaddr_in structure, call rtime with an optional timeout, and print the obtained time or an error message. It requires port 37 to be open on the remote machine. ```c #include #include #include #include #include #include #include static int use_tcp = 0; static const char servername[] = "linux"; int main(void) { int ret; time_t t; struct hostent *hent; struct rpc_timeval time1 = {0, 0}; struct rpc_timeval timeout = {1, 0}; struct sockaddr_in name; memset(&name, 0, sizeof(name)); sethostent(1); hent = gethostbyname(servername); memcpy(&name.sin_addr, hent->h_addr, hent->h_length); ret = rtime(&name, &time1, use_tcp ? NULL : &timeout); if (ret < 0) perror("rtime error"); else { t = time1.tv_sec; printf("%s\n", ctime(&t)); } exit(EXIT_SUCCESS); } ``` -------------------------------- ### Main function setup (C) Source: https://manpages.debian.org/unstable/manpages-dev/seccomp_unotify The main function initializes signal handling and sets up standard output buffering. It checks for the required command-line arguments. ```c int main(int argc, char *argv[]) { int sockPair[2]; struct sigaction sa; setbuf(stdout, NULL); if (argc < 2) { ``` -------------------------------- ### TAILQ_HEAD Initializer and Example Source: https://manpages.debian.org/unstable/manpages-dev/SLIST_INIT Demonstrates the initialization of a tail queue head using TAILQ_HEAD_INITIALIZER and provides a comprehensive example of tail queue operations including initialization, insertion (head, tail, after, before), removal, and forward/reverse traversal. ```c TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); struct tailhead *headp; struct entry { ... TAILQ_ENTRY(entry) entries; } TAILQ_INIT(&head); n1 = malloc(sizeof(struct entry)); TAILQ_INSERT_HEAD(&head, n1, entries); n1 = malloc(sizeof(struct entry)); TAILQ_INSERT_TAIL(&head, n1, entries); n2 = malloc(sizeof(struct entry)); TAILQ_INSERT_AFTER(&head, n1, n2, entries); n3 = malloc(sizeof(struct entry)); TAILQ_INSERT_BEFORE(n2, n3, entries); TAILQ_REMOVE(&head, n2, entries); free(n2); TAILQ_FOREACH(np, &head, entries) np-> ... TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) np-> ... while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1); } n1 = TAILQ_FIRST(&head); while (n1 != NULL) { n2 = TAILQ_NEXT(n1, entries); free(n1); n1 = n2; } TAILQ_INIT(&head); ``` -------------------------------- ### gets() Function Usage Example (Illustrative, Not Recommended) Source: https://manpages.debian.org/unstable/manpages-dev/gets This illustrates how the gets() function is typically called in C. It reads input into a buffer pointed to by _s. However, due to its dangerous nature (lack of buffer overflow checks), this usage is strongly discouraged and should be replaced with fgets(). ```c char buffer[100]; char *result = gets(buffer); ``` -------------------------------- ### open, openat, creat System Calls Source: https://manpages.debian.org/unstable/manpages-dev/creat Documentation for the C system calls used to open and potentially create files. Includes SYNOPSIS and library information. ```APIDOC ## open, openat, creat System Calls ### Description These system calls are used to open and possibly create a file. `open` is the traditional call, `openat` allows opening files relative to a directory file descriptor, and `creat` is a simplified version for creating files. ### Method System Call ### Endpoint N/A (System Calls) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c #include int fd = open("example.txt", O_RDWR | O_CREAT, 0666); ``` ### Response #### Success Response (0) Returns a non-negative file descriptor upon success. #### Response Example ```json { "file_descriptor": 3 } ``` ### Feature Test Macro Requirements for glibc **openat**(): ``` Since glibc 2.10: _POSIX_C_SOURCE >= 200809L Before glibc 2.10: _ATFILE_SOURCE ``` ``` -------------------------------- ### C Example: Get Calling Process Group ID (POSIX) Source: https://manpages.debian.org/unstable/manpages-dev/getpgid.2.en Shows the POSIX.1-compliant way to get the process group ID of the calling process using getpgrp() without arguments. ```c pid_t caller_pgid = getpgrp(); // No error return for this version ``` -------------------------------- ### C Thread Start Function Source: https://manpages.debian.org/unstable/manpages-dev/pthread_getattr_np This is the entry point for a newly created thread. It prints a message and then calls display_thread_attributes to show the attributes of the thread that just started. The thread then terminates the entire process. ```c #define _GNU_SOURCE /* To get pthread_getattr_np() declaration */ #include #include #include #include #include #include static void * /* Start function for thread we create */ thread_start(void *arg) { printf("Attributes of created thread:\n"); display_thread_attributes(pthread_self(), "\t"); exit(EXIT_SUCCESS); /* Terminate all threads */ } ``` -------------------------------- ### io_setup System Call using syscall(2) Source: https://manpages.debian.org/unstable/manpages-dev/io_setup.2.en Example of how to invoke the io_setup system call directly using the syscall(2) function, as there is no direct glibc wrapper. This approach requires careful handling of return values and errno. ```c #include #include #include long io_setup(unsigned int nr_events, aio_context_t *ctx_idp) { return syscall(SYS_io_setup, nr_events, ctx_idp); } ``` -------------------------------- ### Example: Get or Set Baud Rate on Serial Port C Source: https://manpages.debian.org/unstable/manpages-dev/TCSETSW This C example demonstrates how to get or set arbitrary baud rates on a serial port using ioctl calls. It includes logic to handle the TCGETS2 ioctl and the BOTHER flag for advanced baud rate settings, falling back to standard TCGETS if needed. The code requires specific headers and handles file operations for the serial device. ```c /* SPDX-License-Identifier: GPL-2.0-or-later */ #include #include #include #include #include #include int main(int argc, char *argv[]) { #if !defined BOTHER fprintf(stderr, "BOTHER is unsupported\n"); /* Program may fallback to TCGETS/TCSETS with Bnnn constants */ exit(EXIT_FAILURE); #else /* Declare tio structure, its type depends on supported ioctl */ # if defined TCGETS2 struct termios2 tio; # else struct termios tio; # endif int fd, rc; if (argc != 2 && argc != 3 && argc != 4) { fprintf(stderr, "Usage: %s device [output [input] ]\n", argv[0]); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDWR | O_NONBLOCK | O_NOCTTY); if (fd < 0) { perror("open"); exit(EXIT_FAILURE); } /* Get the current serial port settings via supported ioctl */ # if defined TCGETS2 rc = ioctl(fd, TCGETS2, &tio); # else rc = ioctl(fd, TCGETS, &tio); # endif /* ... rest of the example code ... */ ``` -------------------------------- ### Tail Queue Example Implementation Source: https://manpages.debian.org/unstable/manpages-dev/SLIST_FIRST.3.en A comprehensive example demonstrating the declaration, initialization, insertion (head, tail, after, before), removal, and traversal (forward and reverse) of elements in a tail queue. ```c TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); struct tailhead *headp; struct entry { ... TAILQ_ENTRY(entry) entries; ... } *n1, *n2, *n3, *np; TAILQ_INIT(&head); n1 = malloc(sizeof(struct entry)); TAILQ_INSERT_HEAD(&head, n1, entries); n1 = malloc(sizeof(struct entry)); TAILQ_INSERT_TAIL(&head, n1, entries); n2 = malloc(sizeof(struct entry)); TAILQ_INSERT_AFTER(&head, n1, n2, entries); n3 = malloc(sizeof(struct entry)); TAILQ_INSERT_BEFORE(n2, n3, entries); TAILQ_REMOVE(&head, n2, entries); free(n2); TAILQ_FOREACH(np, &head, entries) np-> ... TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) np-> ... while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1); } TAILQ_INIT(&head); ``` -------------------------------- ### spu_create() Usage Notes and Examples Source: https://manpages.debian.org/unstable/manpages-dev/spu_create Provides important notes regarding the intended use of spu_create() and references for examples. ```APIDOC ## NOTES **spu_create**() is meant to be used from libraries that implement a more abstract interface to SPUs, not to be used from regular applications. See http://www.bsc.es/projects/deepcomputing/linuxoncell/ for the recommended libraries. ## EXAMPLES See spu_run(2) for an example of the use of **spu_create**() ## SEE ALSO close(2), spu_run(2), capabilities(7), spufs(7) ``` -------------------------------- ### Example: Get or Set Arbitrary Baud Rate on Serial Port (C) Source: https://manpages.debian.org/unstable/manpages-dev/TCGETS.2const.en An example C program demonstrating how to get or set an arbitrary baud rate on a serial port using ioctl calls like TCGETS2 and TCGETS. It includes error handling and checks for the availability of the BOTHER flag for advanced baud rate settings. The program requires the device path as an argument and optionally output and input baud rates. ```c /* SPDX-License-Identifier: GPL-2.0-or-later */ #include #include #include #include #include #include int main(int argc, char *argv[]) { #if !defined BOTHER fprintf(stderr, "BOTHER is unsupported\n"); /* Program may fallback to TCGETS/TCSETS with Bnnn constants */ exit(EXIT_FAILURE); #else /* Declare tio structure, its type depends on supported ioctl */ # if defined TCGETS2 struct termios2 tio; # else struct termios tio; # endif int fd, rc; if (argc != 2 && argc != 3 && argc != 4) { fprintf(stderr, "Usage: %s device [output [input] ]\n", argv[0]); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDWR | O_NONBLOCK | O_NOCTTY); if (fd < 0) { perror("open"); exit(EXIT_FAILURE); } /* Get the current serial port settings via supported ioctl */ # if defined TCGETS2 rc = ioctl(fd, TCGETS2, &tio); # else rc = ioctl(fd, TCGETS, &tio); # endif ``` -------------------------------- ### Tail Queue Example Source: https://manpages.debian.org/unstable/manpages-dev/SLIST_NEXT A practical example demonstrating the usage of tail queue macros for initialization, insertion, traversal, and deletion. ```APIDOC ## Tail Queue Example ### Description This example illustrates how to define, initialize, and manipulate a tail queue using the provided macros. ### Code ```c #include // Define the tail queue head and the structure for queue elements TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); struct tailhead *headp; // Pointer to the tail queue head struct entry { // ... other fields ... TAILQ_ENTRY(entry) entries; // Tail queue link structure // ... other fields ... } *n1, *n2, *n3, *np; // Initialize the tail queue TAILQ_INIT(&head); // Allocate and insert an element at the head n1 = malloc(sizeof(struct entry)); TAILQ_INSERT_HEAD(&head, n1, entries); // Allocate and insert an element at the tail n1 = malloc(sizeof(struct entry)); TAILQ_INSERT_TAIL(&head, n1, entries); // Insert an element after a specific element n2 = malloc(sizeof(struct entry)); TAILQ_INSERT_AFTER(&head, n1, n2, entries); // Insert an element before a specific element n3 = malloc(sizeof(struct entry)); TAILQ_INSERT_BEFORE(n2, n3, entries); // Remove an element from the queue TAILQ_REMOVE(&head, n2, entries); free(n2); // Forward traversal of the queue TAILQ_FOREACH(np, &head, entries) { // Process element np np-> ... } // Reverse traversal of the queue TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) { // Process element np np-> ... } // Efficient deletion of all elements from the queue TAILQ_INIT(&head); // Re-initialize if needed n1 = TAILQ_FIRST(&head); while (n1 != NULL) { n2 = TAILQ_NEXT(n1, entries); free(n1); n1 = n2; } // Alternative deletion using TAILQ_EMPTY and TAILQ_REMOVE TAILQ_INIT(&head); // Re-initialize if needed while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1); } ``` ``` -------------------------------- ### Example of Getting Group Information by ID Source: https://manpages.debian.org/unstable/manpages-dev/getgrgid Illustrative C code snippet demonstrating the use of `getgrgid` to fetch group details based on a provided group ID. It includes essential error checking. ```c // Example usage of getgrgid #include #include #include int main() { gid_t group_id = 1001; struct group *grp_info; errno = 0; // Reset errno before the call grp_info = getgrgid(group_id); if (grp_info == NULL) { if (errno != 0) { perror("getgrgid"); } else { fprintf(stderr, "Group with ID '%d' not found.\n", group_id); } return 1; } printf("Group Name: %s\n", grp_info->gr_name); printf("Group ID: %d\n", grp_info->gr_gid); // ... further processing of group information return 0; } ``` -------------------------------- ### C: Tail Queue Initialization and Example Usage Source: https://manpages.debian.org/unstable/manpages-dev/SLIST_FOREACH.3.en Demonstrates the initialization of a tail queue and provides examples of common operations like insertion, removal, and traversal. It shows how to create elements, add them to the head or tail, insert them after or before existing elements, and traverse the queue forwards and backwards. It also includes methods for efficient deletion. ```c TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); struct tailhead *headp; /* Tail queue head. */ struct entry { /* ... */ TAILQ_ENTRY(entry) entries; /* Tail queue. */ /* ... */ } *n1, *n2, *n3, *np; TAILQ_INIT(&head); /* Initialize the queue. */ n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ TAILQ_INSERT_HEAD(&head, n1, entries); n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ TAILQ_INSERT_TAIL(&head, n1, entries); n2 = malloc(sizeof(struct entry)); /* Insert after. */ TAILQ_INSERT_AFTER(&head, n1, n2, entries); n3 = malloc(sizeof(struct entry)); /* Insert before. */ TAILQ_INSERT_BEFORE(n2, n3, entries); TAILQ_REMOVE(&head, n2, entries); /* Deletion. */ free(n2); /* Forward traversal. */ TAILQ_FOREACH(np, &head, entries) np-> ... /* Reverse traversal. */ TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) np-> ... /* TailQ Deletion. */ while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1); } /* Faster TailQ Deletion. */ n1 = TAILQ_FIRST(&head); while (n1 != NULL) { n2 = TAILQ_NEXT(n1, entries); free(n1); n1 = n2; } TAILQ_INIT(&head); ``` -------------------------------- ### Example of Getting Group Information by Name Source: https://manpages.debian.org/unstable/manpages-dev/getgrgid Illustrative C code snippet showing how to use `getgrnam` to retrieve group details by a given name. It includes error checking and handling for when a group is not found. ```c // Example usage of getgrnam #include #include #include int main() { const char *group_name = "mygroup"; struct group *grp_info; errno = 0; // Important to set errno to 0 before the call grp_info = getgrnam(group_name); if (grp_info == NULL) { if (errno != 0) { perror("getgrnam"); } else { fprintf(stderr, "Group '%s' not found.\n", group_name); } return 1; } printf("Group Name: %s\n", grp_info->gr_name); printf("Group ID: %d\n", grp_info->gr_gid); // ... process other fields like gr_passwd and gr_mem return 0; } ``` -------------------------------- ### Example Usage of sysctl(2) to Get OS Type Source: https://manpages.debian.org/unstable/manpages-dev/sysctl.2.en Demonstrates how to use the deprecated sysctl(2) system call to retrieve the operating system type. This example utilizes the syscall(2) function and the __sysctl_args structure. ```c #define _GNU_SOURCE #include #include #include #include #include #include #define NITEMS(arr) (sizeof(arr) / sizeof((arr)[0])) int _sysctl(struct __sysctl_args *args); #define OSNAMESZ 100 int main(void) { int name[] = { CTL_KERN, KERN_OSTYPE }; char osname[OSNAMESZ]; size_t osnamelth; struct __sysctl_args args; memset(&args, 0, sizeof(args)); args.name = name; args.nlen = NITEMS(name); args.oldval = osname; args.oldlenp = &osnamelth; osnamelth = sizeof(osname); if (syscall(SYS__sysctl, &args) == -1) { perror("_sysctl"); exit(EXIT_FAILURE); } printf("This machine is running %*s\n", (int) osnamelth, osname); exit(EXIT_SUCCESS); } ``` -------------------------------- ### Compile and Run request-key(8) Example Program - Shell Source: https://manpages.debian.org/unstable/manpages-dev/keyctl This snippet demonstrates the shell commands to compile the C example program for request-key(8), replace the standard program temporarily, execute the example program to request a key, and then restore the original request-key(8) program. It shows the typical workflow for testing custom key instantiation logic. ```shell $** cc -o key_instantiate key_instantiate.c -lkeyutils**; $** sudo mv /sbin/request-key /sbin/request-key.backup**; $** sudo cp key_instantiate /sbin/request-key**; $** ./t_request_key user mykey somepayloaddata**; Key ID is 20d035bf $** sudo mv /sbin/request-key.backup /sbin/request-key**; ``` -------------------------------- ### Complete Tail Queue Example (C) Source: https://manpages.debian.org/unstable/manpages-dev/LIST_ENTRY.3.en A practical example demonstrating the declaration, initialization, insertion, removal, and traversal of elements in a tail queue using C macros. It covers most common operations. ```c #include #include // Assume TAILQ macros are defined elsewhere (e.g., ) // For demonstration, we'll use placeholder definitions if not available. #ifndef TAILQ_HEAD #define TAILQ_HEAD(name, type) struct name { type *tqh_first; type **tqh_last; }; #define TAILQ_ENTRY(type) struct { type *taiq_next; type **taiq_prev; }; #define TAILQ_INIT(head) do { \ (head)->tqh_first = NULL; \ (head)->tqh_last = &(head)->tqh_first; \ } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \ (elm)->field.taiq_next = (head)->tqh_first; \ (elm)->field.taiq_prev = NULL; \ if ((head)->tqh_first != NULL) \ (head)->tqh_first->field.taiq_prev = &(elm)->field.taiq_next; \ else \ (head)->tqh_last = &(elm)->field.taiq_next; \ (head)->tqh_first = (elm); \ } while (0) #define TAILQ_INSERT_TAIL(head, elm, field) do { \ (elm)->field.taiq_next = NULL; \ (elm)->field.taiq_prev = (head)->tqh_last; \ *(head)->tqh_last = (elm); \ (head)->tqh_last = &(elm)->field.taiq_next; \ } while (0) #define TAILQ_REMOVE(head, elm, field) do { \ if ((elm)->field.taiq_next != NULL) (elm)->field.taiq_next->field.taiq_prev = (elm)->field.taiq_prev; else (head)->tqh_last = (elm)->field.taiq_prev; *(elm)->field.taiq_prev = (elm)->field.taiq_next; } while (0) #define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_NEXT(elm, field) ((elm)->field.taiq_next) #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) #define TAILQ_HEAD_INITIALIZER(head) { NULL, &(head).tqh_first } #endif struct entry { int data; TAILQ_ENTRY(entry) entries; }; TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); int main() { struct entry *n1, *n2, *np; TAILQ_INIT(&head); n1 = malloc(sizeof(struct entry)); n1->data = 10; TAILQ_INSERT_TAIL(&head, n1, entries); n2 = malloc(sizeof(struct entry)); n2->data = 20; TAILQ_INSERT_TAIL(&head, n2, entries); printf("Traversing forward:\n"); TAILQ_FOREACH(np, &head, entries) { printf("Data: %d\n", np->data); } TAILQ_REMOVE(&head, n1, entries); free(n1); printf("After removing one element:\n"); TAILQ_FOREACH(np, &head, entries) { printf("Data: %d\n", np->data); } TAILQ_INIT(&head); return 0; } ``` -------------------------------- ### fsconfig Example 3: Reconfiguring /proc filesystem using fspick Source: https://manpages.debian.org/unstable/manpages-dev/fsconfig.2.en This example shows how to use 'fspick' to get a file descriptor for an existing filesystem mounted at '/proc' and then use 'fsconfig' to reconfigure its parameters, such as 'hidepid' and 'subset'. ```APIDOC ## fsconfig Example 3: Reconfiguring /proc filesystem using fspick ### Description This example shows how to use 'fspick' to get a file descriptor for an existing filesystem mounted at '/proc' and then use 'fsconfig' to reconfigure its parameters, such as 'hidepid' and 'subset'. ### Method N/A (System Call Example) ### Endpoint N/A (System Call Example) ### Parameters N/A (System Call Example) ### Request Example ```c int fsfd = fspick(AT_FDCWD, "/proc", FSPICK_CLOEXEC); fsconfig(fsfd, FSCONFIG_SET_STRING, "hidepid", "ptraceable", 0); fsconfig(fsfd, FSCONFIG_SET_STRING, "subset", "pid", 0); fsconfig(fsfd, FSCONFIG_CMD_RECONFIGURE, NULL, NULL, 0); ``` ### Response N/A (System Call Example) ``` -------------------------------- ### Example of Calling getpgid Source: https://manpages.debian.org/unstable/manpages-dev/setpgid This example shows how to use the getpgid() system call in C to retrieve the process group ID of a process. It demonstrates calling getpgid with a process ID of zero to get the PGID of the calling process. ```c getpgid(0); ``` -------------------------------- ### Tail Queue Initialization and Example Operations (C) Source: https://manpages.debian.org/unstable/manpages-dev/TAILQ_REMOVE.3.en Demonstrates the initialization of a tail queue and common operations such as insertion at the head and tail, insertion after and before existing elements, removal, and traversal. It also shows how to efficiently empty the queue. This snippet illustrates practical use cases. ```c TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); struct tailhead *headp; struct entry { ... TAILQ_ENTRY(entry) entries; ... } *n1, *n2, *n3, *np; TAILQ_INIT(&head); n1 = malloc(sizeof(struct entry)); TAILQ_INSERT_HEAD(&head, n1, entries); n1 = malloc(sizeof(struct entry)); TAILQ_INSERT_TAIL(&head, n1, entries); n2 = malloc(sizeof(struct entry)); TAILQ_INSERT_AFTER(&head, n1, n2, entries); n3 = malloc(sizeof(struct entry)); TAILQ_INSERT_BEFORE(n2, n3, entries); TAILQ_REMOVE(&head, n2, entries); free(n2); TAILQ_FOREACH(np, &head, entries) np-> ... TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) np-> ... while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1); } n1 = TAILQ_FIRST(&head); while (n1 != NULL) { n2 = TAILQ_NEXT(n1, entries); free(n1); n1 = n2; } TAILQ_INIT(&head); ``` -------------------------------- ### pthread_getattr_np(3) C Example - Manual Stack Allocation Source: https://manpages.debian.org/unstable/manpages-dev/pthread_getattr_np.3.en Shows an example where a thread's stack is manually allocated. This scenario demonstrates that the guard size attribute is ignored when the application handles stack allocation, and displays the retrieved attributes. ```bash $** ./a.out -g 4096 -s 0x8000 -a** Allocated thread stack at 0x804d000 Thread attributes object after initializations: Guard size = 4096 bytes Stack address = 0x804d000 (EOS = 0x8055000) Stack size = 0x8000 (32768) bytes Attributes of created thread: Guard size = 0 bytes Stack address = 0x804d000 (EOS = 0x8055000) Stack size = 0x8000 (32768) bytes ``` -------------------------------- ### Using io_setup via syscall(2) Source: https://manpages.debian.org/unstable/manpages-dev/io_setup Demonstrates how to invoke the io_setup system call directly using the syscall(2) function, as glibc does not provide a wrapper. This method returns -1 on error with errno set. ```c #include #include #include // ... aio_context_t ctx; unsigned int nr_events = 128; long ret = syscall(SYS_io_setup, nr_events, &ctx); if (ret == -1) { // Handle error, check errno } else { // Success, ctx is now a valid AIO context ID } ``` -------------------------------- ### Tail Queue Example: Initialization, Insertion, and Deletion (C) Source: https://manpages.debian.org/unstable/manpages-dev/TAILQ_INSERT_HEAD.3.en A comprehensive example demonstrating the practical usage of TAILQ macros. It covers initializing a queue, inserting elements at the head and tail, inserting after and before existing elements, removing elements, and traversing the queue in both directions. It also shows how to safely empty and deallocate all elements from a queue. ```c TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); struct tailhead *headp; /* Tail queue head. */ struct entry { ... TAILQ_ENTRY(entry) entries; /* Tail queue. */ ... } *n1, *n2, *n3, *np; TAILQ_INIT(&head); /* Initialize the queue. */ n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ TAILQ_INSERT_HEAD(&head, n1, entries); n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ TAILQ_INSERT_TAIL(&head, n1, entries); n2 = malloc(sizeof(struct entry)); /* Insert after. */ TAILQ_INSERT_AFTER(&head, n1, n2, entries); n3 = malloc(sizeof(struct entry)); /* Insert before. */ TAILQ_INSERT_BEFORE(n2, n3, entries); TAILQ_REMOVE(&head, n2, entries); /* Deletion. */ free(n2); /* Forward traversal. */ TAILQ_FOREACH(np, &head, entries) np-> ... /* Reverse traversal. */ TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) np-> ... /* TailQ Deletion. */ while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1); } /* Faster TailQ Deletion. */ TAILQ_INIT(&head); n1 = TAILQ_FIRST(&head); while (n1 != NULL) { n2 = TAILQ_NEXT(n1, entries); free(n1); n1 = n2; } TAILQ_INIT(&head); ``` -------------------------------- ### C Example Program for Network Interface Listing Source: https://manpages.debian.org/unstable/manpages-dev/if_nameindex A C program demonstrating the usage of if_nameindex() to get network interface details and if_freenameindex() to release the resources. It iterates through the returned structures and prints the index and name of each interface. ```c #include #include #include #include int main(void) { struct if_nameindex *if_ni, *i; if_ni = if_nameindex(); if (if_ni == NULL) { perror("if_nameindex"); exit(EXIT_FAILURE); } for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) printf("%u: %s\n", i->if_index, i->if_name); if_freenameindex(if_ni); exit(EXIT_SUCCESS); } ``` -------------------------------- ### Shell: Example of Failing to Get Parent of Initial User Namespace Source: https://manpages.debian.org/unstable/manpages-dev/NS_GET_USERNS Illustrates a shell command attempting to get the parent of the initial user namespace, which is expected to fail. The output shows an error message indicating the namespace is outside the scope. ```shell $ ./ns_show /proc/self/ns/user p The parent namespace is outside your namespace scope ``` -------------------------------- ### Complete Tail Queue Example - C Source: https://manpages.debian.org/unstable/manpages-dev/STAILQ_HEAD_INITIALIZER A comprehensive C code example demonstrating the usage of various TAILQ_* macros. It covers initialization, insertion at head and tail, insertion after and before existing elements, removal, forward and reverse traversal, and efficient deletion of all elements from the queue. ```c TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); struct tailhead *headp; /* Tail queue head. */ struct entry { ... TAILQ_ENTRY(entry) entries; /* Tail queue. */ ... } *n1, *n2, *n3, *np; TAILQ_INIT(&head); /* Initialize the queue. */ n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ TAILQ_INSERT_HEAD(&head, n1, entries); n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ TAILQ_INSERT_TAIL(&head, n1, entries); n2 = malloc(sizeof(struct entry)); /* Insert after. */ TAILQ_INSERT_AFTER(&head, n1, n2, entries); n3 = malloc(sizeof(struct entry)); /* Insert before. */ TAILQ_INSERT_BEFORE(n2, n3, entries); TAILQ_REMOVE(&head, n2, entries); /* Deletion. */ free(n2); /* Forward traversal. */ TAILQ_FOREACH(np, &head, entries) np-> ... /* Reverse traversal. */ TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) np-> ... /* TailQ Deletion. */ while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1); } /* Faster TailQ Deletion. */ n1 = TAILQ_FIRST(&head); while (n1 != NULL) { n2 = TAILQ_NEXT(n1, entries); free(n1); n1 = n2; } TAILQ_INIT(&head); ```