The API which invokes the system call is written in code, such as a mixture of C and inline assembly. You can put that same, or analogous code into an application, if you are so inclined.
This is very rarely done. The technique is used in demonstration programs for showing how small a completely self-contained executable file can be with no library dependencies, yet do something useful.
Someone working on a run-time for a programming language that isn't C might opt to use raw system calls to avoid a dependency on the C library.
In the GNU/Linux world, the kernel and user space are almost entirely independent projects. It's conceivable to have a situation whereby some useful system call has been developed that an application wants to use, but the application has to run in systems whose C library is older and doesn't expose that system call as an API (yet whose kernel is newer and has the system call). In that situation, the only way the application can use the system call is to issue it itself.
There can be situations in which the API doesn't directly correspond to the underlying system calls, and for various reasons such as performance, the application developers decide to take those system calls into their own hands.
For instance, on GNU/Linux, the POSIX functions opendir
and readdir
, for opening a stream-like object over a directory and reading directory entries one by one, is implemented as getdents
system call: a function for reading an entire batch of directory entries into an array. Someone might be interested in using such a thing directly rather than through the one-by-one API.
The manual page for getdents
cautions:
SYNOPSIS
int getdents(unsigned int fd, struct linux_dirent *dirp,
unsigned int count);
int getdents64(unsigned int fd, struct linux_dirent64 *dirp,
unsigned int count);
[...]
NOTES
Glibc does not provide a wrapper for these system calls; call them using
syscall(2). You will need to define the linux_dirent or linux_dirent64 struc‐
ture yourself. However, you probably want to use readdir(3) instead.
read
andwrite
in that tutorial are not system calls, they're a userspace libc API.read
andwrite
as system calls, I agree with you 100%. While those functions are not a part of the C standard library, they are a part of the POSIX library (which also is an API).