summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2017-01-22 13:06:27 -0500
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2017-02-11 18:21:06 -0500
commitcf55fc180783e5350ec243daf281200c6f6a3191 (patch)
tree4a6776ef2650e514e8a5efd8b26e023a84a249e2 /src
parent89711996b3f561522508306e0b5ecf34f6016638 (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.c60
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)