diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp | 172 |
1 files changed, 167 insertions, 5 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp b/contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp index a4fc605019c2..28ab85d4344c 100644 --- a/contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp +++ b/contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp @@ -13,8 +13,10 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" +#include "llvm/Support/AutoConvert.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Duration.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" @@ -23,11 +25,17 @@ #include "llvm/Support/NativeFormatting.h" #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" +#include "llvm/Support/Threading.h" #include <algorithm> #include <cerrno> #include <cstdio> #include <sys/stat.h> +#ifndef _WIN32 +#include <sys/socket.h> +#include <sys/un.h> +#endif // _WIN32 + // <fcntl.h> may provide O_BINARY. #if defined(HAVE_FCNTL_H) # include <fcntl.h> @@ -58,6 +66,13 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Signals.h" #include "llvm/Support/Windows/WindowsSupport.h" +// winsock2.h must be included before afunix.h. Briefly turn off clang-format to +// avoid error. +// clang-format off +#include <winsock2.h> +#include <afunix.h> +// clang-format on +#include <io.h> #endif using namespace llvm; @@ -644,7 +659,7 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered, // Check if this is a console device. This is not equivalent to isatty. IsWindowsConsole = ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR; -#endif +#endif // _WIN32 // Get the starting position. off_t loc = ::lseek(FD, 0, SEEK_CUR); @@ -845,8 +860,7 @@ size_t raw_fd_ostream::preferred_buffer_size() const { if (IsWindowsConsole) return 0; return raw_ostream::preferred_buffer_size(); -#elif !defined(__minix) - // Minix has no st_blksize. +#else assert(FD >= 0 && "File not yet open!"); struct stat statbuf; if (fstat(FD, &statbuf) != 0) @@ -859,8 +873,6 @@ size_t raw_fd_ostream::preferred_buffer_size() const { return 0; // Return the preferred block size. return statbuf.st_blksize; -#else - return raw_ostream::preferred_buffer_size(); #endif } @@ -898,6 +910,10 @@ void raw_fd_ostream::anchor() {} raw_fd_ostream &llvm::outs() { // Set buffer settings to model stdout behavior. std::error_code EC; +#ifdef __MVS__ + EC = enableAutoConversion(STDOUT_FILENO); + assert(!EC); +#endif static raw_fd_ostream S("-", EC, sys::fs::OF_None); assert(!EC); return S; @@ -905,6 +921,10 @@ raw_fd_ostream &llvm::outs() { raw_fd_ostream &llvm::errs() { // Set standard error to be unbuffered and tied to outs() by default. +#ifdef __MVS__ + std::error_code EC = enableAutoConversion(STDERR_FILENO); + assert(!EC); +#endif static raw_fd_ostream S(STDERR_FILENO, false, true); return S; } @@ -931,6 +951,9 @@ raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC) EC = std::make_error_code(std::errc::invalid_argument); } +raw_fd_stream::raw_fd_stream(int fd, bool shouldClose) + : raw_fd_ostream(fd, shouldClose, false, OStreamKind::OK_FDStream) {} + ssize_t raw_fd_stream::read(char *Ptr, size_t Size) { assert(get_fd() >= 0 && "File already closed."); ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size); @@ -946,6 +969,145 @@ bool raw_fd_stream::classof(const raw_ostream *OS) { } //===----------------------------------------------------------------------===// +// raw_socket_stream +//===----------------------------------------------------------------------===// + +#ifdef _WIN32 +WSABalancer::WSABalancer() { + WSADATA WsaData; + ::memset(&WsaData, 0, sizeof(WsaData)); + if (WSAStartup(MAKEWORD(2, 2), &WsaData) != 0) { + llvm::report_fatal_error("WSAStartup failed"); + } +} + +WSABalancer::~WSABalancer() { WSACleanup(); } + +#endif // _WIN32 + +static std::error_code getLastSocketErrorCode() { +#ifdef _WIN32 + return std::error_code(::WSAGetLastError(), std::system_category()); +#else + return std::error_code(errno, std::system_category()); +#endif +} + +ListeningSocket::ListeningSocket(int SocketFD, StringRef SocketPath) + : FD(SocketFD), SocketPath(SocketPath) {} + +ListeningSocket::ListeningSocket(ListeningSocket &&LS) + : FD(LS.FD), SocketPath(LS.SocketPath) { + LS.FD = -1; +} + +Expected<ListeningSocket> ListeningSocket::createUnix(StringRef SocketPath, + int MaxBacklog) { + +#ifdef _WIN32 + WSABalancer _; + SOCKET MaybeWinsocket = socket(AF_UNIX, SOCK_STREAM, 0); + if (MaybeWinsocket == INVALID_SOCKET) { +#else + int MaybeWinsocket = socket(AF_UNIX, SOCK_STREAM, 0); + if (MaybeWinsocket == -1) { +#endif + return llvm::make_error<StringError>(getLastSocketErrorCode(), + "socket create failed"); + } + + struct sockaddr_un Addr; + memset(&Addr, 0, sizeof(Addr)); + Addr.sun_family = AF_UNIX; + strncpy(Addr.sun_path, SocketPath.str().c_str(), sizeof(Addr.sun_path) - 1); + + if (bind(MaybeWinsocket, (struct sockaddr *)&Addr, sizeof(Addr)) == -1) { + std::error_code Err = getLastSocketErrorCode(); + if (Err == std::errc::address_in_use) + ::close(MaybeWinsocket); + return llvm::make_error<StringError>(Err, "Bind error"); + } + if (listen(MaybeWinsocket, MaxBacklog) == -1) { + return llvm::make_error<StringError>(getLastSocketErrorCode(), + "Listen error"); + } + int UnixSocket; +#ifdef _WIN32 + UnixSocket = _open_osfhandle(MaybeWinsocket, 0); +#else + UnixSocket = MaybeWinsocket; +#endif // _WIN32 + return ListeningSocket{UnixSocket, SocketPath}; +} + +Expected<std::unique_ptr<raw_socket_stream>> ListeningSocket::accept() { + int AcceptFD; +#ifdef _WIN32 + SOCKET WinServerSock = _get_osfhandle(FD); + SOCKET WinAcceptSock = ::accept(WinServerSock, NULL, NULL); + AcceptFD = _open_osfhandle(WinAcceptSock, 0); +#else + AcceptFD = ::accept(FD, NULL, NULL); +#endif //_WIN32 + if (AcceptFD == -1) + return llvm::make_error<StringError>(getLastSocketErrorCode(), + "Accept failed"); + return std::make_unique<raw_socket_stream>(AcceptFD); +} + +ListeningSocket::~ListeningSocket() { + if (FD == -1) + return; + ::close(FD); + unlink(SocketPath.c_str()); +} + +static Expected<int> GetSocketFD(StringRef SocketPath) { +#ifdef _WIN32 + SOCKET MaybeWinsocket = socket(AF_UNIX, SOCK_STREAM, 0); + if (MaybeWinsocket == INVALID_SOCKET) { +#else + int MaybeWinsocket = socket(AF_UNIX, SOCK_STREAM, 0); + if (MaybeWinsocket == -1) { +#endif // _WIN32 + return llvm::make_error<StringError>(getLastSocketErrorCode(), + "Create socket failed"); + } + + struct sockaddr_un Addr; + memset(&Addr, 0, sizeof(Addr)); + Addr.sun_family = AF_UNIX; + strncpy(Addr.sun_path, SocketPath.str().c_str(), sizeof(Addr.sun_path) - 1); + + int status = connect(MaybeWinsocket, (struct sockaddr *)&Addr, sizeof(Addr)); + if (status == -1) { + return llvm::make_error<StringError>(getLastSocketErrorCode(), + "Connect socket failed"); + } +#ifdef _WIN32 + return _open_osfhandle(MaybeWinsocket, 0); +#else + return MaybeWinsocket; +#endif // _WIN32 +} + +raw_socket_stream::raw_socket_stream(int SocketFD) + : raw_fd_stream(SocketFD, true) {} + +Expected<std::unique_ptr<raw_socket_stream>> +raw_socket_stream::createConnectedUnix(StringRef SocketPath) { +#ifdef _WIN32 + WSABalancer _; +#endif // _WIN32 + Expected<int> FD = GetSocketFD(SocketPath); + if (!FD) + return FD.takeError(); + return std::make_unique<raw_socket_stream>(*FD); +} + +raw_socket_stream::~raw_socket_stream() {} + +//===----------------------------------------------------------------------===// // raw_string_ostream //===----------------------------------------------------------------------===// |