static int found_override(const char *top, const char *bottom) { _cleanup_free_ char *dest = NULL; int k; pid_t pid; assert(top); assert(bottom); if (null_or_empty_path(top) > 0) { notify_override_masked(top, bottom); return 0; } k = readlink_malloc(top, &dest); if (k >= 0) { if (equivalent(dest, bottom) > 0) notify_override_equivalent(top, bottom); else notify_override_redirected(top, bottom); return 0; } notify_override_overridden(top, bottom); if (!arg_diff) return 0; putchar('\n'); fflush(stdout); pid = fork(); if (pid < 0) { log_error("Failed to fork off diff: %m"); return -errno; } else if (pid == 0) { execlp("diff", "diff", "-us", "--", bottom, top, NULL); log_error("Failed to execute diff: %m"); _exit(1); } wait_for_terminate(pid, NULL); putchar('\n'); return 0; }
static int found_override(const char *top, const char *bottom) { _cleanup_free_ char *dest = NULL; int k; pid_t pid; assert(top); assert(bottom); if (null_or_empty_path(top) > 0) return notify_override_masked(top, bottom); k = readlink_malloc(top, &dest); if (k >= 0) { if (equivalent(dest, bottom) > 0) return notify_override_equivalent(top, bottom); else return notify_override_redirected(top, bottom); } k = notify_override_overridden(top, bottom); if (!arg_diff) return k; putchar('\n'); fflush(stdout); pid = fork(); if (pid < 0) return log_error_errno(errno, "Failed to fork off diff: %m"); else if (pid == 0) { (void) reset_all_signal_handlers(); (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); execlp("diff", "diff", "-us", "--", bottom, top, NULL); log_error_errno(errno, "Failed to execute diff: %m"); _exit(EXIT_FAILURE); } wait_for_terminate_and_warn("diff", pid, false); putchar('\n'); return k; }
static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid) { pid_t _pid; int r; if (null_or_empty_path(path)) { log_debug("%s is empty (a mask).", path); return 0; } r = safe_fork("(direxec)", FORK_DEATHSIG|FORK_LOG, &_pid); if (r < 0) return r; if (r == 0) { char *_argv[2]; if (stdout_fd >= 0) { r = rearrange_stdio(STDIN_FILENO, stdout_fd, STDERR_FILENO); if (r < 0) _exit(EXIT_FAILURE); } (void) rlimit_nofile_safe(); 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); } *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; char **directory; /* We fork this all off from a child process so that we can * somewhat cleanly make use of SIGALRM to set a time limit */ (void) reset_all_signal_handlers(); (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); pids = hashmap_new(NULL); if (!pids) return log_oom(); seen = set_new(&string_hash_ops); if (!seen) return log_oom(); STRV_FOREACH(directory, directories) { _cleanup_closedir_ DIR *d; struct dirent *de; d = opendir(*directory); if (!d) { if (errno == ENOENT) continue; return log_error_errno(errno, "Failed to open directory %s: %m", *directory); } FOREACH_DIRENT(de, d, break) { _cleanup_free_ char *path = NULL; pid_t pid; int r; if (!dirent_is_file(de)) continue; if (set_contains(seen, de->d_name)) { log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name); continue; } r = set_put_strdup(seen, de->d_name); if (r < 0) return log_oom(); path = strjoin(*directory, "/", de->d_name, NULL); if (!path) return log_oom(); if (null_or_empty_path(path)) { log_debug("%s is empty (a mask).", path); 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) return log_oom(); path = NULL; } }