| // 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 zx; |
| |
| type DirectoryInfo = table { |
| /// Requested attributes for the directory. This is only populated if requested. |
| @available(added=18) |
| 1: attributes NodeAttributes2; |
| }; |
| |
| // TODO(https://fxbug.dev/42056856): Use a generated constant. |
| const DIRECTORY_PROTOCOL_NAME string = "fuchsia.io/Directory"; |
| |
| /// Flags used to specify how a node should be opened. Note that ranges of bits are reserved |
| /// for specific use cases: |
| /// * Bits 1-16: Permission flags `PERM_*` (e.g. [`Flags.PERM_READ`]). |
| /// * Bits 17-32: POSIX compatibile `O_*` flags (e.g. [`Flags.FILE_TRUNCATE`] or `O_TRUNC`). |
| /// * Bits 33-64: Fuchsia-specific flags. |
| type Flags = flexible bits : uint64 { |
| // |
| // Permissions |
| // |
| // Permissions can only be granted if the current connection has them. If a permission is |
| // requested but not available, the request will fail with `ZX_ERR_ACCESS_DENIED`. |
| // Note that the `PERM_INHERIT_*` flags can be used to request permissions that the |
| // connection may lack without failing the request. Callers should not expect that these |
| // permissions are available if the request succeeds. |
| |
| /// Allows opening child nodes with [`PROTOCOL_SERVICE`]. |
| PERM_CONNECT = 0x0001; |
| /// Read byte contents of a file. |
| PERM_READ = 0x0002; |
| /// Write byte contents to a file. |
| PERM_WRITE = 0x0004; |
| /// Execute byte contents of a file. |
| PERM_EXECUTE = 0x0008; |
| /// Get/query attributes of a node. |
| PERM_GET_ATTRIBUTES = 0x0010; |
| /// Set/update attributes of a node. |
| PERM_SET_ATTRIBUTES = 0x0020; |
| /// Enumerate (list) directory entries. |
| PERM_ENUMERATE = 0x0040; |
| /// Allow opening a child node with a node protocol. Must be specified with PERM_ENUMERATE |
| /// otherwise requests will fail with `ZX_ERR_INVALID_ARGS`. |
| PERM_TRAVERSE = 0x0080; |
| /// Modify directory entries (create/rename/link/unlink). Must be specified with PERM_ENUMERATE |
| /// otherwise requests will fail with `ZX_ERR_INVALID_ARGS`. |
| PERM_MODIFY = 0x0100; |
| /// Inherit write permissions when available (PERM_WRITE, PERM_SET_ATTRIBUTES, PERM_MODIFY, |
| /// PERM_ENUMERATE). Servers must ensure this flag is removed if the parent connection lacks any |
| /// of these rights. See [`INHERITED_WRITE_PERMISSIONS`] for the exact set of permissions that |
| /// will be inherited. |
| PERM_INHERIT_WRITE = 0x2000; |
| /// Inherit execute permission when available (PERM_EXECUTE). |
| /// Servers must ensure this flag is removed if the parent connection lacks PERM_EXECUTE. |
| PERM_INHERIT_EXECUTE = 0x4000; |
| |
| // |
| // Protocols |
| // |
| // If several protocols are specified, the caller must be prepared to accept any protocol. |
| // If no protocols are specified, the server will negotiate a node protocol for the caller |
| // based on the protocols the target object supports. Caller can request an event with |
| // [`FLAG_SEND_REPRESENTATION`] to determine which protocol was negotiated. |
| // |
| // If the target node is not compatible with any specified protocols, the request will fail |
| // with the following precedence of errors: |
| // |
| // * `ZX_ERR_NOT_DIR` if [`PROTOCOL_DIRECTORY`] was specified but no other protocol was |
| // negotiated |
| // * `ZX_ERR_NOT_FILE` if [`PROTOCOL_FILE`]` was specified but no other protocol was negotiated |
| // * `ZX_ERR_WRONG_TYPE` for all other cases |
| |
| /// Connect to the underlying protocol if this is a service node. The caller must determine the |
| /// correct protocol to use (e.g. based on path). Unless used with [`PROTOCOL_NODE`], specifying |
| /// other flags with the request will fail with `ZX_ERR_INVALID_ARGS`. |
| PROTOCOL_SERVICE = 0x000100000000; |
| /// Connect to the underlying node. Takes precedence over other protocols. If other `PROTOCOL_*` |
| /// are specified, they will be used to validate the target node type. Requests will fail with |
| /// `ZX_ERR_INVALID_ARGS` if flags other than `PROTOCOL_*` and [`FLAG_SEND_REPRESENTATION`] are |
| /// specified. Equivalent to POSIX `O_PATH`. |
| PROTOCOL_NODE = 0x00400000; |
| /// Caller accepts [`fuchsia.io/Directory`] protocol. Equivalent to POSIX `O_DIRECTORY`. |
| PROTOCOL_DIRECTORY = 0x00080000; |
| /// Caller accepts [`fuchsia.io/File`] protocol. |
| PROTOCOL_FILE = 0x000200000000; |
| /// Caller accepts [`fuchsia.io/Symlink`] protocol. |
| PROTOCOL_SYMLINK = 0x000400000000; |
| |
| // |
| // Options |
| // |
| |
| /// Caller requests a [`fuchsia.io/Node.OnRepresentation`] event on success. |
| FLAG_SEND_REPRESENTATION = 0x010000000000; |
| /// Create a new object if one doesn't exist, otherwise open an existing object. If set, a |
| /// single `PROTOCOL_*` flag must be set indicating the type of object to create. Equivalent |
| /// to POSIX `O_CREAT`. |
| FLAG_MAYBE_CREATE = 0x00010000; |
| /// Create a new object if one doesn't exist, otherwise fail the request with |
| /// `ZX_ERR_ALREADY_EXISTS`. If set, a single `PROTOCOL_*` flag must be set indicating the type |
| /// of object to create. Takes precedence over [`FLAG_CREATE`]. Equivalent to POSIX `O_EXCL`. |
| FLAG_MUST_CREATE = 0x00020000; |
| |
| // |
| // File-Specific Options |
| // |
| |
| /// Open the file in append mode. The seek pointer will be moved to end-of-file (EOF) |
| /// before all writes. Equivalent to POSIX `O_APPEND`. |
| FILE_APPEND = 0x00100000; |
| /// Truncate the file to zero length upon opening it. Equivalent to POSIX `O_TRUNC`. |
| FILE_TRUNCATE = 0x00040000; |
| }; |
| |
| const MASK_PERMISSION_FLAGS uint64 = 0x000000000000FFFF; |
| |
| const MASK_POSIX_FLAGS uint64 = 0x00000000FFFFFFFF; |
| |
| const MASK_KNOWN_PERMISSIONS Flags |
| = Flags.PERM_READ | Flags.PERM_WRITE | Flags.PERM_EXECUTE | Flags.PERM_SET_ATTRIBUTES | Flags.PERM_ENUMERATE | Flags.PERM_MODIFY | Flags.PERM_CONNECT | Flags.PERM_GET_ATTRIBUTES | Flags.PERM_TRAVERSE | Flags.PERM_INHERIT_WRITE | Flags.PERM_INHERIT_EXECUTE; |
| |
| const MASK_KNOWN_PROTOCOLS Flags |
| = Flags.PROTOCOL_DIRECTORY | Flags.PROTOCOL_FILE | Flags.PROTOCOL_NODE | Flags.PROTOCOL_SYMLINK | Flags.PROTOCOL_SERVICE; |
| |
| /// Set of rights that [`Flags.PERM_INHERIT_WRITE`] will inherit from the parent connection if |
| /// specified. Note that if any of these permissions are missing from the connection, none of these |
| /// permissions will be inherited. |
| const INHERITED_WRITE_PERMISSIONS Operations |
| = Operations.WRITE_BYTES | Operations.ENUMERATE | Operations.MODIFY_DIRECTORY | Operations.UPDATE_ATTRIBUTES; |
| |
| /// Set of permissions that are expected when opening a node as readable. |
| const PERM_READABLE Flags |
| = Flags.PERM_CONNECT | Flags.PERM_ENUMERATE | Flags.PERM_TRAVERSE | Flags.PERM_READ | Flags.PERM_GET_ATTRIBUTES; |
| |
| /// Set of permissions that are expected when opening a node as writable. |
| const PERM_WRITABLE Flags |
| = Flags.PERM_CONNECT | Flags.PERM_ENUMERATE | Flags.PERM_TRAVERSE | Flags.PERM_WRITE | Flags.PERM_MODIFY | Flags.PERM_SET_ATTRIBUTES; |
| |
| /// Set of permissions that are expected when opening a node as executable. |
| const PERM_EXECUTABLE Flags |
| = Flags.PERM_CONNECT | Flags.PERM_ENUMERATE | Flags.PERM_TRAVERSE | Flags.PERM_EXECUTE; |
| |
| /// Options which can be used with Open3. Unlike [`Flags`], these options are designed for specific |
| /// use cases (e.g. to reduce round-trip latency when requesting attributes). |
| type Options = table { |
| /// Request a set of attributes to be sent with the OnRepresentation response. Has no effect |
| /// if `Flags.FLAG_SEND_REPRESENTATION` is not set. |
| 1: attributes NodeAttributesQuery; |
| /// Request a set of attributes to be set atomically when creating a new object. Requests will |
| /// fail with `ZX_ERR_INVALID_ARGS` if neither `Flags.FLAG_MAYBE_CREATE` nor |
| /// `Flags.FLAG_MUST_CREATE` are set (i.e. the creation is mode is Never). |
| 2: create_attributes MutableNodeAttributes; |
| }; |
| |
| /// DEPRECATED - Use Flags instead. |
| type OpenFlags = strict bits : uint32 { |
| /// Can read from target object. |
| RIGHT_READABLE = 0x00000001; |
| /// Can write to target object. |
| RIGHT_WRITABLE = 0x00000002; |
| /// Connection can map target object executable. |
| RIGHT_EXECUTABLE = 0x00000008; |
| |
| /// Create the object if it doesn't exist. |
| CREATE = 0x00010000; |
| /// (with Create) Fail if the object already exists. |
| CREATE_IF_ABSENT = 0x00020000; |
| /// Truncate the object before usage. |
| TRUNCATE = 0x00040000; |
| /// Assert that the object to be opened is a directory. |
| /// Return an error if the target object is not a directory. |
| DIRECTORY = 0x00080000; |
| /// Seek to the end of the object before all writes. |
| APPEND = 0x00100000; |
| /// Open a reference to the object, not the object itself. |
| /// It is ONLY valid to pass the following flags together with `NODE_REFERENCE`: |
| /// - `DIRECTORY` |
| /// - `NOT_DIRECTORY` |
| /// - `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 connection allows a limited set of operations: `GetAttr`, `Clone`, `Close`, |
| /// `Describe`, and `GetFlags`. The connection will speak the `Node` protocol. Calling `SetAttr` |
| /// or `SetFlags` will result in `ZX_ERR_BAD_HANDLE`. |
| NODE_REFERENCE = 0x00400000; |
| /// Requests that an "OnOpen" event is sent to the interface request. |
| /// |
| /// The event will contain a non-null `NodeInfoDeprecated` if the open/clone is successful. This |
| /// can be used to open a protocol that does not compose fuchsia.io/Node; the event is sent as |
| /// if the protocol is fuchsia.io/Node and then the target protocol is used exclusively. |
| DESCRIBE = 0x00800000; |
| /// 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 |
| /// `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. |
| POSIX_WRITABLE = 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 |
| /// `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. |
| POSIX_EXECUTABLE = 0x10000000; |
| /// Assert that the object to be opened is not a directory. |
| /// Return an error if the target object is a directory. |
| NOT_DIRECTORY = 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 `RIGHT_*` flags together with `OpenFlags.CLONE_SAME_RIGHTS`. |
| CLONE_SAME_RIGHTS = 0x04000000; |
| |
| /// Open the target object as a block device. |
| // TODO(https://fxbug.dev/42071940): this form of protocol negotiation is unprincipled. |
| BLOCK_DEVICE = 0x01000000; |
| }; |
| |
| /// All known rights. |
| const OPEN_RIGHTS OpenFlags |
| = OpenFlags.RIGHT_READABLE | OpenFlags.RIGHT_WRITABLE | OpenFlags.RIGHT_EXECUTABLE; |
| |
| /// Flags used when opening a node reference must fall within this mask. |
| const OPEN_FLAGS_ALLOWED_WITH_NODE_REFERENCE OpenFlags |
| = OpenFlags.DIRECTORY | OpenFlags.NOT_DIRECTORY | OpenFlags.DESCRIBE | OpenFlags.NODE_REFERENCE; |
| |
| type ModeType = strict bits : uint32 { |
| DO_NOT_USE = 0x80000000; |
| }; |
| |
| /// 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. |
| @available(deprecated=11, removed=12, note="Use MAX_PATH_LENGTH or Path (for strings) instead.") |
| const MAX_PATH uint64 = 4096; |
| /// The maximum length, in bytes, of a single filesystem component. |
| const MAX_FILENAME uint64 = 255; |
| |
| // Dirent type information associated with the results of ReadDirents. |
| // The following values are aligned with the values from libc's "dirent.h" "DT_...". |
| type DirentType = flexible enum : uint8 { |
| /// A dirent with an unknown type. |
| UNKNOWN = 0; |
| /// A dirent representing a directory object. |
| DIRECTORY = 4; |
| /// A dirent representing a block device object. |
| BLOCK_DEVICE = 6; |
| /// A dirent representing a file object. |
| FILE = 8; |
| /// A symbolic link. |
| @available(added=18) |
| SYMLINK = 10; |
| /// A dirent representing a service object. |
| SERVICE = 16; |
| }; |
| |
| /// Nodes which do not have ino values should return this value |
| /// from Readdir and GetAttr. |
| const INO_UNKNOWN uint64 = 0xFFFFFFFFFFFFFFFF; |
| |
| /// 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. |
| /// |
| /// The DirectoryWatcher will send messages of the form: |
| /// ``` |
| /// struct { |
| /// uint8 event; |
| /// uint8 len; |
| /// char name[]; |
| /// }; |
| /// ``` |
| /// Where names are NOT null-terminated. The name is the relative |
| /// path to the entry the event is refering to. It will be empty if |
| /// the event isn't referencing a particular entry (e.g. for the |
| /// `IDLE` event). |
| closed protocol DirectoryWatcher {}; |
| |
| type WatchEvent = strict enum : uint8 { |
| /// Indicates the directory being watched has been deleted. The name returned for this event |
| /// will be `.` (dot), as it is refering to the directory itself. |
| DELETED = 0; |
| /// Indicates a node has been created (either new or moved) into a directory. |
| ADDED = 1; |
| /// Identifies a node has been removed (either deleted or moved) from the directory. |
| REMOVED = 2; |
| /// Identifies a node already existed in the directory when watching started. |
| EXISTING = 3; |
| /// Identifies that no more `EXISTING` events will be sent. The name returned for this event |
| /// will be empty, as it is not refering to a specific entry. |
| IDLE = 4; |
| }; |
| |
| type WatchMask = strict bits : uint32 { |
| /// Used by `Directory.Watch`. Requests transmission of `WatchEvent.DELETED`. |
| DELETED = 0x00000001; |
| /// Used by `Directory.Watch`. Requests transmission of `WatchEvent.ADDED`. |
| ADDED = 0x00000002; |
| /// Used by `Directory.Watch`. Requests transmission of `WatchEvent.REMOVED`. |
| REMOVED = 0x00000004; |
| /// Used by `Directory.Watch`. Requests transmission of `WatchEvent.EXISTING`. |
| EXISTING = 0x00000008; |
| /// Used by `Directory.Watch`. Requests transmission of `WatchEvent.IDLE`. |
| IDLE = 0x00000010; |
| }; |
| |
| /// Directory defines a node which is capable of containing other Objects. |
| @discoverable |
| open protocol Directory { |
| compose AdvisoryLocking; |
| compose Node; |
| |
| /// 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 OpenFlags.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). |
| /// |
| /// If an unknown value is sent for flags the connection should be closed. |
| /// |
| /// `OpenFlags.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. |
| /// |
| /// `mode` is ignored. |
| @selector("fuchsia.io1/Directory.Open") |
| strict Open(resource struct { |
| flags OpenFlags; |
| mode ModeType; |
| |
| @available(deprecated=11, replaced=12) |
| path string:MAX_PATH; |
| @available(added=12) |
| path string:MAX_PATH_LENGTH; |
| |
| object server_end:Node; |
| }); |
| |
| /// Opens or creates a new node relative to this directory node. |
| /// |
| /// This method requires the following rights on the current connection: |
| /// |
| /// * [`Rights.ENUMERATE`] |
| /// * [`Rights.TRAVERSE`] |
| /// |
| /// Errors are presented as an epitaph on the `object_request` channel. |
| /// |
| /// * error `ZX_ERR_ACCESS_DENIED` if the requested rights exceeds what is allowed. |
| /// * error `ZX_ERR_BAD_PATH` if `path` is invalid. |
| @available(removed=23) |
| @selector("fuchsia.io/Directory.Open") |
| strict Open2(resource struct { |
| /// Identifies the node to open. |
| /// |
| /// If it contains multiple segments, then the directory is traversed one segment at a time, |
| /// relative to the directory represented by this connection. |
| path Path; |
| |
| /// The representations accepted by the caller to support a form of protocol negotiation on |
| /// the node being opened. |
| protocols @generated_name("ConnectionProtocols") flexible union { |
| /// Requests that the node's underlying protocol be served on the connection. |
| 1: connector @generated_name("ConnectorFlags") flexible bits : uint64 {}; |
| |
| /// Requests that the underlying [`Node`] protocol be served on the connection. |
| 2: node NodeOptions; |
| }; |
| |
| /// The server end of a channel created for the new connection. The caller may proceed to |
| /// send messages on the corresponding client end right away. |
| object_request zx.Handle:CHANNEL; |
| }); |
| |
| /// Open (or create) a node relative to this directory. Any errors are communicated via an |
| /// epitaph sent on the `object` channel. |
| /// |
| /// Errors: |
| /// * `ZX_ERR_BAD_PATH` if `path` is invalid |
| /// * See [`Flags`] for other errors which may be communicated based on `flags` |
| @selector("fuchsia.io/Directory.Open3") |
| strict Open3(resource struct { |
| path Path; |
| flags Flags; |
| options Options; |
| object zx.Handle:CHANNEL; |
| }); |
| |
| /// 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. |
| /// Each call to ReadDirents will only return whole dirent structures, |
| /// they will not get split across ReadDirent calls. When the seek |
| /// offset reaches the end, `dirents` will be empty. |
| /// |
| /// 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 `DirentType` 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. |
| @selector("fuchsia.io1/Directory.ReadDirents") |
| strict 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. |
| @selector("fuchsia.io1/Directory.Rewind") |
| strict 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. The token will remain valid for as long as the connection requesting the token |
| /// remains open. |
| /// |
| /// This method requires following rights: `OpenFlags.RIGHT_WRITABLE`, otherwise returns |
| /// `ZX_ERR_BAD_HANDLE`. |
| @selector("fuchsia.io1/Directory.GetToken") |
| strict GetToken() -> (resource struct { |
| s zx.Status; |
| token zx.Handle:optional; |
| }); |
| |
| /// 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: `OpenFlags.RIGHT_WRITABLE` and |
| /// `OpenFlags.RIGHT_READABLE`, otherwise returns `ZX_ERR_BAD_HANDLE`. |
| /// |
| /// This will be atomic with respect to renaming or unlinking the source concurrently e.g. if |
| /// there are two actors operating concurrently, and one actor performs a rename that affects |
| /// the source within this directory, and the other does a link, each will appear to occur |
| /// atomically in an unspecified order. |
| @selector("fuchsia.io1/Directory.Link") |
| strict Link(resource struct { |
| src string:MAX_FILENAME; |
| dst_parent_token zx.Handle; |
| dst string:MAX_FILENAME; |
| }) -> (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") |
| strict Unlink(struct { |
| name Name; |
| options @generated_name("UnlinkOptions") table { |
| 1: flags @generated_name("UnlinkFlags") flexible bits : uint64 { |
| /// If set, the unlink will fail (with ZX_ERR_NOT_DIR) if the |
| /// object is not a directory. |
| MUST_BE_DIRECTORY = 0x01; |
| }; |
| }; |
| }) -> () error 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 [`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`] |
| /// |
| /// The following requirements are necessary to avoid rights escalations. |
| /// |
| /// If the source and destination directory differ, the source directory must also have the |
| /// maximal set of abilities supported for files, which would typically be |
| /// [`Rights.READ_BYTES`], [`Rights.WRITE_BYTES`], [`Rights.GET_ATTRIBUTES`] and |
| /// [`Rights.UPDATE_ATTRIBUTES`]. Some filesystems might also support the [`Rights.EXECUTE`] |
| /// right. |
| /// |
| /// If `src` refers to a directory, and differs from the destination directory, then the source |
| /// directory must have also have the [`Rights.CONNECT`] and [`Rights.TRAVERSE`] rights. |
| /// |
| /// * error `ZX_ERR_INVALID_ARGS` if `src` or `dst` is invalid. |
| /// * error `ZX_ERR_ACCESS_DENIED` for insufficient rights. |
| @selector("fuchsia.io/Directory.Rename") |
| strict Rename(resource struct { |
| src Name; |
| dst_parent_token Token; |
| dst Name; |
| }) -> () error zx.Status; |
| |
| // TODO(https://fxbug.dev/42157659): uncomment and implement. |
| // /// Creates a link to a node named `src` by the name `dst`, |
| // /// in a directory represented by `dst_parent_token`. |
| // /// |
| // /// Directories cannot be linked, to prevent reference cycles. |
| // /// |
| // /// `src` and `dst` must be valid node names. |
| // /// See [`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. |
| // /// * error `ZX_ERR_INVALID_ARGS` if `src` is a directory. |
| // @selector("fuchsia.io/Directory.Link") |
| // Link2(resource struct { |
| // src Name; |
| // dst_parent_token Token; |
| // dst Name; |
| // }) -> () error zx.Status; |
| |
| /// Creates a symbolic link. |
| /// |
| /// `name` is the name to be given to the created symbolic link. |
| /// `target` is the target of the symbolic link, which has no meaning on the server. The server |
| /// will perform no validation of `target` except for a server chosen maximum length. |
| /// `connection` is an optional server end of a channel that will speak the Symlink protocol |
| /// on the successfully created node. |
| /// |
| /// * [`Rights.MODIFY_DIRECTORY`] |
| /// |
| /// * error `ZX_ERR_ALREADY_EXISTS` if `name` already exists. |
| /// * error `ZX_ERR_BAD_PATH` if `target` exceeds the server length limit for symbolic links. |
| /// * error `ZX_ERR_INVALID_ARGS` if `name` is not a valid [`Name`]. |
| /// * error `ZX_ERR_NOT_SUPPORTED` if creating symbolic links is not supported by the server. |
| @available(added=18) |
| @selector("fuchsia.io/Directory.CreateSymlink") |
| strict CreateSymlink(resource struct { |
| name Name; |
| target SymlinkTarget; |
| connection server_end:<Symlink, optional>; |
| }) -> () error zx.Status; |
| |
| /// Watches a directory, receiving events of added messages on the |
| /// watcher request channel. |
| /// |
| /// Options must be zero; it is reserved. |
| /// |
| /// This method does not require any rights, similar to ReadDirents. |
| @selector("fuchsia.io1/Directory.Watch") |
| strict Watch(resource struct { |
| mask WatchMask; |
| options uint32; |
| watcher server_end:DirectoryWatcher; |
| }) -> (struct { |
| s zx.Status; |
| }); |
| }; |