From 00119c6cb6b33161bc593947aa0991caf9d7ad65 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 11 Jun 2015 22:49:02 -0700 Subject: [PATCH] Port to Solaris 10 sparc + Sun C 5.13 * configure.ac (SETUP_SLAVE_PTY) [sol2* | unixware]: Adjust to process.c change. * src/process.c (create_process): Declare volatile variables at top level of this function, so that they're less likely to be reused later in the function in the code executed by the vforked child. Do not declare locals used only in the vforked child, as they might share memory with locals still live in the parent. Instead, use the same variables in the child as in the parent. This works around a subtle bug that causes a garbage collector crash when Emacs is built with Sun C 5.13 sparc on Solaris 10. --- configure.ac | 2 +- src/process.c | 76 ++++++++++++++++++++++++--------------------------- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/configure.ac b/configure.ac index 070b0612471..b54bd344aab 100644 --- a/configure.ac +++ b/configure.ac @@ -4420,7 +4420,7 @@ case $opsys in AC_DEFINE(FIRST_PTY_LETTER, ['z']) AC_DEFINE(PTY_NAME_SPRINTF, [strcpy (pty_name, "/dev/ptmx");]) dnl Push various streams modules onto a PTY channel. Used in process.c. - AC_DEFINE(SETUP_SLAVE_PTY, [if (ioctl (xforkin, I_PUSH, "ptem") == -1) fatal ("ioctl I_PUSH ptem"); if (ioctl (xforkin, I_PUSH, "ldterm") == -1) fatal ("ioctl I_PUSH ldterm"); if (ioctl (xforkin, I_PUSH, "ttcompat") == -1) fatal ("ioctl I_PUSH ttcompat");], [How to set up a slave PTY, if needed.]) + AC_DEFINE(SETUP_SLAVE_PTY, [if (ioctl (forkin, I_PUSH, "ptem") == -1) fatal ("ioctl I_PUSH ptem"); if (ioctl (forkin, I_PUSH, "ldterm") == -1) fatal ("ioctl I_PUSH ldterm"); if (ioctl (forkin, I_PUSH, "ttcompat") == -1) fatal ("ioctl I_PUSH ttcompat");], [How to set up a slave PTY, if needed.]) ;; esac diff --git a/src/process.c b/src/process.c index b4f979fd484..3132f19d636 100644 --- a/src/process.c +++ b/src/process.c @@ -1845,35 +1845,29 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) #ifndef WINDOWSNT /* vfork, and prevent local vars from being clobbered by the vfork. */ - { - Lisp_Object volatile current_dir_volatile = current_dir; - Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; - char **volatile new_argv_volatile = new_argv; - int volatile forkin_volatile = forkin; - int volatile forkout_volatile = forkout; - int volatile forkerr_volatile = forkerr; - struct Lisp_Process *p_volatile = p; - - pid = vfork (); - - current_dir = current_dir_volatile; - lisp_pty_name = lisp_pty_name_volatile; - new_argv = new_argv_volatile; - forkin = forkin_volatile; - forkout = forkout_volatile; - forkerr = forkerr_volatile; - p = p_volatile; - - pty_flag = p->pty_flag; - } + Lisp_Object volatile current_dir_volatile = current_dir; + Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; + char **volatile new_argv_volatile = new_argv; + int volatile forkin_volatile = forkin; + int volatile forkout_volatile = forkout; + int volatile forkerr_volatile = forkerr; + struct Lisp_Process *p_volatile = p; + + pid = vfork (); + + current_dir = current_dir_volatile; + lisp_pty_name = lisp_pty_name_volatile; + new_argv = new_argv_volatile; + forkin = forkin_volatile; + forkout = forkout_volatile; + forkerr = forkerr_volatile; + p = p_volatile; + + pty_flag = p->pty_flag; if (pid == 0) #endif /* not WINDOWSNT */ { - int xforkin = forkin; - int xforkout = forkout; - int xforkerr = forkerr; - /* Make the pty be the controlling terminal of the process. */ #ifdef HAVE_PTYS /* First, disconnect its current controlling terminal. */ @@ -1881,30 +1875,30 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) process_set_signal to fail on SGI when using a pipe. */ setsid (); /* Make the pty's terminal the controlling terminal. */ - if (pty_flag && xforkin >= 0) + if (pty_flag && forkin >= 0) { #ifdef TIOCSCTTY /* We ignore the return value because faith@cs.unc.edu says that is necessary on Linux. */ - ioctl (xforkin, TIOCSCTTY, 0); + ioctl (forkin, TIOCSCTTY, 0); #endif } #if defined (LDISC1) - if (pty_flag && xforkin >= 0) + if (pty_flag && forkin >= 0) { struct termios t; - tcgetattr (xforkin, &t); + tcgetattr (forkin, &t); t.c_lflag = LDISC1; - if (tcsetattr (xforkin, TCSANOW, &t) < 0) + if (tcsetattr (forkin, TCSANOW, &t) < 0) emacs_perror ("create_process/tcsetattr LDISC1"); } #else #if defined (NTTYDISC) && defined (TIOCSETD) - if (pty_flag && xforkin >= 0) + if (pty_flag && forkin >= 0) { /* Use new line discipline. */ int ldisc = NTTYDISC; - ioctl (xforkin, TIOCSETD, &ldisc); + ioctl (forkin, TIOCSETD, &ldisc); } #endif #endif @@ -1937,11 +1931,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) /* I wonder if emacs_close (emacs_open (SSDATA (lisp_pty_name), ...)) would work? */ - if (xforkin >= 0) - emacs_close (xforkin); - xforkout = xforkin = emacs_open (SSDATA (lisp_pty_name), O_RDWR, 0); + if (forkin >= 0) + emacs_close (forkin); + forkout = forkin = emacs_open (SSDATA (lisp_pty_name), O_RDWR, 0); - if (xforkin < 0) + if (forkin < 0) { emacs_perror (SSDATA (lisp_pty_name)); _exit (EXIT_CANCELED); @@ -1971,14 +1965,14 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) unblock_child_signal (&oldset); if (pty_flag) - child_setup_tty (xforkout); + child_setup_tty (forkout); - if (xforkerr < 0) - xforkerr = xforkout; + if (forkerr < 0) + forkerr = forkout; #ifdef WINDOWSNT - pid = child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); + pid = child_setup (forkin, forkout, forkerr, new_argv, 1, current_dir); #else /* not WINDOWSNT */ - child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); + child_setup (forkin, forkout, forkerr, new_argv, 1, current_dir); #endif /* not WINDOWSNT */ } -- 2.39.2