diff options
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r-- | src/systemctl/systemctl.c | 94 |
1 files changed, 63 insertions, 31 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index d21ba9a566..34e4751b94 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -431,11 +431,11 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) { if (STR_IN_SET(u->load_state, "error", "not-found", "masked") && !arg_plain) { on_loaded = ansi_highlight_red(); on_circle = ansi_highlight_yellow(); - off_loaded = off_circle = ansi_highlight_off(); + off_loaded = off_circle = ansi_normal(); circle = true; } else if (streq(u->active_state, "failed") && !arg_plain) { on_circle = on_active = ansi_highlight_red(); - off_circle = off_active = ansi_highlight_off(); + off_circle = off_active = ansi_normal(); circle = true; } @@ -482,10 +482,10 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) { "SUB = The low-level unit activation state, values depend on unit type."); puts(job_count ? "JOB = Pending job for the unit.\n" : ""); on = ansi_highlight(); - off = ansi_highlight_off(); + off = ansi_normal(); } else { on = ansi_highlight_red(); - off = ansi_highlight_off(); + off = ansi_normal(); } if (arg_all) @@ -836,12 +836,12 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) { } on = ansi_highlight(); - off = ansi_highlight_off(); + off = ansi_normal(); if (!arg_no_legend) printf("\n"); } else { on = ansi_highlight_red(); - off = ansi_highlight_off(); + off = ansi_normal(); } if (!arg_no_legend) { @@ -1118,12 +1118,12 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) { } on = ansi_highlight(); - off = ansi_highlight_off(); + off = ansi_normal(); if (!arg_no_legend) printf("\n"); } else { on = ansi_highlight_red(); - off = ansi_highlight_off(); + off = ansi_normal(); } if (!arg_no_legend) { @@ -1306,10 +1306,10 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) { UNIT_FILE_DISABLED, UNIT_FILE_INVALID)) { on = ansi_highlight_red(); - off = ansi_highlight_off(); + off = ansi_normal(); } else if (u->state == UNIT_FILE_ENABLED) { on = ansi_highlight_green(); - off = ansi_highlight_off(); + off = ansi_normal(); } else on = off = ""; @@ -1618,7 +1618,7 @@ static int list_dependencies_one( state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true); on = state > 0 ? ansi_highlight_green() : ansi_highlight_red(); - printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off()); + printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_normal()); } r = list_dependencies_print(*c, level, branches, c[1] == NULL); @@ -1837,17 +1837,17 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n) if (streq_ptr(m->state, "degraded")) { on_state = ansi_highlight_red(); - off_state = ansi_highlight_off(); + off_state = ansi_normal(); circle = true; } else if (!streq_ptr(m->state, "running")) { on_state = ansi_highlight_yellow(); - off_state = ansi_highlight_off(); + off_state = ansi_normal(); circle = true; } if (m->n_failed_units > 0) { on_failed = ansi_highlight_red(); - off_failed = ansi_highlight_off(); + off_failed = ansi_normal(); } else on_failed = off_failed = ""; @@ -2020,7 +2020,7 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipp if (n == 0) { if (!arg_no_legend) { on = ansi_highlight_green(); - off = ansi_highlight_off(); + off = ansi_normal(); printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off); } @@ -2061,7 +2061,7 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipp if (streq(j->state, "running")) { on = ansi_highlight(); - off = ansi_highlight_off(); + off = ansi_normal(); } else on = off = ""; @@ -2075,7 +2075,7 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipp if (!arg_no_legend) { on = ansi_highlight(); - off = ansi_highlight_off(); + off = ansi_normal(); printf("\n%s%u jobs listed%s.\n", on, n, off); } @@ -2221,7 +2221,7 @@ static int need_daemon_reload(sd_bus *bus, const char *unit) { static void warn_unit_file_changed(const char *name) { log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.", ansi_highlight_red(), - ansi_highlight_off(), + ansi_normal(), name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user"); } @@ -3005,6 +3005,7 @@ static int prepare_firmware_setup(sd_bus *bus) { } static int start_special(sd_bus *bus, char **args) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; enum action a; int r; @@ -3029,6 +3030,31 @@ static int start_special(sd_bus *bus, char **args) { r = update_reboot_param_file(args[1]); if (r < 0) return r; + } else if (a == ACTION_EXIT && strv_length(args) > 1) { + /* If the exit code is not given on the command line, don't + * reset it to zero: just keep it as it might have been set + * previously. */ + uint8_t code = 0; + + r = safe_atou8(args[1], &code); + if (r < 0) { + log_error("Invalid exit code."); + return -EINVAL; + } + + r = sd_bus_call_method( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "SetExitCode", + &error, + NULL, + "y", code); + if (r < 0) { + log_error("Failed to execute operation: %s", bus_error_message(&error, r)); + return r; + } } if (arg_force >= 2 && @@ -3107,7 +3133,7 @@ static int check_unit_failed(sd_bus *bus, char **args) { static int kill_unit(sd_bus *bus, char **args) { _cleanup_strv_free_ char **names = NULL; - char **name; + char *kill_who = NULL, **name; int r, q; assert(bus); @@ -3118,6 +3144,10 @@ static int kill_unit(sd_bus *bus, char **args) { if (!arg_kill_who) arg_kill_who = "all"; + /* --fail was specified */ + if (streq(arg_job_mode, "fail")) + kill_who = strjoina(arg_kill_who, "-fail", NULL); + r = expand_names(bus, args + 1, NULL, &names); if (r < 0) log_error_errno(r, "Failed to expand names: %m"); @@ -3133,7 +3163,7 @@ static int kill_unit(sd_bus *bus, char **args) { "KillUnit", &error, NULL, - "ssi", *names, arg_kill_who, arg_signal); + "ssi", *names, kill_who ? kill_who : arg_kill_who, arg_signal); if (q < 0) { log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q)); if (r == 0) @@ -3325,10 +3355,10 @@ static void print_status_info( if (streq_ptr(i->active_state, "failed")) { active_on = ansi_highlight_red(); - active_off = ansi_highlight_off(); + active_off = ansi_normal(); } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) { active_on = ansi_highlight_green(); - active_off = ansi_highlight_off(); + active_off = ansi_normal(); } else active_on = active_off = ""; @@ -3344,7 +3374,7 @@ static void print_status_info( if (streq_ptr(i->load_state, "error")) { on = ansi_highlight_red(); - off = ansi_highlight_off(); + off = ansi_normal(); } else on = off = ""; @@ -3425,7 +3455,7 @@ static void print_status_info( s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); printf("Condition: start %scondition failed%s at %s%s%s\n", - ansi_highlight_yellow(), ansi_highlight_off(), + ansi_highlight_yellow(), ansi_normal(), s2, s1 ? "; " : "", s1 ? s1 : ""); if (i->failed_condition_trigger) printf(" none of the trigger conditions were met\n"); @@ -3441,7 +3471,7 @@ static void print_status_info( s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp); printf(" Assert: start %sassertion failed%s at %s%s%s\n", - ansi_highlight_red(), ansi_highlight_off(), + ansi_highlight_red(), ansi_normal(), s2, s1 ? "; " : "", s1 ? s1 : ""); if (i->failed_assert_trigger) printf(" none of the trigger assertions were met\n"); @@ -3482,7 +3512,7 @@ static void print_status_info( good = is_clean_exit_lsb(p->code, p->status, NULL); if (!good) { on = ansi_highlight_red(); - off = ansi_highlight_off(); + off = ansi_normal(); } else on = off = ""; @@ -4483,10 +4513,10 @@ static int show_system_status(sd_bus *bus) { if (streq_ptr(mi.state, "degraded")) { on = ansi_highlight_red(); - off = ansi_highlight_off(); + off = ansi_normal(); } else if (!streq_ptr(mi.state, "running")) { on = ansi_highlight_yellow(); - off = ansi_highlight_off(); + off = ansi_normal(); } else on = off = ""; @@ -4658,7 +4688,7 @@ static int cat_file(const char *filename, bool newline) { newline ? "\n" : "", ansi_highlight_blue(), filename, - ansi_highlight_off()); + ansi_normal()); fflush(stdout); return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false); @@ -6220,7 +6250,7 @@ static void systemctl_help(void) { " poweroff Shut down and power-off the system\n" " reboot [ARG] Shut down and reboot the system\n" " kexec Shut down and reboot the system with kexec\n" - " exit Request user instance exit\n" + " exit [EXIT_CODE] Request user instance or container exit\n" " switch-root ROOT [INIT] Change to a different root file system\n" " suspend Suspend the system\n" " hibernate Hibernate the system\n" @@ -7207,7 +7237,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "default", EQUAL, 1, start_special }, { "rescue", EQUAL, 1, start_special }, { "emergency", EQUAL, 1, start_special }, - { "exit", EQUAL, 1, start_special }, + { "exit", LESS, 2, start_special }, { "reset-failed", MORE, 1, reset_failed }, { "enable", MORE, 2, enable_unit, NOBUS }, { "disable", MORE, 2, enable_unit, NOBUS }, @@ -7675,5 +7705,7 @@ finish: strv_free(arg_states); strv_free(arg_properties); + sd_bus_default_flush_close(); + return r < 0 ? EXIT_FAILURE : r; } |