[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