System Call¶
Examples¶
fork
Call the fork syscall
Parent waits until child exits
Child sleeps 2 seconds, afterwards, it exits
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
} else if (pid == 0) {
printf("I am child, sleep 2 seconds\n");
sleep(2);
printf("I am child, 2 seconds have passed, now I exit\n");
} else {
printf("I am parent, I wait until child exits\n");
wait(NULL);
printf("I am parent, OK, now child has exited, I also exit\n");
}
return 0;
}
fork + execvp
Call the fork syscall
Parent waits until child exits
Child calls the execvp syscall to execute the sleep UNIX command.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
} else if (pid == 0) {
char *argv[3];
argv[0] = "sleep";
argv[1] = "2";
argv[2] = NULL;
printf("I am child, sleep 2 seconds\n");
if (execvp(argv[0], argv) < 0) {
perror("exec failed");
exit(1);
}
} else {
printf("I am parent, I wait until child exits\n");
wait(NULL);
printf("I am parent, OK, now child has exited, I also exit\n");
}
return 0;
}
fork + chdir + execvp
Call the fork syscall
Parent waits until child exits
Child moves to a directory /home.
Child calls the execvp syscall to execute the pwd UNIX command to show the current directory.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
} else if (pid == 0) {
char *argv[3];
printf("I am child, I move to /home\n");
if (chdir("/home") < 0) {
perror("chdir failed");
exit(1);
}
argv[0] = "pwd";
argv[1] = NULL;
printf("I am child, I execute pwd\n");
if (execvp(argv[0], argv) < 0) {
perror("exec failed");
exit(1);
}
} else {
printf("I am parent, I wait until child exits\n");
wait(NULL);
printf("I am parent, OK, now child has exited, I also exit\n");
}
return 0;
}
open + read + close
Open a (special) file “/proc/cpuinfo”
Read the content and print out
Close the file
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <error.h>
int main(void)
{
int fd;
ssize_t len = 0;
char buf[256];
fd = open("/proc/cpuinfo", O_RDONLY);
if (fd < 0) {
perror("open failed");
exit(1);
}
do {
memset(buf, 0, sizeof(buf));
len = read(fd, buf, sizeof(buf)-1);
if (len < 0) {
perror("read failed");
exit(1);
}
buf[len] = '\0';
printf("%s", buf);
} while (len > 0);
close(fd);
return 0;
}
open + write + close
Open a file named “./syscall_write_example.txt”
Write a string “hello” to the file
Close the file
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <error.h>
int main(void)
{
int fd;
ssize_t len = 0;
fd = open("./syscall_write_example.txt", O_WRONLY | O_CREAT, 0644);
if (fd < 0) {
perror("open failed");
exit(1);
}
len = write(fd, "hello\n", 6);
if (len < 0) {
perror("write failed");
exit(1);
}
close(fd);
return 0;
}
Differences between system calls and library functions¶
We can use library functions for reading and writeing files instead of system calls.
The examples of library functions are fputc (write a character) and fgetc (read a character). They are implemented as part of the standard library using system calls. In other words, such library functions are somewhat wrappers of system calls.

To confirm the issue, let’s use the following program that reads data from procfs.
#include <stdio.h>
int main(void)
{
FILE *fp;
fp = fopen("/proc/cpuinfo", "r");
while (1) {
char c = fgetc(fp);
if (c == EOF)
break;
printf("%c", c);
}
fclose(fp);
return 0;
}
Please compile the program above and run it with strace which is a command shows which system calls are called while the program is running.:
$ gcc PROGRAM.c
$ strace ./a.out
If you do not have the strace command on your VM, please install it using the following command.:
$ sudo apt install strace
Supposedly, you will find a lot of write and read system calls are called, but you won’t see fgetc. This is because fgetc just calls the read system call internally.