Fact-checked by Grok 2 weeks ago

unistd.h

<unistd.h> is a standard header file in for POSIX-compliant operating systems, which defines miscellaneous symbolic constants and types, and declares a wide range of functions providing to system calls for management, and operations, primitives, and other system services. The header supports standards by including version test macros such as _POSIX_VERSION (set to 202405L for IEEE Std 1003.1-2024 compliance) and option indicators like _POSIX_JOB_CONTROL to indicate supported features. Key symbolic constants include permissions F_OK, R_OK, W_OK, and X_OK used with the access() , as well as positions SEEK_SET, SEEK_CUR, and SEEK_END for lseek(). It declares essential types such as size_t and ssize_t for sizes, uid_t and gid_t for user and group IDs, off_t for file offsets, pid_t for process IDs, useconds_t for microseconds, and intptr_t for integer pointers. Among the 85 functions declared, notable ones include process creation with fork() and execution with execv(), file operations like open(), close(), read(), and write(), directory changes via chdir(), and process identification with getpid(). These declarations enable portable C programs to interface directly with the operating system's kernel services in Unix-like environments.

History and Development

Origins in Early Unix

The functions and interfaces later declared in unistd.h originated in the early development of Unix at , where and implemented core system calls between 1971 and 1973 as part of Unix Versions 1 through 6. In these initial releases, these system calls abstracted hardware-specific details of process management, including primitives like fork() for creating child processes, the exec() family for replacing a process image, and getpid() for retrieving the process identifier. However, unistd.h itself did not exist at this time; declarations were spread across other headers. By Unix Version 7 in 1979, the scope of these interfaces expanded to incorporate fundamental I/O operations such as read() and write(), emphasizing portable interfaces that decoupled applications from underlying machine dependencies and facilitated broader adoption across hardware platforms. This evolution marked a pivotal shift toward modular, reusable system abstractions in Unix design, though unistd.h was introduced later to consolidate them. The Programmer's Workbench (PWB/UNIX), released around 1980, formalized numerous utilities and tools supporting collaborative programming workflows at , influencing the development of standardized interfaces.

Standardization in POSIX

The <unistd.h> header was first formally standardized in .1 (IEEE Std 1003.1-1988), which mandated the inclusion of key functions and constants to promote portability across operating systems by defining a for process control, file operations, and . The name "unistd.h" derives from "Unix standard," chosen to avoid using the trademarked term "UNIX" during development by standards bodies. This initial standard, identified by the symbolic constant _POSIX_VERSION == 198808L, established the foundational declarations in <unistd.h>, such as fork(), exec(), and getpid(), drawing from established Unix practices to ensure consistent behavior in compliant systems. Subsequent revisions expanded the scope of <unistd.h>. The POSIX.1-1990 standard (ISO/IEC 9945-1:1990), marked by _POSIX_VERSION == 199009L, incorporated additional and management functions, enhancing support for diverse system environments while maintaining backward compatibility. Further advancements came in POSIX.1-2001 (Issue 6, IEEE Std 1003.1-2001), identified by _POSIX_VERSION == 200112L, which introduced extensions including options like _POSIX_CLOCK_SELECTION and _POSIX_MONOTONIC_CLOCK for features such as precise timing in multithreaded and applications (with functions like clock_gettime() declared in <time.h>). Later editions continued this progression: POSIX.1-2008 (Issue 7, _POSIX_VERSION == 200809L) refined base specifications, and POSIX.1-2017 (Issue 8, _POSIX_VERSION == 201710L) added further alignments with modern systems. The most recent, POSIX.1-2024 (IEEE Std 1003.1-2024, _POSIX_VERSION == 202405L), as of 2024, includes updates to support and other enhancements while maintaining the core declarations in <unistd.h>. The standardization of <unistd.h> involves collaboration among key bodies: the IEEE, which develops the core standards; the ISO, which adopts them as international norms (e.g., ISO/IEC 9945-1); and The Open Group, which oversees and . Conformance levels require implementations to support the full set of <unistd.h> declarations without optional extensions unless specified, verifiable via sysconf(_SC_VERSION). Historical milestones trace to the X/Open Portability Guides of the 1980s, particularly Issues 1 (1985) and 2 (1987), which promoted Unix portability and directly influenced POSIX.1 by standardizing interfaces later consolidated in <unistd.h>. From 1995 onward, the Single UNIX Specification (SUS) versions integrated <unistd.h> as a core component, with SUS Version 1 enabling the "UNIX 95" trademark for compliant systems and subsequent editions like SUSv2 (1997) aligning with X/Open extensions.

