blob: f560acedfa01df19c1946a5cec962175cc8869f4 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_ZXIO_ZXIO_H_
#define LIB_ZXIO_ZXIO_H_
#include <fuchsia/io/c/fidl.h>
#include <lib/zxio/types.h>
#include <stdint.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
__BEGIN_CDECLS
typedef fuchsia_io_NodeAttributes zxio_node_attr_t;
typedef fuchsia_io_SeekOrigin zxio_seek_origin_t;
// A IO object.
//
// Provides an ergonomic C interface to the fuchsia.io family of protocols.
// These protocols are optimized for efficiency at the cost of ergonomics. This
// object provides a more ergonomic interface to the same underlying protocol
// without sacrificing (much) performance.
//
// A zxio_t also abstracts over several related protocols (e.g., vmofile,
// file, and directory) to provide a uniform interface. Advanced clients can
// also provide their own implementation of the underlying ops table to
// provide drop-in replacements for zxio_t with different backends.
//
// # Threading model
//
// Most operations on zxio_t objects can be called from any thread with
// external synchronization. However, the caller needs to synchronize
// operations that consume the zxio_t with other operations.
typedef struct zxio zxio_t;
// Node
// Attempt to destroy |io| and produce a |zx_handle_t|.
//
// Recovers the underlying |zx_handle_t| for |io| if one exists. Does not
// terminate the connection with the server.
//
// Does not block.
//
// Always consumes |io|.
zx_status_t zxio_release(zxio_t* io, zx_handle_t* out_handle);
// Attempt to create a |zx_handle_t| that represents another session with |io|.
//
// The returned |zx_handle_t| is suitable for transfer to another process or for
// use within this process.
//
// Does not block.
//
// Does not consume |io|.
zx_status_t zxio_clone(zxio_t* io, zx_handle_t* out_handle);
// Terminates connection with the server.
//
// Always consumes |io|.
zx_status_t zxio_close(zxio_t* io);
// Wait for |signals| to be asserted for |io|.
//
// Returns |ZX_ERR_TIMED_OUT| if |deadline| passes before any of the |signals|
// are asserted for |io|. Returns the set of signals that were actually observed
// via |observed|.
zx_status_t zxio_wait_one(zxio_t* io, zxio_signals_t signals,
zx_time_t deadline, zxio_signals_t* out_observed);
// Translate |zxio_signals_t| into |zx_signals_t| for |io|.
//
// The client should wait on |handle| for |zx_signals| in order to observe the
// given |zxio_signals|.
//
// Use |zxio_wait_end| to translate the observed |zx_signals_t| back into
// |zxio_signals_t|.
void zxio_wait_begin(zxio_t* io, zxio_signals_t zxio_signals,
zx_handle_t* out_handle, zx_signals_t* out_zx_signals);
// Translate |zx_signals_t| into |zxio_signals_t| for |io|.
//
// Typically used with |zxio_wait_begin| to wait asynchronously on a
// |zx_handle_t| and to interpret the observed |zx_signals|.
void zxio_wait_end(zxio_t* io, zx_signals_t zx_signals,
zxio_signals_t* out_zxio_signals);
// Synchronizes updates to the file to the underlying media, if it exists.
zx_status_t zxio_sync(zxio_t* io);
// Returns information about the file.
zx_status_t zxio_attr_get(zxio_t* io, zxio_node_attr_t* out_attr);
// Update information about the file.
//
// See io.fidl for the available |flags|.
zx_status_t zxio_attr_set(zxio_t* io, uint32_t flags,
const zxio_node_attr_t* attr);
// File
// Attempt to read |capacity| bytes from the file at the current seek offset.
//
// The seek offset is moved forward by the actual number of bytes read.
//
// The actual number of bytes read is returned in |out_actual|.
zx_status_t zxio_read(zxio_t* io, void* buffer, size_t capacity,
size_t* out_actual);
// Attempt to read |capacity| bytes from the file at the provided offset.
//
// Does not affect the seek offset.
//
// The actual number of bytes read is returned in |out_actual|.
zx_status_t zxio_read_at(zxio_t* io, size_t offset, void* buffer,
size_t capacity, size_t* out_actual);
// Attempt to write data to the file at the current seek offset.
//
// The seek offset is moved forward by the actual number of bytes written.
//
// The actual number of bytes written is returned in |out_actual|.
zx_status_t zxio_write(zxio_t* io, const void* buffer, size_t capacity,
size_t* out_actual);
// Attempt to write data to the file at the provided offset.
//
// Does not affect the seek offset.
//
// The actual number of bytes written is returned in |out_actual|.
zx_status_t zxio_write_at(zxio_t* io, size_t offset, const void* buffer,
size_t capacity, size_t* out_actual);
// Modify the seek offset.
//
// The seek offset for the file is modified by |offset| relative to |start|.
//
// The resulting seek offset relative to the start of the file is returned in
// |out_offset|.
zx_status_t zxio_seek(zxio_t* io, size_t offset,
zxio_seek_origin_t start, size_t* out_offset);
// Shrink the file size to |length| bytes.
zx_status_t zxio_truncate(zxio_t* io, size_t length);
// Returns the flags associated with the file.
//
// These flags are typically set when the file is opened but can be modified by
// |zxio_flags_set|.
//
// See io.fidl for the available |flags|.
zx_status_t zxio_flags_get(zxio_t* io, uint32_t* out_flags);
// Modifies the flags associated with the file.
//
// This function can modify the following flags:
//
// * |fuchsia_io_OPEN_FLAG_APPEND|.
//
// See io.fidl for the available |flags|.
zx_status_t zxio_flags_set(zxio_t* io, uint32_t flags);
// Get a read-only VMO containing the whole contents of the file.
//
// This function creates a clone of the underlying VMO when possible. If the
// function cannot create a clone, the function will eagerly read the contents
// of the file into a freshly-created VMO.
zx_status_t zxio_vmo_get_copy(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size);
// Get a read-only VMO containing the whole contents of the file.
//
// This function creates a clone of the underlying VMO when possible. If the
// function cannot create a clone, the function will return an error.
zx_status_t zxio_vmo_get_clone(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size);
// Get a read-only handle to the exact VMO used by the file system server to
// represent the file.
//
// This function fails if the server does not have an exact VMO representation
// of the file.
zx_status_t zxio_vmo_get_exact(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size);
// Directory
// Open a new file relative to the given |directory|.
//
// The connection is represented as a |zxio_t|. This call blocks until the
// remote server is able to describe the new connection.
//
// See io.fidl for the available |flags| and |mode|.
zx_status_t zxio_open(zxio_t* directory, uint32_t flags, uint32_t mode,
const char* path, zxio_t** out_io);
// Open a new file relative to the given |directory|.
//
// The connection is represented as a |zx_handle_t|. The caller is responsible
// for creating the |zx_handle_t|, which must be a channel. This call does not
// block on the remote server.
//
// See io.fidl for the available |flags| and |mode|.
zx_status_t zxio_open_async(zxio_t* directory, uint32_t flags,
uint32_t mode, const char* path,
zx_handle_t request);
// Remove an file relative to the given directory.
zx_status_t zxio_unlink(zxio_t* directory, const char* path);
// Attempts to rename |old_path| relative to |old_directory| to |new_path|
// relative to |new_directory|.
//
// |old_directory| and |new_directory| may be aliased.
zx_status_t zxio_rename(zxio_t* old_directory, const char* old_path,
zxio_t* new_directory, const char* new_path);
// Attempts to link |dst_path| relative to |dst_directory| to |src_path|
// relative to |src_directory|.
//
// |src_directory| and |dst_directory| may be aliased.
zx_status_t zxio_link(zxio_t* src_directory, const char* src_path,
zxio_t* dst_directory, const char* dst_path);
// Directory iterator
// An entry in a directory.
typedef struct zxio_dirent {
// The inode number of the entry.
uint64_t inode;
// The length of the name of the entry.
uint8_t size;
// The type of the entry.
//
// Aligned with the POSIX d_type values.
uint8_t type;
// The name of the entry.
//
// This string is not null terminated. Instead, refer to |size| to
// determine the length of the string.
char name[0];
} zxio_dirent_t;
// An iterator for |zxio_dirent_t| objects.
//
// To start iterating directory entries, call |zxio_dirent_iterator_init| to
// initialize the |opaque| contents of the iterator. Then, call
// |zxio_dirent_iterator_next| to advance the iterator.
//
// Typically allocated on the stack.
typedef struct zxio_dirent_iterator {
uint64_t opaque[8];
} zxio_dirent_iterator_t;
// A reasonable default capacity for |zxio_dirent_iterator_init|.
#define ZXIO_DIRENT_ITERATOR_DEFAULT_BUFFER_SIZE ((size_t)4096)
// Initializes a |zxio_dirent_iterator_t| for the given |directory|.
//
// At most one |zxio_dirent_iterator_t| can be active for a given |directory|
// at a time.
//
// |buffer| will be used internally by the iterator to cache chunks of directory
// entries from the remote server. The larger the buffer, the most entries can
// be fetched from the remote server in each chunk. The caller should not
// access or modify the contents of the buffer during iteration.
//
// |ZXIO_DIRENT_ITERATOR_DEFAULT_BUFFER_SIZE| is a reasonable capacity buffer to
// use for this operation. Larger buffers might improve performance. Smaller
// buffers are likely to degrade performance.
zx_status_t zxio_dirent_iterator_init(zxio_dirent_iterator_t* iterator,
zxio_t* directory, void* buffer,
size_t capacity);
// Read a |zxio_dirent_t| from the given |iterator|.
//
// The |zxio_dirent_t| returned via |out_entry| is valid until either (a) the
// next call to |zxio_dirent_iterator_next| or the |buffer| passed to
// |zxio_dirent_iterator_init| is modified or destroyed.
//
// This function |zxio_directory_entry_t| from the server in chunks, but this
// function returns the entries one at a time. When this function crosses into
// a new chunk, the function will block on the remote server to retrieve the
// next chunk.
//
// When there are no more directory entries to enumerate, this function will
// return |ZX_ERR_NOT_FOUND|.
//
// |iterator| must have been previously initialized via
// |zxio_dirent_iterator_init|.
zx_status_t zxio_dirent_iterator_next(zxio_dirent_iterator_t* iterator,
zxio_dirent_t** out_entry);
// Return in |tty| whether or not |io| represents a TTY object (should
// line buffer for stdio, etc).
zx_status_t zxio_isatty(zxio_t* io, bool* tty);
__END_CDECLS
#endif // LIB_ZXIO_ZXIO_H_