diff --git a/llvm/include/llvm/Support/AutoConvert.h b/llvm/include/llvm/Support/AutoConvert.h index 352493e9be25f..56ad91425bcc3 100644 --- a/llvm/include/llvm/Support/AutoConvert.h +++ b/llvm/include/llvm/Support/AutoConvert.h @@ -16,6 +16,7 @@ #ifdef __MVS__ #include <_Ccsid.h> +#endif #ifdef __cplusplus #include "llvm/Support/ErrorOr.h" #include @@ -28,9 +29,11 @@ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ + int enablezOSAutoConversion(int FD); int disablezOSAutoConversion(int FD); int restorezOSStdHandleAutoConversion(int FD); + #ifdef __cplusplus } #endif /* __cplusplus */ @@ -38,6 +41,46 @@ int restorezOSStdHandleAutoConversion(int FD); #ifdef __cplusplus namespace llvm { +inline std::error_code disableAutoConversion(int FD) { +#ifdef __MVS__ + if (::disablezOSAutoConversion(FD) == -1) + return errnoAsErrorCode(); +#endif + return std::error_code(); +} + +inline std::error_code enableAutoConversion(int FD) { +#ifdef __MVS__ + if (::enablezOSAutoConversion(FD) == -1) + return errnoAsErrorCode(); +#endif + return std::error_code(); +} + +inline std::error_code restoreStdHandleAutoConversion(int FD) { +#ifdef __MVS__ + if (::restorezOSStdHandleAutoConversion(FD) == -1) + return errnoAsErrorCode(); +#endif + return std::error_code(); +} + +inline std::error_code setFileTag(int FD, int CCSID, bool Text) { +#ifdef __MVS__ + return setzOSFileTag(FD, CCSID, Text); +#endif + return std::error_code(); +} + +inline ErrorOr needConversion(const char *FileName, const int FD = -1) { +#ifdef __MVS__ + return needzOSConversion(FileName, FD); +#endif + return false; +} + +#ifdef __MVS__ + /** \brief Disable the z/OS enhanced ASCII auto-conversion for the file * descriptor. */ @@ -63,9 +106,8 @@ ErrorOr<__ccsid_t> getzOSFileTag(const char *FileName, const int FD = -1); */ ErrorOr needzOSConversion(const char *FileName, const int FD = -1); +#endif /* __MVS__*/ } /* namespace llvm */ #endif /* __cplusplus */ -#endif /* __MVS__ */ - #endif /* LLVM_SUPPORT_AUTOCONVERT_H */ diff --git a/llvm/lib/Support/AutoConvert.cpp b/llvm/lib/Support/AutoConvert.cpp index f7918548df1d0..c69e9a8f97c0e 100644 --- a/llvm/lib/Support/AutoConvert.cpp +++ b/llvm/lib/Support/AutoConvert.cpp @@ -83,27 +83,6 @@ int enablezOSAutoConversion(int FD) { return fcntl(FD, F_CONTROL_CVT, &Query); } -std::error_code llvm::disablezOSAutoConversion(int FD) { - if (::disablezOSAutoConversion(FD) == -1) - return errnoAsErrorCode(); - - return std::error_code(); -} - -std::error_code llvm::enablezOSAutoConversion(int FD) { - if (::enablezOSAutoConversion(FD) == -1) - return errnoAsErrorCode(); - - return std::error_code(); -} - -std::error_code llvm::restorezOSStdHandleAutoConversion(int FD) { - if (::restorezOSStdHandleAutoConversion(FD) == -1) - return errnoAsErrorCode(); - - return std::error_code(); -} - std::error_code llvm::setzOSFileTag(int FD, int CCSID, bool Text) { assert((!Text || (CCSID != FT_UNTAGGED && CCSID != FT_BINARY)) && "FT_UNTAGGED and FT_BINARY are not allowed for text files"); diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp index 50f7a43cc34a7..b8fbfd21c4f28 100644 --- a/llvm/lib/Support/InitLLVM.cpp +++ b/llvm/lib/Support/InitLLVM.cpp @@ -18,18 +18,28 @@ #include "llvm/Support/Windows/WindowsSupport.h" #endif -#ifdef __MVS__ +#if defined(HAVE_UNISTD_H) #include +#else +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif +#endif void CleanupStdHandles(void *Cookie) { llvm::raw_ostream *Outs = &llvm::outs(), *Errs = &llvm::errs(); Outs->flush(); Errs->flush(); - llvm::restorezOSStdHandleAutoConversion(STDIN_FILENO); - llvm::restorezOSStdHandleAutoConversion(STDOUT_FILENO); - llvm::restorezOSStdHandleAutoConversion(STDERR_FILENO); + llvm::restoreStdHandleAutoConversion(STDIN_FILENO); + llvm::restoreStdHandleAutoConversion(STDOUT_FILENO); + llvm::restoreStdHandleAutoConversion(STDERR_FILENO); } -#endif using namespace llvm; using namespace llvm::sys; @@ -41,10 +51,10 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv, assert(!Initialized && "InitLLVM was already initialized!"); Initialized = true; #endif -#ifdef __MVS__ + // Bring stdin/stdout/stderr into a known state. sys::AddSignalHandler(CleanupStdHandles, nullptr); -#endif + if (InstallPipeSignalExitHandler) // The pipe signal handler must be installed before any other handlers are // registered. This is because the Unix \ref RegisterHandlers function does @@ -68,8 +78,8 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv, // If turning on conversion for stderr fails then the error message // may be garbled. There is no solution to this problem. - ExitOnErr(errorCodeToError(llvm::enablezOSAutoConversion(STDERR_FILENO))); - ExitOnErr(errorCodeToError(llvm::enablezOSAutoConversion(STDOUT_FILENO))); + ExitOnErr(errorCodeToError(llvm::enableAutoConversion(STDERR_FILENO))); + ExitOnErr(errorCodeToError(llvm::enableAutoConversion(STDOUT_FILENO))); #endif #ifdef _WIN32 @@ -97,8 +107,6 @@ InitLLVM::InitLLVM(int &Argc, const char **&Argv, } InitLLVM::~InitLLVM() { -#ifdef __MVS__ CleanupStdHandles(nullptr); -#endif llvm_shutdown(); } diff --git a/llvm/lib/Support/MemoryBuffer.cpp b/llvm/lib/Support/MemoryBuffer.cpp index e2044bcc4e4f0..601f11f6d23c8 100644 --- a/llvm/lib/Support/MemoryBuffer.cpp +++ b/llvm/lib/Support/MemoryBuffer.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Config/config.h" #include "llvm/Support/Alignment.h" +#include "llvm/Support/AutoConvert.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" @@ -34,9 +35,6 @@ #include #endif -#ifdef __MVS__ -#include "llvm/Support/AutoConvert.h" -#endif using namespace llvm; //===----------------------------------------------------------------------===// @@ -508,15 +506,15 @@ getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, } #ifdef __MVS__ - ErrorOr NeedConversion = needzOSConversion(Filename.str().c_str(), FD); - if (std::error_code EC = NeedConversion.getError()) + ErrorOr NeedsConversion = needConversion(Filename.str().c_str(), FD); + if (std::error_code EC = NeedsConversion.getError()) return EC; // File size may increase due to EBCDIC -> UTF-8 conversion, therefore we // cannot trust the file size and we create the memory buffer by copying // off the stream. // Note: This only works with the assumption of reading a full file (i.e, // Offset == 0 and MapSize == FileSize). Reading a file slice does not work. - if (Offset == 0 && MapSize == FileSize && *NeedConversion) + if (*NeedsConversion && Offset == 0 && MapSize == FileSize) return getMemoryBufferForStream(FD, Filename); #endif diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp index 16631a63d1921..07b99896543bd 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -894,21 +894,24 @@ void raw_fd_ostream::anchor() {} raw_fd_ostream &llvm::outs() { // Set buffer settings to model stdout behavior. std::error_code EC; -#ifdef __MVS__ - EC = enablezOSAutoConversion(STDOUT_FILENO); - assert(!EC); -#endif + + // On z/OS we need to enable auto conversion + static std::error_code EC1 = enableAutoConversion(STDOUT_FILENO); + assert(!EC1); + (void)EC1; + static raw_fd_ostream S("-", EC, sys::fs::OF_None); assert(!EC); return S; } raw_fd_ostream &llvm::errs() { - // Set standard error to be unbuffered. -#ifdef __MVS__ - std::error_code EC = enablezOSAutoConversion(STDERR_FILENO); + // On z/OS we need to enable auto conversion + static std::error_code EC = enableAutoConversion(STDERR_FILENO); assert(!EC); -#endif + (void)EC; + + // Set standard error to be unbuffered. static raw_fd_ostream S(STDERR_FILENO, false, true); return S; }