diff options
| author | Paul Eggert | 2013-07-07 11:00:14 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-07 11:00:14 -0700 |
| commit | 067428c1717acd28f205c2cff93f0583eb347f4c (patch) | |
| tree | 5937b119187f9900840e2c1174b408e86bb8d12b /src/callproc.c | |
| parent | 9aff9b3864085addb02b699f9648e547a8c00e54 (diff) | |
| download | emacs-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/callproc.c')
| -rw-r--r-- | src/callproc.c | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/src/callproc.c b/src/callproc.c index 185dc9a493e..3e70b1c2e49 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -519,7 +519,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 519 | { | 519 | { |
| 520 | #ifndef MSDOS | 520 | #ifndef MSDOS |
| 521 | int fd[2]; | 521 | int fd[2]; |
| 522 | if (pipe (fd) == -1) | 522 | if (pipe2 (fd, O_CLOEXEC) != 0) |
| 523 | { | 523 | { |
| 524 | int pipe_errno = errno; | 524 | int pipe_errno = errno; |
| 525 | emacs_close (filefd); | 525 | emacs_close (filefd); |
| @@ -1036,12 +1036,16 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1036 | memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); | 1036 | memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); |
| 1037 | coding_systems = Qt; | 1037 | coding_systems = Qt; |
| 1038 | 1038 | ||
| 1039 | #ifdef HAVE_MKSTEMP | 1039 | #if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP |
| 1040 | { | 1040 | { |
| 1041 | int fd; | 1041 | int fd; |
| 1042 | 1042 | ||
| 1043 | block_input (); | 1043 | block_input (); |
| 1044 | # ifdef HAVE_MKOSTEMP | ||
| 1045 | fd = mkostemp (tempfile, O_CLOEXEC); | ||
| 1046 | # else | ||
| 1044 | fd = mkstemp (tempfile); | 1047 | fd = mkstemp (tempfile); |
| 1048 | # endif | ||
| 1045 | unblock_input (); | 1049 | unblock_input (); |
| 1046 | if (fd == -1) | 1050 | if (fd == -1) |
| 1047 | report_file_error ("Failed to open temporary file", | 1051 | report_file_error ("Failed to open temporary file", |
| @@ -1184,15 +1188,6 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1184 | 1188 | ||
| 1185 | pid_t pid = getpid (); | 1189 | pid_t pid = getpid (); |
| 1186 | 1190 | ||
| 1187 | /* Close Emacs's descriptors that this process should not have. */ | ||
| 1188 | close_process_descs (); | ||
| 1189 | |||
| 1190 | /* DOS_NT isn't in a vfork, so if we are in the middle of load-file, | ||
| 1191 | we will lose if we call close_load_descs here. */ | ||
| 1192 | #ifndef DOS_NT | ||
| 1193 | close_load_descs (); | ||
| 1194 | #endif | ||
| 1195 | |||
| 1196 | /* Note that use of alloca is always safe here. It's obvious for systems | 1191 | /* Note that use of alloca is always safe here. It's obvious for systems |
| 1197 | that do not have true vfork or that have true (stack) alloca. | 1192 | that do not have true vfork or that have true (stack) alloca. |
| 1198 | If using vfork and C_ALLOCA (when Emacs used to include | 1193 | If using vfork and C_ALLOCA (when Emacs used to include |
| @@ -1354,9 +1349,11 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1354 | emacs_close (1); | 1349 | emacs_close (1); |
| 1355 | emacs_close (2); | 1350 | emacs_close (2); |
| 1356 | 1351 | ||
| 1352 | /* Redirect file descriptors and clear FD_CLOEXEC on the redirected ones. */ | ||
| 1357 | dup2 (in, 0); | 1353 | dup2 (in, 0); |
| 1358 | dup2 (out, 1); | 1354 | dup2 (out, 1); |
| 1359 | dup2 (err, 2); | 1355 | dup2 (err, 2); |
| 1356 | |||
| 1360 | emacs_close (in); | 1357 | emacs_close (in); |
| 1361 | if (out != in) | 1358 | if (out != in) |
| 1362 | emacs_close (out); | 1359 | emacs_close (out); |
| @@ -1394,7 +1391,7 @@ relocate_fd (int fd, int minfd) | |||
| 1394 | return fd; | 1391 | return fd; |
| 1395 | else | 1392 | else |
| 1396 | { | 1393 | { |
| 1397 | int new = fcntl (fd, F_DUPFD, minfd); | 1394 | int new = fcntl (fd, F_DUPFD_CLOEXEC, minfd); |
| 1398 | if (new == -1) | 1395 | if (new == -1) |
| 1399 | { | 1396 | { |
| 1400 | const char *message_1 = "Error while setting up child: "; | 1397 | const char *message_1 = "Error while setting up child: "; |