Mercurial > hg > CbC > CbC_gcc
comparison libgfortran/intrinsics/execute_command_line.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Implementation of the EXECUTE_COMMAND_LINE intrinsic. | 1 /* Implementation of the EXECUTE_COMMAND_LINE intrinsic. |
2 Copyright (C) 2009-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2009-2020 Free Software Foundation, Inc. |
3 Contributed by François-Xavier Coudert. | 3 Contributed by François-Xavier Coudert. |
4 | 4 |
5 This file is part of the GNU Fortran runtime library (libgfortran). | 5 This file is part of the GNU Fortran runtime library (libgfortran). |
6 | 6 |
7 Libgfortran is free software; you can redistribute it and/or modify it under | 7 Libgfortran is free software; you can redistribute it and/or modify it under |
30 #include <unistd.h> | 30 #include <unistd.h> |
31 #endif | 31 #endif |
32 #ifdef HAVE_SYS_WAIT_H | 32 #ifdef HAVE_SYS_WAIT_H |
33 #include <sys/wait.h> | 33 #include <sys/wait.h> |
34 #endif | 34 #endif |
35 | 35 #ifdef HAVE_POSIX_SPAWN |
36 #include <spawn.h> | |
37 extern char **environ; | |
38 #endif | |
39 #if defined(HAVE_POSIX_SPAWN) || defined(HAVE_FORK) | |
40 #include <signal.h> | |
41 #endif | |
36 | 42 |
37 enum { EXEC_SYNCHRONOUS = -2, EXEC_NOERROR = 0, EXEC_SYSTEMFAILED, | 43 enum { EXEC_SYNCHRONOUS = -2, EXEC_NOERROR = 0, EXEC_SYSTEMFAILED, |
38 EXEC_CHILDFAILED, EXEC_INVALIDCOMMAND }; | 44 EXEC_CHILDFAILED, EXEC_INVALIDCOMMAND }; |
39 static const char *cmdmsg_values[] = | 45 static const char *cmdmsg_values[] = |
40 { "", | 46 { "", |
57 runtime_error ("%s", msg); | 63 runtime_error ("%s", msg); |
58 } | 64 } |
59 } | 65 } |
60 | 66 |
61 | 67 |
68 #if defined(HAVE_WAITPID) && defined(HAVE_SIGACTION) | |
69 static void | |
70 sigchld_handler (int signum __attribute__((unused))) | |
71 { | |
72 while (waitpid ((pid_t)(-1), NULL, WNOHANG) > 0) {} | |
73 } | |
74 #endif | |
75 | |
62 static void | 76 static void |
63 execute_command_line (const char *command, bool wait, int *exitstat, | 77 execute_command_line (const char *command, bool wait, int *exitstat, |
64 int *cmdstat, char *cmdmsg, | 78 int *cmdstat, char *cmdmsg, |
65 gfc_charlen_type command_len, | 79 gfc_charlen_type command_len, |
66 gfc_charlen_type cmdmsg_len) | 80 gfc_charlen_type cmdmsg_len) |
69 char *cmd = fc_strdup (command, command_len); | 83 char *cmd = fc_strdup (command, command_len); |
70 | 84 |
71 /* Flush all I/O units before executing the command. */ | 85 /* Flush all I/O units before executing the command. */ |
72 flush_all_units(); | 86 flush_all_units(); |
73 | 87 |
74 #if defined(HAVE_FORK) | 88 #if defined(HAVE_POSIX_SPAWN) || defined(HAVE_FORK) |
75 if (!wait) | 89 if (!wait) |
76 { | 90 { |
77 /* Asynchronous execution. */ | 91 /* Asynchronous execution. */ |
78 pid_t pid; | 92 pid_t pid; |
79 | 93 |
80 set_cmdstat (cmdstat, EXEC_NOERROR); | 94 set_cmdstat (cmdstat, EXEC_NOERROR); |
81 | 95 |
96 #if defined(HAVE_SIGACTION) && defined(HAVE_WAITPID) | |
97 static bool sig_init_saved; | |
98 bool sig_init = __atomic_load_n (&sig_init_saved, __ATOMIC_RELAXED); | |
99 if (!sig_init) | |
100 { | |
101 struct sigaction sa; | |
102 sa.sa_handler = &sigchld_handler; | |
103 sigemptyset(&sa.sa_mask); | |
104 sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; | |
105 sigaction(SIGCHLD, &sa, 0); | |
106 __atomic_store_n (&sig_init_saved, true, __ATOMIC_RELAXED); | |
107 } | |
108 #endif | |
109 | |
110 #ifdef HAVE_POSIX_SPAWN | |
111 const char * const argv[] = {"sh", "-c", cmd, NULL}; | |
112 if (posix_spawn (&pid, "/bin/sh", NULL, NULL, | |
113 (char * const* restrict) argv, environ)) | |
114 set_cmdstat (cmdstat, EXEC_CHILDFAILED); | |
115 #elif defined(HAVE_FORK) | |
82 if ((pid = fork()) < 0) | 116 if ((pid = fork()) < 0) |
83 set_cmdstat (cmdstat, EXEC_CHILDFAILED); | 117 set_cmdstat (cmdstat, EXEC_CHILDFAILED); |
84 else if (pid == 0) | 118 else if (pid == 0) |
85 { | 119 { |
86 /* Child process. */ | 120 /* Child process. */ |
87 int res = system (cmd); | 121 int res = system (cmd); |
88 _exit (WIFEXITED(res) ? WEXITSTATUS(res) : res); | 122 _exit (WIFEXITED(res) ? WEXITSTATUS(res) : res); |
89 } | 123 } |
124 #endif | |
90 } | 125 } |
91 else | 126 else |
92 #endif | 127 #endif |
93 { | 128 { |
94 /* Synchronous execution. */ | 129 /* Synchronous execution. */ |
95 int res = system (cmd); | 130 int res = system (cmd); |
96 | 131 |
97 if (res == -1) | 132 if (res == -1) |
98 set_cmdstat (cmdstat, EXEC_SYSTEMFAILED); | 133 set_cmdstat (cmdstat, EXEC_SYSTEMFAILED); |
99 #ifndef HAVE_FORK | 134 #if !defined(HAVE_POSIX_SPAWN) && !defined(HAVE_FORK) |
100 else if (!wait) | 135 else if (!wait) |
101 set_cmdstat (cmdstat, EXEC_SYNCHRONOUS); | 136 set_cmdstat (cmdstat, EXEC_SYNCHRONOUS); |
102 #endif | 137 #endif |
103 else if (res == 127 || res == 126 | 138 else if (res == 127 || res == 126 |
104 #if defined(WEXITSTATUS) && defined(WIFEXITED) | 139 #if defined(WEXITSTATUS) && defined(WIFEXITED) |