16
16
#include " llvm/Support/AutoConvert.h"
17
17
#include " llvm/Support/Compiler.h"
18
18
#include " llvm/Support/Duration.h"
19
+ #include " llvm/Support/Error.h"
19
20
#include " llvm/Support/ErrorHandling.h"
20
21
#include " llvm/Support/FileSystem.h"
21
22
#include " llvm/Support/Format.h"
24
25
#include " llvm/Support/NativeFormatting.h"
25
26
#include " llvm/Support/Process.h"
26
27
#include " llvm/Support/Program.h"
28
+ #include " llvm/Support/Threading.h"
27
29
#include < algorithm>
28
30
#include < cerrno>
29
31
#include < cstdio>
30
32
#include < sys/stat.h>
31
33
34
+ #ifndef _WIN32
35
+ #include < sys/socket.h>
36
+ #include < sys/un.h>
37
+ #endif // _WIN32
38
+
32
39
// <fcntl.h> may provide O_BINARY.
33
40
#if defined(HAVE_FCNTL_H)
34
41
# include < fcntl.h>
59
66
#include " llvm/Support/ConvertUTF.h"
60
67
#include " llvm/Support/Signals.h"
61
68
#include " llvm/Support/Windows/WindowsSupport.h"
69
+ // winsock2.h must be included before afunix.h. Briefly turn off clang-format to
70
+ // avoid error.
71
+ // clang-format off
72
+ #include < winsock2.h>
73
+ #include < afunix.h>
74
+ // clang-format on
75
+ #include < io.h>
62
76
#endif
63
77
64
78
using namespace llvm ;
@@ -645,7 +659,7 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
645
659
// Check if this is a console device. This is not equivalent to isatty.
646
660
IsWindowsConsole =
647
661
::GetFileType ((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR;
648
- #endif
662
+ #endif // _WIN32
649
663
650
664
// Get the starting position.
651
665
off_t loc = ::lseek (FD, 0 , SEEK_CUR);
@@ -937,6 +951,9 @@ raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
937
951
EC = std::make_error_code (std::errc::invalid_argument);
938
952
}
939
953
954
+ raw_fd_stream::raw_fd_stream (int fd, bool shouldClose)
955
+ : raw_fd_ostream(fd, shouldClose, false , OStreamKind::OK_FDStream) {}
956
+
940
957
ssize_t raw_fd_stream::read (char *Ptr, size_t Size) {
941
958
assert (get_fd () >= 0 && " File already closed." );
942
959
ssize_t Ret = ::read (get_fd (), (void *)Ptr, Size);
@@ -951,6 +968,145 @@ bool raw_fd_stream::classof(const raw_ostream *OS) {
951
968
return OS->get_kind () == OStreamKind::OK_FDStream;
952
969
}
953
970
971
+ // ===----------------------------------------------------------------------===//
972
+ // raw_socket_stream
973
+ // ===----------------------------------------------------------------------===//
974
+
975
+ #ifdef _WIN32
976
+ WSABalancer::WSABalancer () {
977
+ WSADATA WsaData = {0 };
978
+ if (WSAStartup (MAKEWORD (2 , 2 ), &WsaData) != 0 ) {
979
+ llvm::report_fatal_error (" WSAStartup failed" );
980
+ }
981
+ }
982
+
983
+ WSABalancer::~WSABalancer () { WSACleanup (); }
984
+
985
+ #endif // _WIN32
986
+
987
+ static std::error_code getLastSocketErrorCode () {
988
+ #ifdef _WIN32
989
+ return std::error_code (::WSAGetLastError (), std::system_category ());
990
+ #else
991
+ return std::error_code (errno, std::system_category ());
992
+ #endif
993
+ }
994
+
995
+ ListeningSocket::ListeningSocket (int SocketFD, StringRef SocketPath)
996
+ : FD(SocketFD), SocketPath(SocketPath) {}
997
+
998
+ ListeningSocket::ListeningSocket (ListeningSocket &&LS)
999
+ : FD(LS.FD), SocketPath(LS.SocketPath) {
1000
+ LS.FD = -1 ;
1001
+ }
1002
+
1003
+ Expected<ListeningSocket> ListeningSocket::createUnix (StringRef SocketPath,
1004
+ int MaxBacklog) {
1005
+
1006
+ #ifdef _WIN32
1007
+ WSABalancer _;
1008
+ SOCKET MaybeWinsocket = socket (AF_UNIX, SOCK_STREAM, 0 );
1009
+ if (MaybeWinsocket == INVALID_SOCKET) {
1010
+ #else
1011
+ int MaybeWinsocket = socket (AF_UNIX, SOCK_STREAM, 0 );
1012
+ if (MaybeWinsocket == -1 ) {
1013
+ #endif
1014
+ return llvm::make_error<StringError>(getLastSocketErrorCode (),
1015
+ " socket create failed" );
1016
+ }
1017
+
1018
+ struct sockaddr_un Addr;
1019
+ memset (&Addr, 0 , sizeof (Addr));
1020
+ Addr.sun_family = AF_UNIX;
1021
+ strncpy (Addr.sun_path , SocketPath.str ().c_str (), sizeof (Addr.sun_path ) - 1 );
1022
+
1023
+ if (bind (MaybeWinsocket, (struct sockaddr *)&Addr, sizeof (Addr)) == -1 ) {
1024
+ std::error_code Err = getLastSocketErrorCode ();
1025
+ if (Err == std::errc::address_in_use)
1026
+ ::close (MaybeWinsocket);
1027
+ return llvm::make_error<StringError>(Err, " Bind error" );
1028
+ }
1029
+ if (listen (MaybeWinsocket, MaxBacklog) == -1 ) {
1030
+ return llvm::make_error<StringError>(getLastSocketErrorCode (),
1031
+ " Listen error" );
1032
+ }
1033
+ int UnixSocket;
1034
+ #ifdef _WIN32
1035
+ UnixSocket = _open_osfhandle (MaybeWinsocket, 0 );
1036
+ #else
1037
+ UnixSocket = MaybeWinsocket;
1038
+ #endif // _WIN32
1039
+ ListeningSocket ListenSocket (UnixSocket, SocketPath);
1040
+ return ListenSocket;
1041
+ }
1042
+
1043
+ Expected<std::unique_ptr<raw_socket_stream>> ListeningSocket::accept () {
1044
+ int AcceptFD;
1045
+ #ifdef _WIN32
1046
+ SOCKET WinServerSock = _get_osfhandle (FD);
1047
+ SOCKET WinAcceptSock = ::accept (WinServerSock, NULL , NULL );
1048
+ AcceptFD = _open_osfhandle (WinAcceptSock, 0 );
1049
+ #else
1050
+ AcceptFD = ::accept (FD, NULL , NULL );
1051
+ #endif // _WIN32
1052
+ if (AcceptFD == -1 )
1053
+ return llvm::make_error<StringError>(getLastSocketErrorCode (),
1054
+ " Accept failed" );
1055
+ return std::make_unique<raw_socket_stream>(AcceptFD);
1056
+ }
1057
+
1058
+ ListeningSocket::~ListeningSocket () {
1059
+ if (FD == -1 )
1060
+ return ;
1061
+ ::close (FD);
1062
+ unlink (SocketPath.c_str ());
1063
+ }
1064
+
1065
+ static Expected<int > GetSocketFD (StringRef SocketPath) {
1066
+ #ifdef _WIN32
1067
+ SOCKET MaybeWinsocket = socket (AF_UNIX, SOCK_STREAM, 0 );
1068
+ if (MaybeWinsocket == INVALID_SOCKET) {
1069
+ #else
1070
+ int MaybeWinsocket = socket (AF_UNIX, SOCK_STREAM, 0 );
1071
+ if (MaybeWinsocket == -1 ) {
1072
+ #endif // _WIN32
1073
+ return llvm::make_error<StringError>(getLastSocketErrorCode (),
1074
+ " Create socket failed" );
1075
+ }
1076
+
1077
+ struct sockaddr_un Addr;
1078
+ memset (&Addr, 0 , sizeof (Addr));
1079
+ Addr.sun_family = AF_UNIX;
1080
+ strncpy (Addr.sun_path , SocketPath.str ().c_str (), sizeof (Addr.sun_path ) - 1 );
1081
+
1082
+ int status = connect (MaybeWinsocket, (struct sockaddr *)&Addr, sizeof (Addr));
1083
+ if (status == -1 ) {
1084
+ return llvm::make_error<StringError>(getLastSocketErrorCode (),
1085
+ " Connect socket failed" );
1086
+ }
1087
+ #ifdef _WIN32
1088
+ return _open_osfhandle (MaybeWinsocket, 0 );
1089
+ #else
1090
+ return MaybeWinsocket;
1091
+ #endif // _WIN32
1092
+ }
1093
+
1094
+ raw_socket_stream::raw_socket_stream (int SocketFD)
1095
+ : raw_fd_stream (SocketFD, true ) {}
1096
+
1097
+ Expected<std::unique_ptr<raw_socket_stream>>
1098
+ raw_socket_stream::createConnectedUnix (StringRef SocketPath) {
1099
+ #ifdef _WIN32
1100
+ WSABalancer _;
1101
+ #endif // _WIN32
1102
+ Expected<int > FD = GetSocketFD (SocketPath);
1103
+ if (!FD)
1104
+ return FD.takeError ();
1105
+ return std::make_unique<raw_socket_stream>(*FD);
1106
+ }
1107
+
1108
+ raw_socket_stream::~raw_socket_stream () {}
1109
+
954
1110
// ===----------------------------------------------------------------------===//
955
1111
// raw_string_ostream
956
1112
// ===----------------------------------------------------------------------===//
0 commit comments