System Calls
In the world of computing, system calls can be thought of as a child asking their parents for help with tasks that are beyond their capabilities or permissions. Just as a child might ask a parent to reach something from a high shelf, bake a cake, or use a tool that's too dangerous for them, an application (like the child) requests the operating system (like the parent) to perform certain tasks that require special privileges or access.
This parent-child analogy highlights the concept of privilege in computing. The operating system (parent) operates with higher privileges, similar to how parents have more authority and capabilities in a household. They can access and modify system resources, manage hardware interactions, and perform critical tasks. Meanwhile, the application (child) operates in a more restricted, less privileged environment. It can perform a variety of tasks independently but must rely on the operating system for anything that requires elevated privileges or access to restricted resources.
In this way, system calls represent a controlled and safe communication channel between applications and the operating system, ensuring that tasks requiring special privileges are handled securely and efficiently, much like how parents ensure the safety and well-being of their children by overseeing activities that are too complex or risky for them to handle alone.
System calls are a key component in the interaction between application software and the operating system. They serve as a bridge for communication between user space (where applications run) and kernel space (where core system functions and resources are managed).
Why Do Application Software Need System Calls?
Resource Management: System calls allow applications to request resources such as memory, CPU time, and I/O devices in a controlled manner.
Security and Stability: By using system calls, applications are restricted from directly accessing hardware or core system features, which helps maintain system integrity and security.
Abstraction and Simplification: They abstract the complexities of hardware interaction, providing a simpler interface for application developers.
How System Calls Enhance Safety by Delegating to the Kernel?
Privileged vs Unprivileged Instructions:
Privileged Instructions are those that can only be executed by the kernel. They include operations that can affect the core functions of the OS, like managing memory or controlling I/O devices.
Unprivileged Instructions can be executed by user applications. They are limited in scope to prevent applications from harming the system or other applications.
Delegation to Kernel: When an application needs to perform an operation that requires privileged access (like accessing a hardware device), it makes a system call. The kernel then safely executes this operation on behalf of the application.
Workflow of a System Call
Here's a simplified ASCII art representation of how software makes system calls, and the subsequent steps:
User Mode Kernel Mode
---------- ----------------
| | | |
| App | -- System Call Request -> | Kernel |
| | | |
| (User) | <-- Results & Control --- | (Privileged) |
---------- ----------------
System Call Request: The application in user mode makes a system call.
CPU Changes Privilege: The CPU switches to a privileged mode to execute the call in the kernel.
OS Checks Input: The OS, in kernel mode, validates and processes the input from the system call.
Execution: The kernel performs the required operations (e.g., accessing hardware, managing resources).
Return to User Mode: Results and control are passed back to the application in user mode.
This mechanism ensures that only safe and controlled interactions occur between the application and the system hardware, maintaining system stability and security.
Let's look at some popular system calls in Linux.
File System
open
: Opens a file or device.close
: Closes an open file descriptor.read
: Reads data from an open file.write
: Writes data to an open file.lseek
: Repositions the file offset of an open file descriptor.stat
: Retrieves information about a file.mkdir
: Creates a new directory.rmdir
: Removes a directory.unlink
: Deletes a file.
Process Control
fork
: Creates a new process.exit
: Terminates the current process.wait
: Waits for a child process to terminate.execve
: Executes a program.getpid
: Returns the process ID of the calling process.kill
: Sends a signal to a process.
Memory Management
brk
: Changes the amount of space allocated for the calling process's data segment.mmap
: Maps files or devices into memory.munmap
: Unmaps a file or device from memory.
Network
socket
: Creates a new socket.bind
: Associates a socket with an address.listen
: Listens for connections on a socket.accept
: Accepts a connection on a socket.connect
: Initiates a connection on a socket.send
: Sends data on the socket.recv
: Receives data from a socket.
Inter-Process Communication (IPC)
pipe
: Creates a pipe for inter-process communication.shmget
: Allocates a shared memory segment.shmat
: Attaches a shared memory segment.msgget
: Creates a message queue.msgsnd
: Sends a message to a message queue.msgrcv
: Receives a message from a message queue.
User and Group Information
getuid
: Returns the user ID of the calling process.setuid
: Sets the user ID of the calling process.getgid
: Returns the group ID of the calling process.setgid
: Sets the group ID of the calling process.
Time
time
: Returns the current time.gettimeofday
: Gets the current time and date.nanosleep
: Suspends the execution of the calling process for an interval measured in nanoseconds.
Miscellaneous
ioctl
: Manipulates the underlying device parameters of special files.syslog
: Reads and/or clears the kernel message ring buffer.getpriority
: Gets the scheduling priority.setpriority
: Sets the scheduling priority.
These system calls provide a wide range of functionalities necessary for the efficient operation of Linux systems, from basic file operations to complex inter-process communications and network interactions.
Subscribe to my newsletter
Read articles from Jyotiprakash Mishra directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Jyotiprakash Mishra
Jyotiprakash Mishra
I am Jyotiprakash, a deeply driven computer systems engineer, software developer, teacher, and philosopher. With a decade of professional experience, I have contributed to various cutting-edge software products in network security, mobile apps, and healthcare software at renowned companies like Oracle, Yahoo, and Epic. My academic journey has taken me to prestigious institutions such as the University of Wisconsin-Madison and BITS Pilani in India, where I consistently ranked among the top of my class. At my core, I am a computer enthusiast with a profound interest in understanding the intricacies of computer programming. My skills are not limited to application programming in Java; I have also delved deeply into computer hardware, learning about various architectures, low-level assembly programming, Linux kernel implementation, and writing device drivers. The contributions of Linus Torvalds, Ken Thompson, and Dennis Ritchie—who revolutionized the computer industry—inspire me. I believe that real contributions to computer science are made by mastering all levels of abstraction and understanding systems inside out. In addition to my professional pursuits, I am passionate about teaching and sharing knowledge. I have spent two years as a teaching assistant at UW Madison, where I taught complex concepts in operating systems, computer graphics, and data structures to both graduate and undergraduate students. Currently, I am an assistant professor at KIIT, Bhubaneswar, where I continue to teach computer science to undergraduate and graduate students. I am also working on writing a few free books on systems programming, as I believe in freely sharing knowledge to empower others.