[flang] [clang] [clang-tools-extra] [llvm] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)

Dan McGregor via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 10 11:39:03 PST 2024


================
@@ -0,0 +1,206 @@
+//===-- runtime/execute.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Runtime/execute.h"
+#include "environment.h"
+#include "stat.h"
+#include "terminator.h"
+#include "tools.h"
+#include "flang/Runtime/descriptor.h"
+#include <cstdlib>
+#include <future>
+#include <limits>
+#ifdef _WIN32
+#define LEAN_AND_MEAN
+#define NOMINMAX
+#include <windows.h>
+#else
+#include <signal.h>
+#include <unistd.h>
+#endif
+
+namespace Fortran::runtime {
+
+// cmdstat specified in 16.9.73
+// −1 if the processor does not support command line execution,
+// a processor-dependent positive value if an error condition occurs
+// −2 if no error condition occurs but WAIT is present with the value false
+// and the processor does not support asynchronous execution. Otherwise it is
+// assigned the value 0
+enum CMD_STAT {
+  ASYNC_NO_SUPPORT_ERR = -2,
+  NO_SUPPORT_ERR = -1,
+  CMD_EXECUTED = 0,
+  FORK_ERR = 1,
+  EXECL_ERR = 2,
+  INVALID_CL_ERR = 3,
+  SIGNAL_ERR = 4
+};
+
+// Override CopyCharsToDescriptor in tools.h, pass string directly
+void CopyCharsToDescriptor(const Descriptor &value, const char *rawValue) {
+  CopyCharsToDescriptor(value, rawValue, std::strlen(rawValue));
+}
+
+void CheckAndCopyCharsToDescriptor(
+    const Descriptor *value, const char *rawValue) {
+  if (value) {
+    CopyCharsToDescriptor(*value, rawValue);
+  }
+}
+
+void CheckAndStoreIntToDescriptor(
+    const Descriptor *intVal, std::int64_t value, Terminator &terminator) {
+  if (intVal) {
+    StoreIntToDescriptor(intVal, value, terminator);
+  }
+}
+
+// If a condition occurs that would assign a nonzero value to CMDSTAT but
+// 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 {
+      CheckAndStoreIntToDescriptor(cmdstat, EXECL_ERR, terminator);
+      CopyCharsToDescriptor(*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)};
----------------
dankm wrote:

Linux defines WEXITSTATUS in stdlib.h (and therefore cstdlib), but at least FreeBSD and NetBSD require including sys/wait.h.

It should be harmless to always include sys/wait.h, so I'd suggest doing that.

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


More information about the cfe-commits mailing list