Purpose and Design

Core Objectives

The unistd.h header serves as a for providing a portable to low-level system services in POSIX-compliant environments, enabling applications to perform operations such as creation, file manipulation, and without dependency on specific implementations. By defining symbolic constants, data types, and function declarations that abstract underlying system calls, it promotes across diverse operating systems, allowing developers to write code that functions consistently regardless of the host system's internal architecture. Central to its design is an emphasis on and , where functions are structured as direct mappings to system calls, eschewing extraneous layers to maintain and clarity. For instance, operations like opening, closing, and reading files are exposed through straightforward interfaces that mirror interactions, facilitating rapid and reducing overhead in resource-constrained environments. This approach aligns with foundational Unix design tenets that prioritize lean, purpose-built mechanisms over complex hierarchies. unistd.h plays a pivotal role in embodying the of constructing small, composable tools that interoperate seamlessly, such as through mechanisms that support shell pipelines by enabling and descriptor manipulation. This design fosters , where individual utilities can chain together to solve complex tasks via simple, text-based streams, enhancing overall system flexibility and maintainability. A key architectural principle of unistd.h is the provision of C library wrappers for system calls, which declare function prototypes to enforce during compilation and standardize error reporting through the global errno variable. These wrappers translate low-level return codes into portable error indicators, ensuring robust handling of failures like invalid arguments or resource unavailability across implementations.

Relationship to Other Headers

The <unistd.h> header provides low-level, unbuffered system interfaces for operations such as , primarily through functions like read() and write(), which directly interact with file descriptors without the buffering abstractions found in <stdio.h>, where higher-level functions like fread() and fwrite() manage stream buffering for portability and efficiency. In contrast, <fcntl.h> complements <unistd.h> by offering advanced file control mechanisms, such as fcntl() for locking and flags, which are not directly included in <unistd.h> but often used in conjunction with its basic file operations like close() and read(). <unistd.h> depends on several foundational headers for type definitions and constants; for instance, it incorporates types such as pid_t, uid_t, and off_t from <sys/types.h>, intptr_t from <stdint.h>, and NULL from <stddef.h>, ensuring consistent data representations across POSIX-compliant systems. It may also expose symbols from <stdio.h>, including shared constants like SEEK_CUR, SEEK_END, and SEEK_SET for file positioning, and optionally the ctermid() prototype. Additionally, constants such as {NAME_MAX} are drawn from <limits.h> to define system limits relevant to pathnames and environments. In the POSIX architecture, <unistd.h> serves as a foundational layer for base system services, including process control and basic I/O, upon which specialized headers build for domain-specific functionality; for example, <signal.h> extends it with signal handling tied to functions like _exit(), while <termios.h> adds terminal I/O controls that reference <unistd.h> primitives such as tcgetpgrp(). This layering promotes modularity, where <unistd.h> provides the core interfaces without overlapping into areas like file status inquiries in <sys/stat.h>, though functions such as fchown() in <unistd.h> interact with status structures defined there. Practically, including <unistd.h> is essential for accessing its functions, such as fork() for process creation, which provides necessary types such as those from <sys/types.h> for portable C programs.

Constants and Macros

Standard File Descriptors

The <unistd.h> header declares three predefined integer constants representing the standard file descriptors for input, output, and error streams in POSIX-compliant systems. These constants are STDIN_FILENO, defined as 0, which corresponds to the standard input stream (stdin); STDOUT_FILENO, defined as 1, for the standard output stream (stdout); and STDERR_FILENO, defined as 2, for the standard error stream (stderr). These values provide low-level, unbuffered access to the underlying file descriptors, typically connected to the terminal or pipes, allowing direct system calls without the buffering overhead of higher-level C standard I/O functions. These constants were introduced in POSIX.1-1990 to standardize the numbers across systems, replacing hardcoded "magic numbers" (0, 1, and 2) in code for improved portability and readability. Prior to , programs often used literal integers, leading to potential inconsistencies in non-POSIX environments, but the symbolic constants ensure consistent behavior in compliant implementations. In practice, these descriptors facilitate portable low-level I/O operations, such as writing diagnostic messages or log data directly to standard output without relying on buffered streams. For example, a program can use the write function to output bytes to STDOUT_FILENO as follows:
c
#include <unistd.h>

