How does a program make a system call

operating systems

I'm reading Tanenbaum's Modern Operating Systems and I really can't grasp the following concept: how does a program make a system call? I mean, i got the very basics down (correct me if I'm wrong): the OS is just another program running on the machine (the difference being that it can run in kernel mode having complete access to the machine's hardware) and when an user's program want to have a sort of advanced feature given by the OS, it tries to get it through a system call to the OS itself, writing the call's type and parameters on its stack and making a trap call. Now, I got this down, but the question is, how does a program know that, let's say, the "read" call on Unix is identified by the "ReadFile" call on the Win32 API? For example, in a program written in C, is this info known by the compiler? And let's say in the future a new OS introduces the "foo" system call, that does the exact same thing as the Unix's "read"… Well, how would a user's program know that?

Best Answer

how does a program know that, let's say, the "read" call on Unix is identified by the "ReadFile" call on the Win32 API? For example, in a program written in C, is this info known by the compiler?

Neither the program nor the compiler knows that. The programmer knows that on POSIX-compliant systems, there is an include file called <unistd.h> that has a function to read from file descriptors with the prototype ssize_t read(int fd, void *buf, size_t count) and has a certain behavior when called. The compiler doesn't treat read() any differently than some function in your program.

How read() does its business is completely opaque. Under the hood on Unix, it does whatever the kernel expects to happen when you want to make that a system call. On Windows, it uses whatever mechanism Windows makes available for that. In some embedded environment where the process has direct access to the device, it might execute code that reads the file directly.

This is what makes code portable: the libraries implement whatever the standard dictates in a way that's compatible with the local environment. As long as the libraries and callers adhere to the standards, programs work as expected and everyone's happy.

Related Topic