[llvm] [flang-rt] Fixes EXECUTE_COMMAND_LINE() status management and double buffering (PR #184285)

Eugene Epshteyn via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 5 06:20:59 PST 2026


================
@@ -74,62 +76,81 @@ std::int64_t TerminationCheck(std::int64_t status, const Descriptor *cmdstat,
     // On Windows, ENOENT means the command interpreter can't be found.
     // On Linux, system calls execl with filepath "/bin/sh", ENOENT means the
     // file pathname does not exist.
+    constexpr char msg[] = "Command line execution is not supported, system "
+                           "returns -1 with errno ENOENT.";
     if (errno == ENOENT) {
       if (!cmdstat) {
-        terminator.Crash("Command line execution is not supported, system "
-                         "returns -1 with errno ENOENT.");
+        terminator.Crash(msg);
       } else {
         StoreIntToDescriptor(cmdstat, NO_SUPPORT_ERR, terminator);
-        CheckAndCopyCharsToDescriptor(cmdmsg,
-            "Command line execution is not supported, system returns -1 with "
-            "errno ENOENT.");
+        CheckAndCopyCharsToDescriptor(cmdmsg, msg);
+        return status;
       }
     } else {
-      char err_buffer[30];
-      char msg[]{"Execution error with system status code: -1, errno: "};
+      char msg[256]{"Execution error with system status code: -1, errno: "};
+      // Append the output of strerror*() to the end of msg. Note that upon
+      // success, the output of strerror*() is always null-terminated.
+      size_t appendIndex = std::strlen(msg);
 #ifdef _WIN32
-      if (strerror_s(err_buffer, sizeof(err_buffer), errno) != 0)
+      if (strerror_s(msg + appendIndex, sizeof(msg) - appendIndex, errno) != 0)
 #else
-      if (strerror_r(errno, err_buffer, sizeof(err_buffer)) != 0)
+      if (strerror_r(errno, msg + appendIndex, sizeof(msg) - appendIndex) != 0)
 #endif
         terminator.Crash("errno to char msg failed.");
-      char *newMsg{static_cast<char *>(AllocateMemoryOrCrash(
-          terminator, std::strlen(msg) + std::strlen(err_buffer) + 1))};
-      std::strcat(newMsg, err_buffer);
 
       if (!cmdstat) {
-        terminator.Crash(newMsg);
+        terminator.Crash(msg);
       } else {
         StoreIntToDescriptor(cmdstat, EXECL_ERR, terminator);
-        CheckAndCopyCharsToDescriptor(cmdmsg, newMsg);
+        CheckAndCopyCharsToDescriptor(cmdmsg, msg);
+        return status;
       }
-      FreeMemory(newMsg);
     }
   }
 
-#ifdef _WIN32
-  // On WIN32 API std::system returns exit status directly
+  // On WIN32 API std::system() returns exit status directly. On other OS'es,
+  // special status codes are handled below.
   std::int64_t exitStatusVal{status};
-  if (exitStatusVal != 0) {
+#ifndef _WIN32
+
+#if defined(WIFSIGNALED) && defined(WTERMSIG)
+  if (WIFSIGNALED(status)) {
     if (!cmdstat) {
-      terminator.Crash(
-          "Invalid command quit with exit status code: %d", exitStatusVal);
+      terminator.Crash("Killed by signal: %d", WTERMSIG(status));
     } else {
-      StoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator);
-      CheckAndCopyCharsToDescriptor(cmdmsg, "Invalid command line");
+      StoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator);
+      CheckAndCopyCharsToDescriptor(cmdmsg, "Killed by signal");
+      return WTERMSIG(status);
     }
   }
----------------
eugeneepshteyn wrote:

I had one Windows buildbot fail:
```
C:/buildbot/flang-x86_64-windows/llvm-project/flang-rt/unittests/Runtime/CommandTest.cpp:415
Death test: _FortranAExecuteCommandLine( *command.get(), wait, nullptr, nullptr, cmdMsg.get())
    Result: failed to die.
 Error msg:
[  DEATH   ] 'InvalidCommand' is not recognized as an internal or external command,
[  DEATH   ] operable program or batch file.
[  DEATH   ]
```
I think I figured it out: cmd.exe returns special code 9009 for "command not found", but there's special magic to return this error code with "cmd.exe /c". A new PR is coming that should fix both "not found" and "death" issue.

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


More information about the llvm-commits mailing list