diff options
| author | Paul Eggert | 2015-06-11 16:41:36 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-06-11 16:42:10 -0700 |
| commit | 32e53667a91ed479743175d5698a89b163c8be94 (patch) | |
| tree | 6f608ebc4a2e184208714fbe93bb03e6580a254e | |
| parent | 8d0efee90c0ad3b44c14b77403599cba1b168044 (diff) | |
| download | emacs-32e53667a91ed479743175d5698a89b163c8be94.tar.gz emacs-32e53667a91ed479743175d5698a89b163c8be94.zip | |
Fix "not a tty" bug on Solaris 10
* configure.ac (PTY_OPEN): Define to plain 'open'
on SVR4-derived hosts, so that the O_CLOEXEC flag isn't set.
* src/process.c (allocate_pty): Set the O_CLOEXEC flag after
calling PTY_TTY_NAME_SPRINTF, for the benefit of SVR4-derived
hosts that call grantpt which does its work via a setuid subcommand
(Bug#19191, Bug#19927, Bug#20555, Bug#20686).
Also, set O_CLOEXEC even if PTY_OPEN is not defined, since it
seems relevant in that case too.
| -rw-r--r-- | configure.ac | 5 | ||||
| -rw-r--r-- | src/process.c | 20 |
2 files changed, 15 insertions, 10 deletions
diff --git a/configure.ac b/configure.ac index 9c6a74aface..070b0612471 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -4397,14 +4397,17 @@ case $opsys in | |||
| 4397 | ;; | 4397 | ;; |
| 4398 | 4398 | ||
| 4399 | sol2* ) | 4399 | sol2* ) |
| 4400 | dnl On SysVr4, grantpt(3) forks a subprocess, so keep sigchld_handler() | 4400 | dnl On SysVr4, grantpt(3) forks a subprocess, so do not use |
| 4401 | dnl O_CLOEXEC when opening the pty, and keep the SIGCHLD handler | ||
| 4401 | dnl from intercepting that death. If any child but grantpt's should die | 4402 | dnl from intercepting that death. If any child but grantpt's should die |
| 4402 | dnl within, it should be caught after sigrelse(2). | 4403 | dnl within, it should be caught after sigrelse(2). |
| 4404 | AC_DEFINE(PTY_OPEN, [fd = open (pty_name, O_RDWR | O_NONBLOCK)]) | ||
| 4403 | AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1 || unlockpt (fd) == -1 || !(ptyname = ptsname (fd))) { emacs_close (fd); return -1; } snprintf (pty_name, PTY_NAME_SIZE, "%s", ptyname); }]) | 4405 | AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1 || unlockpt (fd) == -1 || !(ptyname = ptsname (fd))) { emacs_close (fd); return -1; } snprintf (pty_name, PTY_NAME_SIZE, "%s", ptyname); }]) |
| 4404 | ;; | 4406 | ;; |
| 4405 | 4407 | ||
| 4406 | unixware ) | 4408 | unixware ) |
| 4407 | dnl Comments are as per sol2*. | 4409 | dnl Comments are as per sol2*. |
| 4410 | AC_DEFINE(PTY_OPEN, [fd = open (pty_name, O_RDWR | O_NONBLOCK)]) | ||
| 4408 | AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, PTY_NAME_SIZE, "%s", ptyname); }]) | 4411 | AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, PTY_NAME_SIZE, "%s", ptyname); }]) |
| 4409 | ;; | 4412 | ;; |
| 4410 | esac | 4413 | esac |
diff --git a/src/process.c b/src/process.c index 17fe708a954..b4f979fd484 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -658,22 +658,24 @@ allocate_pty (char pty_name[PTY_NAME_SIZE]) | |||
| 658 | 658 | ||
| 659 | if (fd >= 0) | 659 | if (fd >= 0) |
| 660 | { | 660 | { |
| 661 | #ifdef PTY_OPEN | 661 | #ifdef PTY_TTY_NAME_SPRINTF |
| 662 | PTY_TTY_NAME_SPRINTF | ||
| 663 | #else | ||
| 664 | sprintf (pty_name, "/dev/tty%c%x", c, i); | ||
| 665 | #endif /* no PTY_TTY_NAME_SPRINTF */ | ||
| 666 | |||
| 662 | /* Set FD's close-on-exec flag. This is needed even if | 667 | /* Set FD's close-on-exec flag. This is needed even if |
| 663 | PT_OPEN calls posix_openpt with O_CLOEXEC, since POSIX | 668 | PT_OPEN calls posix_openpt with O_CLOEXEC, since POSIX |
| 664 | doesn't require support for that combination. | 669 | doesn't require support for that combination. |
| 670 | Do this after PTY_TTY_NAME_SPRINTF, which on some platforms | ||
| 671 | doesn't work if the close-on-exec flag is set (Bug#20555). | ||
| 665 | Multithreaded platforms where posix_openpt ignores | 672 | Multithreaded platforms where posix_openpt ignores |
| 666 | O_CLOEXEC (or where PTY_OPEN doesn't call posix_openpt) | 673 | O_CLOEXEC (or where PTY_OPEN doesn't call posix_openpt) |
| 667 | have a race condition between the PTY_OPEN and here. */ | 674 | have a race condition between the PTY_OPEN and here. */ |
| 668 | fcntl (fd, F_SETFD, FD_CLOEXEC); | 675 | fcntl (fd, F_SETFD, FD_CLOEXEC); |
| 669 | #endif | 676 | |
| 670 | /* Check to make certain that both sides are available | 677 | /* Check to make certain that both sides are available. |
| 671 | this avoids a nasty yet stupid bug in rlogins. */ | 678 | This avoids a nasty yet stupid bug in rlogins. */ |
| 672 | #ifdef PTY_TTY_NAME_SPRINTF | ||
| 673 | PTY_TTY_NAME_SPRINTF | ||
| 674 | #else | ||
| 675 | sprintf (pty_name, "/dev/tty%c%x", c, i); | ||
| 676 | #endif /* no PTY_TTY_NAME_SPRINTF */ | ||
| 677 | if (faccessat (AT_FDCWD, pty_name, R_OK | W_OK, AT_EACCESS) != 0) | 679 | if (faccessat (AT_FDCWD, pty_name, R_OK | W_OK, AT_EACCESS) != 0) |
| 678 | { | 680 | { |
| 679 | emacs_close (fd); | 681 | emacs_close (fd); |