// 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.process;

using fuchsia.io;
using zx;

/// Information about a handle provided to a process at startup.
///
/// Processes are given a set of initial handles as part of the bootstrapping
/// sequence. Some of these handles are associated with process argument
/// identifiers that designate their intended use by the new process.
///
/// This structure represents one such handle and its associated identifier.
type HandleInfo = resource struct {
    /// The handle to use for this process argument.
    handle zx.Handle;

    /// Process argument identifier.
    ///
    /// See <zircon/processargs.h> for definitions of well-known process
    /// arguments.
    id uint32;
};

/// A namespace entry provided to a process at startup.
///
/// Processes are given a set of initial handles as part of the bootstrapping
/// sequence. Some of these handles are associated with paths that designate
/// their intended use by the new process as namespace entries.
///
/// This structure represents one such handle and its associated namespace path.
type NameInfo = resource struct {
    /// Path at which to install the associated directory.
    ///
    /// Must be an absolute path (i.e., start with '/').
    path fuchsia.io.Path;

    /// The associated directory.
    directory client_end:fuchsia.io.Directory;
};

/// The information needed to launch a process.
type LaunchInfo = resource struct {
    /// The executable to run in the process.
    executable zx.Handle:VMO;

    /// The job in which to create the process.
    job zx.Handle:JOB;

    /// The name to assign to the created process.
    name string:zx.MAX_NAME_LEN;
};

/// The information required to start a process.
///
/// To start the process, call `zx_process_start` with the arguments provided.
type ProcessStartData = resource struct {
    /// The process that was created.
    process zx.Handle:PROCESS;

    /// The vmar object that was created when the process was created.
    ///
    /// See <https://fuchsia.dev/fuchsia-src/reference/syscalls/process_create.md>.
    root_vmar zx.Handle:VMAR;

    /// The initial thread for the process.
    ///
    /// Should be passed to `zx_process_start` when starting the process.
    thread zx.Handle:THREAD;

    /// The address of the initial entry point in the process.
    ///
    /// Should be passed to `zx_process_start` when starting the process.
    entry uint64;

    /// The stack pointer value for the initial thread of the process.
    ///
    /// Should be passed to `zx_process_start` when starting the process.
    stack uint64;

    /// The bootstrap channel to pass to the process on startup.
    ///
    /// Should be passed to `zx_process_start` when starting the process.
    bootstrap zx.Handle:CHANNEL;

    /// The base address of the vDSO to pass to the process on startup.
    ///
    /// Should be passed to `zx_process_start` when starting the process.
    vdso_base uint64;

    /// The base load address of the ELF file loaded.
    ///
    /// Most often used by debuggers or other tools that inspect the process.
    base uint64;
};

/// A low-level interface for launching processes.
///
/// This interface is used for manually assembling a process. The caller supplies
/// all the capabilities for the newly created process.
///
/// That create processes typically use `fdio_spawn` or `fdio_spawn_etc` rather
/// than using this interface directly. The `fdio_spawn` and `fdio_spawn_etc`
/// functions are implemented using this interface.
///
/// Debuggers and other clients that need to create processes in a suspended
/// state often use this interface directly. These clients use the
/// `CreateWithoutStarting` method to create the process without actually
/// starting it.
@discoverable
closed protocol Launcher {
    /// Creates and starts the process described by `info`.
    ///
    /// After processing this message, the `Launcher` is reset to its initial
    /// state and is ready to launch another process.
    ///
    /// `process` is present if, and only if, `status` is `ZX_OK`.
    strict Launch(resource struct {
        info LaunchInfo;
    }) -> (resource struct {
        status zx.Status;
        process zx.Handle:<PROCESS, optional>;
    });

    /// Creates the process described by `info` but does not start it.
    ///
    /// After processing this message, the `Launcher` is reset to its initial
    /// state and is ready to launch another process.
    ///
    /// The caller is responsible for calling `zx_process_start` using the data
    /// in `ProcessStartData` to actually start the process.
    ///
    /// `data` is present if, and only if, `status` is `ZX_OK`.
    strict CreateWithoutStarting(resource struct {
        info LaunchInfo;
    }) -> (resource struct {
        status zx.Status;
        data box<ProcessStartData>;
    });

    /// Adds the given arguments to the command-line for the process.
    ///
    /// Calling this method multiple times concatenates the arguments.
    strict AddArgs(struct {
        args vector<vector<uint8>:MAX>:MAX;
    });

    /// Adds the given variables to the environment variables for the process.
    ///
    /// Calling this method multiple times concatenates the variables.
    strict AddEnvirons(struct {
        environ vector<vector<uint8>:MAX>:MAX;
    });

    /// Adds the given names to the namespace for the process.
    ///
    /// The paths in the namespace must be non-overlapping. See
    /// <https://fuchsia.dev/fuchsia-src/concepts/process/namespaces> for details.
    ///
    /// Calling this method multiple times concatenates the names.
    strict AddNames(resource struct {
        names vector<NameInfo>:MAX;
    });

    /// Adds the given handles to the startup handles for the process.
    ///
    /// Calling this method multiple times concatenates the handles.
    strict AddHandles(resource struct {
        handles vector<HandleInfo>:MAX;
    });

    /// Sets the options with which the process is created.
    ///
    /// Calling this method multiple times will overwrite the current options.
    @available(added=9)
    strict SetOptions(struct {
        /// These options are expected to be valid process creation options. The options are checked
        /// on `Launch` or `CreateWithoutStarting`.
        ///
        /// See <https://fuchsia.dev/fuchsia-src/reference/syscalls/process_create> for details.
        options uint32;
    });
};
