mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-22 22:03:43 +03:00
pid1,systemctl: allow symbolic exit code names
This commit is contained in:
parent
62b21e2e89
commit
2e2ed88062
3
TODO
3
TODO
@ -220,9 +220,6 @@ Features:
|
||||
|
||||
* add --vacuum-xyz options to coredumpctl, matching those journalctl already has.
|
||||
|
||||
* SuccessExitStatus= and friends should probably also accept symbolic exit
|
||||
codes names, i.e. error codes from the list maintained in exit-codes.[ch]
|
||||
|
||||
* introduce Ephemeral= unit file switch, that creates an ephemeral copy of all
|
||||
files and directories that are left writable for a unit, and which are
|
||||
removed after the unit goes down again. A bit like --ephemeral for
|
||||
|
@ -852,27 +852,32 @@
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>SuccessExitStatus=</varname></term>
|
||||
<listitem><para>Takes a list of exit status definitions that,
|
||||
when returned by the main service process, will be considered
|
||||
successful termination, in addition to the normal successful
|
||||
exit code 0 and the signals <constant>SIGHUP</constant>,
|
||||
<constant>SIGINT</constant>, <constant>SIGTERM</constant>, and
|
||||
<constant>SIGPIPE</constant>. Exit status definitions can
|
||||
either be numeric exit codes or termination signal names,
|
||||
separated by spaces. For example:
|
||||
|
||||
<programlisting>SuccessExitStatus=1 2 8 SIGKILL</programlisting>
|
||||
|
||||
ensures that exit codes 1, 2, 8 and
|
||||
the termination signal <constant>SIGKILL</constant> are
|
||||
considered clean service terminations.
|
||||
</para>
|
||||
<listitem><para>Takes a list of exit status definitions that, when returned by the main service
|
||||
process, will be considered successful termination, in addition to the normal successful exit code 0
|
||||
and the signals <constant>SIGHUP</constant>, <constant>SIGINT</constant>,
|
||||
<constant>SIGTERM</constant>, and <constant>SIGPIPE</constant>. Exit status definitions can be
|
||||
numeric exit codes, termination code names, or termination signal names, separated by spaces. See the
|
||||
Process Exit Codes section in
|
||||
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
|
||||
a list of termination codes names (for this setting only the part without the
|
||||
<literal>EXIT_</literal> or <literal>EX_</literal> prefix should be used). See
|
||||
<citerefentry project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
||||
a list of signal names.</para>
|
||||
|
||||
<para>This option may appear more than once, in which case the
|
||||
list of successful exit statuses is merged. If the empty
|
||||
string is assigned to this option, the list is reset, all
|
||||
prior assignments of this option will have no
|
||||
effect.</para></listitem>
|
||||
effect.</para>
|
||||
|
||||
<example>
|
||||
<title>A service with with the the <varname>SuccessExitStatus=</varname> setting</title>
|
||||
|
||||
<programlisting>SuccessExitStatus=TEMPFAIL 250 SIGUSR1</programlisting>
|
||||
|
||||
<para>Exit codes 75 (<constant>TEMPFAIL</constant>), 250, and the termination signal
|
||||
<constant>SIGKILL</constant> are considered clean service terminations.</para>
|
||||
</example></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -3936,33 +3936,33 @@ int config_parse_set_status(
|
||||
|
||||
FOREACH_WORD(word, l, rvalue, state) {
|
||||
_cleanup_free_ char *temp;
|
||||
int val;
|
||||
Bitmap *bitmap;
|
||||
|
||||
temp = strndup(word, l);
|
||||
if (!temp)
|
||||
return log_oom();
|
||||
|
||||
r = safe_atoi(temp, &val);
|
||||
if (r < 0) {
|
||||
val = signal_from_string(temp);
|
||||
/* We need to call exit_status_from_string() first, because we want
|
||||
* to parse numbers as exit statuses, not signals. */
|
||||
|
||||
if (val <= 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse value, ignoring: %s", word);
|
||||
r = exit_status_from_string(temp);
|
||||
if (r >= 0) {
|
||||
assert(r >= 0 && r < 256);
|
||||
bitmap = &status_set->status;
|
||||
} else {
|
||||
r = signal_from_string(temp);
|
||||
|
||||
if (r <= 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Failed to parse value, ignoring: %s", word);
|
||||
continue;
|
||||
}
|
||||
bitmap = &status_set->signal;
|
||||
} else {
|
||||
if (val < 0 || val > 255) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Value %d is outside range 0-255, ignoring", val);
|
||||
continue;
|
||||
}
|
||||
bitmap = &status_set->status;
|
||||
}
|
||||
|
||||
r = bitmap_set(bitmap, val);
|
||||
r = bitmap_set(bitmap, r);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
return log_error_errno(r, "Failed to set signal or status %s: %m", word);
|
||||
}
|
||||
if (!isempty(state))
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "cpu-set-util.h"
|
||||
#include "escape.h"
|
||||
#include "exec-util.h"
|
||||
#include "exit-status.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "hostname-util.h"
|
||||
#include "in-addr-util.h"
|
||||
@ -1444,7 +1445,6 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
|
||||
|
||||
for (p = eq;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
int val;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE);
|
||||
if (r == 0)
|
||||
@ -1454,24 +1454,30 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Invalid syntax in %s: %s", field, eq);
|
||||
|
||||
r = safe_atoi(word, &val);
|
||||
if (r < 0) {
|
||||
val = signal_from_string(word);
|
||||
if (val < 0)
|
||||
return log_error_errno(r, "Invalid status or signal %s in %s: %m", word, field);
|
||||
/* We need to call exit_status_from_string() first, because we want
|
||||
* to parse numbers as exit statuses, not signals. */
|
||||
|
||||
signal = reallocarray(signal, n_signal + 1, sizeof(int));
|
||||
if (!signal)
|
||||
return log_oom();
|
||||
r = exit_status_from_string(word);
|
||||
if (r >= 0) {
|
||||
assert(r >= 0 && r < 256);
|
||||
|
||||
signal[n_signal++] = val;
|
||||
} else {
|
||||
status = reallocarray(status, n_status + 1, sizeof(int));
|
||||
if (!status)
|
||||
return log_oom();
|
||||
|
||||
status[n_status++] = val;
|
||||
}
|
||||
status[n_status++] = r;
|
||||
|
||||
} else if ((r = signal_from_string(word)) >= 0) {
|
||||
signal = reallocarray(signal, n_signal + 1, sizeof(int));
|
||||
if (!signal)
|
||||
return log_oom();
|
||||
|
||||
signal[n_signal++] = r;
|
||||
|
||||
} else
|
||||
/* original r from exit_status_to_string() */
|
||||
return log_error_errno(r, "Invalid status or signal %s in %s: %m",
|
||||
word, field);
|
||||
}
|
||||
|
||||
r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
|
||||
|
Loading…
x
Reference in New Issue
Block a user