// 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 zx.procarg identifiers
/// that designate their intended use by the new process.
///
/// This structure represents one such handle and its associated zx.procarg
/// identifier.
resource struct HandleInfo {
    /// The handle to use for this process argument.
    zx.handle handle;

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

/// 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.
resource struct NameInfo {
    /// Path at which to install the associated directory.
    ///
    /// Must be an absolute path (i.e., start with '/').
    string:fuchsia.io.MAX_PATH path;

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

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

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

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

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

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

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

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

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

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

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

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

// TODO(fxbug.dev/37281): replace with built-in constant
const uint32 MAX = 0xFFFFFFFF;

/// 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]
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`.
    Launch(LaunchInfo info) -> (zx.status status, zx.handle:PROCESS? process);

    /// 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`.
    CreateWithoutStarting(LaunchInfo info) -> (zx.status status,
                                               ProcessStartData? data);

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

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

    /// 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/framework/namespaces> for details.
    ///
    /// Calling this method multiple times concatenates the names.
    AddNames(vector<NameInfo>:MAX names);

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