]> git.ozlabs.org Git - petitboot/blobdiff - lib/process/process.c
lib/process: Cleanup stdout callback
[petitboot] / lib / process / process.c
index 93fd9c90b9bff4c8c67f0dcf02039d04c8adfd56..bc392dc779510245a315c0061b4a14f5d3c06f24 100644 (file)
@@ -92,7 +92,7 @@ static int process_read_stdout_once(struct process_info *procinfo, char **line)
        if (rc < 0) {
                if (errno == EINTR)
                        return 1;
-               pb_log("%s: read failed: %s\n", __func__, strerror(errno));
+               pb_log_fn("read failed: %s\n", strerror(errno));
                return rc;
        }
 
@@ -114,7 +114,7 @@ static int process_setup_stdout_pipe(struct process_info *procinfo)
 {
        int rc;
 
-       if (!procinfo->process.keep_stdout)
+       if (!procinfo->process.keep_stdout || procinfo->process.raw_stdout)
                return 0;
 
        procinfo->stdout_buf_len = 4096;
@@ -132,7 +132,7 @@ static int process_setup_stdout_pipe(struct process_info *procinfo)
 
 static void process_setup_stdout_parent(struct process_info *procinfo)
 {
-       if (!procinfo->process.keep_stdout)
+       if (!procinfo->process.keep_stdout || procinfo->process.raw_stdout)
                return;
 
        close(procinfo->stdout_pipe[1]);
@@ -142,6 +142,9 @@ static void process_setup_stdout_child(struct process_info *procinfo)
 {
        int log = fileno(pb_log_get_stream());
 
+       if (procinfo->process.raw_stdout)
+               return;
+
        if (procinfo->process.keep_stdout)
                dup2(procinfo->stdout_pipe[1], STDOUT_FILENO);
        else
@@ -175,28 +178,7 @@ static int process_read_stdout(struct process_info *procinfo)
        return rc < 0 ? rc : 0;
 }
 
-static int process_stdout_cb(void *arg)
-{
-       struct process_info *procinfo = arg;
-       int rc;
-
-       rc = process_read_stdout_once(procinfo, NULL);
-
-       /* if we're going to signal to the waitset that we're done (ie, non-zero
-        * return value), then the waiters will remove us, so we drop the
-        * reference */
-       if (rc < 0) {
-               talloc_unlink(procset, procinfo);
-               procinfo->stdout_waiter = NULL;
-               rc = -1;
-       } else {
-               rc = 0;
-       }
-
-       return rc;
-}
-
-int process_stdout_custom(struct process_info *procinfo, char **line)
+int process_process_stdout(struct process_info *procinfo, char **line)
 {
        int rc;
 
@@ -229,7 +211,7 @@ static void sigchld_sigaction(int signo, siginfo_t *info,
 
        rc = write(procset->sigchld_pipe[1], &pid, sizeof(pid));
        if (rc != sizeof(pid))
-               pb_log("%s: write failed: %s\n", __func__, strerror(errno));
+               pb_log_fn("write failed: %s\n", strerror(errno));
 }
 
 static int sigchld_pipe_event(void *arg)
@@ -303,7 +285,7 @@ struct procset *process_init(void *ctx, struct waitset *set, bool dry_run)
 
        rc = pipe(procset->sigchld_pipe);
        if (rc) {
-               pb_log("%s: pipe() failed: %s\n", __func__, strerror(errno));
+               pb_log_fn("pipe() failed: %s\n", strerror(errno));
                goto err_free;
        }
 
@@ -319,7 +301,7 @@ struct procset *process_init(void *ctx, struct waitset *set, bool dry_run)
 
        rc = sigaction(SIGCHLD, &sa, NULL);
        if (rc) {
-               pb_log("%s: sigaction() failed: %s\n", __func__,
+               pb_log_fn("sigaction() failed: %s\n",
                                strerror(errno));
                goto err_remove;
        }
@@ -371,7 +353,7 @@ static int process_run_common(struct process_info *procinfo)
 
        pid = fork();
        if (pid < 0) {
-               pb_log("%s: fork failed: %s\n", __func__, strerror(errno));
+               pb_log_fn("fork failed: %s\n", strerror(errno));
                return pid;
        }
 
@@ -407,17 +389,21 @@ int process_run_sync(struct process *process)
                if (errno == EINTR)
                        continue;
 
-               pb_log("%s: waitpid failed: %s\n", __func__, strerror(errno));
+               pb_log_fn("waitpid failed: %s\n", strerror(errno));
                return rc;
        }
 
        return 0;
 }
 
+static int process_stdout_cb(struct process_info *procinfo)
+{
+       return process_process_stdout(procinfo, NULL);
+}
+
 int process_run_async(struct process *process)
 {
        struct process_info *procinfo = get_info(process);
-       waiter_cb stdout_cb;
        int rc;
 
        rc = process_run_common(procinfo);
@@ -425,7 +411,8 @@ int process_run_async(struct process *process)
                return rc;
 
        if (process->keep_stdout) {
-               stdout_cb = process->stdout_cb ?: process_stdout_cb;
+               waiter_cb stdout_cb = process->stdout_cb ?:
+                       (waiter_cb)process_stdout_cb;
                procinfo->stdout_waiter = waiter_register_io(procset->waitset,
                                                procinfo->stdout_pipe[0],
                                                WAIT_IN, stdout_cb, procinfo);
@@ -440,8 +427,29 @@ int process_run_async(struct process *process)
 
 void process_stop_async(struct process *process)
 {
+       /* Avoid signalling an old pid */
+       if (process->cancelled)
+               return;
+
        pb_debug("process: sending SIGTERM to pid %d\n", process->pid);
        kill(process->pid, SIGTERM);
+       process->cancelled = true;
+}
+
+void process_stop_async_all(void)
+{
+       struct process_info *procinfo;
+       struct process *process = NULL;
+
+       pb_debug("process: cancelling all async jobs\n");
+
+       list_for_each_entry(&procset->async_list, procinfo, async_list) {
+               process = &procinfo->process;
+               /* Ignore the process completion - callbacks may use stale data */
+               process->exit_cb = NULL;
+               process->stdout_cb = NULL;
+               process_stop_async(process);
+       }
 }
 
 int process_run_simple_argv(void *ctx, const char *argv[])