diff options
author | Karel Zak | 2017-09-07 12:09:17 +0200 |
---|---|---|
committer | Karel Zak | 2017-09-18 11:49:11 +0200 |
commit | 13ee2f4d78fd6866cc82b6e237f178752fe60371 (patch) | |
tree | 8e090bc56bbc17b55c71646051d8214935100eff /login-utils | |
parent | su: (pty) simplify stdin usage in poll() (diff) | |
download | kernel-qcow2-util-linux-13ee2f4d78fd6866cc82b6e237f178752fe60371.tar.gz kernel-qcow2-util-linux-13ee2f4d78fd6866cc82b6e237f178752fe60371.tar.xz kernel-qcow2-util-linux-13ee2f4d78fd6866cc82b6e237f178752fe60371.zip |
su: (pty) save child status
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils')
-rw-r--r-- | login-utils/su-common.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/login-utils/su-common.c b/login-utils/su-common.c index bc96967be..925cef983 100644 --- a/login-utils/su-common.c +++ b/login-utils/su-common.c @@ -133,6 +133,7 @@ struct su_context { char *old_user; /* orginal user */ pid_t child; /* fork() baby */ + int childstatus; /* wait() status */ struct sigaction oldact[SIGNALS_IDX_COUNT]; /* original sigactions indexed by SIG*_IDX */ @@ -182,11 +183,18 @@ static void init_tty(struct su_context *su) get_terminal_name(NULL, &su->tty_name, &su->tty_number); } +/* + * Note, this function has to be possible call more than once. If the child is + * already dead than it returns saved result from the previous call. + */ static int wait_for_child(struct su_context *su) { pid_t pid = (pid_t) -1;; int status = 0; + if (su->child == (pid_t) -1) + return su->childstatus; + if (su->child != (pid_t) -1) { DBG(SIG, ul_debug("waiting for child [%d]...", su->child)); for (;;) { @@ -212,12 +220,13 @@ static int wait_for_child(struct su_context *su) DBG(SIG, ul_debug("child %d is dead", su->child)); su->child = (pid_t) -1; /* Don't use the PID anymore! */ + su->childstatus = status; } else if (caught_signal) status = caught_signal + 128; else status = 1; - DBG(SIG, ul_debug("status=%d", status)); + DBG(SIG, ul_debug("child status=%d", status)); return status; } @@ -845,6 +854,8 @@ static void create_watching_parent(struct su_context *su) else status = 1; + DBG(SIG, ul_debug("final child status=%d", status)); + if (caught_signal && su->child != (pid_t)-1) { fprintf(stderr, _("\nSession terminated, killing shell...")); kill(su->child, SIGTERM); |