X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fexecute.c;h=05abd5aaac3aac964488ba564170307695a20041;hp=b4ddf8961f390071f690be5c588e01cb8d247917;hb=e3aa71c38cbecb24e6333411ee19814796a5b1d0;hpb=d6c9574fb558d9e304699b1cc7522c3b133adfc9 diff --git a/src/execute.c b/src/execute.c index b4ddf8961..05abd5aaa 100644 --- a/src/execute.c +++ b/src/execute.c @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef HAVE_PAM #include @@ -51,6 +52,9 @@ #include "cgroup.h" #include "namespace.h" #include "tcpwrap.h" +#include "exit-status.h" +#include "missing.h" +#include "utmp-wtmp.h" /* This assumes there is a 'tty' group */ #define TTY_MODE 0620 @@ -171,7 +175,7 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons sa.sa.sa_family = AF_UNIX; strncpy(sa.un.sun_path+1, LOGGER_SOCKET, sizeof(sa.un.sun_path)-1); - if (connect(fd, &sa.sa, sizeof(sa_family_t) + 1 + sizeof(LOGGER_SOCKET) - 1) < 0) { + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + sizeof(LOGGER_SOCKET) - 1) < 0) { close_nointr_nofail(fd); return -errno; } @@ -1037,6 +1041,11 @@ int exec_spawn(ExecCommand *command, goto fail; } + /* If a socket is connected to STDIN/STDOUT/STDERR, we + * must sure to drop O_NONBLOCK */ + if (socket_fd >= 0) + fd_nonblock(socket_fd, false); + if (!keep_stdin) if (setup_input(context, socket_fd, apply_tty_stdin) < 0) { r = EXIT_STDIN; @@ -1060,15 +1069,27 @@ int exec_spawn(ExecCommand *command, goto fail; } - if (context->oom_adjust_set) { + if (context->oom_score_adjust_set) { char t[16]; - snprintf(t, sizeof(t), "%i", context->oom_adjust); + snprintf(t, sizeof(t), "%i", context->oom_score_adjust); char_array_0(t); - if (write_one_line_file("/proc/self/oom_adj", t) < 0) { - r = EXIT_OOM_ADJUST; - goto fail; + if (write_one_line_file("/proc/self/oom_score_adj", t) < 0) { + /* Compatibility with Linux <= 2.6.35 */ + + int adj; + + adj = (context->oom_score_adjust * -OOM_DISABLE) / OOM_SCORE_ADJ_MAX; + adj = CLAMP(adj, OOM_DISABLE, OOM_ADJUST_MAX); + + snprintf(t, sizeof(t), "%i", adj); + char_array_0(t); + + if (write_one_line_file("/proc/self/oom_adj", t) < 0) { + r = EXIT_OOM_ADJUST; + goto fail; + } } } @@ -1109,6 +1130,9 @@ int exec_spawn(ExecCommand *command, goto fail; } + if (context->utmp_id) + utmp_put_init_process(0, context->utmp_id, getpid(), getsid(0), context->tty_path); + if (context->user) { username = context->user; if (get_user_creds(&username, &uid, &gid, &home) < 0) { @@ -1228,7 +1252,7 @@ int exec_spawn(ExecCommand *command, } } - if (!(our_env = new0(char*, 6))) { + if (!(our_env = new0(char*, 7))) { r = EXIT_MEMORY; goto fail; } @@ -1253,7 +1277,15 @@ int exec_spawn(ExecCommand *command, goto fail; } - assert(n_env <= 6); + if (is_terminal_input(context->std_input) || + context->std_output == EXEC_OUTPUT_TTY || + context->std_error == EXEC_OUTPUT_TTY) + if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) { + r = EXIT_MEMORY; + goto fail; + } + + assert(n_env <= 7); if (!(final_env = strv_env_merge( 4, @@ -1455,10 +1487,10 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { "%sNice: %i\n", prefix, c->nice); - if (c->oom_adjust_set) + if (c->oom_score_adjust_set) fprintf(f, - "%sOOMAdjust: %i\n", - prefix, c->oom_adjust); + "%sOOMScoreAdjust: %i\n", + prefix, c->oom_score_adjust); for (i = 0; i < RLIM_NLIMITS; i++) if (c->rlimit[i]) @@ -1584,6 +1616,11 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { "%sKillSignal: SIG%s\n", prefix, kill_mode_to_string(c->kill_mode), prefix, signal_to_string(c->kill_signal)); + + if (c->utmp_id) + fprintf(f, + "%sUtmpIdentifier: %s\n", + prefix, c->utmp_id); } void exec_status_start(ExecStatus *s, pid_t pid) { @@ -1594,7 +1631,7 @@ void exec_status_start(ExecStatus *s, pid_t pid) { dual_timestamp_get(&s->start_timestamp); } -void exec_status_exit(ExecStatus *s, pid_t pid, int code, int status) { +void exec_status_exit(ExecStatus *s, pid_t pid, int code, int status, const char *utmp_id) { assert(s); if ((s->pid && s->pid != pid) || @@ -1606,6 +1643,9 @@ void exec_status_exit(ExecStatus *s, pid_t pid, int code, int status) { s->code = code; s->status = status; + + if (utmp_id) + utmp_put_dead_process(utmp_id, pid, code, status); } void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) { @@ -1757,117 +1797,6 @@ int exec_command_set(ExecCommand *c, const char *path, ...) { return 0; } -const char* exit_status_to_string(ExitStatus status) { - - /* We cast to int here, so that -Wenum doesn't complain that - * EXIT_SUCCESS/EXIT_FAILURE aren't in the enum */ - - switch ((int) status) { - - case EXIT_SUCCESS: - return "SUCCESS"; - - case EXIT_FAILURE: - return "FAILURE"; - - case EXIT_INVALIDARGUMENT: - return "INVALIDARGUMENT"; - - case EXIT_NOTIMPLEMENTED: - return "NOTIMPLEMENTED"; - - case EXIT_NOPERMISSION: - return "NOPERMISSION"; - - case EXIT_NOTINSTALLED: - return "NOTINSSTALLED"; - - case EXIT_NOTCONFIGURED: - return "NOTCONFIGURED"; - - case EXIT_NOTRUNNING: - return "NOTRUNNING"; - - case EXIT_CHDIR: - return "CHDIR"; - - case EXIT_NICE: - return "NICE"; - - case EXIT_FDS: - return "FDS"; - - case EXIT_EXEC: - return "EXEC"; - - case EXIT_MEMORY: - return "MEMORY"; - - case EXIT_LIMITS: - return "LIMITS"; - - case EXIT_OOM_ADJUST: - return "OOM_ADJUST"; - - case EXIT_SIGNAL_MASK: - return "SIGNAL_MASK"; - - case EXIT_STDIN: - return "STDIN"; - - case EXIT_STDOUT: - return "STDOUT"; - - case EXIT_CHROOT: - return "CHROOT"; - - case EXIT_IOPRIO: - return "IOPRIO"; - - case EXIT_TIMERSLACK: - return "TIMERSLACK"; - - case EXIT_SECUREBITS: - return "SECUREBITS"; - - case EXIT_SETSCHEDULER: - return "SETSCHEDULER"; - - case EXIT_CPUAFFINITY: - return "CPUAFFINITY"; - - case EXIT_GROUP: - return "GROUP"; - - case EXIT_USER: - return "USER"; - - case EXIT_CAPABILITIES: - return "CAPABILITIES"; - - case EXIT_CGROUP: - return "CGROUP"; - - case EXIT_SETSID: - return "SETSID"; - - case EXIT_CONFIRM: - return "CONFIRM"; - - case EXIT_STDERR: - return "STDERR"; - - case EXIT_TCPWRAP: - return "TCPWRAP"; - - case EXIT_PAM: - return "PAM"; - - default: - return NULL; - } -} - static const char* const exec_input_table[_EXEC_INPUT_MAX] = { [EXEC_INPUT_NULL] = "null", [EXEC_INPUT_TTY] = "tty", @@ -1876,6 +1805,8 @@ static const char* const exec_input_table[_EXEC_INPUT_MAX] = { [EXEC_INPUT_SOCKET] = "socket" }; +DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput); + static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = { [EXEC_OUTPUT_INHERIT] = "inherit", [EXEC_OUTPUT_NULL] = "null", @@ -1887,4 +1818,19 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = { DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput); -DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput); +static const char* const kill_mode_table[_KILL_MODE_MAX] = { + [KILL_CONTROL_GROUP] = "control-group", + [KILL_PROCESS_GROUP] = "process-group", + [KILL_PROCESS] = "process", + [KILL_NONE] = "none" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_mode, KillMode); + +static const char* const kill_who_table[_KILL_WHO_MAX] = { + [KILL_MAIN] = "main", + [KILL_CONTROL] = "control", + [KILL_ALL] = "all" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);