From: Janne Blomqvist Date: Fri, 17 May 2019 18:18:04 +0000 (+0300) Subject: libfortran/90038: Use posix_spawn instead of fork X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f888603842067252f8a9d14eaa9d070ae7b00662;p=gcc.git libfortran/90038: Use posix_spawn instead of fork fork() semantics can be problematic. Most unix style OS'es have posix_spawn which can be used to replace fork + exec in many cases. For more information see e.g. https://www.microsoft.com/en-us/research/uploads/prod/2019/04/fork-hotos19.pdf This replaces the one use of fork in libgfortran with posix_spawn. 2019-05-17 Janne Blomqvist PR libfortran/90038 * configure.ac (AC_CHECK_FUNCS_ONCE): Check for posix_spawn. * intrinsics/execute_command_line (execute_command_line): Use posix_spawn. * Makefile.in: Regenerated. * config.h.in: Regenerated. * configure: Regenerated. Regtested on x86_64-pc-linux-gnu. From-SVN: r271340 --- diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index fa87b0d60da..e0bf369561b 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,13 @@ +2019-05-17 Janne Blomqvist + + PR libfortran/90038 + * configure.ac (AC_CHECK_FUNCS_ONCE): Check for posix_spawn. + * intrinsics/execute_command_line (execute_command_line): Use + posix_spawn. + * Makefile.in: Regenerated. + * config.h.in: Regenerated. + * configure: Regenerated. + 2019-05-17 Jakub Jelinek PR fortran/54613 diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in index 954f9feb1ea..6e9612df8ba 100644 --- a/libgfortran/Makefile.in +++ b/libgfortran/Makefile.in @@ -694,6 +694,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in index cbd720a2670..da3968cb94f 100644 --- a/libgfortran/config.h.in +++ b/libgfortran/config.h.in @@ -627,6 +627,9 @@ /* Define to 1 if we have POSIX getpwuid_r which takes 5 arguments. */ #undef HAVE_POSIX_GETPWUID_R +/* Define to 1 if you have the `posix_spawn' function. */ +#undef HAVE_POSIX_SPAWN + /* Define to 1 if you have the `pow' function. */ #undef HAVE_POW diff --git a/libgfortran/configure b/libgfortran/configure index 487d8c090e2..094c7325189 100755 --- a/libgfortran/configure +++ b/libgfortran/configure @@ -780,6 +780,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -870,6 +871,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1122,6 +1124,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1259,7 +1270,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1412,6 +1423,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -2629,6 +2641,7 @@ as_fn_append ac_func_list " ttyname" as_fn_append ac_func_list " alarm" as_fn_append ac_func_list " access" as_fn_append ac_func_list " fork" +as_fn_append ac_func_list " posix_spawn" as_fn_append ac_func_list " setmode" as_fn_append ac_func_list " fcntl" as_fn_append ac_func_list " writev" @@ -12685,7 +12698,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12688 "configure" +#line 12701 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12791,7 +12804,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12794 "configure" +#line 12807 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -16040,7 +16053,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -16086,7 +16099,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -16110,7 +16123,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -16155,7 +16168,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -16179,7 +16192,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -16958,6 +16971,8 @@ done + + diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac index c06db7b1a78..8fd5a1a30a9 100644 --- a/libgfortran/configure.ac +++ b/libgfortran/configure.ac @@ -315,7 +315,7 @@ else AC_CHECK_FUNCS_ONCE(getrusage times mkstemp strtof strtold snprintf \ ftruncate chsize chdir getentropy getlogin gethostname kill link symlink \ sleep ttyname \ - alarm access fork setmode fcntl writev \ + alarm access fork posix_spawn setmode fcntl writev \ gettimeofday stat fstat lstat getpwuid vsnprintf dup \ getcwd localtime_r gmtime_r getpwuid_r ttyname_r clock_gettime \ getgid getpid getuid geteuid umask getegid \ diff --git a/libgfortran/intrinsics/execute_command_line.c b/libgfortran/intrinsics/execute_command_line.c index a234bc328b5..2ef2324b243 100644 --- a/libgfortran/intrinsics/execute_command_line.c +++ b/libgfortran/intrinsics/execute_command_line.c @@ -32,7 +32,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #ifdef HAVE_SYS_WAIT_H #include #endif - +#ifdef HAVE_POSIX_SPAWN +#include +extern char **environ; +#endif enum { EXEC_SYNCHRONOUS = -2, EXEC_NOERROR = 0, EXEC_SYSTEMFAILED, EXEC_CHILDFAILED, EXEC_INVALIDCOMMAND }; @@ -71,7 +74,7 @@ execute_command_line (const char *command, bool wait, int *exitstat, /* Flush all I/O units before executing the command. */ flush_all_units(); -#if defined(HAVE_FORK) +#if defined(HAVE_POSIX_SPAWN) || defined(HAVE_FORK) if (!wait) { /* Asynchronous execution. */ @@ -79,14 +82,21 @@ execute_command_line (const char *command, bool wait, int *exitstat, set_cmdstat (cmdstat, EXEC_NOERROR); - if ((pid = fork()) < 0) +#ifdef HAVE_POSIX_SPAWN + const char * const argv[] = {"sh", "-c", cmd, NULL}; + if (posix_spawn (&pid, "/bin/sh", NULL, NULL, + (char * const* restrict) argv, environ)) set_cmdstat (cmdstat, EXEC_CHILDFAILED); +#elif defined(HAVE_FORK) + if ((pid = fork()) < 0) + set_cmdstat (cmdstat, EXEC_CHILDFAILED); else if (pid == 0) { /* Child process. */ int res = system (cmd); _exit (WIFEXITED(res) ? WEXITSTATUS(res) : res); } +#endif } else #endif @@ -96,7 +106,7 @@ execute_command_line (const char *command, bool wait, int *exitstat, if (res == -1) set_cmdstat (cmdstat, EXEC_SYSTEMFAILED); -#ifndef HAVE_FORK +#if !defined(HAVE_POSIX_SPAWN) && !defined(HAVE_FORK) else if (!wait) set_cmdstat (cmdstat, EXEC_SYNCHRONOUS); #endif