Previous Index Next

Interface To System Calls From C

The following statements should be used by C programs to include the definitions of Grâl kernel interfaces:

#include <syscall.h> #include <syserror.h>

syscall.h contains the definitions of types used by system calls, and system call interface routines:

sysres
is the type of system call return value; if the value is negative it should be treated as an error code defined in syserror.h;
sysmask
type of bitmask for 32 request codes;
sysla
type of local address;
sysinfo
type of a structure containing information about a transaction, namely the request code and the number of in- and out-arguments;
systype
type of a structure containing information about an object type, such as which requests are supported and which are granted, and if the type is primary or derivative;
syscode
enumeration of all system call codes (member names are syscode_XXX, where XXX is the name of system call);
sysarg_XXX
types of arguments of the system calls;
vecp = sysXXX(vecp, ...)
inline system call routines, used to compose the system call vectors. These routines take the current pointer into the vector of system calls, store the system call code and parameters in the vector and return the updated pointer.
result = sys(vector)
this routine executes vector of system calls and returns the completion code.

An example of C code composing and executing a vector of system calls:

long vector[16]; long *vp; sysinfo si; sysres res; /* * Compose the vector */ vp = sysA(vector, 12); /* Place access with local address 12 on stack */ vp = sysA(vp, 17); /* Place access with local address 17 on stack */ si.reqc = 5; /* Transaction parameters: request code = 5 */ si.nin = 1; /* # of in-args = 1 */ si.nout = 0; /* # of out-args = 0 */ vp = sysSREQ(vp, si); /* Synchronous request */ (void) sysEND(vp); /* End of the vector */ /* * Execute the vector */ res = sys(vector);

Note that the vector of system calls has the hardware-dependent type long[].

The include file syserror.h contains the list of error codes generated by the kernel, and macro definitions to aid their interpretation. The Grâl kernel error codes are always negative (zero or positive value always mean successful completion of a system call), and contain a number of fields:

Error type is the kind of error condition; all kinds of kernel error conditions are listed in the enumeration sys_error_code, with member names like ERR_XXXX.

Argument number is used to indicate which access on stack caused the error (1 means the access on top of stack, 2 - the access next to the top one, etc), zero value is used when inapplicable.

Operation number is the number of the system call in the vector, starting from zero. Note that since different system calls may require different space in the vector the operation number may be different from index of the corresponding vector element.

Bit 30 of the error code is used to indicate if the error code was generated by a user process (if set to zero) or by the kernel (if set by one). Higher-order bits, including the bit sign should be always set to one to produce a negative value.

If user specified an invalid address of a system call vector, or provided malformed system call vector, or if some system call was provided an invalid user address in a parameter, one of the following error codes will be returned by sys():

ERR_INVALID_ADDRESS
if an access to user memory failed;
ERR_BAD_SYSCALL
if an element of the vector does not contain valid system call code.


Previous Index Next