1313#include " tools.h"
1414#include " flang/Runtime/descriptor.h"
1515#include < cstdlib>
16- #include < errno.h>
1716#include < future>
1817#include < limits>
19-
2018#ifdef _WIN32
2119#include " flang/Common/windows-include.h"
2220#else
@@ -34,16 +32,13 @@ namespace Fortran::runtime {
3432// and the processor does not support asynchronous execution. Otherwise it is
3533// assigned the value 0
3634enum CMD_STAT {
37- ASYNC_NO_SUPPORT_ERR = -2 , // system returns -1 with ENOENT
38- NO_SUPPORT_ERR = -1 , // Linux setsid() returns -1
39- CMD_EXECUTED = 0 , // command executed with no error
40- FORK_ERR = 1 , // Linux fork() returns < 0
41- EXECL_ERR = 2 , // system returns -1 with other errno
42- COMMAND_EXECUTION_ERR = 3 , // exit code 1
43- COMMAND_CANNOT_EXECUTE_ERR = 4 , // Linux exit code 126
44- COMMAND_NOT_FOUND_ERR = 5 , // Linux exit code 127
45- INVALID_CL_ERR = 6 , // cover all other non-zero exit code
46- SIGNAL_ERR = 7
35+ ASYNC_NO_SUPPORT_ERR = -2 ,
36+ NO_SUPPORT_ERR = -1 ,
37+ CMD_EXECUTED = 0 ,
38+ FORK_ERR = 1 ,
39+ EXECL_ERR = 2 ,
40+ INVALID_CL_ERR = 3 ,
41+ SIGNAL_ERR = 4
4742};
4843
4944// Override CopyCharsToDescriptor in tools.h, pass string directly
@@ -67,86 +62,24 @@ void CheckAndStoreIntToDescriptor(
6762
6863// If a condition occurs that would assign a nonzero value to CMDSTAT but
6964// the CMDSTAT variable is not present, error termination is initiated.
70- std:: int64_t TerminationCheck (std:: int64_t status, const Descriptor *cmdstat,
65+ int TerminationCheck (int status, const Descriptor *cmdstat,
7166 const Descriptor *cmdmsg, Terminator &terminator) {
72- // On both Windows and Linux, errno is set when system returns -1.
7367 if (status == -1 ) {
74- // On Windows, ENOENT means the command interpreter can't be found.
75- // On Linux, system calls execl with filepath "/bin/sh", ENOENT means the
76- // file pathname does not exist.
77- if (errno == ENOENT) {
78- if (!cmdstat) {
79- terminator.Crash (" Command line execution is not supported, system "
80- " returns -1 with errno ENOENT." );
81- } else {
82- StoreIntToDescriptor (cmdstat, NO_SUPPORT_ERR, terminator);
83- CheckAndCopyCharsToDescriptor (cmdmsg,
84- " Command line execution is not supported, system returns -1 with "
85- " errno ENOENT." );
86- }
68+ if (!cmdstat) {
69+ terminator.Crash (" Execution error with system status code: %d" , status);
8770 } else {
88- char err_buffer[30 ];
89- char msg[]{" Execution error with system status code: -1, errno: " };
90- #ifdef _WIN32
91- if (strerror_s (err_buffer, sizeof (err_buffer), errno) != 0 )
92- #else
93- if (strerror_r (errno, err_buffer, sizeof (err_buffer)) != 0 )
94- #endif
95- terminator.Crash (" errno to char msg failed." );
96- char *newMsg{static_cast <char *>(AllocateMemoryOrCrash (
97- terminator, std::strlen (msg) + std::strlen (err_buffer) + 1 ))};
98- std::strcat (newMsg, err_buffer);
99-
100- if (!cmdstat) {
101- terminator.Crash (newMsg);
102- } else {
103- StoreIntToDescriptor (cmdstat, EXECL_ERR, terminator);
104- CheckAndCopyCharsToDescriptor (cmdmsg, newMsg);
105- }
106- FreeMemory (newMsg);
71+ StoreIntToDescriptor (cmdstat, EXECL_ERR, terminator);
72+ CheckAndCopyCharsToDescriptor (cmdmsg, " Execution error" );
10773 }
10874 }
109-
11075#ifdef _WIN32
11176 // On WIN32 API std::system returns exit status directly
112- std::int64_t exitStatusVal{status};
113- if (exitStatusVal != 0 ) {
114- if (!cmdstat) {
115- terminator.Crash (
116- " Invalid command quit with exit status code: %d" , exitStatusVal);
117- } else {
118- StoreIntToDescriptor (cmdstat, INVALID_CL_ERR, terminator);
119- CheckAndCopyCharsToDescriptor (cmdmsg, " Invalid command line" );
120- }
121- }
122- #else
123- std::int64_t exitStatusVal{WEXITSTATUS (status)};
77+ int exitStatusVal{status};
12478 if (exitStatusVal == 1 ) {
125- if (!cmdstat) {
126- terminator.Crash (" Command line execution failed with exit code: 1." );
127- } else {
128- StoreIntToDescriptor (cmdstat, COMMAND_EXECUTION_ERR, terminator);
129- CheckAndCopyCharsToDescriptor (
130- cmdmsg, " Command line execution failed with exit code: 1." );
131- }
132- } else if (exitStatusVal == 126 ) {
133- if (!cmdstat) {
134- terminator.Crash (" Command cannot be executed with exit code: 126." );
135- } else {
136- StoreIntToDescriptor (cmdstat, COMMAND_CANNOT_EXECUTE_ERR, terminator);
137- CheckAndCopyCharsToDescriptor (
138- cmdmsg, " Command cannot be executed with exit code: 126." );
139- }
140- } else if (exitStatusVal == 127 ) {
141- if (!cmdstat) {
142- terminator.Crash (" Command not found with exit code: 127." );
143- } else {
144- StoreIntToDescriptor (cmdstat, COMMAND_NOT_FOUND_ERR, terminator);
145- CheckAndCopyCharsToDescriptor (
146- cmdmsg, " Command not found with exit code: 127." );
147- }
148- // capture all other nonzero exit code
149- } else if (exitStatusVal != 0 ) {
79+ #else
80+ int exitStatusVal{WEXITSTATUS (status)};
81+ if (exitStatusVal == 127 || exitStatusVal == 126 ) {
82+ #endif
15083 if (!cmdstat) {
15184 terminator.Crash (
15285 " Invalid command quit with exit status code: %d" , exitStatusVal);
@@ -155,26 +88,23 @@ std::int64_t TerminationCheck(std::int64_t status, const Descriptor *cmdstat,
15588 CheckAndCopyCharsToDescriptor (cmdmsg, " Invalid command line" );
15689 }
15790 }
158- #endif
159-
16091#if defined(WIFSIGNALED) && defined(WTERMSIG)
16192 if (WIFSIGNALED (status)) {
16293 if (!cmdstat) {
163- terminator.Crash (" Killed by signal: %d" , WTERMSIG (status));
94+ terminator.Crash (" killed by signal: %d" , WTERMSIG (status));
16495 } else {
16596 StoreIntToDescriptor (cmdstat, SIGNAL_ERR, terminator);
166- CheckAndCopyCharsToDescriptor (cmdmsg, " Killed by signal" );
97+ CheckAndCopyCharsToDescriptor (cmdmsg, " killed by signal" );
16798 }
16899 }
169100#endif
170-
171101#if defined(WIFSTOPPED) && defined(WSTOPSIG)
172102 if (WIFSTOPPED (status)) {
173103 if (!cmdstat) {
174- terminator.Crash (" Stopped by signal: %d" , WSTOPSIG (status));
104+ terminator.Crash (" stopped by signal: %d" , WSTOPSIG (status));
175105 } else {
176106 StoreIntToDescriptor (cmdstat, SIGNAL_ERR, terminator);
177- CheckAndCopyCharsToDescriptor (cmdmsg, " Stopped by signal" );
107+ CheckAndCopyCharsToDescriptor (cmdmsg, " stopped by signal" );
178108 }
179109 }
180110#endif
@@ -204,9 +134,8 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
204134
205135 if (wait) {
206136 // either wait is not specified or wait is true: synchronous mode
207- std::int64_t status{std::system (newCmd)};
208- std::int64_t exitStatusVal{
209- TerminationCheck (status, cmdstat, cmdmsg, terminator)};
137+ int status{std::system (newCmd)};
138+ int exitStatusVal{TerminationCheck (status, cmdstat, cmdmsg, terminator)};
210139 // If sync, assigned processor-dependent exit status. Otherwise unchanged
211140 CheckAndStoreIntToDescriptor (exitstat, exitStatusVal, terminator);
212141 } else {
@@ -244,7 +173,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
244173 terminator.Crash (
245174 " CreateProcess failed with error code: %lu." , GetLastError ());
246175 } else {
247- StoreIntToDescriptor (cmdstat, ASYNC_NO_SUPPORT_ERR , terminator);
176+ StoreIntToDescriptor (cmdstat, ( uint32_t ) GetLastError () , terminator);
248177 CheckAndCopyCharsToDescriptor (cmdmsg, " CreateProcess failed." );
249178 }
250179 }
@@ -272,7 +201,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
272201 }
273202 exit (EXIT_FAILURE);
274203 }
275- std:: int64_t status{std::system (newCmd)};
204+ int status{std::system (newCmd)};
276205 TerminationCheck (status, cmdstat, cmdmsg, terminator);
277206 exit (status);
278207 }
0 commit comments