ssize_t bytes_written = write(STDOUT_FILENO, "Hello, world!\n", 14);
if (bytes_written == -1) {
    // Handle error
}
This approach is particularly useful in shell scripts, daemons, or performance-sensitive applications where unbuffered writes to or terminals ensure immediate data transfer. Operations on these standard file descriptors, such as read or write, return -1 on failure and set the global errno variable to indicate the specific error. Common errors include EBADF, which is set if the descriptor is invalid or not open for the requested operation (e.g., writing to a read-only STDIN_FILENO). Other potential errors, like EAGAIN for non-blocking operations or EINTR for signal interruptions, also apply, requiring programs to check errno for robust error handling.

Pathname and Environment Limits

The <unistd.h> header, in conjunction with <limits.h>, defines several macros that establish minimum limits for pathnames, filenames, and environment-related data structures to ensure development. These constants provide compile-time guarantees for buffer sizes, allowing developers to allocate safely without risking overflows in operations involving strings or argument lists. For instance, _POSIX_PATH_MAX is defined as 256, specifying the minimum acceptable maximum number of bytes in a pathname, including the terminating . Similarly, _POSIX_NAME_MAX sets a minimum of 14 bytes for the maximum length of a component, excluding the null terminator. These values originate from the POSIX.1 standard, with formalization in POSIX.1-2001, to support consistent behavior across conforming systems. Another key macro, _POSIX_ARG_MAX, defines a minimum of 4,096 bytes for the total length of arguments and data passed to exec functions, such as execve(), ensuring that command-line invocations and environment variables fit within predictable bounds. These limits guide allocation in functions like getcwd(), which retrieves the current into a user-provided sized at least to PATH_MAX (derived from _POSIX_PATH_MAX). By adhering to these minima, applications avoid assumptions about system-specific capacities, promoting robustness; for example, exceeding _POSIX_NAME_MAX in a pathname component triggers an error on strictly conforming systems via the _POSIX_NO_TRUNC feature. While these macros represent baselines, actual system limits often exceed them and can vary by filesystem or configuration, queryable at runtime for precision. The pathconf() function, declared in <unistd.h>, retrieves file- or directory-specific limits such as _PC_PATH_MAX and _PC_NAME_MAX, while sysconf(_SC_ARG_MAX) provides the effective value for argument lengths. This variability is addressed in SUSv4 (aligned with and later), which permits implementations to support larger values without altering the compile-time constants. On modern filesystems like , effective limits extend to 255 bytes per filename and 4,096 bytes per full pathname, far surpassing minima to accommodate contemporary usage patterns.

Function Categories

Process Control Functions

The process control functions in <unistd.h> provide essential mechanisms for managing process creation, execution, termination, and identification in POSIX-compliant systems. These functions enable the of process hierarchies, allowing processes to spawn children, monitor their status, and retrieve identifiers for both processes and associated users. Key functions include fork(), the exec() family, waitpid(), getpid(), getppid(), and getuid(), which collectively support the lifecycle of processes from duplication to replacement and cleanup. The fork() function creates a new by duplicating the calling , resulting in two nearly identical processes that continue execution from the point immediately after the fork() call. Upon success, fork() returns 0 to the , identifying it as the child, and returns the child's positive process ID () to the parent; if creation fails, it returns -1 to the parent with errno set. The inherits copies of the parent's open file descriptors, which reference the same underlying open files, ensuring shared access to resources like standard input and output streams unless explicitly modified. Errors such as EAGAIN may occur if system resources are insufficient or if the limit on child processes {CHILD_MAX} is exceeded. To execute a new program, the exec() family of functions replaces the current process image with a new one loaded from an executable file, terminating the existing program without creating a new process. Functions like execl() accept a variable number of arguments ending in NULL for the command path and its parameters, while execvp() uses an argument vector (argv) and searches the PATH environment variable if the filename lacks a slash. The execve() variant, foundational to the family, takes both an argv array and an envp array to explicitly pass the environment, preserving it across the replacement; other variants inherit from the global environ pointer. On success, these functions do not return, but on failure, control returns to the caller with errno set, such as ENOEXEC for an invalid executable format or EACCES for permission denials on the file or directories in its path. For non-executable scripts, execlp() and execvp() invoke a shell interpreter using the file's contents as input. Parents can synchronize with children using waitpid(), which suspends the calling process until a specified terminates, stops, or continues, storing status information in a provided pointer. The function takes a argument to select children (-1 for any, >0 for a specific , 0 for the caller's , or < -1 for a ), along with options like WNOHANG for non-blocking operation (returning 0 if no status is available) and WUNTRACED to report stopped children due to signals. Status interpretation relies on macros such as WIFEXITED() to check normal termination and WEXITSTATUS() to extract the exit code, or WIFSIGNALED() and WTERMSIG() for signal-induced termination. It returns the child's on success or -1 on error, such as when no child matches the criteria. This mechanism prevents zombie processes by reaping terminated children. Process and user identification functions facilitate querying runtime attributes without altering the process state. The getpid() function returns the PID of the calling process as a pid_t value and always succeeds. Similarly, getppid() returns the parent PID of the calling process, also always succeeding. The getuid() function retrieves the real user ID of the calling process, distinguishing it from the effective user ID obtained via geteuid(), and succeeds without error conditions. These identifiers are crucial for process management, such as in logging or access control decisions.

