]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - login-utils/su-common.c
mkswap: be more explicit about maximal number of pages
[thirdparty/util-linux.git] / login-utils / su-common.c
index e0604e246d8f4a7ca72415ee2275b602f08f2d27..1662d21bbac3cf82fa7432e85b715d6cd303e5a5 100644 (file)
@@ -276,29 +276,26 @@ static void pty_create(struct su_context *su)
 
        if (su->isterm) {
                DBG(PTY, ul_debug("create for terminal"));
-               struct winsize win;
 
                /* original setting of the current terminal */
                if (tcgetattr(STDIN_FILENO, &su->stdin_attrs) != 0)
                        err(EXIT_FAILURE, _("failed to get terminal attributes"));
-
-               /* reuse the current terminal setting for slave */
-               slave_attrs = su->stdin_attrs;
-               cfmakeraw(&slave_attrs);
-
                ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&su->win);
-
                /* create master+slave */
-               rc = openpty(&su->pty_master, &su->pty_slave, NULL, &slave_attrs, &win);
+               rc = openpty(&su->pty_master, &su->pty_slave, NULL, &su->stdin_attrs, &su->win);
 
+               /* set the current terminal to raw mode; pty_cleanup() reverses this change on exit */
+               slave_attrs = su->stdin_attrs;
+               cfmakeraw(&slave_attrs);
+               slave_attrs.c_lflag &= ~ECHO;
+               tcsetattr(STDIN_FILENO, TCSANOW, &slave_attrs);
        } else {
                DBG(PTY, ul_debug("create for non-terminal"));
                rc = openpty(&su->pty_master, &su->pty_slave, NULL, NULL, NULL);
 
-               /* set slave attributes */
                if (!rc) {
                        tcgetattr(su->pty_slave, &slave_attrs);
-                       cfmakeraw(&slave_attrs);
+                       slave_attrs.c_lflag &= ~ECHO;
                        tcsetattr(su->pty_slave, TCSANOW, &slave_attrs);
                }
        }
@@ -311,12 +308,14 @@ static void pty_create(struct su_context *su)
 
 static void pty_cleanup(struct su_context *su)
 {
-       if (su->pty_master == -1)
+       struct termios rtt;
+
+       if (su->pty_master == -1 || !su->isterm)
                return;
 
        DBG(PTY, ul_debug("cleanup"));
-       if (su->isterm)
-               tcsetattr(STDIN_FILENO, TCSADRAIN, &su->stdin_attrs);
+       rtt = su->stdin_attrs;
+       tcsetattr(STDIN_FILENO, TCSADRAIN, &rtt);
 }
 
 static int write_output(char *obuf, ssize_t bytes)
@@ -438,7 +437,10 @@ static int pty_handle_signal(struct su_context *su, int fd)
 
                /* The child terminated or stopped. Note that we ignore SIGCONT
                 * here, because stop/cont semantic is handled by wait_for_child() */
-               if (info.ssi_code == CLD_EXITED || info.ssi_status == SIGSTOP)
+               if (info.ssi_code == CLD_EXITED
+                   || info.ssi_code == CLD_KILLED
+                   || info.ssi_code == CLD_DUMPED
+                   || info.ssi_status == SIGSTOP)
                        wait_for_child(su);
                /* The child is dead, force poll() timeout. */
                if (su->child == (pid_t) -1)
@@ -989,8 +991,8 @@ static void setenv_path(const struct passwd *pw)
        if (pw->pw_uid)
                rc = logindefs_setenv("PATH", "ENV_PATH", _PATH_DEFPATH);
 
-       else if ((rc = logindefs_setenv("PATH", "ENV_ROOTPATH", NULL)) != 0)
-               rc = logindefs_setenv("PATH", "ENV_SUPATH", _PATH_DEFPATH_ROOT);
+       else if ((rc = logindefs_setenv("PATH", "ENV_SUPATH", NULL)) != 0)
+               rc = logindefs_setenv("PATH", "ENV_ROOTPATH", _PATH_DEFPATH_ROOT);
 
        if (rc)
                err(EXIT_FAILURE, _("failed to set the PATH environment variable"));
@@ -1229,8 +1231,8 @@ static void load_config(void *data)
        struct su_context *su = (struct su_context *) data;
 
        DBG(MISC, ul_debug("loading logindefs"));
-       logindefs_load_file(su->runuser ? _PATH_LOGINDEFS_RUNUSER : _PATH_LOGINDEFS_SU);
        logindefs_load_file(_PATH_LOGINDEFS);
+       logindefs_load_file(su->runuser ? _PATH_LOGINDEFS_RUNUSER : _PATH_LOGINDEFS_SU);
 }
 
 /*