diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-01-22 13:06:27 -0500 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-02-11 18:21:06 -0500 |
commit | cf55fc180783e5350ec243daf281200c6f6a3191 (patch) | |
tree | 4a6776ef2650e514e8a5efd8b26e023a84a249e2 /src | |
parent | 89711996b3f561522508306e0b5ecf34f6016638 (diff) |
basic/exec-util: split out actual execution to a different function
This corrects an error in error handling: if execution fails, we should
never use return, but immediately _exit().
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/exec-util.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/src/basic/exec-util.c b/src/basic/exec-util.c index 757cd3b4ff..23dcac3274 100644 --- a/src/basic/exec-util.c +++ b/src/basic/exec-util.c @@ -40,6 +40,39 @@ /* Put this test here for a lack of better place */ assert_cc(EAGAIN == EWOULDBLOCK); +static int do_spawn(const char *path, char *argv[], pid_t *pid) { + pid_t _pid; + + if (null_or_empty_path(path)) { + log_debug("%s is empty (a mask).", path); + return 0; + } + + _pid = fork(); + if (_pid < 0) + return log_error_errno(errno, "Failed to fork: %m"); + if (_pid == 0) { + char *_argv[2]; + + assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); + + if (!argv) { + _argv[0] = (char*) path; + _argv[1] = NULL; + argv = _argv; + } else + argv[0] = (char*) path; + + execv(path, argv); + log_error_errno(errno, "Failed to execute %s: %m", path); + _exit(EXIT_FAILURE); + } + + log_debug("Spawned %s as " PID_FMT ".", path, _pid); + *pid = _pid; + return 1; +} + static int do_execute(char **directories, usec_t timeout, char *argv[]) { _cleanup_hashmap_free_free_ Hashmap *pids = NULL; _cleanup_set_free_free_ Set *seen = NULL; @@ -94,32 +127,9 @@ static int do_execute(char **directories, usec_t timeout, char *argv[]) { if (!path) return log_oom(); - if (null_or_empty_path(path)) { - log_debug("%s is empty (a mask).", path); + r = do_spawn(path, argv, &pid); + if (r <= 0) continue; - } - - pid = fork(); - if (pid < 0) { - log_error_errno(errno, "Failed to fork: %m"); - continue; - } else if (pid == 0) { - char *_argv[2]; - - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - - if (!argv) { - _argv[0] = path; - _argv[1] = NULL; - argv = _argv; - } else - argv[0] = path; - - execv(path, argv); - return log_error_errno(errno, "Failed to execute %s: %m", path); - } - - log_debug("Spawned %s as " PID_FMT ".", path, pid); r = hashmap_put(pids, PID_TO_PTR(pid), path); if (r < 0) |