================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits