X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;ds=sidebyside;f=execute.c;h=0374eaec5dae56ff2e339d225f1f2ec9078475cd;hb=8e471ccd1583371cab19a6263b8952b37d069b07;hp=85d9873918464432d2e8b64880e7540a28f3171b;hpb=693ced48727b3e40defd95147148a361acd7dcce;p=elogind.git diff --git a/execute.c b/execute.c index 85d987391..0374eaec5 100644 --- a/execute.c +++ b/execute.c @@ -42,55 +42,7 @@ #include "log.h" #include "ioprio.h" #include "securebits.h" - -static int close_fds(int except[], unsigned n_except) { - DIR *d; - struct dirent *de; - int r = 0; - - /* Modifies the fds array! (sorts it) */ - - if (!(d = opendir("/proc/self/fd"))) - return -errno; - - while ((de = readdir(d))) { - int fd; - - if (de->d_name[0] == '.') - continue; - - if ((r = safe_atoi(de->d_name, &fd)) < 0) - goto finish; - - if (fd < 3) - continue; - - if (fd == dirfd(d)) - continue; - - if (except) { - bool found; - unsigned i; - - found = false; - for (i = 0; i < n_except; i++) - if (except[i] == fd) { - found = true; - break; - } - - if (found) - continue; - } - - if ((r = close_nointr(fd)) < 0) - goto finish; - } - -finish: - closedir(d); - return r; -} +#include "cgroup.h" static int shift_fds(int fds[], unsigned n_fds) { int start, restart_from; @@ -98,6 +50,8 @@ static int shift_fds(int fds[], unsigned n_fds) { if (n_fds <= 0) return 0; + /* Modifies the fds array! (sorts it) */ + assert(fds); start = 0; @@ -136,6 +90,7 @@ static int shift_fds(int fds[], unsigned n_fds) { static int flags_fds(int fds[], unsigned n_fds, bool nonblock) { unsigned i; + int r; if (n_fds <= 0) return 0; @@ -145,27 +100,16 @@ static int flags_fds(int fds[], unsigned n_fds, bool nonblock) { /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */ for (i = 0; i < n_fds; i++) { - int flags; - if ((flags = fcntl(fds[i], F_GETFL, 0)) < 0) - return -errno; - - if (nonblock) - flags |= O_NONBLOCK; - else - flags &= ~O_NONBLOCK; - - if (fcntl(fds[i], F_SETFL, flags) < 0) - return -errno; + if ((r = fd_nonblock(fds[i], nonblock)) < 0) + return r; /* We unconditionally drop FD_CLOEXEC from the fds, * since after all we want to pass these fds to our * children */ - if ((flags = fcntl(fds[i], F_GETFD, 0)) < 0) - return -errno; - if (fcntl(fds[i], F_SETFD, flags &~FD_CLOEXEC) < 0) - return -errno; + if ((r = fd_cloexec(fds[i], false)) < 0) + return r; } return 0; @@ -508,9 +452,11 @@ int exec_spawn(const ExecCommand *command, int *fds, unsigned n_fds, bool apply_permissions, bool apply_chroot, + CGroupBonding *cgroup_bondings, pid_t *ret) { pid_t pid; + int r; assert(command); assert(context); @@ -519,11 +465,15 @@ int exec_spawn(const ExecCommand *command, log_debug("About to execute %s", command->path); + if (cgroup_bondings) + if ((r = cgroup_bonding_realize_list(cgroup_bondings))) + return r; + if ((pid = fork()) < 0) return -errno; if (pid == 0) { - int i, r; + int i; sigset_t ss; const char *username = NULL, *home = NULL; uid_t uid = (uid_t) -1; @@ -539,9 +489,16 @@ int exec_spawn(const ExecCommand *command, goto fail; } - if (setpgid(0, 0) < 0) { - r = EXIT_PGID; - goto fail; + if (context->new_session) { + if (setsid() < 0) { + r = EXIT_SETSID; + goto fail; + } + } else { + if (setpgid(0, 0) < 0) { + r = EXIT_PGID; + goto fail; + } } umask(context->umask); @@ -556,6 +513,12 @@ int exec_spawn(const ExecCommand *command, goto fail; } + if (cgroup_bondings) + if ((r = cgroup_bonding_install_list(cgroup_bondings, 0)) < 0) { + r = EXIT_CGROUP; + goto fail; + } + if (context->oom_adjust_set) { char t[16]; @@ -650,7 +613,7 @@ int exec_spawn(const ExecCommand *command, free(d); } - if (close_fds(fds, n_fds) < 0 || + if (close_all_fds(fds, n_fds) < 0 || shift_fds(fds, n_fds) < 0 || flags_fds(fds, n_fds, context->non_blocking) < 0) { r = EXIT_FDS; @@ -754,6 +717,12 @@ void exec_context_init(ExecContext *c) { c->cpu_sched_set = false; CPU_ZERO(&c->cpu_affinity); c->cpu_affinity_set = false; + c->timer_slack_ns = 0; + c->timer_slack_ns_set = false; + + c->cpu_sched_reset_on_fork = false; + c->non_blocking = false; + c->new_session = false; c->input = 0; c->output = 0; @@ -834,11 +803,13 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { "%sUMask: %04o\n" "%sWorkingDirectory: %s\n" "%sRootDirectory: %s\n" - "%sNonBlocking: %s\n", + "%sNonBlocking: %s\n" + "%sNewSession: %s\n", prefix, c->umask, prefix, c->working_directory ? c->working_directory : "/", prefix, c->root_directory ? c->root_directory : "/", - prefix, yes_no(c->non_blocking)); + prefix, yes_no(c->non_blocking), + prefix, yes_no(c->new_session)); if (c->environment) for (e = c->environment; *e; e++)