blob: 6789aedb785922f287078cf19b30a07352bf0650 [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.io;
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 MAX_TRANSFER_SIZE uint64 = 8192;
/// The byte vector type used for read/write operations.
alias Transfer = bytes:MAX_TRANSFER_SIZE;
/// A [`Node2`] which contains a sequence of bytes of definite
/// length.
protocol File2 {
compose Node2;
compose AdvisoryLocking;
/// 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.
@selector("fuchsia.io/File.Seek")
Seek(struct {
origin SeekOrigin;
offset int64;
}) -> (struct {
offset_from_start uint64;
}) 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.
///
/// Returns `ZX_ERR_OUT_OF_RANGE` if `count` is greater than `MAX_TRANSFER_SIZE`.
@selector("fuchsia.io/File.Read")
Read(struct {
count uint64;
}) -> (struct {
data Transfer;
}) 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 no bytes
/// could be written, an error is returned.
/// * If `data.length` is zero, the server should perform all the checks
/// ensuring write access without mutating the file and return a
/// successful write of zero bytes. The seek offset is still updated if
/// in append mode.
///
/// This method requires the [`Rights.WRITE_BYTES`] right.
@selector("fuchsia.io/File.Write")
Write(struct {
data Transfer;
}) -> (struct {
actual_count uint64;
}) 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.
///
/// Returns `ZX_ERR_OUT_OF_RANGE` if `count` is greater than `MAX_TRANSFER_SIZE`.
@selector("fuchsia.io/File.ReadAt")
ReadAt(struct {
count uint64;
offset uint64;
}) -> (struct {
data Transfer;
}) 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 no bytes
/// could be written, an error is returned.
/// * If `data.length` is zero, the server should perform all the checks
/// ensuring write access without mutating the file, and will return a
/// successful write of zero bytes.
///
/// This method requires the [`Rights.WRITE_BYTES`] right.
@selector("fuchsia.io/File.WriteAt")
WriteAt(struct {
data Transfer;
offset uint64;
}) -> (struct {
actual_count uint64;
}) 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.
@selector("fuchsia.io/File.Resize")
Resize(struct {
length uint64;
}) -> (struct {}) error zx.status;
/// Acquires a [`zx.handle:VMO`] representing this file, if
/// there is one, with the requested access rights.
///
/// + request `flags` a [`VmoFlags`] indicating the desired mode of access.
/// - response `vmo` the requested [`zx.handle:VMO`].
/// * 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`].
@selector("fuchsia.io/File.GetBackingMemory")
GetBackingMemory(struct {
flags VmoFlags;
}) -> (resource struct {
vmo zx.handle:VMO;
}) error zx.status;
};
type VmoFlags = strict bits : uint32 {
/// 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;
};
/// The reference point for updating the seek offset. See [`File.Seek`].
///
/// This enum matches the `zx_stream_seek_origin_t` enum.
type SeekOrigin = strict enum : 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 = 0;
/// Seek from the current position in the file.
/// The seek offset will be the current seek offset plus `offset` bytes.
CURRENT = 1;
/// Seek from the end of the file.
/// The seek offset will be the file size plus `offset` bytes.
END = 2;
};
type FileSignal = strict bits : 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
};