]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
llib/pty-session: split PTY and signalfd setup
authorKarel Zak <kzak@redhat.com>
Wed, 16 Nov 2022 08:17:52 +0000 (09:17 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 16 Nov 2022 08:17:52 +0000 (09:17 +0100)
In some cases applications need to use PTY before signalfd is enabled.

Signed-off-by: Karel Zak <kzak@redhat.com>
include/pty-session.h
lib/pty-session.c
login-utils/su-common.c
term-utils/scriptlive.c

index 7176d6ba729ac25e9aa0927a05775280830b4f4d..bece863f5c51652f7da49d27f28ead952fc90b73 100644 (file)
@@ -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);
index 360adb6f37a2d77abcd48ed320fd83a2a0b5311a..3849065475f88b7ba44ac84a98b093497bb8b154 100644 (file)
@@ -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);                 /* ??? */
 
index 3021b88bc0acd67971c7a96c97b16a483a936883..6f30c607f0204292a96d7e4d9eaa9f34f2e7f884 100644 (file)
@@ -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);                 /* ??? */
index d81712d36f6dac4d7968bb5aa997286c60549af5..3e68f3c067fcb50c9357d3d6bedb30c70e88e56e 100644 (file)
@@ -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);                 /* ??? */