diff options
| author | Paul Eggert | 2015-06-11 22:49:02 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-06-11 22:50:30 -0700 |
| commit | 00119c6cb6b33161bc593947aa0991caf9d7ad65 (patch) | |
| tree | 5f3f430b4b8cca1578700be14de36afaf908f3af /src/process.c | |
| parent | f7a381382b2468b1616e0649263c0c0e4bcf0748 (diff) | |
| download | emacs-00119c6cb6b33161bc593947aa0991caf9d7ad65.tar.gz emacs-00119c6cb6b33161bc593947aa0991caf9d7ad65.zip | |
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.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 76 |
1 files changed, 35 insertions, 41 deletions
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) | |||
| 1845 | 1845 | ||
| 1846 | #ifndef WINDOWSNT | 1846 | #ifndef WINDOWSNT |
| 1847 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 1847 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 1848 | { | 1848 | Lisp_Object volatile current_dir_volatile = current_dir; |
| 1849 | Lisp_Object volatile current_dir_volatile = current_dir; | 1849 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; |
| 1850 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; | 1850 | char **volatile new_argv_volatile = new_argv; |
| 1851 | char **volatile new_argv_volatile = new_argv; | 1851 | int volatile forkin_volatile = forkin; |
| 1852 | int volatile forkin_volatile = forkin; | 1852 | int volatile forkout_volatile = forkout; |
| 1853 | int volatile forkout_volatile = forkout; | 1853 | int volatile forkerr_volatile = forkerr; |
| 1854 | int volatile forkerr_volatile = forkerr; | 1854 | struct Lisp_Process *p_volatile = p; |
| 1855 | struct Lisp_Process *p_volatile = p; | 1855 | |
| 1856 | 1856 | pid = vfork (); | |
| 1857 | pid = vfork (); | 1857 | |
| 1858 | 1858 | current_dir = current_dir_volatile; | |
| 1859 | current_dir = current_dir_volatile; | 1859 | lisp_pty_name = lisp_pty_name_volatile; |
| 1860 | lisp_pty_name = lisp_pty_name_volatile; | 1860 | new_argv = new_argv_volatile; |
| 1861 | new_argv = new_argv_volatile; | 1861 | forkin = forkin_volatile; |
| 1862 | forkin = forkin_volatile; | 1862 | forkout = forkout_volatile; |
| 1863 | forkout = forkout_volatile; | 1863 | forkerr = forkerr_volatile; |
| 1864 | forkerr = forkerr_volatile; | 1864 | p = p_volatile; |
| 1865 | p = p_volatile; | 1865 | |
| 1866 | 1866 | pty_flag = p->pty_flag; | |
| 1867 | pty_flag = p->pty_flag; | ||
| 1868 | } | ||
| 1869 | 1867 | ||
| 1870 | if (pid == 0) | 1868 | if (pid == 0) |
| 1871 | #endif /* not WINDOWSNT */ | 1869 | #endif /* not WINDOWSNT */ |
| 1872 | { | 1870 | { |
| 1873 | int xforkin = forkin; | ||
| 1874 | int xforkout = forkout; | ||
| 1875 | int xforkerr = forkerr; | ||
| 1876 | |||
| 1877 | /* Make the pty be the controlling terminal of the process. */ | 1871 | /* Make the pty be the controlling terminal of the process. */ |
| 1878 | #ifdef HAVE_PTYS | 1872 | #ifdef HAVE_PTYS |
| 1879 | /* First, disconnect its current controlling terminal. */ | 1873 | /* First, disconnect its current controlling terminal. */ |
| @@ -1881,30 +1875,30 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1881 | process_set_signal to fail on SGI when using a pipe. */ | 1875 | process_set_signal to fail on SGI when using a pipe. */ |
| 1882 | setsid (); | 1876 | setsid (); |
| 1883 | /* Make the pty's terminal the controlling terminal. */ | 1877 | /* Make the pty's terminal the controlling terminal. */ |
| 1884 | if (pty_flag && xforkin >= 0) | 1878 | if (pty_flag && forkin >= 0) |
| 1885 | { | 1879 | { |
| 1886 | #ifdef TIOCSCTTY | 1880 | #ifdef TIOCSCTTY |
| 1887 | /* We ignore the return value | 1881 | /* We ignore the return value |
| 1888 | because faith@cs.unc.edu says that is necessary on Linux. */ | 1882 | because faith@cs.unc.edu says that is necessary on Linux. */ |
| 1889 | ioctl (xforkin, TIOCSCTTY, 0); | 1883 | ioctl (forkin, TIOCSCTTY, 0); |
| 1890 | #endif | 1884 | #endif |
| 1891 | } | 1885 | } |
| 1892 | #if defined (LDISC1) | 1886 | #if defined (LDISC1) |
| 1893 | if (pty_flag && xforkin >= 0) | 1887 | if (pty_flag && forkin >= 0) |
| 1894 | { | 1888 | { |
| 1895 | struct termios t; | 1889 | struct termios t; |
| 1896 | tcgetattr (xforkin, &t); | 1890 | tcgetattr (forkin, &t); |
| 1897 | t.c_lflag = LDISC1; | 1891 | t.c_lflag = LDISC1; |
| 1898 | if (tcsetattr (xforkin, TCSANOW, &t) < 0) | 1892 | if (tcsetattr (forkin, TCSANOW, &t) < 0) |
| 1899 | emacs_perror ("create_process/tcsetattr LDISC1"); | 1893 | emacs_perror ("create_process/tcsetattr LDISC1"); |
| 1900 | } | 1894 | } |
| 1901 | #else | 1895 | #else |
| 1902 | #if defined (NTTYDISC) && defined (TIOCSETD) | 1896 | #if defined (NTTYDISC) && defined (TIOCSETD) |
| 1903 | if (pty_flag && xforkin >= 0) | 1897 | if (pty_flag && forkin >= 0) |
| 1904 | { | 1898 | { |
| 1905 | /* Use new line discipline. */ | 1899 | /* Use new line discipline. */ |
| 1906 | int ldisc = NTTYDISC; | 1900 | int ldisc = NTTYDISC; |
| 1907 | ioctl (xforkin, TIOCSETD, &ldisc); | 1901 | ioctl (forkin, TIOCSETD, &ldisc); |
| 1908 | } | 1902 | } |
| 1909 | #endif | 1903 | #endif |
| 1910 | #endif | 1904 | #endif |
| @@ -1937,11 +1931,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1937 | 1931 | ||
| 1938 | /* I wonder if emacs_close (emacs_open (SSDATA (lisp_pty_name), ...)) | 1932 | /* I wonder if emacs_close (emacs_open (SSDATA (lisp_pty_name), ...)) |
| 1939 | would work? */ | 1933 | would work? */ |
| 1940 | if (xforkin >= 0) | 1934 | if (forkin >= 0) |
| 1941 | emacs_close (xforkin); | 1935 | emacs_close (forkin); |
| 1942 | xforkout = xforkin = emacs_open (SSDATA (lisp_pty_name), O_RDWR, 0); | 1936 | forkout = forkin = emacs_open (SSDATA (lisp_pty_name), O_RDWR, 0); |
| 1943 | 1937 | ||
| 1944 | if (xforkin < 0) | 1938 | if (forkin < 0) |
| 1945 | { | 1939 | { |
| 1946 | emacs_perror (SSDATA (lisp_pty_name)); | 1940 | emacs_perror (SSDATA (lisp_pty_name)); |
| 1947 | _exit (EXIT_CANCELED); | 1941 | _exit (EXIT_CANCELED); |
| @@ -1971,14 +1965,14 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1971 | unblock_child_signal (&oldset); | 1965 | unblock_child_signal (&oldset); |
| 1972 | 1966 | ||
| 1973 | if (pty_flag) | 1967 | if (pty_flag) |
| 1974 | child_setup_tty (xforkout); | 1968 | child_setup_tty (forkout); |
| 1975 | 1969 | ||
| 1976 | if (xforkerr < 0) | 1970 | if (forkerr < 0) |
| 1977 | xforkerr = xforkout; | 1971 | forkerr = forkout; |
| 1978 | #ifdef WINDOWSNT | 1972 | #ifdef WINDOWSNT |
| 1979 | pid = child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); | 1973 | pid = child_setup (forkin, forkout, forkerr, new_argv, 1, current_dir); |
| 1980 | #else /* not WINDOWSNT */ | 1974 | #else /* not WINDOWSNT */ |
| 1981 | child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); | 1975 | child_setup (forkin, forkout, forkerr, new_argv, 1, current_dir); |
| 1982 | #endif /* not WINDOWSNT */ | 1976 | #endif /* not WINDOWSNT */ |
| 1983 | } | 1977 | } |
| 1984 | 1978 | ||