### 25.6 System Calls

A system call is a request for service that a program makes of the kernel. The service is generally something that only the kernel has the privilege to do, such as doing I/O. Programmers don't normally need to be concerned with system calls because there are functions in the GNU C Library to do virtually everything that system calls do. These functions work by making system calls themselves. For example, there is a system call that changes the permissions of a file, but you don't need to know about it because you can just use the GNU C Library's `chmod` function.

System calls are sometimes called kernel calls.

However, there are times when you want to make a system call explicitly, and for that, the GNU C Library provides the `syscall` function. `syscall` is harder to use and less portable than functions like `chmod`, but easier and more portable than coding the system call in assembler instructions.

`syscall` is most useful when you are working with a system call which is special to your system or is newer than the GNU C Library you are using. `syscall` is implemented in an entirely generic way; the function does not know anything about what a particular system call does or even if it is valid.

The description of `syscall` in this section assumes a certain protocol for system calls on the various platforms on which the GNU C Library runs. That protocol is not defined by any strong authority, but we won't describe it here either because anyone who is coding `syscall` probably won't accept anything less than kernel and C library source code as a specification of the interface between them anyway.

`syscall` is declared in `unistd.h`.

— Function: long int syscall (long int sysno, ...)

> `syscall` performs a generic system call.

> sysno is the system call number. Each kind of system call is identified by a number. Macros for all the possible system call numbers are defined in `sys/syscall.h`

> The remaining arguments are the arguments for the system call, in order, and their meanings depend on the kind of system call. Each kind of system call has a definite number of arguments, from zero to five. If you code more arguments than the system call takes, the extra ones to the right are ignored.

> The return value is the return value from the system call, unless the system call failed. In that case, `syscall` returns `-1` and sets `errno` to an error code that the system call returned. Note that system calls do not return `-1` when they succeed. If you specify an invalid sysno, `syscall` returns `-1` with `errno` = `ENOSYS`.

> Example:

>               #include <unistd.h>
>               #include <sys/syscall.h>
>               #include <errno.h>

>               ...

>               int rc;

>               rc = syscall(SYS_chmod, "/etc/passwd", 0444);

>               if (rc == -1)
>                  fprintf(stderr, "chmod failed, errno = %d\n", errno);

> This, if all the compatibility stars are aligned, is equivalent to the following preferable code:

>               #include <sys/types.h>
>               #include <sys/stat.h>
>               #include <errno.h>

>               ...

>               int rc;

>               rc = chmod("/etc/passwd", 0444);
>               if (rc == -1)
>                  fprintf(stderr, "chmod failed, errno = %d\n", errno);