POSIX Standards and Standardization
The Portable Operating System Interface (POSIX) is a family of standards specified by the IEEE Computer Society to maintain compatibility across operating systems. It defines a standard application programming interface (API), command-line shells, and utility interfaces to guarantee that software remains source-code compatible across diverse Unix-like distributions.
Historical Context
In the 1980s, the Unix ecosystem split into competing commercial branches: AT&T’s System V and UC Berkeley’s BSD. Vendors customized their distributions (such as SunOS, HP-UX, and AIX) by modifying system calls, library signatures, and directory layouts.
This fragmentation meant that a C application compiled on SunOS could fail to compile on HP-UX without extensive refactoring of the source files.
For example, prior to POSIX standardization, developers had to write complex preprocessor conditionals (#ifdef) to handle conflicting headers and arguments across different target platforms:
/* Example of pre-POSIX fragmentation requiring system-specific conditional compilation */
#if defined(SYS_V)
#include <sys/termio.h>
#define SET_BAUD(t, b) ((t)->c_cflag = (b))
#elif defined(BSD_OS)
#include <sys/ioctl.h>
#define SET_BAUD(t, b) ((t)->sg_ispeed = (t)->sg_ospeed = (b))
#endif
To resolve this issue, the IEEE initiated the POSIX project (a term coined by Richard Stallman) to define a standardized interface abstraction layer, allowing developers to target a single compliance standard rather than specific distributions.
Core POSIX Interfaces
POSIX defines standard C library interfaces that abstract underlying kernel system calls. Key specifications include:
- File and Directory Operations:
open(),read(),write(),close(),mkdir(),readdir(). - Process Management:
fork(),exec(),wait(),kill(). - Inter-Process Communication (IPC): Sockets, pipes, FIFOs, POSIX shared memory, and POSIX message queues.
- Threading (POSIX Threads): The
pthreadlibrary specifying APIs for thread creation, mutexes, condition variables, and synchronization primitives.
For example, a C program demonstrates process creation using the POSIX standard fork() system interface:
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
int main(void) {
pid_t pid = fork();
if (pid == 0) {
printf("Child process running with POSIX fork.\n");
} else if (pid > 0) {
printf("Parent process started child with PID %d.\n", pid);
}
return 0;
}
This code compiles and executes without modifications on Linux, macOS, FreeBSD, NetBSD, and Solaris, because each OS conforms to the standard POSIX process specification.
Levels of Compliance
Operating systems implement POSIX requirements at different levels of compliance:
- Fully Certified POSIX: Systems that have undergone formal verification testing by the Open Group and paid for certification. Examples include macOS, AIX, HP-UX, and Solaris.
- Mostly Compliant (De Facto POSIX): Systems like Linux, FreeBSD, and OpenBSD that implement nearly all POSIX requirements but choose not to obtain formal certification due to the associated costs, administrative processes, or rapid release models.
- Non-UNIX translation layers: Systems like Windows that translate POSIX calls to native system formats via subsystems (such as WSL, Cygwin, or MSYS).
For example, a developer can run the POSIX standard getconf utility to query system-defined POSIX capability limits and specifications:
# Query if the operating system supports the POSIX Threads (pthreads) standard
getconf _POSIX_THREADS
On a POSIX-compliant system, this command returns the standard version date, verifying support:
200809L
This indicates compliance with the POSIX.1-2008 specification.
Exercise: Identifying POSIX Boundaries
To practice or explore further, see the scenario below for an example of porting applications between systems:
A developer has written a daemon in C that utilizes standard POSIX APIs such as `fork()`, `read()`, and `write()`. This code was originally compiled and extensively tested on a Linux server. The developer is now asked to port this application to run natively on a fleet of machines running macOS.
Based on the levels of compliance discussed, why should this codebase theoretically compile and run correctly on macOS?
References & Further Reading
To practice or explore further, see the publications below for an example of research in these domains:
- Lewine, D. (1991). POSIX Programmer’s Guide: Writing Portable UNIX Programs. O’Reilly Media.
- IEEE Std 1003.1-2017. The Open Group Base Specifications Issue 7 / POSIX.1-2017.
- Stevens, W. R., & Rago, S. A. (2013). Advanced Programming in the UNIX Environment (3rd ed.). Addison-Wesley.
- Kerrisk, M. (2010). The Linux Programming Interface. No Starch Press.
- IEEE Standard for Information Technology - POSIX(TM) Realtime Application Support. IEEE Std 1003.1g-1998.