A System Call is a way for programs (particularly user programs) to interact with the operating system (OS). When a program needs to perform an operation that requires access to hardware or needs to request services from the OS, it uses system calls. These operations may include tasks like file management, process control, or device manipulation, which cannot be directly performed by user-level programs due to security and system integrity concerns.
System calls provide a controlled interface between the user space (where user applications run) and the kernel space (where the OS core operates). Here's a detailed explanation of system calls:
A system call is a function that allows a user application to request services from the operating system. System calls serve as the gateway between user-level applications and kernel-level operations, providing a mechanism for controlled access to system resources.
For example, an application might request a system call to open a file, allocate memory, or communicate over a network. System calls allow the OS to manage resources, enforce security policies, and ensure that user programs do not violate system rules or interfere with other programs.
System calls can be categorized based on the types of services they provide. Common categories of system calls include:
Process Control: These system calls manage the execution of processes. They allow processes to create, terminate, or communicate with each other.
fork() — Creates a new process by duplicating the calling process.exit() — Terminates the calling process.wait() — Waits for a child process to terminate.exec() — Replaces the current process image with a new one.kill() — Sends a signal to a process, typically used to terminate a process.File Management: These system calls are used for manipulating files and directories.
open() — Opens a file.read() — Reads data from a file.write() — Writes data to a file.close() — Closes an open file.delete() — Deletes a file.mkdir() — Creates a directory.rmdir() — Removes a directory.Device Management: These system calls control devices like printers, disks, or any hardware resource.
ioctl() — Used to control device parameters or operations.read() / write() — Can be used for interacting with devices like disk drives or terminals.Memory Management: These system calls are used to allocate and manage memory for processes.
brk() — Adjusts the end of the data (heap) segment.mmap() — Maps files or devices into memory.munmap() — Unmaps memory regions.sbrk() — Increases or decreases the program’s data space.Communication: These system calls allow processes to communicate with one another, especially in inter-process communication (IPC).
pipe() — Creates a pipe for communication between processes.shmget() — Allocates shared memory.msgget() — Creates a message queue.semop() — Operates on semaphores for synchronization.Information Retrieval: These system calls provide information about the system, processes, or files.
getpid() — Returns the process ID of the calling process.getuid() — Returns the user ID of the calling process.stat() — Retrieves information about a file (e.g., size, permissions).uname() — Retrieves information about the system's hardware and software.System calls are typically invoked using the following process:
User Request: The user-level application triggers a system call by invoking a specific function or API provided by the OS.
Switching to Kernel Mode: When a system call is invoked, the processor switches from user mode (where the application runs) to kernel mode (where the OS runs). This context switch is necessary because only the OS has direct access to hardware resources.
System Call Handler: The OS kernel has a system call dispatcher that receives the request. The kernel then processes the request and takes the necessary actions (e.g., accessing the file system, managing memory, scheduling processes).
Return to User Mode: After the kernel performs the requested action, control is returned to the user program, typically with a result (such as the status of the request or data).
The system call interface (SCI) is the mechanism that allows programs to communicate with the operating system kernel. The interface provides a set of defined system call numbers and parameters that the OS understands. Here's how it typically works:
System Call Table: The operating system maintains a system call table where each system call is assigned a unique number. When a system call is made, the kernel uses this table to identify which function should be executed.
Wrapper Functions: Most high-level programming languages provide wrapper functions that hide the complexity of invoking system calls. For example, in C, a function like fopen() is a higher-level wrapper for the open() system call.
Context Switch: When a system call is made, a context switch occurs. The system must switch from user space to kernel space, which involves saving the state of the user program, loading the kernel state, and executing the requested system call.
Let’s consider a few examples of system calls:
open(): This system call is used to open a file. It takes the file name and mode (read, write, etc.) as arguments.
int fd = open("example.txt", O_RDONLY);read(): This system call reads data from a file into a buffer.
ssize_t bytesRead = read(fd, buffer, 1024);write(): This system call writes data to a file or device.
ssize_t bytesWritten = write(fd, buffer, 1024);close(): This system call closes an open file descriptor.
close(fd);fork(): This system call creates a new process by duplicating the calling process.
pid_t pid = fork();
if (pid == 0) {
// Child process code
} else {
// Parent process code
}
exec(): This system call loads a new program into the process’s address space, replacing the current program.
execvp("/bin/ls", args);mmap(): This system call maps files or devices into memory, creating a memory region that can be accessed directly.
void *addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);pipe(): This system call creates a unidirectional communication channel between two processes.
int pipefd[2];
pipe(pipefd);
shmget(): This system call creates a shared memory segment that can be accessed by multiple processes.
int shmId = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0666);Here is a simple example using the fork(), exec(), and wait() system calls in C to create a child process:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
// Child process
printf("Child process: Executing 'ls'\n");
execlp("/bin/ls", "ls", NULL); // Replace child process with ls
} else if (pid > 0) {
// Parent process
wait(NULL); // Wait for child to finish
printf("Parent process: Child process finished\n");
} else {
// Error occurred
printf("Fork failed\n");
}
return 0;
}
In this example:
fork() creates a new process.execlp() replaces the child process with the ls program.wait() ensures the parent process waits until the child process completes.System calls are essential for enabling programs to interact with the operating system. They provide a controlled interface to access OS services, ranging from process management to file handling. By using system calls, applications can request resources and perform essential tasks like file I/O, process control, and memory management. Understanding system calls is fundamental for understanding how operating systems work and how low-level programming interfaces with the OS.
Open this section to load past papers