1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
/*@ S-nail - a mail user agent derived from Berkeley Mail.
*@ Child process handling, direct (pipe streams are in file-streams.h).
*
* Copyright (c) 2012 - 2020 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
* SPDX-License-Identifier: ISC
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef mx_CHILD_H
#define mx_CHILD_H
#include <mx/nail.h>
#define mx_HEADER
#include <su/code-in.h>
struct mx_child_ctx;
/* */
#define mx_CHILD_MAXARGS 3 /* xxx vector */
enum mx_child_flags{
mx_CHILD_NONE = 0,
/* Ensure the forked child has started running (as opposed to the default
* success which only remarks "fork(2) has returned successfully") */
mx_CHILD_SPAWN_CONTROL = 1u<<0,
/* On top of SPAWN_CONTROL, wait until the child called execve */
mx_CHILD_SPAWN_CONTROL_LINGER = 1u<<1,
/* run(): handle all the lifetime, and wait etc., return final status */
mx_CHILD_RUN_WAIT_LIFE = 1u<<2,
/* Child uses terminal and requires termios handling */
mx__CHILD_JOBCTL = 1u<<8
};
/* mx_child_ctx_setup() to zero out */
struct mx_child_ctx{
/* Output: */
s32 cc_pid; /* Filled upon successful start (when not waited..) */
s32 cc_exit_status; /* WEXITSTATUS(); -WEXITSTATUS() if !WIFEXITED */
/* err_no() on failure; with SPAWN_CONTROL it could be set to errors that
* happen in the child, too; set to ERR_CHILD when there was error and there
* was no error */
s32 cc_error;
u32 cc_flags; /* child_flags */
/* Input: the arguments are all optional */
/* Signals must be handled by the caller. If this is set, then it is
* a sigset_t*: the signals to ignore in the new process.
* SIGINT is enabled unless it is in the mask. */
void *cc_mask; /* In fact a sigset_t XXX su_sigset! */
s32 cc_fds[2]; /* A real FD, or _FD_PASS or _FD_NULL XXX sz[2] */
char const *cc_cmd; /* The command to run, */
char const *cc_args[mx_CHILD_MAXARGS]; /* and its optional arguments */
/* NIL or NIL terminated array; Note: is modified if set! */
char const **cc_env_addon; /* TODO su_dict */
sz cc__cpipe[2];
};
/* Slots in .cc_fds */
#define mx_CHILD_FD_IN 0
#define mx_CHILD_FD_OUT 1
/* Special file descriptors for .cc_fds */
#define mx_CHILD_FD_PASS (-1)
#define mx_CHILD_FD_NULL (-2)
/* At program startup: initialize controller (panic on failure) */
EXPORT void mx_child_controller_setup(void);
/* Initialize (zero out etc.). The .cc_fds are set to CHILD_FD_PASS */
EXPORT void mx_child_ctx_setup(struct mx_child_ctx *ccp);
/* Start and run a command, with optional arguments and splicing of stdin and
* stdout, as defined by the ctx_setup()d ccp, return whether the process has
* been started successfully.
* With RUN_WAIT_LIFE the return value also indicates whether the parent has
* child_wait()ed successfully, i.e., whether the child has terminated
* already; .cc_exit_status etc. can be examined for more.
* Otherwise _signal(), _forget() and _wait() can be used on ccp */
EXPORT boole mx_child_run(struct mx_child_ctx *ccp);
/* Fork a child process, "enable" the below functions upon success.
* With SPAWN_CONTROL the parent will linger until the child has called
* in_child_setup() or even (with SPAWN_CONTROL_LINGER) until it execve's.
* Children can start children themselves, but we do not care about termios
* XXX or child handling no more in recursive levels */
EXPORT boole mx_child_fork(struct mx_child_ctx *ccp);
/* Setup an image in the child; signals are still blocked before that! */
EXPORT void mx_child_in_child_setup(struct mx_child_ctx *ccp);
/* This can only be used if SPAWN_CONTROL_LINGER had been used.
* It will pass err up to the parent, and close the control pipe.
* It does not exit the program */
EXPORT void mx_child_in_child_exec_failed(struct mx_child_ctx *ccp, s32 err);
/* Send a signal to a managed process, return 0 on success, a negative value
* if the process does no(t) (longer) exist, or an error constant */
EXPORT s32 mx_child_signal(struct mx_child_ctx *ccp, s32 sig);
/* Loose any knowledge we might have regarding ccp.
* Neither waiting nor any other status report will be available.
* This must not be used in conjunction with FD_PASS. */
EXPORT void mx_child_forget(struct mx_child_ctx *ccp);
/* Wait on the child and return whether ccp was a known child and has been
* waited for successfully; examine ccp for error / status */
EXPORT boole mx_child_wait(struct mx_child_ctx *ccp);
#include <su/code-ou.h>
#endif /* mx_CHILD_H */
/* s-it-mode */
|