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