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

// TODO(fxb/39732): This should be read as "library zx".
library zz;

[Transport = "Syscall"]
protocol process {
    /// Exits the currently running process.
    [noreturn]
    process_exit(int64 retcode);

    // TODO(ZX-2967): job with ZX_RIGHT_WRITE is also accepted.
    /// Create a new process.
    /// Rights: job must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_MANAGE_PROCESS.
    process_create(handle<job> job, string name, uint32 options)
        -> (status status, handle<process> proc_handle, handle<vmar> vmar_handle);

    /// Start execution on a process.
    /// Rights: handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
    /// Rights: thread must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_WRITE.
    /// Rights: arg1 must have ZX_RIGHT_TRANSFER.
    process_start(handle<process> handle, handle<thread> thread,
                  vaddr entry, vaddr stack,
                  handle arg1, uintptr arg2)
        -> (status status);

    /// Read from the given process's address space.
    /// Rights: handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
    process_read_memory(handle<process> handle, vaddr vaddr)
        -> (status status, vector_void buffer, usize actual);

    /// Write into the given process's address space.
    /// Rights: handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
    process_write_memory(handle<process> handle, vaddr vaddr, vector_void buffer)
        -> (status status, usize actual);
};
