blob: c95cfdca9a043f93a550f4018aa617a0bd5df3ff [file] [log] [blame] [edit]
// 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_TYPES_H_
#define LIB_ZXIO_TYPES_H_
#include <stdbool.h>
#include <stdint.h>
#include <zircon/compiler.h>
// This header defines the public types used in the zxio and zxio_ops interface.
__BEGIN_CDECLS
// Flags -----------------------------------------------------------------------
typedef uint32_t zxio_flags_t;
#define ZXIO_PEEK ((zxio_flags_t)1u << 0)
// Signals ---------------------------------------------------------------------
// Signals are single bits of information that reflect some state on the
// I/O object, i.e. they are level-triggered. Signals are implemented under
// the hood using Zircon signals, but they are distinct. One may wait for
// signals using the |zxio_wait_*| set of APIs.
//
// The signals defined here are rather generic (e.g. ZXIO_SIGNAL_READABLE
// applies to both files and sockets); as such, not all I/O objects support
// all signals. Unsupported signals are ignored during waiting.
typedef uint32_t zxio_signals_t;
#define ZXIO_SIGNAL_NONE ((zxio_signals_t)0u)
// Indicates the object is ready for reading.
#define ZXIO_SIGNAL_READABLE ((zxio_signals_t)1u << 0)
// Indicates the object is ready for writing.
#define ZXIO_SIGNAL_WRITABLE ((zxio_signals_t)1u << 1)
// Indicates writing is disabled permanently for the remote endpoint.
// Note that reads on the local endpoint may succeed until all unread data
// have been depleted.
#define ZXIO_SIGNAL_READ_DISABLED ((zxio_signals_t)1u << 2)
// Indicates writing is disabled permanently for the local endpoint.
#define ZXIO_SIGNAL_WRITE_DISABLED ((zxio_signals_t)1u << 3)
// Indicates data queued up on the object for reading exceeds the read threshold.
#define ZXIO_SIGNAL_READ_THRESHOLD ((zxio_signals_t)1u << 4)
// Indicates space available on the object for writing exceeds the write threshold.
#define ZXIO_SIGNAL_WRITE_THRESHOLD ((zxio_signals_t)1u << 5)
// Indicates an out-of-band state transition has occurred that needs attention.
// Primarily used for devices with some out-of-band signalling mechanism.
#define ZXIO_SIGNAL_OUT_OF_BAND ((zxio_signals_t)1u << 6)
// Indicates the object has encountered an error state.
#define ZXIO_SIGNAL_ERROR ((zxio_signals_t)1u << 7)
// Indicates the object has closed the current connection.
// Further I/O may not be performed.
#define ZXIO_SIGNAL_PEER_CLOSED ((zxio_signals_t)1u << 8)
#define ZXIO_SIGNAL_ALL \
(ZXIO_SIGNAL_READABLE | ZXIO_SIGNAL_WRITABLE | ZXIO_SIGNAL_READ_DISABLED | \
ZXIO_SIGNAL_WRITE_DISABLED | ZXIO_SIGNAL_READ_THRESHOLD | ZXIO_SIGNAL_WRITE_THRESHOLD | \
ZXIO_SIGNAL_OUT_OF_BAND | ZXIO_SIGNAL_ERROR | ZXIO_SIGNAL_PEER_CLOSED)
// File and directory access ---------------------------------------------------
// The set of supported representations of a node.
// Refer to |fuchsia.io2/NodeProtocols| for the documentation of each item.
typedef uint64_t zxio_node_protocols_t;
#define ZXIO_NODE_PROTOCOL_NONE ((zxio_node_protocols_t)0ul)
#define ZXIO_NODE_PROTOCOL_CONNECTOR ((zxio_node_protocols_t)1ul << 0)
#define ZXIO_NODE_PROTOCOL_DIRECTORY ((zxio_node_protocols_t)1ul << 1)
#define ZXIO_NODE_PROTOCOL_FILE ((zxio_node_protocols_t)1ul << 2)
#define ZXIO_NODE_PROTOCOL_MEMORY ((zxio_node_protocols_t)1ul << 3)
#define ZXIO_NODE_PROTOCOL_POSIX_SOCKET ((zxio_node_protocols_t)1ul << 4)
#define ZXIO_NODE_PROTOCOL_PIPE ((zxio_node_protocols_t)1ul << 5)
#define ZXIO_NODE_PROTOCOL_DEBUGLOG ((zxio_node_protocols_t)1ul << 6)
#define ZXIO_NODE_PROTOCOL_DEVICE ((zxio_node_protocols_t)0x10000000ul)
#define ZXIO_NODE_PROTOCOL_TTY ((zxio_node_protocols_t)0x20000000ul)
#define ZXIO_NODE_PROTOCOL_ALL \
(ZXIO_NODE_PROTOCOL_CONNECTOR | ZXIO_NODE_PROTOCOL_DIRECTORY | ZXIO_NODE_PROTOCOL_FILE | \
ZXIO_NODE_PROTOCOL_MEMORY | ZXIO_NODE_PROTOCOL_POSIX_SOCKET | ZXIO_NODE_PROTOCOL_PIPE | \
ZXIO_NODE_PROTOCOL_DEBUGLOG | ZXIO_NODE_PROTOCOL_DEVICE | ZXIO_NODE_PROTOCOL_TTY)
typedef uint64_t zxio_id_t;
// The kinds of operations behind |zxio_rights_t| and |zxio_abilities_t|.
// Refer to |fuchsia.io2/Operations| for the documentation of each item.
typedef uint64_t zxio_operations_t;
#define ZXIO_OPERATION_NONE ((zxio_operations_t)0ul)
#define ZXIO_OPERATION_CONNECT ((zxio_operations_t)1ul << 0)
#define ZXIO_OPERATION_READ_BYTES ((zxio_operations_t)1ul << 1)
#define ZXIO_OPERATION_WRITE_BYTES ((zxio_operations_t)1ul << 2)
#define ZXIO_OPERATION_EXECUTE ((zxio_operations_t)1ul << 3)
#define ZXIO_OPERATION_GET_ATTRIBUTES ((zxio_operations_t)1ul << 4)
#define ZXIO_OPERATION_UPDATE_ATTRIBUTES ((zxio_operations_t)1ul << 5)
#define ZXIO_OPERATION_ENUMERATE ((zxio_operations_t)1ul << 6)
#define ZXIO_OPERATION_TRAVERSE ((zxio_operations_t)1ul << 7)
#define ZXIO_OPERATION_MODIFY_DIRECTORY ((zxio_operations_t)1ul << 8)
#define ZXIO_OPERATION_ADMIN ((zxio_operations_t)0x100000000000000ul)
#define ZXIO_OPERATION_ALL \
(ZXIO_OPERATION_CONNECT | ZXIO_OPERATION_READ_BYTES | ZXIO_OPERATION_WRITE_BYTES | \
ZXIO_OPERATION_EXECUTE | ZXIO_OPERATION_GET_ATTRIBUTES | ZXIO_OPERATION_UPDATE_ATTRIBUTES | \
ZXIO_OPERATION_ENUMERATE | ZXIO_OPERATION_TRAVERSE | ZXIO_OPERATION_MODIFY_DIRECTORY | \
ZXIO_OPERATION_ADMIN)
typedef zxio_operations_t zxio_rights_t;
typedef zxio_operations_t zxio_abilities_t;
// Objective information about a node.
//
// Each field has a corresponding presence indicator. When creating
// a new object, it is desirable to use the ZXIO_NODE_ATTR_SET helper macro
// to set the fields, to avoid forgetting to change the presence indicator.
typedef struct zxio_node_attr {
// The kinds of representations supported by the node.
zxio_node_protocols_t protocols;
// The kinds of operations supported by the node.
zxio_abilities_t abilities;
// A filesystem-unique ID.
zxio_id_t id;
// Node size, in bytes.
uint64_t content_size;
// Space needed to store the node (possibly larger than size), in bytes.
uint64_t storage_size;
// Hard link count.
uint64_t link_count;
// Time of creation in nanoseconds since Unix epoch, UTC.
uint64_t creation_time;
// Time of last modification in ns since Unix epoch, UTC.
uint64_t modification_time;
// Presence indicator for these fields.
//
// If a particular field is absent, it should be set to zero/none,
// and the corresponding presence indicator will be false.
// Therefore, a completely empty |zxio_node_attributes_t| may be conveniently
// obtained via value-initialization e.g. `zxio_node_attributes_t a = {};`.
struct zxio_node_attr_has_t {
bool protocols;
bool abilities;
bool id;
bool content_size;
bool storage_size;
bool link_count;
bool creation_time;
bool modification_time;
#ifdef __cplusplus
constexpr bool operator==(const zxio_node_attr_has_t& other) const {
return protocols == other.protocols && abilities == other.abilities && id == other.id &&
content_size == other.content_size && storage_size == other.storage_size &&
link_count == other.link_count && creation_time == other.creation_time &&
modification_time == other.modification_time;
}
constexpr bool operator!=(const zxio_node_attr_has_t& other) const { return !(*this == other); }
#endif // _cplusplus
} has;
#ifdef __cplusplus
constexpr bool operator==(const zxio_node_attr& other) const {
if (has != other.has) {
return false;
}
if (has.protocols && (protocols != other.protocols)) {
return false;
}
if (has.abilities && (abilities != other.abilities)) {
return false;
}
if (has.id && (id != other.id)) {
return false;
}
if (has.content_size && (content_size != other.content_size)) {
return false;
}
if (has.storage_size && (storage_size != other.storage_size)) {
return false;
}
if (has.link_count && (link_count != other.link_count)) {
return false;
}
if (has.creation_time && (creation_time != other.creation_time)) {
return false;
}
if (has.modification_time && (modification_time != other.modification_time)) {
return false;
}
return true;
}
constexpr bool operator!=(const zxio_node_attr& other) const { return !(*this == other); }
#endif // _cplusplus
} zxio_node_attributes_t;
#define ZXIO_NODE_ATTR_SET(attr, field_name, value) \
do { \
zxio_node_attributes_t* _tmp_attr = &(attr); \
_tmp_attr->field_name = value; \
_tmp_attr->has.field_name = true; \
} while (0)
// The zxio_seek_origin_t enum matches zx_stream_seek_origin_t.
typedef uint32_t zxio_seek_origin_t;
#define ZXIO_SEEK_ORIGIN_START ((zxio_seek_origin_t)0u)
#define ZXIO_SEEK_ORIGIN_CURRENT ((zxio_seek_origin_t)1u)
#define ZXIO_SEEK_ORIGIN_END ((zxio_seek_origin_t)2u)
// An entry in a directory.
typedef struct zxio_dirent {
// The kinds of representations supported by the node.
zxio_node_protocols_t protocols;
// The kinds of operations supported by the node.
zxio_abilities_t abilities;
// A filesystem-unique ID.
zxio_id_t id;
// Presence indicator for the above fields. Note that the |name| field
// is never absent.
//
// If a particular field is absent, it should be set to zero/none,
// and the corresponding presence indicator will be false.
struct zxio_dirent_has_t {
bool protocols;
bool abilities;
bool id;
} has;
// The length of the name of the entry.
uint8_t name_length;
// The name of the entry.
//
// This string is null terminated. Also, |name_length| is offered
// as a convenience.
char* name;
} zxio_dirent_t;
#define ZXIO_DIRENT_SET(attr, field_name, value) \
do { \
zxio_dirent_t* _tmp_attr = &(attr); \
_tmp_attr->field_name = value; \
_tmp_attr->has.field_name = true; \
} while (0)
__END_CDECLS
#endif // LIB_ZXIO_TYPES_H_