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
#include
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.