diff options
-rw-r--r-- | main.c | 67 |
1 files changed, 43 insertions, 24 deletions
@@ -5,6 +5,7 @@ #include <string.h> #include <signal.h> #include <errno.h> +#include <sys/wait.h> struct auth_env a_env; struct proc_env p_env = { @@ -54,32 +55,50 @@ int main(int argc, char **argv) { } a_env.exe[len] = '\0'; - /* Because we need to frequently dup(2). */ - setbuf(stdout, NULL); - signal(SIGHUP, SIG_IGN); - struct sigaction sa = { - .sa_flags = 0, - .sa_handler = interrupt_int - }; - sigemptyset(&sa.sa_mask); - /* Return EINTR on these signals to exit safely. */ - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); + pid_t chld; + /* Detach from the current session. */ + if (!(chld = fork())) { + /* Because we need to frequently dup(2). */ + setbuf(stdout, NULL); + signal(SIGHUP, SIG_IGN); + struct sigaction sa = { + .sa_flags = 0, + .sa_handler = interrupt_int + }; + sigemptyset(&sa.sa_mask); + /* Return EINTR on these signals to exit safely. */ + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); - int r = sd_setup(); - if (r == -1) { - sd_cleanup(); - return 13; + int r = sd_setup(); + if (r == -1) { + sd_cleanup(); + return 13; + } + if (r) { + sd_cleanup(); + r = main_consent(0); + } else { + dprintf(p_env.err, "Complete authorization on TTY %d by running `chvt %d`.\n", + p_env.vt, + p_env.vt); + r = main_consent(1); + sd_cleanup(); + } + return r; } - if (r) { - sd_cleanup(); - r = main_consent(0); + if (chld == -1) { + LOGFV("Cannot fork: %m", errno); + return errno; + } + int status; + if (waitpid(chld, &status, 0) == -1) { + LOGFV("Cannot wait for child: %m", errno); + return errno; + } + if (WIFEXITED(status)) { + return WEXITSTATUS(status); } else { - dprintf(p_env.err, "Complete authorization on TTY %d by running `chvt %d`.\n", - p_env.vt, - p_env.vt); - r = main_consent(1); - sd_cleanup(); + return 255; } - return r; } |