Commit ef536b41 by Janne Blomqvist

libfortran/90038 Reap dead children when wait=.false.

When using posix_spawn or fork to launch a child process, the parent
needs to wait for the child, otherwise the dead child is left as a
zombie process. For this purpose one can install a signal handler for
SIGCHLD.

2019-05-19  Janne Blomqvist  <jb@gcc.gnu.org>

	PR libfortran/90038
	* intrinsics/execute_command_line (sigchld_handler): New function.
        (execute_command_line): Install handler for SIGCHLD.
        * configure.ac: Check for presence of sigaction and waitpid.
        * config.h.in: Regenerated.
        * configure: Regenerated.

Regtested on x86_64-pc-linux-gnu.

From-SVN: r271384
parent dbd5df2e
2019-05-19 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/90038
* intrinsics/execute_command_line (sigchld_handler): New function.
(execute_command_line): Install handler for SIGCHLD.
* configure.ac: Check for presence of sigaction and waitpid.
* config.h.in: Regenerated.
* configure: Regenerated.
2019-05-17 Janne Blomqvist <jb@gcc.gnu.org> 2019-05-17 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/90038 PR libfortran/90038
......
...@@ -666,6 +666,9 @@ ...@@ -666,6 +666,9 @@
/* Define to 1 if you have the `setmode' function. */ /* Define to 1 if you have the `setmode' function. */
#undef HAVE_SETMODE #undef HAVE_SETMODE
/* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGACTION
/* Define to 1 if you have the `sin' function. */ /* Define to 1 if you have the `sin' function. */
#undef HAVE_SIN #undef HAVE_SIN
...@@ -831,6 +834,9 @@ ...@@ -831,6 +834,9 @@
/* Define to 1 if you have the `vsnprintf' function. */ /* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF #undef HAVE_VSNPRINTF
/* Define to 1 if you have the `waitpid' function. */
#undef HAVE_WAITPID
/* Define if target has a reliable stat. */ /* Define if target has a reliable stat. */
#undef HAVE_WORKING_STAT #undef HAVE_WORKING_STAT
......
...@@ -2638,6 +2638,8 @@ as_fn_append ac_func_list " link" ...@@ -2638,6 +2638,8 @@ as_fn_append ac_func_list " link"
as_fn_append ac_func_list " symlink" as_fn_append ac_func_list " symlink"
as_fn_append ac_func_list " sleep" as_fn_append ac_func_list " sleep"
as_fn_append ac_func_list " ttyname" as_fn_append ac_func_list " ttyname"
as_fn_append ac_func_list " sigaction"
as_fn_append ac_func_list " waitpid"
as_fn_append ac_func_list " alarm" as_fn_append ac_func_list " alarm"
as_fn_append ac_func_list " access" as_fn_append ac_func_list " access"
as_fn_append ac_func_list " fork" as_fn_append ac_func_list " fork"
...@@ -12698,7 +12700,7 @@ else ...@@ -12698,7 +12700,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 12701 "configure" #line 12703 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
...@@ -12804,7 +12806,7 @@ else ...@@ -12804,7 +12806,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 12807 "configure" #line 12809 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
...@@ -16976,6 +16978,10 @@ done ...@@ -16976,6 +16978,10 @@ done
fi fi
# Check strerror_r, cannot be above as versions with two and three arguments exist # Check strerror_r, cannot be above as versions with two and three arguments exist
......
...@@ -314,7 +314,7 @@ if test "${hardwire_newlib:-0}" -eq 1; then ...@@ -314,7 +314,7 @@ if test "${hardwire_newlib:-0}" -eq 1; then
else else
AC_CHECK_FUNCS_ONCE(getrusage times mkstemp strtof strtold snprintf \ AC_CHECK_FUNCS_ONCE(getrusage times mkstemp strtof strtold snprintf \
ftruncate chsize chdir getentropy getlogin gethostname kill link symlink \ ftruncate chsize chdir getentropy getlogin gethostname kill link symlink \
sleep ttyname \ sleep ttyname sigaction waitpid \
alarm access fork posix_spawn setmode fcntl writev \ alarm access fork posix_spawn setmode fcntl writev \
gettimeofday stat fstat lstat getpwuid vsnprintf dup \ gettimeofday stat fstat lstat getpwuid vsnprintf dup \
getcwd localtime_r gmtime_r getpwuid_r ttyname_r clock_gettime \ getcwd localtime_r gmtime_r getpwuid_r ttyname_r clock_gettime \
......
...@@ -36,6 +36,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -36,6 +36,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <spawn.h> #include <spawn.h>
extern char **environ; extern char **environ;
#endif #endif
#if defined(HAVE_POSIX_SPAWN) || defined(HAVE_FORK)
#include <signal.h>
#endif
enum { EXEC_SYNCHRONOUS = -2, EXEC_NOERROR = 0, EXEC_SYSTEMFAILED, enum { EXEC_SYNCHRONOUS = -2, EXEC_NOERROR = 0, EXEC_SYSTEMFAILED,
EXEC_CHILDFAILED, EXEC_INVALIDCOMMAND }; EXEC_CHILDFAILED, EXEC_INVALIDCOMMAND };
...@@ -62,6 +65,14 @@ set_cmdstat (int *cmdstat, int value) ...@@ -62,6 +65,14 @@ set_cmdstat (int *cmdstat, int value)
} }
#if defined(HAVE_WAITPID) && defined(HAVE_SIGACTION)
static void
sigchld_handler (int signum __attribute__((unused)))
{
while (waitpid ((pid_t)(-1), NULL, WNOHANG) > 0) {}
}
#endif
static void static void
execute_command_line (const char *command, bool wait, int *exitstat, execute_command_line (const char *command, bool wait, int *exitstat,
int *cmdstat, char *cmdmsg, int *cmdstat, char *cmdmsg,
...@@ -82,6 +93,20 @@ execute_command_line (const char *command, bool wait, int *exitstat, ...@@ -82,6 +93,20 @@ execute_command_line (const char *command, bool wait, int *exitstat,
set_cmdstat (cmdstat, EXEC_NOERROR); set_cmdstat (cmdstat, EXEC_NOERROR);
#if defined(HAVE_SIGACTION) && defined(HAVE_WAITPID)
static bool sig_init_saved;
bool sig_init = __atomic_load_n (&sig_init_saved, __ATOMIC_RELAXED);
if (!sig_init)
{
struct sigaction sa;
sa.sa_handler = &sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
sigaction(SIGCHLD, &sa, 0);
__atomic_store_n (&sig_init_saved, true, __ATOMIC_RELAXED);
}
#endif
#ifdef HAVE_POSIX_SPAWN #ifdef HAVE_POSIX_SPAWN
const char * const argv[] = {"sh", "-c", cmd, NULL}; const char * const argv[] = {"sh", "-c", cmd, NULL};
if (posix_spawn (&pid, "/bin/sh", NULL, NULL, if (posix_spawn (&pid, "/bin/sh", NULL, NULL,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment