Beginner’s guide to System Call in Linux: Learn how programs interact with the kernel for files, processes, memory, and device management
Imagine this: You’re sitting in front of your laptop, typing a command like ls to see the files in a folder. Instantly, your terminal prints the list of files. Seems simple, right? But behind the scenes, something magical happens — your command doesn’t talk directly to your hardware. Instead, it asks the operating system for help.
That “help request” is what we call a system call in Linux.
Just like when you need to withdraw cash, you don’t walk into the bank’s vault directly — you interact with a teller or ATM. In the same way, programs don’t access hardware (like CPU, memory, or disk) directly. They use system calls as a secure and controlled gateway.
Making it more understandable System Call
It’s a hot summer afternoon. The sun is blazing, and you’re sitting in your room, sweating. You don’t want to get up, but you’re terribly thirsty. There’s a chilled water bottle in the fridge, but instead of walking to the kitchen yourself, you call your younger brother:
“Hey, can you please get me some cold water from the fridge?”
Your brother goes, opens the fridge, and hands you the bottle.
Now think about this carefully — you didn’t go to the fridge yourself, but you still got the water. You just requested the help of someone who had access.
This is exactly how system calls in Linux work.
Your program (you) can’t directly touch the fridge (hardware). Instead, it has to request help from someone who can access it safely — in this case, your brother (the kernel). The request you made (“get me water”) is like a system call.
Just like you trust your brother not to break the fridge while getting water, the Linux kernel ensures programs interact with hardware safely and efficiently.
What is a System Call in Linux?
A system call in Linux is the way a program requests a service from the kernel.
The kernel is the heart of Linux — it manages resources like memory, files, devices, and processes. Since user programs cannot directly interact with the kernel for safety reasons, system calls act as a middleman.
In short: System calls are APIs provided by the Linux kernel that allow user-space applications to request kernel-level services.
Why Do We Need System Calls?
Without system calls, your program would be like a driverless car on a busy highway — unsafe and chaotic. System calls bring order, security, and efficiency.
Here’s what they help with:
- Process Management – Create, schedule, or terminate processes (
fork,exec,exit). - File Management – Open, read, write, and close files (
open,read,write). - Device Management – Communicate with devices like keyboard, mouse, or disk.
- Memory Management – Allocate or free memory (
mmap,brk). - Communication – Enable interaction between processes (
pipe,socket).
Types of System Calls in Linux
System calls can be grouped into categories for easier understanding:
- Process Control
- Examples:
fork(),exec(),exit(),wait(). - Used to start or stop programs.
- Examples:
- File Management
- Examples:
open(),read(),write(),close(). - Deal with files and directories.
- Examples:
- Device Management
- Examples:
ioctl(),read(),write(). - For reading and writing from devices.
- Examples:
- Information Maintenance
- Examples:
getpid(),alarm(),sleep(). - Retrieve or update system information.
- Examples:
- Communication
- Examples:
pipe(),shmget(),msgsnd(). - For inter-process communication (IPC).
- Examples:
Example: How a System Call Works
Let’s look at a small C program:
#include <stdio.h>
#include <unistd.h>
int main() {
write(1, "Hello, Linux!\n", 14);
return 0;
}
Here, the function write() is a system call.
1→ Standard output (your terminal)."Hello, Linux!\n"→ Message to print.14→ Number of characters.
Real Linux system call example in C
Example 1: Using system() to run ls
#include <stdio.h>
#include <stdlib.h> // for system()
int main() {
printf("Listing files in the current directory using a system call:\n\n");
// system() calls the shell to execute a command like 'ls'
int ret = system("ls -l");
if (ret == -1) {
perror("system call failed");
return 1;
}
return 0;
}
Explanation:
system()is a library function, but internally it makes a system call to the kernel to execute/bin/shwith your command.- The kernel interacts with the filesystem (hardware) to fetch the list of files.
- Just like in your story, you asked the kernel to do a task (fetch water → fetch file list).
Example 2: Using fork() and exec() (more low-level, like real system calls)
#include <stdio.h>
#include <unistd.h> // for fork(), execl()
#include <sys/wait.h> // for wait()
int main() {
pid_t pid = fork(); // create a new process
if (pid == 0) {
// Child process: kernel executes this
printf("Child process: Executing 'ls -l'\n");
execl("/bin/ls", "ls", "-l", NULL); // replace child process with 'ls'
perror("execl failed"); // only runs if execl fails
} else if (pid > 0) {
// Parent process: wait for child to finish
wait(NULL);
printf("\nParent process: 'ls' command completed by child process.\n");
} else {
perror("fork failed");
return 1;
}
return 0;
}
Explanation:
fork()→ asks the kernel to create a new process.execl()→ tells the kernel to run a program (ls) in the child process.wait()→ parent waits for the kernel to complete the task.
Analogy to your story:
- You (user program) don’t fetch files yourself.
- Kernel (brother) executes the command (
ls) and brings results back.
Example: Reading a File Using System Calls in C
#include <stdio.h>
#include <fcntl.h> // For open()
#include <unistd.h> // For read(), write(), close()
#include <errno.h> // For perror()
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <filename>\n", argv[0]);
return 1;
}
const char *filename = argv[1];
// System call: open the file
int fd = open(filename, O_RDONLY);
if (fd == -1) {
perror("open failed");
return 1;
}
char buffer[BUFFER_SIZE];
ssize_t bytesRead;
// System call: read from the file
while ((bytesRead = read(fd, buffer, sizeof(buffer))) > 0) {
// System call: write to stdout
if (write(STDOUT_FILENO, buffer, bytesRead) == -1) {
perror("write failed");
close(fd);
return 1;
}
}
if (bytesRead == -1) {
perror("read failed");
}
// System call: close the file
if (close(fd) == -1) {
perror("close failed");
return 1;
}
return 0;
}
Explanation: Real System Call Application
open()→ Ask the kernel to open a file (like requesting a resource).read()→ Ask the kernel to read data from that file.write()→ Ask the kernel to print data to your terminal.close()→ Ask the kernel to release the file.
Analogy:
- You (user program) don’t directly touch the disk (hardware).
- Kernel handles all low-level operations.
- System calls are the bridge between user space and space.
System Calls vs Interrupts in Linux
When you run a command like ls in Linux, it’s easy to assume that the kernel immediately knows what to do. But under the hood, Linux uses system calls to let user programs request services from the kernel, while interrupts handle hardware events asynchronously. Let’s break this down.
1. What is a System Call?
A system call is a request from a user-space program to the kernel to perform a privileged operation, such as:
- Opening files or directories (
open()) - Reading file contents (
read()) - Writing output to the terminal (
write())
When you run ls, it doesn’t directly access the filesystem. Instead, it makes system calls to the kernel, which safely retrieves directory contents and returns the data to ls for display.
2. What is an Interrupt?
An interrupt is a signal from hardware or software that temporarily halts the CPU to handle urgent tasks, such as:
- A key press on the keyboard
- Data ready from a disk or network card
- Timer expiration for multitasking
Interrupts are asynchronous. They can occur at any time, even when the kernel is busy handling a system call.
3. How ls Executes in Linux
- User types
lsin the shell. - Shell executes the
lsprogram in user space. lsmakes system calls (open(),read(),write()) to interact with the kernel.- Meanwhile, the kernel may be interrupted by hardware events (like timers or I/O signals), ensuring it remains responsive.
Key Point: Running ls does not trigger an interrupt. System calls are synchronous requests to the kernel, while interrupts handle asynchronous hardware events.
| Feature | System Call | Interrupt |
|---|---|---|
| Trigger | User program | Hardware or software |
| Timing | Synchronous | Asynchronous |
| Purpose | Request kernel service | Notify kernel of event |
| Example | read(), write(), open() | Keyboard press, timer, disk ready |
Hardware interrupts and Software interrupts
1. Hardware Interrupts (HW Interrupts)
- Origin: Physical hardware devices.
- Purpose: Notify the CPU that something urgent happened.
- Examples:
- Keyboard key pressed
- Mouse movement
- Network packet arrival
- Disk read/write complete
- Timer tick for process scheduling
Key point: Hardware interrupts can occur at any time, even if the CPU is executing a system call or kernel code.
2. Software Interrupts (SW Interrupts)
- Origin: Software requests, usually from programs or the OS itself.
- Purpose: Trigger CPU to switch from user mode to kernel mode.
- Example: System calls like
read(),write(),open()in Linux on x86 usingint 0x80(historical) orsyscallinstruction (modern).
Note:
- They behave like interrupts in the sense that they transfer control to the kernel.
- But they are synchronous, caused intentionally by a program, not asynchronously by hardware.
Applications of System Calls in Linux
1. File Operations
System calls allow programs to create, read, write, and manage files.
- Common system calls:
open()read()write()close()lseek()unlink()
Example in C:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_CREAT | O_WRONLY, 0644);
if (fd < 0) {
perror("open");
return 1;
}
char *msg = "Hello, Linux system call!\n";
write(fd, msg, 25); // write to file
close(fd);
return 0;
}
Application: Writing log files, reading configuration files, or handling user data.
2. Process Management
System calls help in creating and controlling processes.
- Common system calls:
fork()– create a child processexec()– execute a programwait()– wait for a process to finishexit()– terminate a processgetpid()/getppid()– get process IDs
Example in C:
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t pid = fork(); // create a child process
if (pid == 0) {
printf("Child process: PID = %d\n", getpid());
} else if (pid > 0) {
printf("Parent process: PID = %d, child PID = %d\n", getpid(), pid);
} else {
perror("fork");
}
return 0;
}
Application: Running background tasks, launching shells, or process scheduling.
3. Memory Management
System calls allow a program to allocate or manipulate memory.
- Common system calls:
mmap()– map files or devices into memorybrk()/sbrk()– manage heap memorymunmap()– unmap memory
Example in C:
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
int main() {
int *arr = mmap(NULL, 10 * sizeof(int), PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (arr == MAP_FAILED) {
perror("mmap");
return 1;
}
for (int i = 0; i < 10; i++)
arr[i] = i * i;
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
munmap(arr, 10 * sizeof(int));
return 0;
}
Application: Allocating shared memory, memory-mapped files, or dynamic memory management.
4. Interprocess Communication (IPC)
System calls are used to communicate between processes.
- Common system calls:
pipe()shmget()/shmat()(shared memory)msgget()/msgsnd()/msgrcv()(message queues)socket()(network communication)
Example in C (Pipe):
#include <stdio.h>
#include <unistd.h>
int main() {
int fd[2];
pipe(fd); // create a pipe
pid_t pid = fork();
if (pid == 0) { // child
close(fd[0]); // close read end
write(fd[1], "Hi parent", 10);
} else { // parent
char buffer[20];
close(fd[1]); // close write end
read(fd[0], buffer, 10);
printf("Parent received: %s\n", buffer);
}
return 0;
}
Application: Data sharing, client-server communication, or synchronization.
5. Device Control
System calls interact with hardware devices via device files.
- Common system calls:
ioctl()– device-specific operationsread()/write()– reading/writing to devices
Example in C:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main() {
int fd = open("/dev/ttyS0", O_RDWR);
if (fd < 0) {
perror("open device");
return 1;
}
// Example: ioctl(fd, some_command, argument);
close(fd);
return 0;
}
Application: Controlling sensors, serial devices, or custom hardware.
6. Networking
System calls enable network programming.
- Common system calls:
socket()bind()listen()accept()connect()send()/recv()
Example in C (Socket Creation):
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket");
return 1;
}
printf("Socket created successfully!\n");
return 0;
}
Application: Building network servers, clients, or IoT communication.
System calls form the backbone of Linux application development, enabling programs to:
- Access and manage files
- Control processes
- Handle memory
- Communicate between processes
- Interface with hardware
- Enable networking
Almost every real-world Linux program relies on system calls under the hood.
Advantages of System Calls in Linux
Security – Prevents programs from directly accessing sensitive hardware.
Simplicity – Provides a clean interface for programmers.
Portability – Same code works across different Linux distributions.
Efficiency – Optimized by the kernel for fast execution.
Disadvantages of System Calls
Overhead – Each system call involves switching from user mode to kernel mode, which can slow things down.
Complexity for Beginners – Understanding low-level details may feel overwhelming.
Limited Control – Programs depend on what the kernel allows.
Final Thoughts
Think of system calls in Linux as the trusted gatekeepers between your program and the kernel. They ensure smooth, safe, and efficient communication. Without them, Linux wouldn’t be the stable powerhouse we know today.
So, the next time you run a command or write a program, remember — every action, from printing text to creating files, relies on system calls working silently in the background.
System Call in Linux – Interview Questions
Beginner-Level Questions
- What is a System Call in Linux?
- Why are System Calls needed in Linux?
- Can you name a few common System Calls in Linux?
- What is the difference between a System Call and a function call?
- How does a Linux program switch from user space to kernel space?
- Which System Call is used to create a new process in Linux?
- What is the role of the
fork()System Call in Linux? - How is file handling done using System Calls in Linux?
- Can you explain the purpose of the
open()andclose()System Calls? - What is the difference between
read()andwrite()System Calls in Linux?
Intermediate-Level Questions
- How does the Linux kernel identify which System Call a process is requesting?
- What is the purpose of the
exec()family of System Calls in Linux? - How does the
wait()System Call work in process management? - Can you explain the use of the
mmap()System Call in Linux? - What happens if a System Call in Linux fails?
- How are System Calls implemented at the assembly level in Linux?
- What is the role of System Call numbers in Linux?
- How does the Linux kernel return results or error codes from a System Call?
- Can you explain how signals relate to System Calls in Linux?
- What is the difference between blocking and non-blocking System Calls?
Advanced-Level Questions
- How does the Linux kernel handle System Call context switching?
- What are Virtual System Calls (vsyscall) in Linux?
- How do System Calls in Linux ensure security and privilege separation?
- Can you explain the role of
ioctl()System Call in device drivers? - How does Linux optimize System Calls using the
vdsomechanism? - What is the difference between System Calls, Library Calls, and APIs in Linux?
- How are System Calls traced using tools like
stracein Linux? - Can you explain the difference between synchronous and asynchronous System Calls?
- What changes are needed in the Linux kernel to add a new System Call?
- How do System Calls differ across different architectures in Linux (x86 vs ARM)?
You can also Visit other tutorials of Embedded Prep
- Multithreading in C++
- Multithreading Interview Questions
- Multithreading in Operating System
- Multithreading in Java
- POSIX Threads pthread Beginner’s Guide in C/C++
- Speed Up Code using Multithreading
- Limitations of Multithreading
- Common Issues in Multithreading
- Multithreading Program with One Thread for Addition and One for Multiplication
- Advantage of Multithreading
- Disadvantages of Multithreading
- Applications of Multithreading: How Multithreading Makes Modern Software Faster and Smarter”
- Master CAN Bus Interview Questions 2025
- What Does CAN Stand For in CAN Bus?
- CAN Bus Message Filtering Explained
- CAN Bus Communication Between Nodes With Different Bit Rates
- How Does CAN Bus Handle Message Collisions
- Message Priority Using Identifiers in CAN Protocol
Mr. Raj Kumar is a highly experienced Technical Content Engineer with 7 years of dedicated expertise in the intricate field of embedded systems. At Embedded Prep, Raj is at the forefront of creating and curating high-quality technical content designed to educate and empower aspiring and seasoned professionals in the embedded domain.
Throughout his career, Raj has honed a unique skill set that bridges the gap between deep technical understanding and effective communication. His work encompasses a wide range of educational materials, including in-depth tutorials, practical guides, course modules, and insightful articles focused on embedded hardware and software solutions. He possesses a strong grasp of embedded architectures, microcontrollers, real-time operating systems (RTOS), firmware development, and various communication protocols relevant to the embedded industry.
Raj is adept at collaborating closely with subject matter experts, engineers, and instructional designers to ensure the accuracy, completeness, and pedagogical effectiveness of the content. His meticulous attention to detail and commitment to clarity are instrumental in transforming complex embedded concepts into easily digestible and engaging learning experiences. At Embedded Prep, he plays a crucial role in building a robust knowledge base that helps learners master the complexities of embedded technologies.
