System Call PDF
System Call PDF
The user interface can vary from system to system and even from user
to user within a system. It typically is substantially removed from the actual
system structure. The design of a useful and friendly user interface is therefore
not a direct function of the operating system. In this book, we concentrate on
the fundamental problems of providing adequate service to user programs.
From the point of view of the operating system, we do not distinguish between
user programs and system programs.
Finally, after the entire file is copied, the program may close both files
(another system call), write a message to the console or window (more system
calls), and finally terminate normally (the final system call). This system-call
sequence is shown in Figure 2.5.
As you can see, even simple programs may make heavy use of the
operating system. Frequently, systems execute thousands of system calls
per second. Most programmers never see this level of detail, however.
Typically, application developers design programs according to an application
programming interface (API). The API specifies a set of functions that are
available to an application programmer, including the parameters that are
passed to each function and the return values the programmer can expect.
Three of the most common APIs available to application programmers are
the Windows API for Windows systems, the POSIX API for POSIX-based systems
(which include virtually all versions of UNIX, Linux, and Mac OS X), and the Java
API for programs that run on the Java virtual machine. A programmer accesses
an API via a library of code provided by the operating system. In the case of
UNIX and Linux for programs written in the C language, the library is called
libc. Note that —unless specified —the system-call names used throughout
this text are generic examples. Each operating system has its own name for
each system call.
Behind the scenes, the functions that make up an API typically invoke the
actual system calls on behalf of the application programmer. For example, the
Windows function CreateProcess() (which unsurprisingly is used to create
a new process) actually invokes the NTCreateProcess() system call in the
Windows kernel.
Why would an application programmer prefer programming according to
an API rather than invoking actual system calls? There are several reasons for
doing so. One benefit concerns program portability. An application program-
#include <unistd.h>
A program that uses the read() function must include the unistd.h header
file, as this file defines the ssize t and size t data types (among other
things). The parameters passed to read() are as follows:
mer designing a program using an API can expect her program to compile and
run on any system that supports the same API (although, in reality, architectural
differences often make this more difficult than it may appear). Furthermore,
actual system calls can often be more detailed and difficult to work with than
the API available to an application programmer. Nevertheless, there often exists
a strong correlation between a function in the API and its associated system call
within the kernel. In fact, many of the POSIX and Windows APIs are similar to
the native system calls provided by the UNIX, Linux, and Windows operating
systems.
For most programming languages, the run-time support system (a set of
functions built into libraries included with a compiler) provides a system-
call interface that serves as the link to system calls made available by the
operating system. The system-call interface intercepts function calls in the API
and invokes the necessary system calls within the operating system. Typically,
a number is associated with each system call, and the system-call interface
maintains a table indexed according to these numbers. The system call interface
2.3 System Calls 65
user application
open ( )
user
mode
system call interface
kernel
mode
open ( )
Implementation
i of open ( )
system call
return
Figure 2.6 The handling of a user application invoking the open() system call.
then invokes the intended system call in the operating-system kernel and
returns the status of the system call and any return values.
The caller need know nothing about how the system call is implemented
or what it does during execution. Rather, the caller need only obey the API and
understand what the operating system will do as a result of the execution of
that system call. Thus, most of the details of the operating-system interface
are hidden from the programmer by the API and are managed by the run-time
support library. The relationship between an API, the system-call interface,
and the operating system is shown in Figure 2.6, which illustrates how the
operating system handles a user application invoking the open() system call.
System calls occur in different ways, depending on the computer in use.
Often, more information is required than simply the identity of the desired
system call. The exact type and amount of information vary according to the
particular operating system and call. For example, to get input, we may need
to specify the file or device to use as the source, as well as the address and
length of the memory buffer into which the input should be read. Of course,
the device or file and length may be implicit in the call.
Three general methods are used to pass parameters to the operating system.
The simplest approach is to pass the parameters in registers. In some cases,
however, there may be more parameters than registers. In these cases, the
parameters are generally stored in a block, or table, in memory, and the
address of the block is passed as a parameter in a register (Figure 2.7). This
is the approach taken by Linux and Solaris. Parameters also can be placed,
or pushed, onto the stack by the program and popped off the stack by the
operating system. Some operating systems prefer the block or stack method
because those approaches do not limit the number or length of parameters
being passed.