File and I/O Operations

The file handling functions in <unistd.h> provide mechanisms for opening, closing, and removing files, as well as checking access permissions. The open() function opens a file specified by a pathname, using flags such as O_RDONLY for read-only access or O_CREAT to create the file if it does not exist, requiring an optional mode argument for new files. It returns a non-negative integer file descriptor on success, which serves as a reference to the open file, or -1 on failure with errno set. The close() function releases a file descriptor, deallocating it and freeing associated resources, such as removing record locks and discarding any remaining data in pipes; it returns 0 on success or -1 on error. For file removal, unlink() deletes a directory entry for the specified pathname, decrementing the file's link count and potentially freeing space if no other links or open descriptors remain; it fails with EROFS if the entry is on a read-only filesystem. Prior to operations, access() checks permissions using the real user ID, with modes like R_OK for read access or W_OK for write access, returning 0 if accessible or -1 on failure. The I/O primitives enable unbuffered data transfer and position management. The read() function transfers up to nbyte bytes from the into a , returning the number of bytes read as ssize_t (which may be less than requested due to partial reads at or interruptions), 0 on , or -1 on error. Similarly, write() appends up to nbyte bytes from a to the descriptor, returning the number written or -1 on error; for pipes and FIFOs, POSIX.1 requires atomicity for writes of PIPE_BUF bytes or fewer, ensuring they are not interleaved with writes from other processes, though larger writes may be partial or non-atomic. The lseek() function repositions the offset using an off_t displacement from a reference point specified by whence—such as SEEK_CUR for the current position or SEEK_END for the —returning the new or -1 on error; the use of off_t supports large files beyond traditional limits. Pipes and descriptor duplication facilitate interprocess communication and I/O redirection. The pipe() function creates a bidirectional channel, populating an array with two file descriptors: the read end (fildes[0]) and write end (fildes[1]), allowing data written to one end to be read from the other in first-in-first-out order; it returns 0 on success or -1 on error. For duplication, dup() clones an existing descriptor to the lowest available slot, while dup2() clones it to a specific target descriptor (closing the target if open), both sharing the underlying file description and locks; these are particularly useful for redirecting standard I/O streams, such as duplicating a pipe end to STDOUT_FILENO.
c
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

int fd = open("example.txt", O_RDONLY);  // Open for reading
if (fd == -1) { /* Handle error */ }
ssize_t bytes = read(fd, buffer, sizeof(buffer));  // Read data
close(fd);  // Release descriptor
These functions form the foundation of low-level file I/O in systems, emphasizing portability and efficiency for unbuffered operations.

User and System Identification

