Introduction to System Call in Linux
In Linux, system calls are the interface between user-space applications and the kernel. They allow processes to request services and interact with the underlying operating system. System calls provide a way for user-level programs to perform privileged operations and access resources managed by the kernel. Here is a detailed explanation of system calls in Linux:
1. System Call?:
A system call is a programmatic way for a process to request a service from the kernel. These services can include tasks like creating a new process, reading or writing data from files, allocating memory, managing processes, and more.
2. Types of System Calls:
There are several categories of system calls in Linux:
- Process Control: Create, terminate, or manipulate processes (e.g.,
fork
,exec
,exit
,wait
). - File Management: Perform operations on files and directories (e.g.,
open
,read
,write
,close
). - Device Management: Control and interact with devices (e.g.,
ioctl
,read
,write
for devices). - Information Maintenance: Retrieve system information (e.g.,
getpid
,getuid
,uname
). - Communication: Enable communication between processes (e.g.,
pipe
,shmget
,msgsnd
). - Synchronisation and Scheduling: Manage process synchronisation and scheduling (e.g.,
semaphore
operations,sched_yield
).
3. How System Calls Work:
When a user-space program needs to perform a privileged operation (like reading from a file), it executes a specific instruction in the program (often referred to as a “trap” or “interrupt”). This triggers a context switch, transferring control from the user-space program to the kernel.
The kernel then identifies the requested system call based on a predefined system call number and the associated arguments. It executes the requested operation, and upon completion, it returns the result to the user-space program.
4. System Call Interface:
The system call interface is a set of functions that provide a way for user-space programs to invoke system calls. In C, these functions are typically provided by the C library (e.g., glibc) and are prefixed with an underscore (e.g., _syscall()
or _syscallX()
).
5. System Call Numbers:
Each system call is associated with a unique number that the kernel uses to identify the requested service. These numbers are defined in system call tables.
6. Examples of Common System Calls:
a. open()
:
- Purpose: Open a file for reading, writing, or both.
- Arguments: File path, flags (read, write, etc.), mode (permissions).
- Returns: File descriptor on success, -1 on error.
b. read()
:
- Purpose: Read data from a file descriptor.
- Arguments: File descriptor, buffer, number of bytes to read.
- Returns: Number of bytes actually read, or -1 on error.
c. write()
:
- Purpose: Write data to a file descriptor.
- Arguments: File descriptor, buffer with data, number of bytes to write.
- Returns: Number of bytes actually written, or -1 on error.
d. close()
:
- Purpose: Close a file descriptor.
- Arguments: File descriptor.
- Returns: 0 on success, -1 on error.
e. fork()
:
- Purpose: Create a new process (child) by duplicating the existing process (parent).
- Arguments: None.
- Returns: Returns twice: once in the parent with the child’s PID, and once in the child with 0.
7. System Call Handling in the Kernel:
The kernel maintains a system call table that maps system call numbers to corresponding functions in the kernel’s code. When a system call is invoked, the kernel uses the system call number to look up the appropriate function to execute.
8. Security and Privilege:
System calls are a critical part of ensuring the security and integrity of the operating system. The kernel enforces access controls to prevent unauthorised access to sensitive resources.
9. Error Handling:
System calls return -1 to indicate an error condition. The specific error can be retrieved using errno
, a global variable that holds the error code.
10. Wrappers and Libraries:
High-level programming languages often provide wrappers for system calls, making it easier for developers to interact with the kernel without needing to manage the low-level details.
Understanding system calls is essential for systems programming, kernel development, and debugging. It allows developers to work closely with the operating system to perform a wide range of tasks, from basic file operations to process management and beyond.