Expert · Embedded C, system calls and careers · topic 58 of 60 · 30 min
C on Linux: files and processes with system calls
Explanation
User space and the kernel
Your program runs in user space and cannot touch hardware, other processes' memory or the disk directly. To do those things it asks the operating-system kernel through a system call. The C library wraps each system call in a function: open, read, write, close, fork, execvp, waitpid and so on (documented in section 2 of the manual: man 2 open). printf, fopen and fgets (section 3) are library functions that add buffering and formatting and eventually call write or read.
File descriptors
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(void) {
int fd = open("log.txt", O_WRONLY | O_CREAT | O_APPEND, 0644); /* returns a small int, or -1 */
if (fd == -1) { perror("open log.txt"); return 1; }
const char msg[] = "order 1042 placed\n";
ssize_t n = write(fd, msg, sizeof msg - 1); /* bytes written, or -1 */
if (n == -1) perror("write");
close(fd);
write(1, "done\n", 5); /* fd 1 is stdout */
return 0;
}| fd | Stream | Default |
|---|---|---|
| 0 | stdin | keyboard / piped input |
| 1 | stdout | terminal / redirected output |
| 2 | stderr | terminal (error messages) |
read(fd, buf, n) may return FEWER bytes than requested (a "short read"), for example from a pipe or network socket, and 0 at end of file. Robust code loops until it has what it needs. The same is true for write on sockets and pipes.
Errors: -1 and errno
System calls report failure by returning -1 and setting the global errno to a code such as ENOENT (no such file) or EACCES (permission denied). perror("context") or strerror(errno) turns it into a readable message. Check errno only right after a call has failed, because other calls may change it.
Processes: fork, exec, wait
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main(void) {
pid_t pid = fork(); /* now TWO processes run from here */
if (pid == -1) { perror("fork"); return 1; }
if (pid == 0) { /* child */
char *args[] = {"ls", "-l", NULL};
execvp("ls", args); /* replace the child's program with ls */
perror("execvp"); /* only reached if exec failed */
_exit(127);
}
int status; /* parent */
waitpid(pid, &status, 0); /* wait for the child to finish */
if (WIFEXITED(status)) printf("child exited with %d\n", WEXITSTATUS(status));
return 0;
}Where to go next
The same system-call style continues into sockets (network programming), pipes and signals, memory mapping (mmap) and threads (pthread_create). These topics are the core of Linux systems programming and of many interviews for systems roles; the man pages and the book "The Linux Programming Interface" are standard references.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
C on Linux: files and processes with system calls · 1/6
In this lesson you will talk to the Linux kernel with system calls.
Prefer a video by a teacher? Find free videos on “linux system calls c open read write fork exec wait tutorial” on YouTube ↗
In real life: A tiny shell
Writing a minimal shell is a classic systems project: read a line, split it into words, fork, exec the command in the child, and wait in the parent. Many Indian university operating-systems labs and systems-programming interviews ask for exactly this.
char line[256];
for (;;) {
printf("mysh> ");
fflush(stdout);
if (!fgets(line, sizeof line, stdin)) break;
char *argv[16]; int argc = 0;
for (char *tok = strtok(line, " \t\n"); tok && argc < 15; tok = strtok(NULL, " \t\n")) argv[argc++] = tok;
argv[argc] = NULL;
if (argc == 0) continue;
if (strcmp(argv[0], "exit") == 0) break;
pid_t pid = fork();
if (pid == 0) { execvp(argv[0], argv); perror(argv[0]); _exit(127); }
if (pid > 0) waitpid(pid, NULL, 0);
}Practice (0/3 done)
What does write(2, "error\n", 6) do?
After pid = fork() succeeds, what does each process see?
On Linux (or WSL), write a C program that copies one file to another using only open, read, write and close (no stdio), in 4 KB chunks, handling short writes and reporting errors with perror. Then write the tiny shell from the example, run a few commands, and use strace on your copy program.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- C interview questionsEmbedded C, system calls and careers · same module
- Embedded C basicsEmbedded C, system calls and careers · same module
- Processes, signals and systemd servicesDevOps: Git, Docker, Kubernetes and CI/CD · Linux for DevOps
- What Linux and Red Hat Enterprise Linux areLinux and Red Hat (RHCSA to RHCE) · Linux and the shell
- Containers, images and registriesDevOps: Git, Docker, Kubernetes and CI/CD · Docker
- Your first program and Go modulesGo Programming (backend and cloud) · Getting started with Go
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Which man page section documents system calls?
Answer: 2
Section 2: system calls; section 3: library functions.
What does read return at end of file?
Answer: 0
0 means no more data; -1 means an error.
What does exec do?
Answer: Replaces the current process's program with another
fork creates; exec replaces.
What is errno?
Answer: A code describing the last error from a failed call
Read it right after the failure.
What does fopen return when the file cannot be opened?Related
What does strerror(errno) return?Related
Answer: A text description of the last error
For example "Permission denied".
What exit code means a command succeeded?Related
Answer: 0
0 is success. Any non-zero code is a failure; 127 means command not found.
What does the Linux kernel do?Related
Answer: Talks to the hardware and runs processes
The kernel is the core of the OS: hardware, memory, processes.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 2 more topics in “Embedded C, system calls and careers” before its exam: C interview questions, Projects and careers with C.
- Module 12 exam: Embedded C, system calls and careers · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- 60 topics left in the course before the final exam.
← Previous: Embedded patterns: interrupts, timing and constraints