From: Karel Zak Date: Wed, 16 Nov 2022 08:17:52 +0000 (+0100) Subject: llib/pty-session: split PTY and signalfd setup X-Git-Tag: v2.39-rc1~421 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4681d88ba1034d488814bbbb6e7d06d17e33322d;p=thirdparty%2Futil-linux.git llib/pty-session: split PTY and signalfd setup In some cases applications need to use PTY before signalfd is enabled. Signed-off-by: Karel Zak --- diff --git a/include/pty-session.h b/include/pty-session.h index 7176d6ba72..bece863f5c 100644 --- a/include/pty-session.h +++ b/include/pty-session.h @@ -105,6 +105,7 @@ void ul_pty_set_child(struct ul_pty *pty, pid_t child); struct ul_pty_callbacks *ul_pty_get_callbacks(struct ul_pty *pty); int ul_pty_is_running(struct ul_pty *pty); int ul_pty_setup(struct ul_pty *pty); +int ul_pty_signals_setup(struct ul_pty *pty); void ul_pty_cleanup(struct ul_pty *pty); int ul_pty_chownmod_slave(struct ul_pty *pty, uid_t uid, gid_t gid, mode_t mode); void ul_pty_init_slave(struct ul_pty *pty); diff --git a/lib/pty-session.c b/lib/pty-session.c index 360adb6f37..3849065475 100644 --- a/lib/pty-session.c +++ b/lib/pty-session.c @@ -160,12 +160,12 @@ static void pty_signals_cleanup(struct ul_pty *pty) int ul_pty_setup(struct ul_pty *pty) { struct termios attrs; - sigset_t ourset; int rc = 0; assert(pty->sigfd == -1); - /* save the current signals setting */ + /* save the current signals setting (to make ul_pty_cleanup() usable, + * otherwise see ul_pty_signals_setup() */ sigprocmask(0, NULL, &pty->orgsig); if (pty->isterm) { @@ -211,6 +211,26 @@ int ul_pty_setup(struct ul_pty *pty) fcntl(pty->master, F_SETFL, O_NONBLOCK); +done: + if (rc) + ul_pty_cleanup(pty); + + DBG(SETUP, ul_debugobj(pty, "pty setup done [master=%d, slave=%d, rc=%d]", + pty->master, pty->slave, rc)); + return rc; +} + +/* call me before fork() */ +int ul_pty_signals_setup(struct ul_pty *pty) +{ + sigset_t ourset; + int rc = 0; + + assert(pty->sigfd == -1); + + /* save the current signals setting */ + sigprocmask(0, NULL, &pty->orgsig); + sigfillset(&ourset); if (sigprocmask(SIG_BLOCK, &ourset, NULL)) { rc = -errno; @@ -234,8 +254,7 @@ done: if (rc) ul_pty_cleanup(pty); - DBG(SETUP, ul_debugobj(pty, "pty setup done [master=%d, slave=%d, rc=%d]", - pty->master, pty->slave, rc)); + DBG(SETUP, ul_debugobj(pty, "pty signals setup done [rc=%d]", rc)); return rc; } @@ -783,6 +802,8 @@ int main(int argc, char *argv[]) if (ul_pty_setup(pty)) err(EXIT_FAILURE, "failed to create pseudo-terminal"); + if (ul_pty_signals_setup(pty)) + err(EXIT_FAILURE, "failed to initialize signals handler"); fflush(stdout); /* ??? */ diff --git a/login-utils/su-common.c b/login-utils/su-common.c index 3021b88bc0..6f30c607f0 100644 --- a/login-utils/su-common.c +++ b/login-utils/su-common.c @@ -542,6 +542,8 @@ static void create_watching_parent(struct su_context *su) /* create pty */ if (ul_pty_setup(su->pty)) err(EXIT_FAILURE, _("failed to create pseudo-terminal")); + if (ul_pty_signals_setup(su->pty)) + err(EXIT_FAILURE, _("failed to initialize signals handler")); } #endif fflush(stdout); /* ??? */ diff --git a/term-utils/scriptlive.c b/term-utils/scriptlive.c index d81712d36f..3e68f3c067 100644 --- a/term-utils/scriptlive.c +++ b/term-utils/scriptlive.c @@ -294,6 +294,8 @@ main(int argc, char *argv[]) if (ul_pty_setup(ss.pty)) err(EXIT_FAILURE, _("failed to create pseudo-terminal")); + if (ul_pty_signals_setup(ss.pty)) + err(EXIT_FAILURE, _("failed to initialize signals handler")); fflush(stdout); /* ??? */