aboutsummaryrefslogtreecommitdiffstats
path: root/src/sysdep.c
diff options
context:
space:
mode:
authorPaul Eggert2013-07-07 11:00:14 -0700
committerPaul Eggert2013-07-07 11:00:14 -0700
commit067428c1717acd28f205c2cff93f0583eb347f4c (patch)
tree5937b119187f9900840e2c1174b408e86bb8d12b /src/sysdep.c
parent9aff9b3864085addb02b699f9648e547a8c00e54 (diff)
downloademacs-067428c1717acd28f205c2cff93f0583eb347f4c.tar.gz
emacs-067428c1717acd28f205c2cff93f0583eb347f4c.zip
Make file descriptors close-on-exec when possible.
This simplifies Emacs a bit, since it no longer needs to worry about closing file descriptors by hand in some cases. It also fixes some unlikely races. Not all such races, as libraries often open files internally without setting close-on-exec, but it's an improvement. * admin/merge-gnulib (GNULIB_MODULES): Add fcntl, pipe2. (GNULIB_TOOL_FLAGS): Avoid binary-io, close. Do not avoid fcntl. * configure.ac (mkostemp): New function to check for. (PTY_OPEN): Pass O_CLOEXEC to posix_openpt. * lib/fcntl.c, lib/getdtablesize.c, lib/pipe2.c, m4/fcntl.m4: * m4/getdtablesize.m4, m4/pipe2.m4: New files, taken from gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * nt/gnulib.mk: Remove empty gl_GNULIB_ENABLED_verify section; otherwise, gnulib-tool complains given close-on-exec changes. * nt/inc/ms-w32.h (pipe): Remove. * nt/mingw-cfg.site (ac_cv_func_fcntl, gl_cv_func_fcntl_f_dupfd_cloexec) (gl_cv_func_fcntl_f_dupfd_works, ac_cv_func_pipe2): New vars. * src/alloc.c (valid_pointer_p) [!WINDOWSNT]: * src/callproc.c (Fcall_process) [!MSDOS]: * src/emacs.c (main) [!DOS_NT]: * src/nsterm.m (ns_term_init): * src/process.c (create_process): Use 'pipe2' with O_CLOEXEC instead of 'pipe'. * src/emacs.c (Fcall_process_region) [HAVE_MKOSTEMP]: * src/filelock.c (create_lock_file) [HAVE_MKOSTEMP]: Prefer mkostemp with O_CLOEXEC to mkstemp. * src/callproc.c (relocate_fd) [!WINDOWSNT]: * src/emacs.c (main): Use F_DUPFD_CLOEXEC, not plain F_DUPFD. No need to use fcntl (..., F_SETFD, FD_CLOEXEC), since we're now using pipe2. * src/filelock.c (create_lock_file) [! HAVE_MKOSTEMP]: Make the resulting file descriptor close-on-exec. * src/lisp.h, src/lread.c, src/process.c (close_load_descs, close_process_descs): * src/lread.c (load_descriptor_list, load_descriptor_unwind): Remove; no longer needed. All uses removed. * src/process.c (SOCK_CLOEXEC): Define to 0 if not supplied by system. (close_on_exec, accept4, process_socket) [!SOCK_CLOEXEC]: New functions. (socket) [!SOCK_CLOEXEC]: Supply a substitute. (Fmake_network_process, Fnetwork_interface_list): (Fnetwork_interface_info, server_accept_connection): Make newly-created socket close-on-exec. * src/sysdep.c (emacs_open, emacs_fopen): Make new-created descriptor close-on-exec. * src/w32.c (fcntl): Support F_DUPFD_CLOEXEC well enough for Emacs. * src/w32.c, src/w32.h (pipe2): Rename from 'pipe', with new flags arg. Fixes: debbugs:14803
Diffstat (limited to 'src/sysdep.c')
-rw-r--r--src/sysdep.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/sysdep.c b/src/sysdep.c
index 91e941a2050..faca7fae461 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -543,8 +543,6 @@ sys_subshell (void)
543#endif 543#endif
544 } 544 }
545 545
546 close_process_descs (); /* Close Emacs's pipes/ptys */
547
548#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */ 546#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
549 { 547 {
550 char *epwd = getenv ("PWD"); 548 char *epwd = getenv ("PWD");
@@ -2152,6 +2150,8 @@ emacs_abort (void)
2152#endif 2150#endif
2153 2151
2154/* Open FILE for Emacs use, using open flags OFLAG and mode MODE. 2152/* Open FILE for Emacs use, using open flags OFLAG and mode MODE.
2153 Arrange for subprograms to not inherit the file descriptor.
2154 Prefer a method that is multithread-safe, if available.
2155 Do not fail merely because the open was interrupted by a signal. 2155 Do not fail merely because the open was interrupted by a signal.
2156 Allow the user to quit. */ 2156 Allow the user to quit. */
2157 2157
@@ -2159,8 +2159,11 @@ int
2159emacs_open (const char *file, int oflags, int mode) 2159emacs_open (const char *file, int oflags, int mode)
2160{ 2160{
2161 int fd; 2161 int fd;
2162 oflags |= O_CLOEXEC;
2162 while ((fd = open (file, oflags, mode)) < 0 && errno == EINTR) 2163 while ((fd = open (file, oflags, mode)) < 0 && errno == EINTR)
2163 QUIT; 2164 QUIT;
2165 if (! O_CLOEXEC && 0 <= fd)
2166 fcntl (fd, F_SETFD, FD_CLOEXEC);
2164 return fd; 2167 return fd;
2165} 2168}
2166 2169
@@ -2170,10 +2173,29 @@ emacs_open (const char *file, int oflags, int mode)
2170FILE * 2173FILE *
2171emacs_fopen (char const *file, char const *mode) 2174emacs_fopen (char const *file, char const *mode)
2172{ 2175{
2173 FILE *fp; 2176 int fd, omode, oflags;
2174 while (! (fp = fopen (file, mode)) && errno == EINTR) 2177 int bflag = 0;
2175 QUIT; 2178 char const *m = mode;
2176 return fp; 2179
2180 switch (*m++)
2181 {
2182 case 'r': omode = O_RDONLY; oflags = 0; break;
2183 case 'w': omode = O_WRONLY; oflags = O_CREAT | O_TRUNC; break;
2184 case 'a': omode = O_WRONLY; oflags = O_CREAT | O_APPEND; break;
2185 default: emacs_abort ();
2186 }
2187
2188 while (*m)
2189 switch (*m++)
2190 {
2191 case '+': omode = O_RDWR; break;
2192 case 'b': bflag = O_BINARY; break;
2193 case 't': bflag = O_TEXT; break;
2194 default: /* Ignore. */ break;
2195 }
2196
2197 fd = emacs_open (file, omode | oflags | bflag, 0666);
2198 return fd < 0 ? 0 : fdopen (fd, mode);
2177} 2199}
2178 2200
2179int 2201int