The Zircon system interface is expressed as the libzircon.so
vDSO API surface.
Functions that are part of the interface must have names that start with zx_
and preprocessor macros must have names that start with ZX_
. Types defined as
part of the interface must have names that begin with zx_
and end with _t
.
Every function that is part of the interface must be documented with a markdown file in /docs/zircon/syscalls/ and linked from /docs/zircon/syscalls.md .
Function Names
Functions must have names consisting entirely of lowercase letters and underscores and that conform to the following grammar:
zx_<noun>_<verb>{_<direct-object>}
For example:
zx_handle_close, zx_channel_write, zx_object_signal_peer
Typically, the noun is a kernel object type but can be other nouns, such as
clock
or ticks
for which there is no corresponding kernel object. Other
functions use more abstract nouns, such as system
or status
.
The nouns and verbs must not contain underscores (to avoid confusing the grammar). The noun and verb should each be single English words but acronyms (or abbreviations) may be used if there is no suitable word or the word is too long.
The direct object may contain underscores.
Some functions perform composite operations. In such cases, the function may be named by concatenating the names of the component operations.
Some functions operate on several types of kernel object, in which case the noun
is a more abstract object type. For example, functions with the noun object
operate on most kernel objects and functions with the noun task
operate on
jobs, processes, and threads.
Types
Use zx_status_t
to represent success and failure.
Use fixed-size integer types. Functions must not use short
, int
, or
unsigned long
(or similar types). Instead, use types such as int16_t
,
int32_t
, and uint64_t
.
Use size_t
for buffer lengths, element sizes, and element counts.
Use void*
for pointers to arbitrary types in the caller's address space. Use
zx_vaddr_t
/ zx_paddr_t
for addresses that might be in other address spaces.
Use zx_time_t
for timeouts, which must be expressed as absolute deadlines in
nanoseconds in the system's monotonic clock timebase. In scenarios where
absolute deadlines do not make sense (for example, timer slack), use
zx_duration_t
to represent an amount of time in nanoseconds with no specific
timebase.
Parameters
Receiver
The vast majority of functions act on a handle, which is a reference to a kernel object of a type matching the noun in the function name. This handle is the first argument to such functions and is referred to as the receiver.
Use the name handle
for the receiver.
Object creation functions (eg, zx_channel_create
, zx_event_create
) may not
take a handle argument. These functions implicitly operate on the current
process.
Options Parameter
Often functions include an options
parameter to allow for flags that affect
the operation, and include room for further flags being added to future
revisions of the API.
Use the type uint32_t
and the name options
for the options
parameter.
When present, an options
parameter must be the first argument after the
receiver handle or the first argument overall if the function does not have a
receiver.
An options
parameter is not required for all functions.
Individual option values must be defined as preprocessor macros that cast a
numeric literal to uint32_t
. The options must be bit flags that can be
combined using the bitwise |
operator.
Handles
When a function is given a handle as a parameter, the function must either always consume the handle or never consume, with the following exceptions:
If the function takes an
options
parameter, the function may have a non-default option to avoid consuming handles in various error conditions.If the function does not take an
options
parameter, the function may avoid consuming handles if/when it returnsZX_ERR_SHOULD_WAIT
.
Buffers with Data, Count/Size, and/or Actual
Always accompany arrays or buffers with a count or size (of type size_t
),
including strings. If the buffer is written by the function, the function must
have an out parameter that returns the count or size of the data written.
For read and write style operations, the pointer(s) to the buffer(s) are followed by the buffer count(s) or size(s), and if a short read or write is possible, an out parameter provides the actual count(s) or size(s) on success:
zx_status_t zx_socket_write(zx_handle_t handle, uint32_t options,
const void* buffer, size_t size, size_t* actual);
When there are multiple buffers, the buffers, lengths, and out parameters appear
interleaved in a consistent order. For example, see zx_channel_read
:
zx_status_t zx_channel_read(zx_handle_t handle, uint32_t options,
void* bytes, zx_handle_t* handles,
uint32_t num_bytes, uint32_t num_handles,
uint32_t* actual_bytes, uint32_t* actual_handles);
Outputs
An out parameter is a scalar value written by the function. For example, a
function that returns the number of CPUs by writing to a uint32_t
has an out
parameter. If the function populates a buffer provided by the client, the buffer
isn’t an out parameter.
Out parameters always come at the end of the parameter list.
An out parameter must not also be an in parameter. For example, if a function has an out parameter through which it returns the number of bytes written to a buffer, that parameter must not also be used by the function to receive the length of the buffer from the caller.
Return Type
The vast majority of functions have a return type of zx_status_t
, which is
ZX_OK
on success and ZX_ERR_...
on failure.
Do not return other values through zx_status_t
, for example using the
positive value range. Instead, use an out parameter.
Other return types may be used for functions that cannot fail. For example,
zx_thread_exit
never fails to exit the thread and has a return type of void.
Similarly, zx_clock_get_monotonic
cannot fail to get the current time and has
a return type of zx_time_t
.
Function-specific rules
zx_object_get_property versus zx_object_get_info
There are two similar mechanisms for exposing data about objects:
zx_object_get_property
and zx_object_get_info
. Prefer exposing data through
zx_object_get_property
if (a) the property can be set using
zx_object_set_property
or (b) the property exist across multiple types of
objects. In other case, consider including the data in the general
zx_object_get_info
topic for the type of object that has the property.