Why do we need system calls

Recently I took an Introduction to Operating Systemcourse and a few questions came to my mind, like how many system calls are there? Which one are the most common ones? Well, it’s surprising that Linux kernel 3.0 has whopping 326 system calls. However, it’s not efficient to go through all the system calls that exists, we’ll look at some of the common ones, so, here’s the System calls every programmer should know.

We all know that system calls are basically a way in which a program requests a service from the kernel of the OS which may include hardware-related services like accessing files from hard disk, creation, and execution of new processes, etc. You can read more about operating systems at Operating System: Introduction.

All the system calls that we’re discussing here are grouped into three categories, these are:-

  • System Calls for Process Management
  • System Calls for Signalling
  • System Calls for Protection

System Calls for Process Management

Some important process management system calls are fork, wait, exec, getpid, brk. The fork system call is basically used for creating a new process identical to parent process including all the file descriptors, stack pointer, program counter, and all other registers too, i.e. everything. Fork returns the child’s PID in the parent process and 0 in the child process if it encounters some error it returns -1. If you want to read more about fork like its description, argument, return type, error, just execute

man 2 fork

command in your Linux terminal and you can see Linux Programmer’s manual something like this.

Typical output of a man command

Thesystem call waitis used in the parent process to wait for the child to get terminated, stopped by a signal or resumed by a signal. It returns PID of the child which is being terminated, stopped or resumed and takes a pointer to a status variable as an argument. If you need to wait for a particular child (PID), you can use waitpidwhich is another variant of wait system call. The wait system call is necessary otherwise the child process will go into the zombie state. The execve (or exec, execv) system call exit the current process that it is running and starts a new program. It takes three arguments as input, by convention the first parameter is the filename (string) which points to the program that is going to be executed, the second parameter is an array of string which is the argument vector for the program which is going to be executed by execve, with a null pointer at the end. The exec system call replaces the core image of the process with the image of the new process, hence exec never returns anything, except when some error occurs. The system call getpid simply returns the PID of the current process. The system call brkused to increase or decrease the process’s data segment. It returns the new address where the data segment of the process is to end. However, brk is not defined by the POSIX standard and hence programmers are encouraged to use the malloc library procedure for dynamically allocating memory.

I think it’s enough for the theory, let’s do some coding by making use of fork, execv, wait, getpid and exit system call.

forkExample.cexecExample.c

In the above code, I’ve added a 5 seconds sleep time at two places, one in forkExample.c and other in execExample.c, so that during sleep I can execute

ps -a

command in the terminal, which gives the list of all the active processes.

Now, when we first execute our forkExample program, its output during its first 5-seconds sleep is:

forkExample output during its 5 second sleep

meanwhile, the output of ps -a is:

ps -a output

Clearly, in the second image, we can see, the PID of forkExample is 4290 which is the same as in the first image.

After the first sleep, fork is called and child process is created which again goes into 5-seconds sleep, during this the output of program and ps -a are as follows:

forkExample output during its child’s 5 second sleepps -a output

in the above image, we can see that a child process is created with PID 4297 which is the same as in forkExample output.

After the completion of the child process’s 5-seconds sleep, the rest of the parent process is executed. In the image below we can clearly see the value returned by the child process, i.e. 52.

forkExample output

System Calls for Signalling

A Signal in an operating system is a limited form of inter-process communication, it is a way in which the operating system sends a notification to a process or a thread to notify it of an event, for example when CTRL + C is pressed in the terminal, the terminal sends an interrupt signal to the running foreground process. Let’s take an example to understand better.

signalExample.c

In this example, a handler is assigned to the SIGINT signal, wiz. Interrupt from the keyboard, which occurs when CTRL + C is pressed. The output of the program is:

output

In the above example, when CTRL + C is pressed, the SIGINT signal is sent to the signalExample process which doesn’t stop the process instead it invokes the handler. However, when CTRL + \ is pressed, the SIGQUIT signal is sent to the process which is not handled manually like SIGINT and hence default action is performed and the process is stopped. Handlers are sometimes used to ignore some specific signals, for example, a background process is supposed to ignore CTRL + C interrupt signal from the keyboard.

When a signal is generated, the state of the process is pushed into its stack and the signal handler is invoked. When the signal handling procedure is done, it calls sigreturn to continue where it left off before the signal. The system call sigaction is often used in place of signal. Apart from SIGINT and SIGQUIT, there are few more pre-defined signals like SIGPIPE, SIGPOLL, SIGRTMIN, SIGRTMAX, SIGSEGV, SIGSTOP, etc. You can read more about these signals at Signal (IPC).

There is also an alarm system call, which sends SIGALRM signal after a specific time interval. The pause system call causes the calling process (or thread) to sleep until a signal is delivered and meanwhile the operating system can schedule other processes to the CPU.

System Calls for Protection

Permissions are important to keep our system secure, every user should have well-defined permissions for each file. Every file in UNIX has 11-bit mode protection, of which 9 bits are read-write-executable bits for the owner, group, and others. Suppose if you’re the owner of a file and want to change its permission to read, write and execute for the owner, read and execute for your group and execute for others, you can run the following command in the terminal.

chmod u=rwx,g=rx,o=r myfile

where u, g, and o stands for the user, group and owner respectively, you can also run

chmod 754 myfile

command which is in octal permissions notion.

Following is the octal permission notion table for chmod command:

Octal permission notion table

where r, w, and x stands for read, write and executable.

The other two bits are set-group-id and set-user-id bits. To understand better, suppose we have an executable program which performs such operations which only a superuser is authorised to do so (such as creating directories), in such cases the SETUID bit is set on the executable program so that when the program is run, the program will have the privileges of the owner instead of the real user for the duration of the execution. Similarly, if we want to execute the program with the privileges of a group then the SETGID bit is set. 02000 and 04000 are the SETGID and SETUID bits. So, in the above example, if we want to set the SETUID bit, with the same read write and execute permissions for owner, group, and other, we can execute

chmod 4754 myfile

command in the terminal. Similarly, if we want to set SETGID bit, we can execute

chmod 2754 myfile

command in the terminal.

We can also run the following command in the terminal in order to check all the permission granted to a particular file.

ls -l myfile

The system call getuid , getgid , geteuid , and getegid are used to get real and effective UID and GID of a file. To change the owner and group of a file the system call chown canbeused, it takes the file path, owner’s UID and group’s GID as the input argument. The lchown and fchown are another variant of chown system call and differ only in how the file is specified.

These were some important and commonly used system calls that every programmer should know.

Good luck and happy learning!

Follow me here on Medium Akhand Mishra

On a lighter note, remember: If you are acting like a sheep do not blame the shepherd. You cannot herd lions. Wake up and roar and you are free.

What is the function of a system call?

In computing, a system call (commonly abbreviated to syscall) is the programmatic way in which a computer program requests a service from the kernel of the operating system on which it is executed.

Why do we use system calls in Linux?

It is mainly used for Shared memory communication. This system call is used to access the shared memory and access the messages in order to communicate with the process.

What is the purpose of system calls Quora?

System Calls are a way for user programs (running in user mode) to request some service from Operating System. In other words, system calls allow the user programs to ask OS to do some stuff on behalf of the user program.

Chủ đề