blob: 42c16727ad13ffcfb29fe3e507e30deaa9d9fdd5 [file] [log] [blame]
// 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.
#ifndef LIB_FDIO_INCLUDE_LIB_FDIO_SPAWN_H_
#define LIB_FDIO_INCLUDE_LIB_FDIO_SPAWN_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <zircon/analyzer.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
__BEGIN_CDECLS
// The |fdio_spawn| and |fdio_spawn_etc| functions allow some or all of the
// environment of the running process to be shared with the process being
// spawned.
// Provides the spawned process with the job in which the process was created.
//
// The spawned process receives the job using the |PA_JOB_DEFAULT| process
// argument.
#define FDIO_SPAWN_CLONE_JOB ((uint32_t)0x0001u)
// Provides the spawned process with the shared library loader resolved via
// fuchsia.process.Resolver (if resolved), or that which is used by this
// process.
//
// The shared library loader is passed as |PA_LDSVC_LOADER|.
#define FDIO_SPAWN_DEFAULT_LDSVC ((uint32_t)0x0002u)
// Clones the filesystem namespace into the spawned process.
#define FDIO_SPAWN_CLONE_NAMESPACE ((uint32_t)0x0004u)
// Clones file descriptors 0, 1, and 2 into the spawned process.
//
// Skips any of these file descriptors that are closed without generating an
// error.
#define FDIO_SPAWN_CLONE_STDIO ((uint32_t)0x0008u)
// Clones the environment into the spawned process.
#define FDIO_SPAWN_CLONE_ENVIRON ((uint32_t)0x0010u)
// Clones the process-global UTC clock into the spawned process.
#define FDIO_SPAWN_CLONE_UTC_CLOCK ((uint32_t)0x0020u)
// Clones all of the above into the spawned process.
#define FDIO_SPAWN_CLONE_ALL ((uint32_t)0xFFFFu)
// Spawn a process in the given job.
//
// The program for the process is loaded from the given |path| and passed |argv|.
// The aspects of this process' environment indicated by |flags| are shared with
// the process. If the target program begins with |#!resolve | then the binary is
// resolved by url via |fuchsia.process.Resolver|.
//
// The |argv| array must be terminated with a null pointer.
//
// If |job| is |ZX_HANDLE_INVALID|, then the process is spawned in
// |zx_job_default()|. Does not take ownership of |job|.
//
// Upon success, |process_out| will be a handle to the process.
//
// # Errors
//
// ZX_ERR_NOT_FOUND: |path| cannot be opened.
//
// ZX_ERR_BAD_HANDLE: |path| cannot be opened as an executable VMO.
//
// Returns the result of |fdio_spawn_vmo| in all other cases.
zx_status_t fdio_spawn(ZX_HANDLE_USE zx_handle_t job, uint32_t flags, const char* path,
const char* const* argv, ZX_HANDLE_ACQUIRE zx_handle_t* process_out);
// The |fdio_spawn_etc| function allows the running process to control the file
// descriptor table in the process being spawned.
// Duplicate a descriptor |local_fd| into |target_fd| in the spawned process.
//
// Uses the |fd| entry in the |fdio_spawn_action_t| union.
#define FDIO_SPAWN_ACTION_CLONE_FD ((uint32_t)0x0001u)
// Transfer local descriptor |local_fd| into |target_fd| in the spawned process.
//
// This action will fail if |local_fd| is not a valid |local_fd|, if |local_fd|
// has been duplicated, if |local_fd| is being used in an io operation, or if
// |local_fd| does not support this operation.
//
// From the point of view of the calling process, the |local_fd| will appear to
// have been closed, regardless of whether the |fdio_spawn_etc| call succeeds.
//
// Uses the |fd| entry in the |fdio_spawn_action_t| union.
#define FDIO_SPAWN_ACTION_TRANSFER_FD ((uint32_t)0x0002u)
// Add the given entry to the namespace of the spawned process.
//
// If |FDIO_SPAWN_CLONE_NAMESPACE| is specified via |flags|, the namespace entry
// is added to the cloned namespace from the calling process.
//
// The namespace entries are added in the order they appear in the action list.
// If |FDIO_SPAWN_CLONE_NAMESPACE| is specified via |flags|, the entries from
// the calling process are added before any entries specified with
// |FDIO_SPAWN_ACTION_ADD_NS_ENTRY|.
//
// The spawned process decides how to process and interpret the namespace
// entries. Typically, the spawned process with disregard duplicate entries
// (i.e., the first entry for a given name wins) and will ignore nested entries
// (e.g., |/foo/bar| when |/foo| has already been added to the namespace).
//
// To override or replace an entry in the namespace of the calling process,
// use |fdio_ns_export_root| to export the namespace table of the calling
// process and construct the namespace for the spawned process explicitly using
// |FDIO_SPAWN_ACTION_ADD_NS_ENTRY|.
//
// The given handle will be closed regardless of whether the |fdio_spawn_etc|
// call succeeds.
//
// Uses the |ns| entry in the |fdio_spawn_action_t| union.
#define FDIO_SPAWN_ACTION_ADD_NS_ENTRY ((uint32_t)0x0003u)
// Add the given handle to the process arguments of the spawned process.
//
// The given handle will be closed regardless of whether the |fdio_spawn_etc|
// call succeeds.
//
// Uses the |h| entry in the |fdio_spawn_action_t| union.
#define FDIO_SPAWN_ACTION_ADD_HANDLE ((uint32_t)0x0004u)
// Sets the name of the spawned process to the given name.
//
// Overrides the default of use the first argument to name the process.
//
// Uses the |name| entry in the |fdio_spawn_action_t| union.
#define FDIO_SPAWN_ACTION_SET_NAME ((uint32_t)0x0005u)
// Shares the given directory by installing it into the namespace of spawned
// process.
//
// Uses the |dir| entry in the |fdio_spawn_action_t| union
#define FDIO_SPAWN_ACTION_CLONE_DIR ((uint32_t)0x0006u)
// Instructs |fdio_spawn_etc| which actions to take.
typedef struct fdio_spawn_action fdio_spawn_action_t;
struct fdio_spawn_action {
// The action to take.
//
// See |FDIO_SPAWN_ACTION_*| above. If |action| is invalid, the action will
// be ignored (rather than generate an error).
uint32_t action;
union {
struct {
// The file descriptor in this process to clone or transfer.
int local_fd;
// The file descriptor in the spawned process that will receive the
// clone or transfer.
int target_fd;
} fd;
struct {
// The prefix in which to install the given handle in the namespace
// of the spawned process.
const char* prefix;
// The handle to install with the given prefix in the namespace of
// the spawned process.
zx_handle_t handle;
} ns;
struct {
// The process argument identifier of the handle to pass to the
// spawned process.
uint32_t id;
// The handle to pass to the process on startup.
zx_handle_t handle;
} h;
struct {
// The name to assign to the spawned process.
const char* data;
} name;
struct {
// The directory to share with the spawned process. |prefix| may match zero or more
// entries in the callers flat namespace.
const char* prefix;
} dir;
};
};
// The maximum size for error messages from |fdio_spawn_etc|.
//
// Including the null terminator.
#define FDIO_SPAWN_ERR_MSG_MAX_LENGTH ((size_t)1024u)
// Spawn a process in the given job.
//
// The binary for the process is loaded from the given |path| and passed |argv|.
// The aspects of this process' environment indicated by |clone| are shared with
// the process.
//
// The spawned process is also given |environ| as its environment and the given
// |actions| are applied when creating the process.
//
// The |argv| array must be terminated with a null pointer.
//
// If non-null, the |environ| array must be terminated with a null pointer.
//
// If non-null, the |err_msg_out| buffer must have space for
// |FDIO_SPAWN_ERR_MSG_MAX_LENGTH| bytes.
//
// If both |FDIO_SPAWN_CLONE_ENVIRON| and |environ| are specified, then the
// spawned process is given |environ| as its environment. If both
// |FDIO_SPAWN_CLONE_STDIO| and |actions| that target any of fds 0, 1, and 2 are
// specified, then the actions that target those fds will control their
// semantics in the spawned process.
//
// If |job| is |ZX_HANDLE_INVALID|, then the process is spawned in
// |zx_job_default()|. Does not take ownership of |job|.
//
// Upon success, |process_out| will be a handle to the process. Upon failure, if
// |err_msg_out| is not null, an error message will be we written to
// |err_msg_out|, including a null terminator.
//
// # Errors
//
// ZX_ERR_NOT_FOUND: |path| cannot be opened.
//
// ZX_ERR_BAD_HANDLE: |path| cannot be opened as an executable VMO.
//
// Returns the result of |fdio_spawn_vmo| in all other cases.
zx_status_t fdio_spawn_etc(ZX_HANDLE_USE zx_handle_t job, uint32_t flags, const char* path,
const char* const* argv, const char* const* environ, size_t action_count,
ZX_HANDLE_RELEASE const fdio_spawn_action_t* actions,
ZX_HANDLE_ACQUIRE zx_handle_t* process_out,
char err_msg_out[FDIO_SPAWN_ERR_MSG_MAX_LENGTH]);
// Spawn a process using the given executable in the given job.
//
// See |fdio_spawn_etc| for details. Rather than loading the binary for the
// process from a path, this function receives the binary as the contents of a
// vmo.
//
// Always consumes |executable_vmo|.
//
// # Errors
//
// ZX_ERR_INVALID_ARGS: any supplied action is invalid, or the process name is unset.
//
// ZX_ERR_IO_INVALID: the recursion limit is hit resolving the executable name.
//
// ZX_ERR_BAD_HANDLE: |executable_vmo| is not a valid handle.
//
// ZX_ERR_WRONG_TYPE: |executable_vmo| is not a VMO handle.
//
// ZX_ERR_ACCESS_DENIED: |executable_vmo| is not readable.
//
// ZX_ERR_OUT_OF_RANGE: |executable_vmo| is smaller than the resolver prefix.
//
// ZX_ERR_INTERNAL: Cannot connect to process launcher.
//
// May return other errors.
zx_status_t fdio_spawn_vmo(ZX_HANDLE_USE zx_handle_t job, uint32_t flags,
zx_handle_t executable_vmo, const char* const* argv,
const char* const* environ, size_t action_count,
ZX_HANDLE_RELEASE const fdio_spawn_action_t* actions,
ZX_HANDLE_ACQUIRE zx_handle_t* process_out,
char err_msg_out[FDIO_SPAWN_ERR_MSG_MAX_LENGTH]);
__END_CDECLS
#endif // LIB_FDIO_INCLUDE_LIB_FDIO_SPAWN_H_