summaryrefslogtreecommitdiff
path: root/m4
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 /m4
parent9aff9b3864085addb02b699f9648e547a8c00e54 (diff)
downloademacs-067428c1717acd28f205c2cff93f0583eb347f4c.tar.gz
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 'm4')
-rw-r--r--m4/fcntl.m495
-rw-r--r--m4/getdtablesize.m417
-rw-r--r--m4/gnulib-comp.m450
-rw-r--r--m4/pipe2.m418
4 files changed, 163 insertions, 17 deletions
diff --git a/m4/fcntl.m4 b/m4/fcntl.m4
new file mode 100644
index 00000000000..5481cae4d80
--- /dev/null
+++ b/m4/fcntl.m4
@@ -0,0 +1,95 @@
+# fcntl.m4 serial 5
+dnl Copyright (C) 2009-2013 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# For now, this module ensures that fcntl()
+# - supports F_DUPFD correctly
+# - supports or emulates F_DUPFD_CLOEXEC
+# - supports F_GETFD
+# Still to be ported to mingw:
+# - F_SETFD
+# - F_GETFL, F_SETFL
+# - F_GETOWN, F_SETOWN
+# - F_GETLK, F_SETLK, F_SETLKW
+AC_DEFUN([gl_FUNC_FCNTL],
+[
+ dnl Persuade glibc to expose F_DUPFD_CLOEXEC.
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+ AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_CHECK_FUNCS_ONCE([fcntl])
+ if test $ac_cv_func_fcntl = no; then
+ gl_REPLACE_FCNTL
+ else
+ dnl cygwin 1.5.x F_DUPFD has wrong errno, and allows negative target
+ dnl haiku alpha 2 F_DUPFD has wrong errno
+ AC_CACHE_CHECK([whether fcntl handles F_DUPFD correctly],
+ [gl_cv_func_fcntl_f_dupfd_works],
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <fcntl.h>
+#include <errno.h>
+]], [[int result = 0;
+ if (fcntl (0, F_DUPFD, -1) != -1) result |= 1;
+ if (errno != EINVAL) result |= 2;
+ return result;
+ ]])],
+ [gl_cv_func_fcntl_f_dupfd_works=yes],
+ [gl_cv_func_fcntl_f_dupfd_works=no],
+ [# Guess that it works on glibc systems
+ case $host_os in #((
+ *-gnu*) gl_cv_func_fcntl_f_dupfd_works="guessing yes";;
+ *) gl_cv_func_fcntl_f_dupfd_works="guessing no";;
+ esac])])
+ case $gl_cv_func_fcntl_f_dupfd_works in
+ *yes) ;;
+ *) gl_REPLACE_FCNTL
+ AC_DEFINE([FCNTL_DUPFD_BUGGY], [1], [Define this to 1 if F_DUPFD
+ behavior does not match POSIX]) ;;
+ esac
+
+ dnl Many systems lack F_DUPFD_CLOEXEC
+ AC_CACHE_CHECK([whether fcntl understands F_DUPFD_CLOEXEC],
+ [gl_cv_func_fcntl_f_dupfd_cloexec],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <fcntl.h>
+#ifndef F_DUPFD_CLOEXEC
+choke me
+#endif
+ ]])],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef __linux__
+/* The Linux kernel only added F_DUPFD_CLOEXEC in 2.6.24, so we always replace
+ it to support the semantics on older kernels that failed with EINVAL. */
+choke me
+#endif
+ ]])],
+ [gl_cv_func_fcntl_f_dupfd_cloexec=yes],
+ [gl_cv_func_fcntl_f_dupfd_cloexec="needs runtime check"])],
+ [gl_cv_func_fcntl_f_dupfd_cloexec=no])])
+ if test "$gl_cv_func_fcntl_f_dupfd_cloexec" != yes; then
+ gl_REPLACE_FCNTL
+ dnl No witness macro needed for this bug.
+ fi
+ fi
+ dnl Replace fcntl() for supporting the gnulib-defined fchdir() function,
+ dnl to keep fchdir's bookkeeping up-to-date.
+ m4_ifdef([gl_FUNC_FCHDIR], [
+ gl_TEST_FCHDIR
+ if test $HAVE_FCHDIR = 0; then
+ gl_REPLACE_FCNTL
+ fi
+ ])
+])
+
+AC_DEFUN([gl_REPLACE_FCNTL],
+[
+ AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
+ AC_CHECK_FUNCS_ONCE([fcntl])
+ if test $ac_cv_func_fcntl = no; then
+ HAVE_FCNTL=0
+ else
+ REPLACE_FCNTL=1
+ fi
+])
diff --git a/m4/getdtablesize.m4 b/m4/getdtablesize.m4
new file mode 100644
index 00000000000..8f04b3b8c2a
--- /dev/null
+++ b/m4/getdtablesize.m4
@@ -0,0 +1,17 @@
+# getdtablesize.m4 serial 4
+dnl Copyright (C) 2008-2013 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_GETDTABLESIZE],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ AC_CHECK_FUNCS_ONCE([getdtablesize])
+ if test $ac_cv_func_getdtablesize != yes; then
+ HAVE_GETDTABLESIZE=0
+ fi
+])
+
+# Prerequisites of lib/getdtablesize.c.
+AC_DEFUN([gl_PREREQ_GETDTABLESIZE], [:])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 344b77642b9..e813692aeaf 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -63,6 +63,7 @@ AC_DEFUN([gl_EARLY],
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
# Code from module extern-inline:
# Code from module faccessat:
+ # Code from module fcntl:
# Code from module fcntl-h:
# Code from module fdatasync:
# Code from module fdopendir:
@@ -70,6 +71,7 @@ AC_DEFUN([gl_EARLY],
# Code from module fpending:
# Code from module fstatat:
# Code from module fsync:
+ # Code from module getdtablesize:
# Code from module getgroups:
# Code from module getloadavg:
# Code from module getopt-gnu:
@@ -92,6 +94,7 @@ AC_DEFUN([gl_EARLY],
# Code from module nocrash:
# Code from module openat-h:
# Code from module pathmax:
+ # Code from module pipe2:
# Code from module pselect:
# Code from module pthread_sigmask:
# Code from module putenv:
@@ -191,6 +194,11 @@ AC_DEFUN([gl_INIT],
fi
gl_MODULE_INDICATOR([faccessat])
gl_UNISTD_MODULE_INDICATOR([faccessat])
+ gl_FUNC_FCNTL
+ if test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1; then
+ AC_LIBOBJ([fcntl])
+ fi
+ gl_FCNTL_MODULE_INDICATOR([fcntl])
gl_FCNTL_H
gl_FUNC_FDATASYNC
if test $HAVE_FDATASYNC = 0; then
@@ -273,6 +281,8 @@ AC_DEFUN([gl_INIT],
fi
gl_TIME_MODULE_INDICATOR([mktime])
gl_MULTIARCH
+ gl_FUNC_PIPE2
+ gl_UNISTD_MODULE_INDICATOR([pipe2])
gl_FUNC_PSELECT
if test $HAVE_PSELECT = 0 || test $REPLACE_PSELECT = 1; then
AC_LIBOBJ([pselect])
@@ -364,6 +374,7 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
gl_gnulib_enabled_dosname=false
gl_gnulib_enabled_euidaccess=false
+ gl_gnulib_enabled_getdtablesize=false
gl_gnulib_enabled_getgroups=false
gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false
@@ -373,7 +384,6 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_stat=false
gl_gnulib_enabled_strtoll=false
gl_gnulib_enabled_strtoull=false
- gl_gnulib_enabled_verify=false
gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false
func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b ()
{
@@ -407,6 +417,18 @@ AC_DEFUN([gl_INIT],
fi
fi
}
+ func_gl_gnulib_m4code_getdtablesize ()
+ {
+ if ! $gl_gnulib_enabled_getdtablesize; then
+ gl_FUNC_GETDTABLESIZE
+ if test $HAVE_GETDTABLESIZE = 0; then
+ AC_LIBOBJ([getdtablesize])
+ gl_PREREQ_GETDTABLESIZE
+ fi
+ gl_UNISTD_MODULE_INDICATOR([getdtablesize])
+ gl_gnulib_enabled_getdtablesize=true
+ fi
+ }
func_gl_gnulib_m4code_getgroups ()
{
if ! $gl_gnulib_enabled_getgroups; then
@@ -479,9 +501,6 @@ AC_DEFUN([gl_INIT],
if test $REPLACE_STAT = 1; then
func_gl_gnulib_m4code_pathmax
fi
- if test $REPLACE_STAT = 1; then
- func_gl_gnulib_m4code_verify
- fi
fi
}
func_gl_gnulib_m4code_strtoll ()
@@ -508,12 +527,6 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_strtoull=true
fi
}
- func_gl_gnulib_m4code_verify ()
- {
- if ! $gl_gnulib_enabled_verify; then
- gl_gnulib_enabled_verify=true
- fi
- }
func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec ()
{
if ! $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then
@@ -532,6 +545,9 @@ AC_DEFUN([gl_INIT],
if test $HAVE_FACCESSAT = 0; then
func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
fi
+ if test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1; then
+ func_gl_gnulib_m4code_getdtablesize
+ fi
if test $HAVE_FDOPENDIR = 0; then
func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b
fi
@@ -568,19 +584,14 @@ AC_DEFUN([gl_INIT],
if { test $HAVE_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; } && test $ac_cv_type_long_long_int = yes; then
func_gl_gnulib_m4code_strtoll
fi
- if test $HAVE_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; then
- func_gl_gnulib_m4code_verify
- fi
if test $ac_cv_func_strtoumax = no && test $ac_cv_type_unsigned_long_long_int = yes; then
func_gl_gnulib_m4code_strtoull
fi
- if test $ac_cv_func_strtoumax = no; then
- func_gl_gnulib_m4code_verify
- fi
m4_pattern_allow([^gl_GNULIB_ENABLED_])
AM_CONDITIONAL([gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b], [$gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b])
AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname])
AM_CONDITIONAL([gl_GNULIB_ENABLED_euidaccess], [$gl_gnulib_enabled_euidaccess])
+ AM_CONDITIONAL([gl_GNULIB_ENABLED_getdtablesize], [$gl_gnulib_enabled_getdtablesize])
AM_CONDITIONAL([gl_GNULIB_ENABLED_getgroups], [$gl_gnulib_enabled_getgroups])
AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36])
AM_CONDITIONAL([gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1], [$gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1])
@@ -590,7 +601,6 @@ AC_DEFUN([gl_INIT],
AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat])
AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll])
AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull])
- AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify])
AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec])
# End of code from modules
m4_ifval(gl_LIBSOURCES_LIST, [
@@ -764,6 +774,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/execinfo.c
lib/execinfo.in.h
lib/faccessat.c
+ lib/fcntl.c
lib/fcntl.in.h
lib/fdatasync.c
lib/fdopendir.c
@@ -776,6 +787,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/fsync.c
lib/ftoastr.c
lib/ftoastr.h
+ lib/getdtablesize.c
lib/getgroups.c
lib/getloadavg.c
lib/getopt.c
@@ -799,6 +811,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/openat-proc.c
lib/openat.h
lib/pathmax.h
+ lib/pipe2.c
lib/pselect.c
lib/pthread_sigmask.c
lib/putenv.c
@@ -870,6 +883,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/extern-inline.m4
m4/faccessat.m4
m4/fcntl-o.m4
+ m4/fcntl.m4
m4/fcntl_h.m4
m4/fdatasync.m4
m4/fdopendir.m4
@@ -877,6 +891,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/fpending.m4
m4/fstatat.m4
m4/fsync.m4
+ m4/getdtablesize.m4
m4/getgroups.m4
m4/getloadavg.m4
m4/getopt.m4
@@ -897,6 +912,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/nocrash.m4
m4/off_t.m4
m4/pathmax.m4
+ m4/pipe2.m4
m4/pselect.m4
m4/pthread_sigmask.m4
m4/putenv.m4
diff --git a/m4/pipe2.m4 b/m4/pipe2.m4
new file mode 100644
index 00000000000..6ccee105239
--- /dev/null
+++ b/m4/pipe2.m4
@@ -0,0 +1,18 @@
+# pipe2.m4 serial 2
+dnl Copyright (C) 2009-2013 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_PIPE2],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+
+ dnl Persuade glibc <unistd.h> to declare pipe2().
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_CHECK_FUNCS_ONCE([pipe2])
+ if test $ac_cv_func_pipe2 != yes; then
+ HAVE_PIPE2=0
+ fi
+])