util-linux/backport-llib-pty-session-split-PTY-and-signalfd-setup.patch

122 lines
3.6 KiB
Diff
Raw Normal View History

From 4681d88ba1034d488814bbbb6e7d06d17e33322d Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Wed, 16 Nov 2022 09:17:52 +0100
Subject: [PATCH] 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 <kzak@redhat.com>
---
include/pty-session.h | 1 +
lib/pty-session.c | 29 +++++++++++++++++++++++++----
login-utils/su-common.c | 2 ++
term-utils/scriptlive.c | 2 ++
4 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/include/pty-session.h b/include/pty-session.h
index 09eff43..3242992 100644
--- a/include/pty-session.h
+++ b/include/pty-session.h
@@ -98,6 +98,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 6f038e1..d89dfbb 100644
--- a/lib/pty-session.c
+++ b/lib/pty-session.c
@@ -149,12 +149,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) {
@@ -198,6 +198,26 @@ int ul_pty_setup(struct ul_pty *pty)
tcsetattr(pty->slave, TCSANOW, &attrs);
}
+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;
@@ -221,8 +241,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;
}
@@ -692,6 +711,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 afd0ea8..46dc116 100644
--- a/login-utils/su-common.c
+++ b/login-utils/su-common.c
@@ -536,6 +536,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 d81712d..3e68f3c 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); /* ??? */
--
2.27.0