blob: 7b1a8eb199c3d9175b51a317270b33e0a20c156b [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.
library fuchsia.io;
using fuchsia.io2;
using fuchsia.mem;
using zx;
/// Connection information.
///
/// Refer to [`Node.Describe`] and [`Node.OnOpen`] for usage.
type NodeInfo = strict resource union {
/// No protocol information was supplied by the connection.
1: service Service;
/// The connection composes [`File`].
2: file FileObject;
/// The connection composes [`Directory`].
3: directory DirectoryObject;
4: pipe Pipe;
/// The connection composes [`File`]. Its implementation is backed by a VMO.
5: vmofile Vmofile;
6: device Device;
7: tty Tty;
8: reserved;
/// The connection composes [`fuchsia.posix.socket/DatagramSocket`].
9: datagram_socket DatagramSocket;
/// The connection composes [`fuchsia.posix.socket/StreamSocket`].
10: stream_socket StreamSocket;
};
/// A [`NodeInfo`] variant.
// TODO(https://fxbug.dev/74683): replace with an anonymous struct inline.
type Service = struct {};
/// Indicates the file is ready for reading.
const FILE_SIGNAL_READABLE uint32 = 0x01000000; // ZX_USER_SIGNAL_0
/// Indicates the file is ready for writing.
const FILE_SIGNAL_WRITABLE uint32 = 0x02000000; // ZX_USER_SIGNAL_1
/// A [`NodeInfo`] variant.
// TODO(https://fxbug.dev/74683): replace with an anonymous struct inline.
type FileObject = resource struct {
/// An optional event which transmits information about an object's readability
/// or writability. This event relays information about the underlying object, not
/// the capability granted to client: this event may be signalled "readable" on a
/// connection that does not have the capability to read.
///
/// The "`FILE_SIGNAL_`" values may be observed on this event.
event zx.handle:<EVENT, optional>;
/// A placeholder for future stream support.
///
/// Currently, servers are required not to send a handle in this field.
stream zx.handle:<STREAM, optional>;
};
/// A [`NodeInfo`] variant.
// TODO(https://fxbug.dev/74683): replace with an anonymous struct inline.
type DirectoryObject = struct {};
/// A [`NodeInfo`] variant.
// TODO(https://fxbug.dev/74683): replace with an anonymous struct inline.
type Pipe = resource struct {
socket zx.handle:SOCKET;
};
/// A [`NodeInfo`] variant.
// TODO(https://fxbug.dev/74683): replace with an anonymous struct inline.
type Vmofile = resource struct {
/// The VMO which backs this file.
vmo zx.handle:VMO;
/// The index into `vmo` which represents the first byte of the file.
offset uint64;
/// The number of bytes, starting at `offset`, which may be used to represent this file.
length uint64;
};
/// Indicates the device is ready for reading.
const DEVICE_SIGNAL_READABLE uint32 = 0x01000000; // ZX_USER_SIGNAL_0
/// Indicates an out-of-band state transition has occurred.
const DEVICE_SIGNAL_OOB uint32 = 0x02000000; // ZX_USER_SIGNAL_1
/// Indicates the device is ready for writing.
const DEVICE_SIGNAL_WRITABLE uint32 = 0x04000000; // ZX_USER_SIGNAL_2
/// Indicates the device has encountered an error state.
const DEVICE_SIGNAL_ERROR uint32 = 0x08000000; // ZX_USER_SIGNAL_3
/// Indicates the device has hung up on the current connection.
const DEVICE_SIGNAL_HANGUP uint32 = 0x10000000; // ZX_USER_SIGNAL_4
/// A [`NodeInfo`] variant.
// TODO(https://fxbug.dev/74683): replace with an anonymous struct inline.
type Device = resource struct {
/// An optional event which transmits information about a device's state.
///
/// The "`DEVICE_SIGNAL_`" values may be observed on this event.
event zx.handle:<EVENTPAIR, optional>;
};
/// A [`NodeInfo`] variant.
// TODO(https://fxbug.dev/74683): replace with an anonymous struct inline.
type Tty = resource struct {
event zx.handle:<EVENTPAIR, optional>;
};
/// A [`NodeInfo`] variant.
// TODO(https://fxbug.dev/74683): replace with an anonymous struct inline.
type DatagramSocket = resource struct {
/// See [`fuchsia.posix.socket.DatagramSocket`] for details.
event zx.handle:EVENTPAIR;
};
/// A [`NodeInfo`] variant.
// TODO(https://fxbug.dev/74683): replace with an anonymous struct inline.
type StreamSocket = resource struct {
socket zx.handle:SOCKET;
};
/// Can read from target object.
const OPEN_RIGHT_READABLE uint32 = 0x00000001;
/// Can write to target object.
const OPEN_RIGHT_WRITABLE uint32 = 0x00000002;
/// Connection can mount/umount filesystem.
const OPEN_RIGHT_ADMIN uint32 = 0x00000004;
/// Connection can map target object executable.
const OPEN_RIGHT_EXECUTABLE uint32 = 0x00000008;
/// Create the object if it doesn't exist.
const OPEN_FLAG_CREATE uint32 = 0x00010000;
/// (with Create) Fail if the object already exists.
const OPEN_FLAG_CREATE_IF_ABSENT uint32 = 0x00020000;
/// Truncate the object before usage.
const OPEN_FLAG_TRUNCATE uint32 = 0x00040000;
/// Assert that the object to be opened is a directory.
/// Return an error if the target object is not a directory.
const OPEN_FLAG_DIRECTORY uint32 = 0x00080000;
/// Seek to the end of the object before all writes.
const OPEN_FLAG_APPEND uint32 = 0x00100000;
/// If the object is a mount point, open the local directory.
const OPEN_FLAG_NO_REMOTE uint32 = 0x00200000;
/// Open a reference to the object, not the object itself.
/// It is ONLY valid to pass the following flags together with `OPEN_FLAG_NODE_REFERENCE`:
/// - `OPEN_FLAG_DIRECTORY`
/// - `OPEN_FLAG_NOT_DIRECTORY`
/// - `OPEN_FLAG_DESCRIBE`
/// otherwise an error is returned.
/// If an object is opened or cloned using this method, the resulting connection does not carry
/// any permission flags.
/// The resulting node allows a limited set of operations: `GetAttr`, `Clone`, `Close`, `Describe`,
/// and, if the node is a file, these extra operations: `GetFlags`, `SetFlags`.
const OPEN_FLAG_NODE_REFERENCE uint32 = 0x00400000;
/// Binary OR of `OPEN_FLAG_DIRECTORY`, OPEN_FLAG_NOT_DIRECTORY, OPEN_FLAG_DESCRIBE, and
/// `OPEN_FLAG_NODE_REFERENCE`. Flags used when opening a node reference must fall within this mask.
const OPEN_FLAGS_ALLOWED_WITH_NODE_REFERENCE uint32 = 0x02c80000;
/// Requests that an "OnOpen" event is sent to the interface request.
/// The event will contain a non-null NodeInfo if the open/clone is successful.
const OPEN_FLAG_DESCRIBE uint32 = 0x00800000;
/// Specify this flag to request POSIX-compatibility with respect to execute and write permissions.
/// This flag implies OPEN_FLAG_POSIX_WRITABLE and OPEN_FLAG_POSIX_EXECUTABLE.
///
/// Use of this flag is being deprecated, and should be replaced with a combination of
/// OPEN_FLAG_POSIX_WRITABLE and/or OPEN_FLAG_POSIX_EXECUTABLE.
const OPEN_FLAG_POSIX uint32 = 0x01000000;
/// Specify this flag to request POSIX-compatibility with respect to write permission handling.
/// Currently, it affects permission handling specifically during Open:
/// - If the target path is a directory, the rights on the new connection expand to include
/// `OPEN_RIGHT_WRITABLE` if and only if the current connection and all intermediate mount points
/// are writable.
/// - Otherwise, this flag is ignored. It is an access denied error to request more rights
/// than those on the current connection, or any intermediate mount points.
///
/// If this flag is omitted, opening always uses the requested rights, failing the operation with
/// access denied error if requested rights exceeds the rights attached to the current connection.
///
/// If the requesting connection is read-only and the requested rights are read-only, the flag
/// may be ignored by the server, and is not forwarded downstream. This is an implementation detail,
/// necessary to enforce hierarchical permissions across mount points, and should have no effect
/// on the expected behavior for clients.
const OPEN_FLAG_POSIX_WRITABLE uint32 = 0x08000000;
/// Specify this flag to request POSIX-compatibility with respect to execute permission handling.
/// Currently, it affects permission handling specifically during Open:
/// - If the target path is a directory, the rights on the new connection expand to include
/// `OPEN_RIGHT_EXECUTABLE` if and only if the current connection and all intermediate mount
/// points are executable.
/// - Otherwise, this flag is ignored. It is an access denied error to request more rights
/// than those on the current connection, or any intermediate mount points.
///
/// If this flag is omitted, opening always uses the requested rights, failing the operation with
/// access denied error if requested rights exceeds the rights attached to the current connection.
///
/// If the requesting connection is read-only and the requested rights are read-only, the flag
/// may be ignored by the server, and is not forwarded downstream. This is an implementation detail,
/// necessary to enforce hierarchical permissions across mount points, and should have no effect
/// on the expected behavior for clients.
const OPEN_FLAG_POSIX_EXECUTABLE uint32 = 0x10000000;
/// Assert that the object to be opened is not a directory.
/// Return an error if the target object is a directory.
const OPEN_FLAG_NOT_DIRECTORY uint32 = 0x02000000;
/// When used during clone, the new connection inherits the rights on the source connection,
/// regardless if it is a file or directory. Otherwise, clone attempts to use the requested rights.
/// It is invalid to pass any of the `OPEN_RIGHT_*` flags together with `CLONE_FLAG_SAME_RIGHTS`.
const CLONE_FLAG_SAME_RIGHTS uint32 = 0x04000000;
/// Node defines the minimal interface for entities which can be accessed in a filesystem.
protocol Node {
/// Create another connection to the same remote object.
///
/// `flags` may be any of:
///
/// - `OPEN_RIGHT_*`
/// - `OPEN_FLAG_APPEND`
/// - `OPEN_FLAG_NO_REMOTE`
/// - `OPEN_FLAG_DESCRIBE`
/// - `CLONE_FLAG_SAME_RIGHTS`
///
/// All other flags are ignored.
///
/// The `OPEN_RIGHT_*` bits in `flags` request corresponding rights over the resulting
/// cloned object.
/// The cloned object must have rights less than or equal to the original object, otherwise
/// returns `ZX_ERR_ACCESS_DENIED`.
/// Alternatively, pass `CLONE_FLAG_SAME_RIGHTS` to inherit the rights on the source connection.
/// It is invalid to pass any of the `OPEN_RIGHT_*` flags together with
/// `CLONE_FLAG_SAME_RIGHTS`.
Clone(resource struct {
flags uint32;
object server_end:Node;
});
/// Terminates connection with object.
///
/// This method does not require any rights.
Close() -> (struct {
s zx.status;
});
/// Returns extra information about the type of the object.
/// If the `Describe` operation fails, the connection is closed.
///
/// This method does not require any rights.
Describe() -> (resource struct {
info NodeInfo;
});
/// An event produced eagerly by a FIDL server if requested by `OPEN_FLAG_DESCRIBE`.
///
/// Indicates the success or failure of the open operation, and optionally describes the
/// object. If the status is `ZX_OK`, `info` contains descriptive information about the object
/// (the same as would be returned by `Describe`).
-> OnOpen(resource struct {
s zx.status;
info NodeInfo:optional;
});
/// Synchronizes updates to the node to the underlying media, if it exists.
///
/// This method does not require any rights.
Sync() -> (struct {
s zx.status;
});
/// Acquires information about the node.
///
/// This method does not require any rights.
GetAttr() -> (struct {
s zx.status;
attributes NodeAttributes;
});
/// Updates information about the node.
/// `flags` may be any of `NODE_ATTRIBUTE_FLAG_*`.
///
/// This method requires following rights: `OPEN_RIGHT_WRITABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
SetAttr(struct {
flags uint32;
attributes NodeAttributes;
}) -> (struct {
s zx.status;
});
/// Acquires the `Directory.Open` rights and flags used to access this file.
///
/// This method does not require any rights.
/// This method has the same functionality as GetFlags for File and is
/// meant as an in-progress replacement.
@transitional
NodeGetFlags() -> (struct {
s zx.status;
flags uint32;
});
/// Changes the `Directory.Open` flags used to access the file.
/// Supported flags which can be turned on / off:
/// - `OPEN_FLAG_APPEND`
///
/// This method does not require any rights.
/// This method has the same functionality as SetFlags for File and is
/// meant as an in-progress replacement.
@transitional
NodeSetFlags(struct {
flags uint32;
}) -> (struct {
s zx.status;
});
};
/// Bits reserved for posix protections. Native fuchsia filesystems
/// are not required to set bits contained within `MODE_PROTECTION_MASK`,
/// but filesystems that wish to do so may refer to sys/stat.h for their
/// definitions.
const MODE_PROTECTION_MASK uint32 = 0x00FFF;
/// Bits indicating node type. The canonical mechanism to check
/// for a node type is to take 'mode', bitwise AND it with the
/// `MODE_TYPE_MASK`, and check exact equality against a mode type.
const MODE_TYPE_MASK uint32 = 0xFF000;
const MODE_TYPE_DIRECTORY uint32 = 0x04000;
const MODE_TYPE_BLOCK_DEVICE uint32 = 0x06000;
const MODE_TYPE_FILE uint32 = 0x08000;
const MODE_TYPE_SOCKET uint32 = 0x0C000;
const MODE_TYPE_SERVICE uint32 = 0x10000;
/// NodeAttributes defines generic information about a filesystem node.
type NodeAttributes = struct {
/// Protection bits and node type information describe in 'mode'.
mode uint32;
/// A filesystem-unique ID.
id uint64;
/// Node size, in bytes.
content_size uint64;
/// Space needed to store node (possibly larger than size), in bytes.
storage_size uint64;
/// Hard link count.
link_count uint64;
/// Time of creation (may be updated manually after creation) in ns since Unix epoch, UTC.
creation_time uint64;
/// Time of last modification in ns since Unix epoch, UTC.
modification_time uint64;
};
/// The maximal buffer size which can be transmitted for buffered operations.
/// This capacity is currently set somewhat arbitrarily.
const MAX_BUF uint64 = 8192;
/// The maximum length, in bytes, of a filesystem string.
// TODO(smklein): Update to 4095. +1 is for null-terminator, which shouldn't be
// part of the FIDL length.
const MAX_PATH uint64 = 4096;
/// The maximum length, in bytes, of a single filesystem component.
const MAX_FILENAME uint64 = 255;
/// The fields of 'attributes' which are used to update the Node are indicated
/// by the 'flags' argument.
const NODE_ATTRIBUTE_FLAG_CREATION_TIME uint32 = 0x00000001;
const NODE_ATTRIBUTE_FLAG_MODIFICATION_TIME uint32 = 0x00000002;
/// Update the Seek offset.
type SeekOrigin = strict enum : uint32 {
/// Seek from the start of the file.
START = 0;
/// Seek from the current position in the file.
CURRENT = 1;
/// Seek from the end of the file.
END = 2;
};
/// Requests that the VMO be readable.
const VMO_FLAG_READ uint32 = 0x00000001;
/// Requests that the VMO be writable.
const VMO_FLAG_WRITE uint32 = 0x00000002;
/// Requests that the VMO be executable.
const VMO_FLAG_EXEC uint32 = 0x00000004;
/// Require a copy-on-write clone of the underlying VMO.
/// The request should fail if the VMO is not cloned.
/// May not be supplied with fuchsia_io_`VMO_FLAG_EXACT`.
const VMO_FLAG_PRIVATE uint32 = 0x00010000;
/// Require an exact (non-cloned) handle to the underlying VMO.
/// The request should fail if a handle to the exact VMO is not returned.
/// May not be supplied with `VMO_FLAG_PRIVATE`.
const VMO_FLAG_EXACT uint32 = 0x00020000;
/// File defines the interface of a node which contains a flat layout of data.
protocol File {
compose Node;
compose fuchsia.io2.AdvisoryLocking;
/// Reads `count` bytes at the seek offset.
/// The seek offset is moved forward by the number of bytes read.
///
/// This method requires following rights: `OPEN_RIGHT_READABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
Read(struct {
count uint64;
}) -> (struct {
s zx.status;
data vector<uint8>:MAX_BUF;
});
/// Reads `count` bytes at the provided offset.
/// Does not affect the seek offset.
///
/// This method requires following rights: `OPEN_RIGHT_READABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
ReadAt(struct {
count uint64;
offset uint64;
}) -> (struct {
s zx.status;
data vector<uint8>:MAX_BUF;
});
/// Writes data at the seek offset.
/// The seek offset is moved forward by the number of bytes written.
///
/// This method requires following rights: `OPEN_RIGHT_WRITABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
Write(struct {
data vector<uint8>:MAX_BUF;
}) -> (struct {
s zx.status;
actual uint64;
});
/// Writes data to the provided offset.
/// Does not affect the seek offset.
///
/// This method requires following rights: `OPEN_RIGHT_WRITABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
WriteAt(struct {
data vector<uint8>:MAX_BUF;
offset uint64;
}) -> (struct {
s zx.status;
actual uint64;
});
/// Moves the offset at which the next invocation of `Read()` or `Write()` will
/// occur.
///
/// This method does not require any rights.
Seek(struct {
offset int64;
start SeekOrigin;
}) -> (struct {
s zx.status;
offset uint64;
});
/// Shrinks the file size to 'length' bytes.
///
/// This method requires following rights: `OPEN_RIGHT_WRITABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
Truncate(struct {
length uint64;
}) -> (struct {
s zx.status;
});
/// Acquires the `Directory.Open` rights and flags used to access this file.
///
/// This method does not require any rights.
GetFlags() -> (struct {
s zx.status;
flags uint32;
});
/// Changes the `Directory.Open` flags used to access the file.
/// Supported flags which can be turned on / off:
/// - `OPEN_FLAG_APPEND`
///
/// This method does not require any rights.
SetFlags(struct {
flags uint32;
}) -> (struct {
s zx.status;
});
/// Acquires a buffer representing this file, if there is one, with the
/// requested access rights.
///
/// `flags` may be any of `VMO_FLAG_*`.
///
/// This method requires following rights:
///
/// - `OPEN_RIGHT_WRITABLE` if `flags` includes `VMO_FLAG_WRITE`.
/// - `OPEN_RIGHT_READABLE` if `flags` includes `VMO_FLAG_READ` or `VMO_FLAG_EXEC`.
GetBuffer(struct {
flags uint32;
}) -> (resource struct {
s zx.status;
buffer box<fuchsia.mem.Buffer>;
});
};
// Dirent type information associated with the results of ReadDirents.
// The following values are aligned with the values from libc's "dirent.h" "DT_...".
/// A dirent with an unknown type.
const DIRENT_TYPE_UNKNOWN uint8 = 0;
/// A dirent representing a directory object.
const DIRENT_TYPE_DIRECTORY uint8 = 4;
/// A dirent representing a block device object.
const DIRENT_TYPE_BLOCK_DEVICE uint8 = 6;
/// A dirent representing a file object.
const DIRENT_TYPE_FILE uint8 = 8;
/// A dirent representing a socket object.
const DIRENT_TYPE_SOCKET uint8 = 12;
/// A dirent representing a service object.
const DIRENT_TYPE_SERVICE uint8 = 16;
/// Nodes which do not have ino values should return this value
/// from Readdir and GetAttr.
const INO_UNKNOWN uint64 = 0xFFFFFFFFFFFFFFFF;
/// Indicates the directory being watched has been deleted.
const WATCH_EVENT_DELETED uint8 = 0;
/// Indicates a node has been created (either new or moved) into a directory.
const WATCH_EVENT_ADDED uint8 = 1;
/// Identifies a node has been removed (either deleted or moved) from the directory.
const WATCH_EVENT_REMOVED uint8 = 2;
/// Identifies a node already existed in the directory when watching started.
const WATCH_EVENT_EXISTING uint8 = 3;
/// Identifies that no more `WATCH_EVENT_EXISTING` events will be sent.
const WATCH_EVENT_IDLE uint8 = 4;
/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_DELETED`.
const WATCH_MASK_DELETED uint32 = 0x00000001;
/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_ADDED`.
const WATCH_MASK_ADDED uint32 = 0x00000002;
/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_REMOVED`.
const WATCH_MASK_REMOVED uint32 = 0x00000004;
/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_EXISTING`.
const WATCH_MASK_EXISTING uint32 = 0x00000008;
/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_IDLE`.
const WATCH_MASK_IDLE uint32 = 0x00000010;
/// Used by `Directory.Watch`. Requests transmission of all watcher events.
const WATCH_MASK_ALL uint32 = 0x0000001F;
// TODO(fxbug.dev/7903): Unused.
/// WatchedEvent describes events returned from a DirectoryWatcher.
type WatchedEvent = struct {
event uint8;
len uint8;
name vector<uint8>:MAX_FILENAME;
};
// TODO(fxbug.dev/7903): Unused.
/// DirectoryWatcher transmits messages from a filesystem server
/// about events happening in the filesystem. Clients can register
/// new watchers using the `Directory.Watch` method, where they can
/// filter which events they want to receive notifications for.
protocol DirectoryWatcher {
// TODO(smklein): Convert this to a vector of WatchedEvents, when possible.
OnEvent(struct {
events vector<uint8>:MAX_BUF;
});
};
/// Directory defines a node which is capable of containing other Objects.
protocol Directory {
compose Node;
compose fuchsia.io2.AdvisoryLocking;
/// Opens a new object relative to this directory object.
///
/// `path` may contain multiple segments, separated by "/" characters, and should never be
/// empty; i.e. "" is an invalid path. A trailing slash implies OPEN_FLAG_DIRECTORY. Components
/// must not be empty (i.e. "foo//bar" is invalid). ".." is disallowed anywhere in the path. "."
/// is only allowed if the path is exactly ".", but not otherwise. A leading '/' is allowed (and
/// is treated the same way as if not present, i.e. "/foo/bar' and "foo/bar" are the same).
///
/// `flags` may be any of the `OPEN_FLAG_*` and `OPEN_RIGHT_*` values, bitwise ORed together.
/// The `OPEN_FLAG_DESCRIBE` flag may cause an `OnOpen` event to be transmitted
/// on the `object` handle, indicating the type of object opened.
///
/// If an unknown value is sent for flags the connection should be closed.
///
/// `OPEN_RIGHT_*` flags provided in `flags` will restrict access rights on
/// the `object` channel which will be connected to the opened entity.
///
/// Rights are never increased. When you open a nested entity within a directory, you may only
/// request the same rights as what the directory connection already has, or a subset of those.
/// Exceeding those rights causes an access denied error to be transmitted in the
/// `OnOpen` event if applicable, and the `object` connection closed.
///
/// The caller must specify either one or more of the `OPEN_RIGHT_*` flags, or
/// the `OPEN_FLAG_NODE_REFERENCE` flag.
///
/// `mode` is only used if an object is created and indicates the type of object to be
/// created. An unsupported mode will cause the connection to be closed.
/// The mode type, if set, must always be consistent with the OPEN_FLAG_DIRECTORY and
/// OPEN_FLAG_NOT_DIRECTORY flags, even if an object is not being created. If an object is not
/// being created, `mode` is otherwise ignored. If an object is being created and the mode
/// type is not set, a directory will be created if OPEN_FLAG_DIRECTORY is set (explicitly or
/// implicitly), or otherwise a server chosen object type.
Open(resource struct {
flags uint32;
mode uint32;
path string:MAX_PATH;
object server_end:Node;
});
/// Adds a new inotify filter for an object relative to this directory object.
///
/// + 'filter` is a mask of different inotify events that need to be watched by the server
/// for a specific file/directory.
///
/// + `path` may contain multiple segments, separated by "/" characters,
/// and should never be empty; i.e., "" is an invalid path. Paths should not contain
/// a leading "/".
///
/// +`watch_descriptor` is client assigned value to identify a filter.
/// Server shouldn't trust the client-assigned watch_descriptor. They should just send it
/// back to the client in the socket.
/// This value is not used by server, but it is returned back as part of InotifyEvent,
/// to help the client correlate filter with events on this filter.
///
/// + `socket` is shared between different filter objects i.e every new filter will
/// have a different server end of the socket and there will be a single client end per
/// inotify instance on inotify init.
///
AddInotifyFilter(resource struct {
path fuchsia.io2.Path;
filter fuchsia.io2.InotifyWatchMask;
watch_descriptor uint32;
socket zx.handle:SOCKET;
}) -> ();
/// Detaches an object from this directory object.
///
/// The underlying object may or may not be deleted after this method
/// completes: although the link will be removed from the containing directory,
/// objects with multiple references (such as files which are still open)
/// will not actually be destroyed until all references are removed.
///
/// If a directory is unlinked while it still has an open reference,
/// it must become read-only, preventing new entries from being created
/// until all references close and the directory is destroyed.
///
/// `path` identifies the file which should be detached.
/// If `path` contains multiple segments, separated by "/" characters,
/// then the directory is traversed, one segment at a time, relative to the
/// originally accessed Directory.
///
/// Returns:
/// `ZX_ERR_ACCESS_DENIED` if the connection (or the underlying filesystem) does not
/// allow writable access.
/// `ZX_ERR_INVALID_ARGS` if `path` contains ".." segments.
/// `ZX_ERR_NOT_EMPTY` if `path` refers to a non-empty directory.
/// `ZX_ERR_UNAVAILABLE` if `path` refers to a mount point, containing a remote channel.
/// `ZX_ERR_UNAVAILABLE` if `path` is ".".
///
/// Other errors may be returned for filesystem-specific reasons.
///
/// This method requires following rights: `OPEN_RIGHT_WRITABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
Unlink(struct {
path string:MAX_PATH;
}) -> (struct {
s zx.status;
});
/// Removes a child node from the this directory's list of entries.
///
/// Note: this does not guarantee that the underlying object is destroyed.
/// Although the link will be removed from the containing directory,
/// objects with multiple references (such as files which are still open)
/// will not actually be destroyed until all references are closed.
///
/// * error `ZX_ERR_ACCESS_DENIED` if the connection does not have
/// [`Rights.WRITE_BYTES`].
/// * error `ZX_ERR_NOT_SUPPORTED` if the underlying filesystem does not
/// support writing.
/// * error `ZX_ERR_BAD_PATH` if `name` is invalid.
/// * error `ZX_ERR_NOT_EMPTY` if `name` refers to a non-empty directory.
/// * error `ZX_ERR_UNAVAILABLE` if `name` refers to a mount point,
/// containing a remote channel.
/// * error `ZX_ERR_NOT_DIR` if the options requested a directory but something other than a
/// directory was found.
///
/// Other errors may be returned for filesystem-specific reasons.
///
/// This method requires the following rights:
///
/// * [`Rights.ENUMERATE`]
/// * [`Rights.MODIFY_DIRECTORY`]
@selector("fuchsia.io/Directory.Unlink")
@transitional
Unlink2(struct {
name fuchsia.io2.Name;
options fuchsia.io2.UnlinkOptions;
}) -> (struct {}) error zx.status;
/// Reads a collection of variably sized dirents into a buffer.
/// The number of dirents in a directory may be very large: akin to
/// calling read multiple times on a file, directories have a seek
/// offset which is updated on subsequent calls to ReadDirents.
///
/// These dirents are of the form:
/// ```
/// struct dirent {
/// // Describes the inode of the entry.
/// uint64 ino;
/// // Describes the length of the dirent name in bytes.
/// uint8 size;
/// // Describes the type of the entry. Aligned with the
/// // POSIX d_type values. Use `DIRENT_TYPE_*` constants.
/// uint8 type;
/// // Unterminated name of entry.
/// char name[0];
/// }
/// ```
///
/// This method does not require any rights, since one could always probe for
/// directory contents by triggering name conflicts during file creation.
// TODO(smklein): Convert to a vector of variable-length objects, when
// llcpp arrives.
// TODO(smklein): Get rid of "max_bytes".
// TODO(smklein): Document the behavior when the seek pointer reaches the end of the directory.
ReadDirents(struct {
max_bytes uint64;
}) -> (struct {
s zx.status;
dirents vector<uint8>:MAX_BUF;
});
/// Resets the directory seek offset.
///
/// This method does not require any rights, similar to ReadDirents.
Rewind() -> (struct {
s zx.status;
});
/// Acquires a token to a Directory which can be used to identify
/// access to it at a later point in time.
///
/// This method requires following rights: `OPEN_RIGHT_WRITABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
GetToken() -> (resource struct {
s zx.status;
token zx.handle:optional;
});
/// Renames an object named src to the name dst, in a directory represented by token.
///
/// `src/dst` must be resolved object names. Including "/" in any position
/// other than the end of the string will return `ZX_ERR_INVALID_ARGS`.
/// Returning "/" at the end of either string implies that it must be a
/// directory, or else `ZX_ERR_NOT_DIR` should be returned.
///
/// This method requires following rights: `OPEN_RIGHT_WRITABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
@transitional // Rename is being removed, use Rename2 instead.
Rename(resource struct {
src string:MAX_PATH;
dst_parent_token zx.handle;
dst string:MAX_PATH;
}) -> (struct {
s zx.status;
});
/// Renames a node named `src` to the name `dst`, in a directory represented
/// by `dst_parent_token`.
///
/// `src` and `dst` must be valid node names.
/// See [`fuchsia.io2/Name`] for what constitutes a valid name.
///
/// This method requires the following rights on both the current
/// connection, and the connection identified by `dst_parent_token`:
///
/// * [`Rights.ENUMERATE`]
/// * [`Rights.MODIFY_DIRECTORY`]
///
/// * error `ZX_ERR_INVALID_ARGS` if `src` or `dst` is invalid.
@selector("fuchsia.io/Directory.Rename")
Rename2(resource struct {
src fuchsia.io2.Name;
dst_parent_token fuchsia.io2.Token;
dst fuchsia.io2.Name;
}) -> (struct {}) error zx.status;
/// Creates a link to an object named src by the name dst, within a directory represented by
/// token.
///
/// `src` must be a resolved object name. Including "/" in the string will
/// return `ZX_ERR_INVALID_ARGS`.
///
/// `dst` must be a resolved object name. Including "/" in the string will
/// return `ZX_ERR_INVALID_ARGS`.
///
/// This method requires following rights: `OPEN_RIGHT_WRITABLE`, otherwise returns
/// `ZX_ERR_BAD_HANDLE`.
Link(resource struct {
src string:MAX_PATH;
dst_parent_token zx.handle;
dst string:MAX_PATH;
}) -> (struct {
s zx.status;
});
// TODO(smklein): When stablized, remove the "This API is unstable" comment
/// Watches a directory, receiving events of added messages on the
/// watcher request channel.
///
/// The `watcher` handle will send messages of the form:
/// ```
/// struct {
/// uint8 event;
/// uint8 len;
/// char name[];
/// };
/// ```
/// Where names are NOT null-terminated.
///
/// This API is unstable; in the future, watcher will be a `DirectoryWatcher` client.
///
/// Mask specifies a bitmask of events to observe.
/// Options must be zero; it is reserved.
///
/// This method does not require any rights, similar to ReadDirents.
Watch(resource struct {
mask uint32;
options uint32;
watcher zx.handle:CHANNEL;
}) -> (struct {
s zx.status;
});
};
const MOUNT_CREATE_FLAG_REPLACE uint32 = 0x00000001;
const MAX_FS_NAME_BUFFER uint64 = 32;
type FilesystemInfo = struct {
/// The number of data bytes which may be stored in a filesystem.
total_bytes uint64;
/// The number of data bytes which are in use by the filesystem.
used_bytes uint64;
/// The number of nodes which may be stored in the filesystem.
total_nodes uint64;
/// The number of nodes used by the filesystem.
used_nodes uint64;
/// The amount of space which may be allocated from the underlying
/// volume manager. If unsupported, this will be zero.
free_shared_pool_bytes uint64;
/// A unique identifier for this filesystem instance. Will not be preserved
/// across reboots.
fs_id uint64;
/// The size of a single filesystem block.
block_size uint32;
/// The maximum length of a filesystem name.
max_filename_size uint32;
/// A unique identifier for the type of the underlying filesystem.
fs_type uint32;
padding uint32;
// TODO(smklein): Replace this field with a string when supported
// by the "Simple" interface. At the moment, name is a fixed-size,
// null-terminated buffer.
name array<int8, MAX_FS_NAME_BUFFER>;
};
/// DirectoryAdmin defines a directory which is capable of handling
/// administrator tasks within the filesystem.
protocol DirectoryAdmin {
compose Directory;
/// Mount a channel representing a remote filesystem onto this directory.
/// All future requests to this node will be forwarded to the remote filesystem.
/// To re-open a node without forwarding to the remote target, the node
/// should be opened with `OPEN_FLAG_NO_REMOTE`.
Mount(resource struct {
remote client_end:Directory;
}) -> (struct {
s zx.status;
});
/// Atomically create a directory with a provided path, and mount the
/// remote handle to the newly created directory.
MountAndCreate(resource struct {
remote client_end:Directory;
name string:MAX_FILENAME;
flags uint32;
}) -> (struct {
s zx.status;
});
/// Unmount this filesystem. After this function returns successfully,
/// all connections to the filesystem will be terminated.
Unmount() -> (struct {
s zx.status;
});
/// Detach a node which was previously attached to this directory
/// with Mount.
UnmountNode() -> (resource struct {
s zx.status;
remote client_end:<Directory, optional>;
});
/// Query the filesystem for filesystem-specific information.
QueryFilesystem() -> (struct {
s zx.status;
info box<FilesystemInfo>;
});
/// Acquire the path to the device backing this filesystem, if there is one.
GetDevicePath() -> (struct {
s zx.status;
path string:<MAX_PATH, optional>;
});
};