diff --git a/docs/swupd.1 b/docs/swupd.1 index 83f84eae..f6d0992e 100644 --- a/docs/swupd.1 +++ b/docs/swupd.1 @@ -645,6 +645,8 @@ The non\-zero return codes for other operations are listed here: \fB27\fP: Unable to rename a directory .IP \(bu 2 \fB28\fP: Unable to rename a file +.IP \(bu 2 +\fB29\fP: Unable to execute another program in a subprocess .UNINDENT .UNINDENT .UNINDENT diff --git a/docs/swupd.1.rst b/docs/swupd.1.rst index 2d02eb4f..cf68fa42 100644 --- a/docs/swupd.1.rst +++ b/docs/swupd.1.rst @@ -437,6 +437,7 @@ The non-zero return codes for other operations are listed here: - **26**: Unexpected condition found - **27**: Unable to rename a directory - **28**: Unable to rename a file + - **29**: Unable to execute another program in a subprocess SEE ALSO diff --git a/src/autoupdate.c b/src/autoupdate.c index dc604c28..7ce31bf3 100644 --- a/src/autoupdate.c +++ b/src/autoupdate.c @@ -87,6 +87,26 @@ static void policy_warn(void) "out of compliance with your IT policy\n\n"); } +static int system_command(const char *cmd) +{ + int ret; + + ret = system(cmd); + if (ret == -1) { + /* it wasn't possible to create the shell process */ + return SWUPD_SUBPROCESS_ERROR; + } + + ret = WEXITSTATUS(ret); + + if (ret == 126 || ret == 128) { + /* the command invoked cannot execute or was not found */ + return SWUPD_SUBPROCESS_ERROR; + } + + return ret; +} + int autoupdate_main(int argc, char **argv) { if (!parse_options(argc, argv)) { @@ -94,48 +114,41 @@ int autoupdate_main(int argc, char **argv) } if (enable && disable) { fprintf(stderr, "Can not enable and disable at the same time\n"); - exit(EXIT_FAILURE); + return SWUPD_INVALID_OPTION; } if (enable) { int rc; check_root(); fprintf(stderr, "Running systemctl to enable updates\n"); - rc = system("/usr/bin/systemctl unmask --now swupd-update.service swupd-update.timer" - " && /usr/bin/systemctl restart swupd-update.timer > /dev/null"); - if (rc != -1) { - rc = WEXITSTATUS(rc); + rc = system_command("/usr/bin/systemctl unmask --now swupd-update.service swupd-update.timer" + " && /usr/bin/systemctl restart swupd-update.timer > /dev/null"); + if (rc) { + return SWUPD_SUBPROCESS_ERROR; } - return (rc); + return SWUPD_OK; } else if (disable) { int rc; check_root(); policy_warn(); fprintf(stderr, "Running systemctl to disable updates\n"); - rc = system("/usr/bin/systemctl mask --now swupd-update.service swupd-update.timer > /dev/null"); - if (rc != -1) { - rc = WEXITSTATUS(rc); + rc = system_command("/usr/bin/systemctl mask --now swupd-update.service swupd-update.timer > /dev/null"); + if (rc) { + return SWUPD_SUBPROCESS_ERROR; } - return (rc); + return SWUPD_OK; } else { /* In a container, "/usr/bin/systemctl" will return 1 with * "Failed to connect to bus: No such file or directory" * However /usr/bin/systemctl is-enabled ... will not fail, even when it * should. Check that systemctl is working before reporting the output * of is-enabled. */ - int rc = system("/usr/bin/systemctl > /dev/null 2>&1"); - if (rc != -1) { - rc = WEXITSTATUS(rc); - } - + int rc = system_command("/usr/bin/systemctl > /dev/null 2>&1"); if (rc) { fprintf(stderr, "Unable to determine autoupdate status\n"); - return rc; + return SWUPD_SUBPROCESS_ERROR; } - rc = system("/usr/bin/systemctl is-enabled swupd-update.service > /dev/null"); - if (rc != -1) { - rc = WEXITSTATUS(rc); - } + rc = system_command("/usr/bin/systemctl is-enabled swupd-update.service > /dev/null"); switch (rc) { case SWUPD_OK: printf("Enabled\n"); @@ -144,6 +157,7 @@ int autoupdate_main(int argc, char **argv) printf("Disabled\n"); break; default: + rc = SWUPD_SUBPROCESS_ERROR; fprintf(stderr, "Unable to determine autoupdate status\n"); } return (rc); diff --git a/src/swupd_exit_codes.h b/src/swupd_exit_codes.h index 26bae671..c9e6e462 100644 --- a/src/swupd_exit_codes.h +++ b/src/swupd_exit_codes.h @@ -38,7 +38,8 @@ typedef enum { SWUPD_PATH_NOT_IN_MANIFEST, /* 25 the required path is not in any manifest */ SWUPD_UNEXPECTED_CONDITION, /* 26 an unexpected condition was found */ SWUPD_COULDNT_RENAME_DIR, /* 27 couldn't rename a directory */ - SWUPD_COULDNT_RENAME_FILE /* 28 couldn't rename a file */ + SWUPD_COULDNT_RENAME_FILE, /* 28 couldn't rename a file */ + SWUPD_SUBPROCESS_ERROR /* 29 failure to execute another program in a subprocess */ } swupd_code; diff --git a/test/functional/testlib.bash b/test/functional/testlib.bash index afac333c..a3a9e02d 100644 --- a/test/functional/testlib.bash +++ b/test/functional/testlib.bash @@ -41,6 +41,7 @@ export SWUPD_PATH_NOT_IN_MANIFEST=25 # the required path is not in any manifest export SWUPD_UNEXPECTED_CONDITION=26 # an unexpected condition was found export SWUPD_COULDNT_RENAME_DIR=27 # couldn't rename a directory export SWUPD_COULDNT_RENAME_FILE=28 # couldn't rename a file +export SWUPD_SUBPROCESS_ERROR=29 # failure to execute another program in a subprocess # global constant export zero_hash="0000000000000000000000000000000000000000000000000000000000000000"