[flang-commits] [flang] [flang] Fix execute_command_line cmdstat is not set when error occurs (PR #93023)

Yi Wu via flang-commits flang-commits at lists.llvm.org
Mon Jun 10 09:33:21 PDT 2024


================
@@ -64,22 +64,40 @@ void CheckAndStoreIntToDescriptor(
 // the CMDSTAT variable is not present, error termination is initiated.
 int TerminationCheck(int status, const Descriptor *cmdstat,
     const Descriptor *cmdmsg, Terminator &terminator) {
-  if (status == -1) {
-    if (!cmdstat) {
-      terminator.Crash("Execution error with system status code: %d", status);
-    } else {
-      StoreIntToDescriptor(cmdstat, EXECL_ERR, terminator);
-      CheckAndCopyCharsToDescriptor(cmdmsg, "Execution error");
-    }
-  }
 #ifdef _WIN32
   // On WIN32 API std::system returns exit status directly
   int exitStatusVal{status};
-  if (exitStatusVal == 1) {
 #else
   int exitStatusVal{WEXITSTATUS(status)};
-  if (exitStatusVal == 127 || exitStatusVal == 126) {
+  if (exitStatusVal == 1) {
+    if (!cmdstat) {
+      terminator.Crash("General Error with exit status code: 1");
+    } else {
+      StoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator);
+      CheckAndCopyCharsToDescriptor(cmdmsg,
+          "General Error: a catch-all exit code for a variety of general "
+          "errors.");
+    }
+  } else if (exitStatusVal == 126) {
+    if (!cmdstat) {
+      terminator.Crash("Command cannot execute with exit status code: 126");
+    } else {
+      StoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator);
+      CheckAndCopyCharsToDescriptor(cmdmsg,
+          "Command cannot execute: command was found, but it could not be "
+          "executed.");
+    }
+  } else if (exitStatusVal == 127) {
+    if (!cmdstat) {
+      terminator.Crash("Command not found with exit status code: 127");
+    } else {
+      StoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator);
+      CheckAndCopyCharsToDescriptor(cmdmsg,
+          "Command not found: command was not found in the system's PATH");
+    }
+  } else
 #endif
+  if (exitStatusVal != 0) {
----------------
yi-wu-arm wrote:

Thanks a lot for your inputs, I agree that give specific `CMD_STAT` for common exit code is a good idea.

---

`exitStatusVal != 0` was meant to be a general error message, covers all other error code that wasn't specified by the if-else. Otherwise `CMD_MSG` and `CMD_STAT` would only be set if error code is 1, 126, 127.

---

>BTW, `NO_SUPPORT_ERR` seems is not used anywhere otherwise.  

On Windows
>https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/system-wsystem?view=msvc-170
>A return value of -1 indicates an error, and errno is set to one of the following values  

| Value | Description |
| --- | --- |
| E2BIG | The argument list (which is system-dependent) is too large. |
| ENOENT | The command interpreter can't be found. |
| ENOEXEC | The command-interpreter file can't be executed because the format isn't valid. |
| ENOMEM | Not enough memory is available to execute command; or available memory has been corrupted; or a non-valid block exists, which indicates that the calling process has been allocated incorrectly. |

On Linux: (`std::system` is achieved by `fork()`)
>https://man7.org/linux/man-pages/man3/system.3.html
>If a child process could not be created, or its status could not be retrieved, the return value is -1 and [errno](https://man7.org/linux/man-pages/man3/errno.3.html) is set to indicate the error.

In other words, a return code of -1 could mean `EXECL_ERR` **or** `NO_SUPPORT_ERR` based on the value of errno, thats why I used `EXECL_ERR`, for safety. On a second thought, I think it would be best to report the value of `errno` as well.


https://github.com/llvm/llvm-project/pull/93023


More information about the flang-commits mailing list