System Call

A system call differs from a user-land function in that it triggers the operating system kernel to perform some operation. This usually applies to I/O, such as reading from files or sockets with write. Other than that, system calls are no different than regular functions — they're invoked, have return values, and so on.

In mdoc, however, a system call is a special function consisting of at least one section not found in ordinary function manuals.

The first difference between ordinary functions and system calls is the manual category. Let's study a function khello, kernel hello, which is similar to the hello function described earlier.

.Dd May 30, 2011
.Dt KHELLO 2
.Os

All system calls are in category 2. Furthermore, unless under special circumstances, system call are each accorded their own manual.

I'll use the same descriptive text as in the hello example. Note that for system calls, the hello.h header file should be in the compiler's standard include path. This is usually /usr/include on UNIX systems.

.Sh NAME
.Nm hello
.Nd print greeting messages
.Sh SYNOPSIS
.In hello.h
.Ft int
.Fo hello
.Fa "int C" "const char *prefix"
.Fc
.Sh DESCRIPTION
The
.Nm
function prints out a greeting message.
.Pp
It accepts a value
.Fa C ,
which if non-zero indicates output should be uppercase; and
.Fa prefix ,
which, if not
.Dv NULL ,
shall be prefixed to the output.
The
.Fa prefix
argument, if not
.Dv NULL ,
must be nil-terminated.

You'll notice I've omitted the LIBRARY section in this example, as system calls by definition aren't a part of a library. Furthermore, I've used the Dv macro to annotate the term NULL as a constant variable.

Let's examine the output so far.

NAME

helloprint greeting messages

SYNOPSIS

#include <hello.h>

int
hello(int C, const char *prefix);

DESCRIPTION

The hello function prints out a greeting message.

It accepts a value C, which if non-zero indicates output should be uppercase; and prefix, which, if not NULL, shall be prefixed to the output. The prefix argument, if not NULL, must be nil-terminated.

In the hello example, I included a section RETURN VALUES detailing the return value of the function. System calls, however, usually return a standard value and have a side effect of setting the C library errno variable when invoked within a C language context. This is documented with a special macro Rv.

.Sh RETURN VALUES
.Rv -std

The std flag is by convention always specified. This macro will produce standard text regarding the errno value and that the function returns -1 on failure and 0 on success.

If you have multiple functions specified in your manual, you must list them individually as arguments to Rv.

Next, the possible values of errno must be specified in the ERRORS section as a list. Let's assume that EFAULT may be set if the pointer is invalid.

.Sh ERRORS
.Bl -tag -width Er
.It Er EFAULT
.Fa prefix
points outside the allocated address space.
.El

The syntax of this list differs from lists we've already encountered. Earlier we used the special term Ds as an argument to width to specify a generic width. Here, we used Er, which is also specified at the start of each list tag (lines beginning with It).

The macro Er specifies a possible value of errno. There are many standard variable names for errno values, such as EFAULT used in our example. When we stipulate this as the argument of width, the formatter is able to translate this into a generic width of most Er macro contents.

You should avoid using this construct unless it's in a conventional way, as it is here.

If your system call is part of an operating system, it's common to add some lines as to when it was added. Let's assume you're adding the function to a fictional Foo OS. Most modern UNIX operating systems have their own macros, such as Bx for BSD UNIX. Be sure to note the version of the operating system.

.Sh HISTORY
The
.Nm
function call appeared in Foo OS version 1.0.

Let's put all of these sections together and preview the output.

NAME

helloprint greeting messages

SYNOPSIS

#include <hello.h>

int
hello(int C, const char *prefix);

DESCRIPTION

The hello function prints out a greeting message.

It accepts a value C, which if non-zero indicates output should be uppercase; and prefix, which, if not NULL, shall be prefixed to the output. The prefix argument, if not NULL, must be nil-terminated.

RETURN VALUES

The hello() function returns the value 0 if successful; otherwise the value -1 is returned and the global variable errno is set to indicate the error.

ERRORS

EFAULT
prefix points outside the allocated address space.

HISTORY

The hello function call appeared in Foo OS version 1.0.

We can make sure the manual is complete by reviewing the checklist for function documentation.

First we implied linking information by using category two (which does not need to be specially linked). Then we introduced the calling syntax of the function, naming its arguments. We also stipulated the necessary header files. In the DESCRIPTION, we described the function and its arguments in full. Lastly, we documented return values in the RETURN VALUES section and the errors set in ERRORS.

We also added a HISTORY section, which isn't mentioned as part of our checklist but is considered good practise for system calls. In general, a note on historical information is useful to put your component in the general context of related machinery.

Last edited by $Author: kristaps $ on $Date: 2014/04/07 21:27:38 $. Copyright © 2011, Kristaps Dzonsons. CC BY-SA.