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);
}
}
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)
/* 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)
DBG(LOG, ul_debug("btmp logging"));
memset(&ut, 0, sizeof(ut));
- strncpy(ut.ut_user,
+ str2memcpy(ut.ut_user,
su->pwd && su->pwd->pw_name ? su->pwd->pw_name : "(unknown)",
sizeof(ut.ut_user));
if (su->tty_number)
- xstrncpy(ut.ut_id, su->tty_number, sizeof(ut.ut_id));
+ str2memcpy(ut.ut_id, su->tty_number, sizeof(ut.ut_id));
if (su->tty_name)
- xstrncpy(ut.ut_line, su->tty_name, sizeof(ut.ut_line));
+ str2memcpy(ut.ut_line, su->tty_name, sizeof(ut.ut_line));
gettimeofday(&tv, NULL);
ut.ut_tv.tv_sec = tv.tv_sec;
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"));
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);
}
/*