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

Yi Wu via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 5 01:19:11 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);
     }
   }
----------------
yiwu0b11 wrote:

The previous logic on Win is to mark all non-zero exit status with a cmdStat=6 and cmdMsg="Invalid command line". This is probably not the best way to do it, but this is why the test didn't fail previously. 

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


More information about the llvm-commits mailing list