The <unistd.h> header provides several functions for querying and group identifiers associated with the calling , enabling programs to determine ownership and privileges without modifying the state. The getuid() function returns the real ID () of the , which corresponds to the who originally invoked the program, while geteuid() retrieves the effective , which may differ if the has elevated privileges through mechanisms like executables. Similarly, getgid() and getegid() return the real and effective group IDs (GIDs), respectively, with the effective GID reflecting any privileges that grant additional rights. These always succeed and do not set errno, providing reliable, read-only to information essential for checks and auditing. For supplementary group memberships, getgroups() populates an array with the process's supplementary group IDs, up to {NGROUPS_MAX} entries, potentially including the effective GID depending on the implementation. The function takes the array size as input and returns the number of groups stored, or -1 on error (e.g., invalid size), allowing applications to allocate sufficient space by first calling it with size 0. This supports scenarios where processes need to verify access based on multiple group affiliations, such as file permissions. System and host identification functions in <unistd.h> include gethostname(), which stores the current host's name in a provided buffer, limited to {HOST_NAME_MAX} bytes (typically 256), null-terminating the string unless truncated. It returns 0 on success or -1 on failure, though no specific errors are defined in POSIX. The getlogin() function returns a pointer to the login name associated with the process's controlling terminal, obtained via file descriptors 0, 1, or 2; if unavailable, alternatives like querying the password database with getpwuid(getuid()) or getpwuid(geteuid()) from <pwd.h> can provide the username. Errors such as [ENOTTY] (no controlling terminal) or [EMFILE] (file descriptor limit) may occur, and the function is not thread-safe. Environment variable access is handled by getenv(), which searches environment for a by name (e.g., "HOME") and returns a pointer to its value string or if not found, without modifying errno. For modifications, setenv() adds or updates a by copying the name and value strings into the , returning 0 on success or -1 with errno set (e.g., [ENOMEM] for memory allocation failure or [EINVAL] for invalid name). The unsetenv() function removes a by name, succeeding silently if it does not exist and failing only on invalid input like an empty name or one containing '='. These operations update the global environ array but are not thread-safe, and subsequent calls may invalidate prior pointers. Unlike IDs from getpid(), which identify instances, these queries focus on persistent user and system attributes.

Time and Signal Utilities

The <unistd.h> header includes functions for implementing time delays, setting alarms that interact with signals, and resolving pathnames through management, enabling precise control over process execution timing and asynchronous event handling in environments. These utilities are foundational for applications requiring pauses, timeouts, or directory navigation while adhering to standards that ensure portability across systems. Sleep functions provide mechanisms to suspend execution for specified intervals, allowing other tasks to proceed. The sleep() function pauses the calling for the number of real-time seconds provided as its , or until a caught signal interrupts it; upon interruption by a non-terminating signal with default or ignore action, it returns the remaining sleep time, facilitating retry logic in signal-aware code. For sub-second precision, usleep() suspends execution for the specified number of microseconds, but it was deprecated in POSIX.1-2001 in favor of the more flexible nanosleep() from <time.h>, which supports structured time specifications and better signal handling. POSIX.1-2008 further marks usleep() as obsolescent, recommending against its use in new applications to promote consistent behavior across implementations. Alarm-related functions integrate basic signal delivery for time-based events, often used to implement timeouts or periodic actions. The alarm() sets an interval timer that generates a SIGALRM signal after the specified number of seconds elapse, returning the previous alarm's remaining time or zero if none was pending; specifying zero seconds cancels any active alarm. This mechanism relies on signal handling routines from <signal.h> to process interruptions, such as invoking handlers for SIGALRM to avoid default termination behavior. Complementing this, the pause() suspends the calling thread indefinitely until delivery of any signal that either executes a catching or terminates , returning -1 with errno set to EINTR if interrupted by a catchable signal, thus enabling simple signal-wait patterns. Pathname resolution utilities in <unistd.h> focus on dynamic management of the current , supporting navigation in operations. The getcwd() function copies the absolute pathname of the current into a user-provided of specified size, returning the on success or NULL with errno set to ERANGE if the pathname exceeds the length (which must accommodate at least PATH_MAX bytes including the null terminator). The chdir() function changes the current to the path specified, succeeding only if it names an accessible directory; failure occurs with return value -1 and errno set to ENOENT if the path does not exist, ensuring error handling for invalid navigations. These functions are particularly useful in multi-user contexts alongside user identification queries to enforce secure access to directories.

Implementation Considerations

Portability Across Systems

