blob: 3db66bca07809e12e3732e58aad586ab1d545818 [file] [log] [blame] [view]
# Zircon System Interface Rubric
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 which 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 returns `ZX_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
isnt 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.