blob: 2a9bd7c95db5cc14226b817e32508e91e213d269 [file] [log] [blame]
// Copyright 2019 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.io2;
using fuchsia.mem;
using zx;
// TODO: We should run some experiments to see what's the optimum value, or
// what's the point of diminishing marginal returns.
/// The maximum I/O size that is allowed for read/write operations using
/// byte vectors.
const uint64 MAX_TRANSFER_SIZE = 8192;
/// The byte vector type used for read/write operations.
using Transfer = bytes:MAX_TRANSFER_SIZE;
/// A [`fuchsia.io2/Node`] which contains a sequence of bytes of definite
/// length.
protocol File {
compose Node;
/// Moves the offset at which the next invocation of [`Read`] or [`Write`]
/// will occur. The seek offset is specific to each file connection.
///
/// + request `origin` the reference point where `offset` will be based on.
/// + request `offset` the number of bytes to seek.
/// - response `offset_from_start` the adjusted seek offset, from the start
/// of the file.
///
/// This method does not require any rights.
Seek(SeekOrigin origin, int64 offset)
-> (uint64 offset_from_start) error zx.status;
/// Reads up to 'count' bytes at the seek offset.
/// The seek offset is moved forward by the number of bytes read.
///
/// ## Invariants
///
/// * The returned `data.length` will never be greater than `count`.
/// * If `data.length` is less than `count`, it means that the seek offset
/// has reached the end of file as part of this operation.
/// * If `data.length` is zero while `count` is not, it means that the
/// seek offset is already at or beyond the end of file, and no data could
/// be read.
/// * If `count` is zero, the server should perform all the checks ensuring
/// read access without actually read anything, and return an empty
/// `data` vector.
///
/// This method requires the [`Rights.READ_BYTES`] right.
Read(uint64 count) -> (Transfer data) error zx.status;
/// Writes data at the seek offset.
/// The seek offset is moved forward by the number of bytes written.
/// If the file is in append mode, the seek offset is first set to the end
/// of the file, followed by the write, in one atomic step.
///
/// The file size may grow if the seek offset plus `data.length` is beyond
/// the current end of file.
///
/// + request `data` the byte buffer to write to the file.
/// - response `actual_count` the number of bytes written.
///
/// ## Invariants
///
/// * The returned `actual_count` will never be greater than `data.length`.
/// * If the server is unable to write all the data due to e.g. not enough
/// space, `actual_count` may be less than `data.length`.
/// * If `data.length` is zero, the server should perform all the checks
/// ensuring write access without mutating the file. The seek offset
/// is still updated if in append mode.
///
/// This method requires the [`Rights.WRITE_BYTES`] right.
Write(Transfer data) -> (uint64 actual_count) error zx.status;
/// Reads up to 'count' bytes at the provided offset.
/// Does not affect the seek offset.
///
/// ## Invariants
///
/// * The returned `data.length` will never be greater than `count`.
/// * If `data.length` is less than `count`, it means that `ReadAt` has hit
/// the end of file as part of this operation.
/// * If `data.length` is zero while `count` is not, it means that `offset`
/// is at or past the end of file, and no data can be read.
/// * If `count` is zero, the server should perform all the checks ensuring
/// read access without actually reading anything, and return an empty
/// `data` vector.
///
/// This method requires the [`Rights.READ_BYTES`] right.
ReadAt(uint64 count, uint64 offset) -> (Transfer data) error zx.status;
/// Writes data at the provided offset.
/// Does not affect the seek offset.
///
/// The file size may grow if `offset` plus `data.length` is past the
/// current end of file.
///
/// + request `data` the byte buffer to write to the file.
/// + request `offset` the offset from start of the file to begin writing.
/// - response `actual_count` the number of bytes written.
///
/// ## Invariants
///
/// * The returned `actual_count` will never be greater than `data.length`.
/// * If the server is unable to write all the data due to e.g. not enough
/// space, `actual_count` may be less than `data.length`.
/// * If `data.length` is zero, the server should perform all the checks
/// ensuring write access without mutating the file.
///
/// This method requires the [`Rights.WRITE_BYTES`] right.
WriteAt(Transfer data, uint64 offset)
-> (uint64 actual_count) error zx.status;
/// Shrinks or grows the file size to 'length' bytes.
///
/// If file size is reduced by this operation, the extra trailing data'
/// is discarded.
/// If file size is increased by this operation, the extended area appears
/// as if it was zeroed.
///
/// This method requires the [`Rights.WRITE_BYTES`] right.
Resize(uint64 length) -> () error zx.status;
/// Acquires a [`fuchsia.mem/Range`] representing this file, if
/// there is one, with the requested access rights.
///
/// + request `flags` a [`VmoFlags`] indicating the desired mode of access.
/// - response `buffer` the requested [`fuchsia.mem/Range`].
/// * error a [`zx.status`] value indicating the failure.
///
/// This method requires the following rights:
///
/// * [`Rights.READ_BYTES`] if `flags` includes [`VmoFlags.READ`].
/// * [`Rights.WRITE_BYTES`] if `flags` includes [`VmoFlags.WRITE`].
/// * [`Rights.EXECUTE`] if `flags` includes [`VmoFlags.EXECUTE`].
GetMemRange(VmoFlags flags) -> (fuchsia.mem.Range buffer) error zx.status;
};
/// The reference point for updating the seek offset. See [`File.Seek`].
enum SeekOrigin : uint32 {
/// Seek from the start of the file.
/// The seek offset will be set to `offset` bytes.
/// The seek offset cannot be negative in this case.
START = 1;
/// Seek from the current position in the file.
/// The seek offset will be the current seek offset plus `offset` bytes.
CURRENT = 2;
/// Seek from the end of the file.
/// The seek offset will be the file size plus `offset` bytes.
END = 3;
};
bits VmoFlags : uint64 {
/// Requests that the VMO be readable.
READ = 0x00000001;
/// Requests that the VMO be writable.
WRITE = 0x00000002;
//// Request that the VMO be executable.
EXECUTE = 0x00000004;
/// Require a copy-on-write clone of the underlying VMO.
/// The request should fail if the VMO cannot be cloned.
/// May not be supplied with `SHARED_BUFFER`.
PRIVATE_CLONE = 0x00010000;
/// Require an exact (non-cloned) handle to the underlying VMO.
/// All clients using this flag would get a VMO with the same koid.
/// The request should fail if a handle to the exact VMO cannot be returned.
/// May not be supplied with `PRIVATE_CLONE`.
SHARED_BUFFER = 0x00020000;
};
/// Auxiliary data for the file representation of a node.
/// The selection of this variant in [`Representation`] implies that the
/// connection speaks the [`fuchsia.io2/File`] protocol.
table FileInfo {
/// 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.
///
/// This event will be present if the following conditions are met:
///
/// - The `available_operations` on the file connection is not empty.
/// - The filesystem supports signalling readability/writability events.
///
/// The [`FileSignal`] values may be observed on this event.
1: handle<event> observer;
/// Returns if the file is opened in append mode.
/// In append mode, the seek offset is moved to the end before every
/// write, the two steps performed in an atomic manner.
2: bool is_append;
};
bits FileSignal : uint32 {
/// Indicates the file is ready for reading.
READABLE = 0x01000000; // ZX_USER_SIGNAL_0
/// Indicates the file is ready for writing.
WRITABLE = 0x02000000; // ZX_USER_SIGNAL_1
};