13
13
#include " tools.h"
14
14
#include " flang/Runtime/descriptor.h"
15
15
#include < cstdlib>
16
- #include < errno.h>
17
16
#include < future>
18
17
#include < limits>
19
-
20
18
#ifdef _WIN32
21
19
#include " flang/Common/windows-include.h"
22
20
#else
@@ -34,16 +32,13 @@ namespace Fortran::runtime {
34
32
// and the processor does not support asynchronous execution. Otherwise it is
35
33
// assigned the value 0
36
34
enum 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
47
42
};
48
43
49
44
// Override CopyCharsToDescriptor in tools.h, pass string directly
@@ -67,86 +62,24 @@ void CheckAndStoreIntToDescriptor(
67
62
68
63
// If a condition occurs that would assign a nonzero value to CMDSTAT but
69
64
// 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,
71
66
const Descriptor *cmdmsg, Terminator &terminator) {
72
- // On both Windows and Linux, errno is set when system returns -1.
73
67
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);
87
70
} 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" );
107
73
}
108
74
}
109
-
110
75
#ifdef _WIN32
111
76
// 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};
124
78
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
150
83
if (!cmdstat) {
151
84
terminator.Crash (
152
85
" Invalid command quit with exit status code: %d" , exitStatusVal);
@@ -155,26 +88,23 @@ std::int64_t TerminationCheck(std::int64_t status, const Descriptor *cmdstat,
155
88
CheckAndCopyCharsToDescriptor (cmdmsg, " Invalid command line" );
156
89
}
157
90
}
158
- #endif
159
-
160
91
#if defined(WIFSIGNALED) && defined(WTERMSIG)
161
92
if (WIFSIGNALED (status)) {
162
93
if (!cmdstat) {
163
- terminator.Crash (" Killed by signal: %d" , WTERMSIG (status));
94
+ terminator.Crash (" killed by signal: %d" , WTERMSIG (status));
164
95
} else {
165
96
StoreIntToDescriptor (cmdstat, SIGNAL_ERR, terminator);
166
- CheckAndCopyCharsToDescriptor (cmdmsg, " Killed by signal" );
97
+ CheckAndCopyCharsToDescriptor (cmdmsg, " killed by signal" );
167
98
}
168
99
}
169
100
#endif
170
-
171
101
#if defined(WIFSTOPPED) && defined(WSTOPSIG)
172
102
if (WIFSTOPPED (status)) {
173
103
if (!cmdstat) {
174
- terminator.Crash (" Stopped by signal: %d" , WSTOPSIG (status));
104
+ terminator.Crash (" stopped by signal: %d" , WSTOPSIG (status));
175
105
} else {
176
106
StoreIntToDescriptor (cmdstat, SIGNAL_ERR, terminator);
177
- CheckAndCopyCharsToDescriptor (cmdmsg, " Stopped by signal" );
107
+ CheckAndCopyCharsToDescriptor (cmdmsg, " stopped by signal" );
178
108
}
179
109
}
180
110
#endif
@@ -204,9 +134,8 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
204
134
205
135
if (wait) {
206
136
// 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)};
210
139
// If sync, assigned processor-dependent exit status. Otherwise unchanged
211
140
CheckAndStoreIntToDescriptor (exitstat, exitStatusVal, terminator);
212
141
} else {
@@ -244,7 +173,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
244
173
terminator.Crash (
245
174
" CreateProcess failed with error code: %lu." , GetLastError ());
246
175
} else {
247
- StoreIntToDescriptor (cmdstat, ASYNC_NO_SUPPORT_ERR , terminator);
176
+ StoreIntToDescriptor (cmdstat, ( uint32_t ) GetLastError () , terminator);
248
177
CheckAndCopyCharsToDescriptor (cmdmsg, " CreateProcess failed." );
249
178
}
250
179
}
@@ -272,7 +201,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
272
201
}
273
202
exit (EXIT_FAILURE);
274
203
}
275
- std:: int64_t status{std::system (newCmd)};
204
+ int status{std::system (newCmd)};
276
205
TerminationCheck (status, cmdstat, cmdmsg, terminator);
277
206
exit (status);
278
207
}
0 commit comments