* bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty"
[not found] <86twvjjj2c.fsf@gko.net>
@ 2015-05-12 6:08 ` Paul Eggert
2015-05-12 6:36 ` Glenn Morris
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Paul Eggert @ 2015-05-12 6:08 UTC (permalink / raw)
To: gko, 20555
[moving this to bug-gnu-emacs, so that it gets a proper bug number]
Georges Ko wrote:
> What were the changes done on Emacs 24.4 regarding subshells (or
> processes), compared to version 24.2?
Quite a few, I suspect. You can use 'diff' to find out the details....
> When compiled in the same environment, "tty" in a subshell
> (M-x shell) has different outputs:
>
> - in Emacs 24.2, "tty" outputs the tty,
> - in Emacs 24.4, "tty" outputs "not a tty".
>
> That is, if I run the command below to spawn a shell:
>
> (apply 'start-process "shell" "*shell*" "/bin/ksh" '("-i"))
>
> - in Emacs 24.2, "ps" shows the shell has a normal tty,
> - in Emacs 24.4, "ps" shows the shell has a tty with "?".
I don't observe either problem when running Emacs 24.5 under Solaris 11 x86-64
compiled with the bundled GCC (4.5.2). However, I do observe them when running
Emacs 24.5 under Solaris 10 sparc compiled with Sun C 5.13.
> I couldn't compile 24.3 due to some errors, so I don't know its behavior.
Emacs 24.3 is bundled within Solaris 11.2, for what it's worth.
If you're still running into problems, I suggest replying with details of how
you built Emacs (version of OS and compiler, 'configure' arguments, log from
'configure' and 'make', etc.).
PS. This looks a bit like Bug#9150 <http://bugs.gnu.org/9150>, but that bug was
in an older Emacs, which probably means it's independent.
^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty"
2015-05-12 6:08 ` bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty" Paul Eggert
@ 2015-05-12 6:36 ` Glenn Morris
2015-05-13 7:12 ` Georges Ko
2015-06-01 16:53 ` 白井彰
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Glenn Morris @ 2015-05-12 6:36 UTC (permalink / raw)
To: Paul Eggert; +Cc: 20555, gko
Paul Eggert wrote:
> [moving this to bug-gnu-emacs, so that it gets a proper bug number]
It already has one: http://debbugs.gnu.org/19191
^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty"
2015-05-12 6:36 ` Glenn Morris
@ 2015-05-13 7:12 ` Georges Ko
0 siblings, 0 replies; 7+ messages in thread
From: Georges Ko @ 2015-05-13 7:12 UTC (permalink / raw)
To: 20555; +Cc: okshirai
Glenn Morris <rgm@gnu.org> writes:
> Paul Eggert wrote:
>
>> [moving this to bug-gnu-emacs, so that it gets a proper bug number]
>
> It already has one: http://debbugs.gnu.org/19191
I have been able to "fix" the problem by trial and error.
On my system, the function allocate_pty (process.c) calls the macro
PTY_TTY_NAME_SPRINTF, generated in config.h, which is:
#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);
}
It turned out that grantpt(fd) returns -1, with errno = 13 (EACCES),
so -1 is returned by allocate_pty.
After checking EACCES of grantpt():
The slave pseudoterminal was opened before grantpt(), or a grantpt() was
already issued. In either case, slave pseudoterminal permissions and
ownership have already been updated. If you use grantpt() to change slave
pseudoterminal permissions, you must issue grantpt() between the master
open and the first pseudoterminal open, and grantpt() can only be issued
once.
I changed the macro to:
if ( /* grantpt_result == -1 || */ unlockpt (fd) == -1 || !(ptyname = ptsname (fd)))
and it "fixed" the problem. I'll let the experts figure out the root cause...
The diff of configure (24.5):
$ diff configure.24.5 configure.24.5.ttyfix
17105c17105
< $as_echo "#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); }" >>confdefs.h
---
> $as_echo "#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); }" >>confdefs.h
Georges
--
Georges Ko gko@gko.net 2015-05-13
^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty"
2015-05-12 6:08 ` bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty" Paul Eggert
2015-05-12 6:36 ` Glenn Morris
@ 2015-06-01 16:53 ` 白井彰
2015-06-07 18:11 ` Glenn Morris
2015-06-02 16:45 ` 白井彰
2015-06-11 23:48 ` Paul Eggert
3 siblings, 1 reply; 7+ messages in thread
From: 白井彰 @ 2015-06-01 16:53 UTC (permalink / raw)
To: 20555; +Cc: Akira Shirai
I wrote a small program my-emacs-24.5.c, and found that grantpt(fd)
returned -1 after fcntl(fd, F_SETFD, FD_CLOEXEC).
Without fcntl(fd, F_SETFD, FD_CLOEXEC), grantpt(fd) returns 0.
aaa% sh emacs-24.5/build-aux/config.guess
i386-pc-solaris2.10
aaa% ls my-emacs-24.5.c
my-emacs-24.5.c
aaa% make my-emacs-24.5 && ./my-emacs-24.5
cc -o my-emacs-24.5 my-emacs-24.5.c
call_fcntl_fd_cloexec: 1
fcntl_result: 0
fd: 3
grantpt_result: -1
errno: 13
grantpt: Permission denied
aaa% make my-emacs-24.5 && ./my-emacs-24.5 call_fcntl_fd_cloexec=0
`my-emacs-24.5' is up to date.
call_fcntl_fd_cloexec: 0
fd: 3
grantpt_result: 0
bbb% sh emacs-24.5/build-aux/config.guess
sparc-sun-solaris2.8
bbb% rm my-emacs-24.5
bbb% make my-emacs-24.5 && ./my-emacs-24.5
cc -o my-emacs-24.5 my-emacs-24.5.c
call_fcntl_fd_cloexec: 1
fcntl_result: 0
fd: 3
grantpt_result: -1
errno: 0
grantpt: Error 0
bbb% make my-emacs-24.5 && ./my-emacs-24.5 call_fcntl_fd_cloexec=0
`my-emacs-24.5' is up to date.
call_fcntl_fd_cloexec: 0
fd: 3
grantpt_result: 0
% cat -n my-emacs-24.5.c
1 /* 24.5 */
2
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11
12 int call_fcntl_fd_cloexec;
13
14 enum { PTY_NAME_SIZE = 24 };
15
16 int emacs_open(const char *file, int oflags, int mode) {
17 #define O_CLOEXEC 0
18 int fd;
19 oflags |= O_CLOEXEC;
20 while ((fd = open(file, oflags, mode)) < 0 && errno == EINTR) abort();
21 if (! O_CLOEXEC && 0 <= fd) {
22 fprintf(stderr, "call_fcntl_fd_cloexec: %d\n", call_fcntl_fd_cloexec);
23 if (call_fcntl_fd_cloexec) {
24 int fcntl_result = fcntl(fd, F_SETFD, FD_CLOEXEC);
25 fprintf(stderr, "fcntl_result: %d\n", fcntl_result);
26 }
27 }
28 return fd;
29 }
30
31 static int allocate_pty(char pty_name[PTY_NAME_SIZE]) {
32 int fd;
33 strcpy(pty_name, "/dev/ptmx");
34 fd = emacs_open(pty_name, O_RDWR | O_NONBLOCK, 0);
35 fprintf(stderr, "fd: %d\n", fd);
36 if (fd >= 0) {
37 int grantpt_result = grantpt(fd);
38 fprintf(stderr, "grantpt_result: %d\n", grantpt_result);
39 if (grantpt_result != 0) {
40 fprintf(stderr, "errno: %d\n", errno);
41 perror("grantpt");
42 }
43 }
44 return fd;
45 }
46
47 int main(int argc, char **argv) {
48 char pty_name[PTY_NAME_SIZE];
49 if (argc == 2) call_fcntl_fd_cloexec = 0;
50 else call_fcntl_fd_cloexec = 1;
51 allocate_pty(pty_name);
52 return 0;
53 }
^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty"
2015-05-12 6:08 ` bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty" Paul Eggert
2015-05-12 6:36 ` Glenn Morris
2015-06-01 16:53 ` 白井彰
@ 2015-06-02 16:45 ` 白井彰
2015-06-11 23:48 ` Paul Eggert
3 siblings, 0 replies; 7+ messages in thread
From: 白井彰 @ 2015-06-02 16:45 UTC (permalink / raw)
To: 20555; +Cc: Akira Shirai
Today I found the same problem on Ruby:
| grantpt() doesn't work with CLOEXEC on Solaris 10
| http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=33519&view=revision
They say that Solaris grantpt() internally uses a setuid root program
/usr/lib/pt_chmod which receives an fd and calls ptsname(), chown(),
and chmod(). If FD_CLOEXEC is set for the fd, the fd passed for
/usr/lib/pt_chmod is already closed and /usr/lib/pt_chmod does not
work.
The following is their fix for the problem:
% gzcat ruby-2.2.2.tar.gz | tar tvf - | grep ruby-2.2.2/ext/pty/pty.c
-rw-r--r-- 1044/1044 22152 Nov 15 20:49 2014 ruby-2.2.2/ext/pty/pty.c
% cat -n ruby-2.2.2/ext/pty/pty.c | sed -n '221,223p;234,256p;330,341p;450p'
221 static int
222 get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, int fail)
223 {
234 #if defined(__sun) || (defined(__FreeBSD__) && __FreeBSD_version < 902000)
235 /* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */
236 /* FreeBSD 9.2 or later supports O_CLOEXEC
237 * http://www.freebsd.org/cgi/query-pr.cgi?pr=162374 */
238 if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error;
239 if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
240 if (grantpt(masterfd) == -1) goto grantpt_error;
241 rb_fd_fix_cloexec(masterfd);
242 #else
243 {
244 int flags = O_RDWR|O_NOCTTY;
245 # if defined(O_CLOEXEC)
246 /* glibc posix_openpt() in GNU/Linux calls open("/dev/ptmx", flags) internally.
247 * So version dependency on GNU/Linux is same as O_CLOEXEC with open().
248 * O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */
249 flags |= O_CLOEXEC;
250 # endif
251 if ((masterfd = posix_openpt(flags)) == -1) goto error;
252 }
253 rb_fd_fix_cloexec(masterfd);
254 if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
255 if (grantpt(masterfd) == -1) goto grantpt_error;
256 #endif
330 #if defined(__sun)
331 /* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */
332 if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
333 s = signal(SIGCHLD, SIG_DFL);
334 if(grantpt(masterfd) == -1) goto error;
335 rb_fd_fix_cloexec(masterfd);
336 #else
337 if((masterfd = rb_cloexec_open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
338 rb_update_max_fd(masterfd);
339 s = signal(SIGCHLD, SIG_DFL);
340 if(grantpt(masterfd) == -1) goto error;
341 #endif
450 }
^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty"
2015-06-01 16:53 ` 白井彰
@ 2015-06-07 18:11 ` Glenn Morris
0 siblings, 0 replies; 7+ messages in thread
From: Glenn Morris @ 2015-06-07 18:11 UTC (permalink / raw)
To: Paul Eggert; +Cc: okshirai, 20555
Paul, you are the go-to-guy for these kind of problems.
Any thoughts on
http://debbugs.gnu.org/20555#13
http://debbugs.gnu.org/20555#20
http://debbugs.gnu.org/20555#23
?
^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty"
2015-05-12 6:08 ` bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty" Paul Eggert
` (2 preceding siblings ...)
2015-06-02 16:45 ` 白井彰
@ 2015-06-11 23:48 ` Paul Eggert
3 siblings, 0 replies; 7+ messages in thread
From: Paul Eggert @ 2015-06-11 23:48 UTC (permalink / raw)
To: Akira Shirai; +Cc: Georges Ko, 20555-done, Warren, John W CIV (US)
[-- Attachment #1: Type: text/plain, Size: 234 bytes --]
Akira Shirai, thanks for the info about grantpt and its internal setuid program;
that made the problem obvious. I installed the attached patch into the Emacs
master sources and am (perhaps optimistically) marking this bug as done.
[-- Attachment #2: 0001-Fix-not-a-tty-bug-on-Solaris-10.patch --]
[-- Type: text/x-diff, Size: 3904 bytes --]
From 099cb9f7b8b1d00293298d947fc77b8c96120820 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Thu, 11 Jun 2015 16:41:36 -0700
Subject: [PATCH] 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.
---
configure.ac | 5 ++++-
src/process.c | 20 +++++++++++---------
2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/configure.ac b/configure.ac
index 9c6a74a..070b061 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4397,14 +4397,17 @@ case $opsys in
;;
sol2* )
- dnl On SysVr4, grantpt(3) forks a subprocess, so keep sigchld_handler()
+ dnl On SysVr4, grantpt(3) forks a subprocess, so do not use
+ dnl O_CLOEXEC when opening the pty, and keep the SIGCHLD handler
dnl from intercepting that death. If any child but grantpt's should die
dnl within, it should be caught after sigrelse(2).
+ AC_DEFINE(PTY_OPEN, [fd = open (pty_name, O_RDWR | O_NONBLOCK)])
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); }])
;;
unixware )
dnl Comments are as per sol2*.
+ AC_DEFINE(PTY_OPEN, [fd = open (pty_name, O_RDWR | O_NONBLOCK)])
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); }])
;;
esac
diff --git a/src/process.c b/src/process.c
index 17fe708..b4f979f 100644
--- a/src/process.c
+++ b/src/process.c
@@ -658,22 +658,24 @@ allocate_pty (char pty_name[PTY_NAME_SIZE])
if (fd >= 0)
{
-#ifdef PTY_OPEN
+#ifdef PTY_TTY_NAME_SPRINTF
+ PTY_TTY_NAME_SPRINTF
+#else
+ sprintf (pty_name, "/dev/tty%c%x", c, i);
+#endif /* no PTY_TTY_NAME_SPRINTF */
+
/* Set FD's close-on-exec flag. This is needed even if
PT_OPEN calls posix_openpt with O_CLOEXEC, since POSIX
doesn't require support for that combination.
+ Do this after PTY_TTY_NAME_SPRINTF, which on some platforms
+ doesn't work if the close-on-exec flag is set (Bug#20555).
Multithreaded platforms where posix_openpt ignores
O_CLOEXEC (or where PTY_OPEN doesn't call posix_openpt)
have a race condition between the PTY_OPEN and here. */
fcntl (fd, F_SETFD, FD_CLOEXEC);
-#endif
- /* Check to make certain that both sides are available
- this avoids a nasty yet stupid bug in rlogins. */
-#ifdef PTY_TTY_NAME_SPRINTF
- PTY_TTY_NAME_SPRINTF
-#else
- sprintf (pty_name, "/dev/tty%c%x", c, i);
-#endif /* no PTY_TTY_NAME_SPRINTF */
+
+ /* Check to make certain that both sides are available.
+ This avoids a nasty yet stupid bug in rlogins. */
if (faccessat (AT_FDCWD, pty_name, R_OK | W_OK, AT_EACCESS) != 0)
{
emacs_close (fd);
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-06-11 23:48 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <86twvjjj2c.fsf@gko.net>
2015-05-12 6:08 ` bug#20555: Emacs 24.2 vs 24.4 on Solaris: M-x shell and "tty => not a tty" Paul Eggert
2015-05-12 6:36 ` Glenn Morris
2015-05-13 7:12 ` Georges Ko
2015-06-01 16:53 ` 白井彰
2015-06-07 18:11 ` Glenn Morris
2015-06-02 16:45 ` 白井彰
2015-06-11 23:48 ` Paul Eggert
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).