The <unistd.h> header provides full support on Unix-like operating systems such as , BSD variants, and macOS, which conform to the standard and implement the majority of its functions for process control, file operations, and system utilities. On non- systems like native Windows, support is partial and requires compatibility layers; emulates APIs including <unistd.h> but with limitations, such as emulated fork() that does not behave identically to native Unix implementations due to underlying Windows process model constraints. Similarly, (WSL) offers full compatibility through its Linux kernel, enabling standard <unistd.h> functions, though native Windows lacks fork() and other process-related calls without these layers. POSIX conformance can be tested at compile time using macros defined in <unistd.h>, such as _POSIX_VERSION, which indicates the supported .1 version (e.g., 200809L for .1-2008 or 202405L for .1-2024) to verify baseline functionality availability. For extensions beyond core , feature test macros like _XOPEN_SOURCE (set to 500 or higher) expose additional functions such as getpass() in compliant environments. Common portability pitfalls include variations in exec() family function behavior regarding PATH handling; while POSIX requires searching the PATH environment variable for executables without slashes in their names, the behavior is implementation-defined if PATH is unset or empty, leading to differences across systems in whether a shell is invoked or current directory is searched. Another issue arises with lseek() and the off_t type size, where on 32-bit systems off_t defaults to 32 bits, but modern implementations support 64-bit offsets via _LARGEFILE_SOURCE or _FILE_OFFSET_BITS=64 to handle large files exceeding 2 . Specific adaptations address platform constraints; the provides a subset of <unistd.h> functions through its Bionic libc, supporting core I/O operations like read(), write(), and close() but omitting others such as confstr() and crypt() to align with mobile resource limits. In embedded real-time systems like , <unistd.h> implements core functions (e.g., _exit(), getpid()) for single-process multithreaded environments, with stubs for unsupported process creation calls like fork() to ensure real-time predictability while maintaining partial alignment. POSIX standardization serves as the baseline for these portability strategies, enabling conditional compilation and runtime checks via sysconf() for feature availability.

Common Extensions and Variations

In and environments, the GNU C Library () extends <unistd.h> with non-standard functions such as sync_file_range(), which offers advanced I/O synchronization for specific file ranges, allowing explicit control over write-out and waiting operations to optimize disk flushing, and is gated by _GNU_SOURCE. These -specific additions, successors to the older __USE_GNU macro, enhance performance in resource-intensive applications but reduce portability. However, functions like getresuid() and getresgid(), which retrieve the real, effective, and saved set-user-ID and set-group-ID of the calling process respectively and were previously extensions requiring _GNU_SOURCE, have been adopted into the POSIX.1-2024 standard, providing finer control over user and group identity management. In BSD-derived systems like and macOS (), variations include fchdir() in <unistd.h>, which changes the current using a instead of a , originating from 4.2BSD and providing safer directory operations in environments with restricted access. further introduces cap_getmode() for its capability framework, declared via <sys/capsicum.h> but interacting with <unistd.h> functions; it checks if the process is in capability mode, a that restricts global system calls like access() to only those on capability-bounded s, thereby altering access()'s behavior to enforce boundaries. Windows approximations through emulate <unistd.h> with limitations; for instance, fork() is not natively supported and is typically stubbed or replaced with CreateProcess() calls in extended environments like MSYS2, which simulate process creation but lose semantics such as state. Additionally, getcwd() in aligns with by returning the current directory but differs in handling, where it may conflict with Windows-native _getcwd() due to variations (e.g., drive letters) and deprecation warnings in headers, requiring careful conditional compilation for cross-platform code. Historically, System V UNIX introduced functions like nice() to <unistd.h> for adjusting process scheduling priority by incrementing the nice value, influencing CPU allocation in favor of lower-priority tasks; while now standardized in .1-2001, implementations vary in default behaviors and error handling, such as System V's treatment of negative increments as zero versus BSD's permission denial. These extensions highlight early divergences that POSIX later harmonized, though vendor-specific defaults persist for compatibility.

