summaryrefslogtreecommitdiff
path: root/src/sysdep.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2013-07-07 11:00:14 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2013-07-07 11:00:14 -0700
commit067428c1717acd28f205c2cff93f0583eb347f4c (patch)
tree5937b119187f9900840e2c1174b408e86bb8d12b /src/sysdep.c
parent9aff9b3864085addb02b699f9648e547a8c00e54 (diff)
downloademacs-067428c1717acd28f205c2cff93f0583eb347f4c.tar.gz
emacs-067428c1717acd28f205c2cff93f0583eb347f4c.tar.bz2
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)
#endif
}
- close_process_descs (); /* Close Emacs's pipes/ptys */
-
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
{
char *epwd = getenv ("PWD");
@@ -2152,6 +2150,8 @@ emacs_abort (void)
#endif
/* Open FILE for Emacs use, using open flags OFLAG and mode MODE.
+ Arrange for subprograms to not inherit the file descriptor.
+ Prefer a method that is multithread-safe, if available.
Do not fail merely because the open was interrupted by a signal.
Allow the user to quit. */
@@ -2159,8 +2159,11 @@ int
emacs_open (const char *file, int oflags, int mode)
{
int fd;
+ oflags |= O_CLOEXEC;
while ((fd = open (file, oflags, mode)) < 0 && errno == EINTR)
QUIT;
+ if (! O_CLOEXEC && 0 <= fd)
+ fcntl (fd, F_SETFD, FD_CLOEXEC);
return fd;
}
@@ -2170,10 +2173,29 @@ emacs_open (const char *file, int oflags, int mode)
FILE *
emacs_fopen (char const *file, char const *mode)
{
- FILE *fp;
- while (! (fp = fopen (file, mode)) && errno == EINTR)
- QUIT;
- return fp;
+ int fd, omode, oflags;
+ int bflag = 0;
+ char const *m = mode;
+
+ switch (*m++)
+ {
+ case 'r': omode = O_RDONLY; oflags = 0; break;
+ case 'w': omode = O_WRONLY; oflags = O_CREAT | O_TRUNC; break;
+ case 'a': omode = O_WRONLY; oflags = O_CREAT | O_APPEND; break;
+ default: emacs_abort ();
+ }
+
+ while (*m)
+ switch (*m++)
+ {
+ case '+': omode = O_RDWR; break;
+ case 'b': bflag = O_BINARY; break;
+ case 't': bflag = O_TEXT; break;
+ default: /* Ignore. */ break;
+ }
+
+ fd = emacs_open (file, omode | oflags | bflag, 0666);
+ return fd < 0 ? 0 : fdopen (fd, mode);
}
int