blob: dd1383b8a8984bef03fc3a549609858051178b40 [file] [log] [blame] [view]
# Fuchsia fdio Library
The core Fuchsia method for talking about files and other I/O primitives are
FIDL protocols over Zircon channels. But since most applications are written
against Unix integer file descriptors ("FD"s), Fuchsia provides the FDIO library
to adapt the core protocols to POSIX-like file descriptors.
To see how FDIO fits into the overall I/O stack, see [life of an
open](/docs/concepts/filesystems/life_of_an_open.md).
## Conceptual overview
### Converting between FDs and kernel handles
The main functions to convert between channels and file descriptors are:
* [fdio_fd_create()] creates a file descriptor from a channel.
* [fdio_get_service_handle()] converts from a file descriptor to a kernel
handle. This is normally used to connect to FIDL services in the `/svc`
directory.
These other variants also create handles from file descriptors. A "transfer"
means that the source file descriptor is closed and ownership transferred to the
`out_handle` (this is identical to [fdio_get_service_handle()]. However, if a
file descriptor has been `dup()`ed and there are more than one descriptor
representing the kernel handle, it can not be simply closed. In these cases, the
file descriptor can be "cloned" meaning that the original file descriptor is not
modified. The output handle is a new handle that the caller owns.
* [fdio_fd_clone()] creates a handle for the given FD.
* [fdio_fd_transfer()] closes the FD (if possible) and returns the handle.
* [fdio_fd_transfer_or_clone()] transfers with a clone fallback.
* [fdio_cwd_clone()] creates a handle to the current working directory.
Internally, FDIO uses the opaque `fdio_t` type to refer to a file descriptor.
These can be separately created and bound to channels and FDs:
* [fdio_create()]
* [fdio_default_create()]
* [fdio_null_create()]
* [fdio_fd_create_null()]
* [fdio_bind_to_fd()]
* [fdio_unbind_from_fd()]
### zxio integration
The fdio library is built on top of the zxio library. These functions provide
integration between fdio and zxio.
* [fdio_get_zxio()]
* [fdio_zxio_create()]
### Waiting
* [fdio_wait_fd()] waits for events on a file descriptor.
* [fdio_handle_fd()] creates a file descriptor from a kernel handle
specifically for waiting (via `select()`, `epoll()`, etc.).
### Watching
Clients can use watch for changes in a given directory. This does not watch
for changes in subdirectories of the given directory.
* [fdio_watch_directory()]
### VMO functions
Most standard Fuchsia files are represented by an underlying [virtual memory
object](/docs/reference/kernel_objects/vm_object.md) (VMO). FDIO provides access
to the kernel handle for this VMO when low-level operations are required.
These functions (which all have the same signature) convert a FDIO file handle
to a kernel handle to a VMO. They differ by the handling of error conditions and
the type of VMO provided. Since not all FDIO file handles represent normal files
and filesystems are not obligated to provide a VMO representation of a file,
callers should consider what behavior they want in such cases.
* [fdio_get_vmo_exact()]
* [fdio_get_vmo_clone()]
* [fdio_get_vmo_copy()]
* [fdio_get_vmo_exec()]
### Directories
These functions provide ways to open files or connect to services in
directories. To open or connect, a client will create a channel and send the
handle to the server end of that channel (the `request` parameters)
to the service for the directory (identified here either by handle file
descriptor, or by name bound in the current process' installed namespace).
There are also variants that automatically create the channel and register the
client end as a file descriptor in the current process.
* [fdio_service_connect()]
* [fdio_service_connect_at()]
* [fdio_service_connect_by_name()]
* [fdio_open()]
* [fdio_open_at()]
* [fdio_open_fd()]
* [fdio_open_fd_at()]
* [fdio_service_clone()]
* [fdio_service_clone_to()]
### Namespaces
A namespace represents an application's view of a filesystem. The application's
view into the rest of the system is constructed by binding services (such as a
directory in a filesystem) to names in the namespace (such as "/data").
Typically applications only interact with their installed but other namespaces
can be constructed and destroyed if desired.
* [fdio_ns_get_installed()] returns the application-global "installed" namespace.
* [fdio_ns_create()]
* [fdio_ns_destroy()]
An application can bind or unbind names in a namespace:
* [fdio_ns_bind_fd()]
* [fdio_ns_bind()]
* [fdio_ns_unbind()]
* [fdio_ns_is_bound()]
Namespaces support basic filesystem-like operations. These functions are used as
the basis for higher-level functions in FDIO like the directory functions:
* [fdio_ns_opendir()]
* [fdio_ns_chdir()]
* [fdio_ns_open()]
* [fdio_ns_service_connect()]
Namespaces can be converted into parallel arrays of path/handle/type. This
flat namespace structure is typically used to communicate a namespace between
processes:
* [fdio_ns_export()]
* [fdio_ns_export_root()]
* [fdio_ns_free_flat_ns()]
### Process spawning
The fdio library provides process spawning functions that allow some or all of
the current process' environment to be shared. The spawned executable can be
identified either by a `path` in the current process' installed namespace or by
a VMO containing the binary.
* [fdio_spawn()]
* [fdio_spawn_etc()]
* [fdio_spawn_vmo()]
### Other functions
These interfaces exist to allow integration of FDIO file descriptors with
handle-centric message loops. If used incorrectly they can corrupt the internal
FDIO state.
* [fdio_unsafe_fd_to_io()]
* [fdio_unsafe_borrow_channel()]
* [fdio_unsafe_release()]
* [fdio_unsafe_wait_begin()]
* [fdio_unsafe_wait_end()]
This function assists in creating POSIX-style pipes that will be shared with
other processes:
* [fdio_pipe_half()]