References

  1. [1]
    <unistd.h>
    DESCRIPTION. The <unistd.h> header defines miscellaneous symbolic constants and types, and declares miscellaneous functions. The actual values of the constants ...
  2. [2]
    [PDF] The UNIX Time- Sharing System
    The UNIX Time-. Sharing System. Dennis M. Ritchie and Ken Thompson. Bell Laboratories. UNIX is a general-purpose, multi-user, interactive operating system for ...
  3. [3]
    The UNIX System -- History and Timeline
    The history of UNIX starts back in 1969, when Ken Thompson, Dennis Ritchie and others started working on the "little-used PDP-7 in a corner" at Bell Labs and ...
  4. [4]
    [PDF] A Research UNIX Reader - Dartmouth Computer Science
    Shortly thereafter the Programmer's Workbench project undertook to. Page 4. -4 ... In the 1980s, as the lab's work spread across a network of machines,.
  5. [5]
    Evolution of the Unix Time-sharing System - Nokia
    Thompson, R. H. Canaday, and Ritchie developed, on blackboards and scribbled notes, the basic design of a file system that was later to become the heart of ...
  6. [6]
    An Introduction to the Programmer's Workbench - ACM Digital Library
    The Programmer's Workbench (PWB) is a specialized computing facility dedicated to supporting large software development pro- jects. Although it performs ...
  7. [7]
    <unistd.h>
    The `<unistd.h>` header defines standard symbolic constants, types, and miscellaneous functions. It includes types like `size_t`, `uid_t`, and `pid_t`.
  8. [8]
    www.opengroup.org
    ### Summary of IEEE, ISO, Open Group Roles and POSIX Milestones
  9. [9]
    [PDF] Portable Operating System Interface (POSIX ) Draft Technical ...
    Oct 31, 2006 · X/Open Portability Guide, July 1985 (ISBN: 0-444-87839-4). Issue 2. X/Open Portability Guide, January 1987: • Volume 1: XVS Commands and ...
  10. [10]
    <unistd.h>
    The <unistd.h> header defines miscellaneous symbolic constants and types, and declares miscellaneous functions. The contents of this header are shown below.
  11. [11]
    Basics of the Unix Philosophy - catb. Org
    Rule of Simplicity: Design for simplicity; add complexity only where you must. Rule of Parsimony: Write a big program only when it is clear by demonstration ...Missing: h | Show results with:h
  12. [12]
    System Calls (The GNU C Library)
    If you specify an invalid sysno , syscall returns -1 with errno = ENOSYS . Example: #include <unistd.h> #include <sys/syscall.h> #include <errno.h> ..
  13. [13]
  14. [14]
  15. [15]
    [PDF] IEEE standard portable operating system interface for computer ...
    The X/OPEN Portability Guide proved useful because X/Open had in many cases already addressed the same issues as P1003.1, though often in a slightly.
  16. [16]
    write
    ### Summary of Error Handling for `write` Function (Standard File Descriptors, errno, EBADF)
  17. [17]
    File I/O · Insight into Linux - kenshin
    The term unbuffered means that each read or write invokes a system call in the kernel. These unbuffered I/O functions are not part of ISO C, but are part of ...
  18. [18]
    <limits.h>
    ### Extracted Definitions and Values
  19. [19]
  20. [20]
    fork - The Open Group Publications Catalog
    The fork() function shall create a new process. The new process (child process) shall be an exact copy of the calling process (parent process) except as ...
  21. [21]
    exec - The Open Group Publications Catalog
    When the execlp() and execvp() functions encounter such a file, they assume the file to be a shell script and invoke a known command interpreter to interpret ...
  22. [22]
    wait
    The waitpid() function shall be equivalent to wait() if the pid argument is (pid_t)-1 and the options argument is 0. Otherwise, its behavior shall be modified ...
  23. [23]
    getpid
    The getpid() function shall return the process ID of the calling process. RETURN VALUE The getpid() function shall always be successful and no return value is ...
  24. [24]
    getppid
    The getppid() function shall return the parent process ID of the calling process. RETURN VALUE. The getppid() function shall always be successful and no return ...
  25. [25]
    getuid
    The getuid() function shall return the real user ID of the calling process. RETURN VALUE. The getuid() function shall always be successful and no return value ...
  26. [26]
    open
    ### Summary of `open()` Flags, Return Value, and File Descriptors
  27. [27]
    close
    ### Summary of close() Description: Releasing Descriptors
  28. [28]
    unlink
    ### Summary of `unlink()` from https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html
  29. [29]
    access
    ### Summary of `access()` from https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html
  30. [30]
    read
    ### Summary of `read()` from https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html
  31. [31]
    write
    An attempt to write to a pipe or FIFO has several major characteristics: Atomic/non-atomic: A write is atomic if the whole amount written in one operation ...
  32. [32]
    lseek
    ### Summary of lseek() from https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html
  33. [33]
    pipe
    ### Summary of pipe() for Creating Bidirectional Channels
  34. [34]
    dup
    ### Summary of `dup()` and `dup2()` for Cloning Descriptors (Useful for Redirection)
  35. [35]
    getuid
    ### Summary of getuid() from https://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html
  36. [36]
    geteuid
    The geteuid() function shall return the effective user ID of the calling process. RETURN VALUE The geteuid() function shall always be successful.
  37. [37]
    getgid
    ### Summary of getgid()
  38. [38]
    getegid
    The following new requirements on POSIX implementations derive from alignment with the Single UNIX Specification: The requirement to include <sys/types.h> ...
  39. [39]
    getgroups
    ### Summary of getgroups()
  40. [40]
    gethostname
    ### Summary of gethostname from https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html
  41. [41]
    getlogin
    ### Summary of getlogin and getlogin_r
  42. [42]
    getpwuid
    The getpwuid() function shall search the user database for an entry with a matching uid. The getpwuid() function need not be reentrant.
  43. [43]
    getenv
    ### Summary of `getenv` from https://pubs.opengroup.org/onlinepubs/9699919799/functions/getenv.html
  44. [44]
    None
    Nothing is retrieved...<|separator|>
  45. [45]
    unsetenv
    ### Summary of `unsetenv` from https://pubs.opengroup.org/onlinepubs/9699919799/functions/unsetenv.html
  46. [46]
    sleep
    ... <unistd.h>. CHANGE HISTORY. First released in Issue 1. Derived from Issue 1 of the SVID. Issue 5. The DESCRIPTION is updated for alignment with the POSIX ...
  47. [47]
    usleep
    The usleep() function shall cause the calling thread to be suspended from execution until either the number of realtime microseconds specified by the argument ...
  48. [48]
    alarm - The Open Group
    Application writers should be aware of possible interactions when the same process uses both the alarm() and sleep() functions. ... h>, <unistd.h>. CHANGE ...
  49. [49]
    pause
    The pause() function shall suspend the calling thread until delivery of a signal whose action is either to execute a signal-catching function or to terminate ...
  50. [50]
    getcwd
    The getcwd() function shall place an absolute pathname of the current working directory in the array pointed to by buf, and return buf.
  51. [51]
    chdir - The Open Group
    Changing the Current Working Directory. The following example makes the value pointed to by directory, /tmp, the current working directory. #include <unistd.h> ...
  52. [52]
  53. [53]
    What is Windows Subsystem for Linux
    ### Summary on POSIX Compliance and unistd.h Functions in WSL
  54. [54]
    exec
    ### Summary of exec Family Functions and PATH Handling
  55. [55]
    feature_test_macros(7) - Linux manual page - man7.org
    The program below can be used to explore how the various feature test macros are set depending on the glibc version and what feature test macros are explicitly ...
  56. [56]
    Android bionic status
    ### List of Supported unistd.h Functions in Android Bionic
  57. [57]
    RTEMS POSIX 1003.1 Compliance Guide 7.491f6c8 (12th May 2025) documentation
    ### Summary of RTEMS POSIX 1003.1 Compliance Guide: `<unistd.h>` and Core Functions for Real-Time Use
  58. [58]
    getresuid(2) - Linux manual page
    - **Description**: `getresuid()` retrieves the real UID, effective UID, and saved set-user-ID of the calling process, storing them in `ruid`, `euid`, and `suid` respectively. `getresgid()` does the same for group IDs.
  59. [59]
    sync_file_range(2) - Linux manual page - man7.org
    sync_file_range() permits fine control when synchronizing the open file referred to by the file descriptor fd with disk.
  60. [60]
    Glibc unistd.h (GNU Gnulib)
    13.115 Glibc Extensions to <unistd.h> ¶. acct · brk · chroot · closefrom · close_range · copy_file_range · daemon · eaccess · endusershell · euidaccess ...Missing: Linux | Show results with:Linux
  61. [61]
    Mac OS X Developer Tools Manual Page For fchdir(2)
    This document is a Mac OS X manual page. Manual pages are a command-line technology for providing documentation. You can view these manual pages locally ...Missing: cap_getmode | Show results with:cap_getmode
  62. [62]
    cap_getmode(2)
    ### Summary of `cap_getmode`
  63. [63]
    Windows-vs-Linux-fork()/exec()-semantics
    fork() creates new process as an almost identical copy of an existing one. exec() loads another executable into the new process and starts to execute it.
  64. [64]
  65. [65]
    nice(2) - Linux manual page - man7.org
    C library/kernel differences POSIX.1 specifies that nice() should return the new nice value. However, the raw Linux system call returns 0 on success. Likewise, ...Missing: V | Show results with:V
  66. [66]
    nice
    A process' nice value is a non-negative number for which a more positive value shall result in less favorable scheduling.Missing: v | Show results with:v