int main (int ac, char **av) { int rc; struct subprocess_manager *sm; struct subprocess *p; flux_reactor_t *r; zsys_handler_set (NULL); plan (NO_PLAN); if (!(sm = subprocess_manager_create ())) BAIL_OUT ("Failed to create subprocess manager"); ok (sm != NULL, "create subprocess manager"); if (!(r = flux_reactor_create (FLUX_REACTOR_SIGCHLD))) BAIL_OUT ("Failed to create a reactor"); rc = subprocess_manager_set (sm, SM_REACTOR, r); ok (rc == 0, "set subprocess manager reactor (rc=%d, %s)", rc, strerror (errno)); if (!(p = subprocess_create (sm))) BAIL_OUT ("Failed to create a subprocess object"); ok (subprocess_set_callback (p, exit_handler, r) >= 0, "set subprocess exit handler"); ok (subprocess_set_io_callback (p, io_cb) >= 0, "set subprocess io callback"); ok (subprocess_set_command (p, "sleep 0.5 && /bin/echo -n 'hello\nworld\n'") >= 0, "set subprocess command"); ok (subprocess_set_environ (p, environ) >= 0, "set subprocess environ"); ok (subprocess_fork (p) >= 0, "subprocess_fork"); ok (subprocess_exec (p) >= 0, "subprocess_exec"); ok (flux_reactor_run (r, 0) == 0, "reactor returned normally"); subprocess_manager_destroy (sm); flux_reactor_destroy (r); done_testing (); }
int runlevel_set_rc (runlevel_t *r, int level, const char *command, const char *local_uri) { struct subprocess *p = NULL; const char *shell = getenv ("SHELL"); if (!shell) shell = "/bin/bash"; if (level < 1 || level > 3 || r->rc[level] != NULL || !r->sm) { errno = EINVAL; goto error; } if (!(p = subprocess_create (r->sm)) || subprocess_set_context (p, "runlevel", r) < 0 || subprocess_add_hook (p, SUBPROCESS_COMPLETE, subprocess_cb) < 0 || subprocess_argv_append (p, shell) < 0 || (command && subprocess_argv_append (p, "-c") < 0) || (command && subprocess_argv_append (p, command) < 0) || subprocess_set_environ (p, environ) < 0 || subprocess_unsetenv (p, "PMI_FD") < 0 || subprocess_unsetenv (p, "PMI_RANK") < 0 || subprocess_unsetenv (p, "PMI_SIZE") < 0 || (local_uri && subprocess_setenv (p, "FLUX_URI", local_uri, 1) < 0)) goto error; if (level == 1 || level == 3) { if (subprocess_setenv (p, "FLUX_NODESET_MASK", r->nodeset, 1) < 0) goto error; if (subprocess_set_io_callback (p, subprocess_io_cb) < 0) goto error; if (subprocess_set_context (p, "runlevel_t", r) < 0) goto error; } r->rc[level] = p; return 0; error: if (p) subprocess_destroy (p); return -1; }
struct subprocess * subprocess_manager_run (struct subprocess_manager *sm, int ac, char **av, char **env) { struct subprocess *p = subprocess_create (sm); if (p == NULL) return (NULL); if ((subprocess_set_args (p, ac, av) < 0) || (env && subprocess_set_environ (p, env) < 0)) { subprocess_destroy (p); return (NULL); } if (subprocess_run (p) < 0) { subprocess_destroy (p); return (NULL); } return (p); }