52
52
using namespace lldb ;
53
53
using namespace lldb_private ;
54
54
55
+ #ifdef _WIN32
56
+ const shared_fd_t SharedSocket::kInvalidFD = LLDB_INVALID_PIPE;
57
+ #else
58
+ const shared_fd_t SharedSocket::kInvalidFD = Socket::kInvalidSocketValue ;
59
+ #endif
60
+
61
+ SharedSocket::SharedSocket (Connection *conn, Status &error) {
62
+ m_fd = kInvalidFD ;
63
+
64
+ const Socket *socket =
65
+ static_cast <const Socket *>(conn->GetReadObject ().get ());
66
+ if (socket == nullptr ) {
67
+ error = Status (" invalid conn socket" );
68
+ return ;
69
+ }
70
+
71
+ #ifdef _WIN32
72
+ m_socket = socket->GetNativeSocket ();
73
+
74
+ // Create a pipe to transfer WSAPROTOCOL_INFO to the child process.
75
+ error = m_socket_pipe.CreateNew (true );
76
+ if (error.Fail ())
77
+ return ;
78
+
79
+ m_fd = m_socket_pipe.GetReadPipe ();
80
+ #else
81
+ m_fd = socket->GetNativeSocket ();
82
+ error = Status ();
83
+ #endif
84
+ }
85
+
86
+ Status SharedSocket::CompleteSending (lldb::pid_t child_pid) {
87
+ #ifdef _WIN32
88
+ // Transfer WSAPROTOCOL_INFO to the child process.
89
+ m_socket_pipe.CloseReadFileDescriptor ();
90
+
91
+ WSAPROTOCOL_INFO protocol_info;
92
+ if (::WSADuplicateSocket (m_socket, child_pid, &protocol_info) ==
93
+ SOCKET_ERROR) {
94
+ int last_error = ::WSAGetLastError ();
95
+ return Status (" WSADuplicateSocket() failed, error: %d" , last_error);
96
+ }
97
+
98
+ size_t num_bytes;
99
+ Status error =
100
+ m_socket_pipe.WriteWithTimeout (&protocol_info, sizeof (protocol_info),
101
+ std::chrono::seconds (10 ), num_bytes);
102
+ if (error.Fail ())
103
+ return error;
104
+ if (num_bytes != sizeof (protocol_info))
105
+ return Status (" WriteWithTimeout(WSAPROTOCOL_INFO) failed: %d bytes" ,
106
+ num_bytes);
107
+ #endif
108
+ return Status ();
109
+ }
110
+
111
+ Status SharedSocket::GetNativeSocket (shared_fd_t fd, NativeSocket &socket) {
112
+ #ifdef _WIN32
113
+ socket = Socket::kInvalidSocketValue ;
114
+ // Read WSAPROTOCOL_INFO from the parent process and create NativeSocket.
115
+ WSAPROTOCOL_INFO protocol_info;
116
+ {
117
+ Pipe socket_pipe (fd, LLDB_INVALID_PIPE);
118
+ size_t num_bytes;
119
+ Status error =
120
+ socket_pipe.ReadWithTimeout (&protocol_info, sizeof (protocol_info),
121
+ std::chrono::seconds (10 ), num_bytes);
122
+ if (error.Fail ())
123
+ return error;
124
+ if (num_bytes != sizeof (protocol_info)) {
125
+ return Status (
126
+ " socket_pipe.ReadWithTimeout(WSAPROTOCOL_INFO) failed: % d bytes" ,
127
+ num_bytes);
128
+ }
129
+ }
130
+ socket = ::WSASocket (FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
131
+ FROM_PROTOCOL_INFO, &protocol_info, 0 , 0 );
132
+ if (socket == INVALID_SOCKET) {
133
+ return Status (" WSASocket(FROM_PROTOCOL_INFO) failed: error %d" ,
134
+ ::WSAGetLastError ());
135
+ }
136
+ return Status ();
137
+ #else
138
+ socket = fd;
139
+ return Status ();
140
+ #endif
141
+ }
142
+
55
143
ConnectionFileDescriptor::ConnectionFileDescriptor (bool child_processes_inherit)
56
144
: Connection(), m_pipe(), m_mutex(), m_shutting_down(false ),
57
145
@@ -149,7 +237,7 @@ ConnectionFileDescriptor::Connect(llvm::StringRef path,
149
237
150
238
if (!path.empty ()) {
151
239
auto method =
152
- llvm::StringSwitch<ConnectionStatus (ConnectionFileDescriptor::*)(
240
+ llvm::StringSwitch<ConnectionStatus (ConnectionFileDescriptor:: *)(
153
241
llvm::StringRef, socket_id_callback_type, Status *)>(scheme)
154
242
.Case (" listen" , &ConnectionFileDescriptor::AcceptTCP)
155
243
.Cases (" accept" , " unix-accept" ,
@@ -162,8 +250,10 @@ ConnectionFileDescriptor::Connect(llvm::StringRef path,
162
250
.Case (" unix-connect" , &ConnectionFileDescriptor::ConnectNamedSocket)
163
251
.Case (" unix-abstract-connect" ,
164
252
&ConnectionFileDescriptor::ConnectAbstractSocket)
165
- #if LLDB_ENABLE_POSIX
253
+ #if LLDB_ENABLE_POSIX || defined(_WIN32)
166
254
.Case (" fd" , &ConnectionFileDescriptor::ConnectFD)
255
+ #endif
256
+ #if LLDB_ENABLE_POSIX
167
257
.Case (" file" , &ConnectionFileDescriptor::ConnectFile)
168
258
.Case (" serial" , &ConnectionFileDescriptor::ConnectSerialPort)
169
259
#endif
@@ -666,7 +756,23 @@ ConnectionStatus
666
756
ConnectionFileDescriptor::ConnectFD (llvm::StringRef s,
667
757
socket_id_callback_type socket_id_callback,
668
758
Status *error_ptr) {
669
- #if LLDB_ENABLE_POSIX
759
+ #ifdef _WIN32
760
+ int64_t fd = -1 ;
761
+ if (!s.getAsInteger (0 , fd)) {
762
+ // Assume we own fd.
763
+ std::unique_ptr<TCPSocket> tcp_socket =
764
+ std::make_unique<TCPSocket>((NativeSocket)fd, true , false );
765
+ m_io_sp = std::move (tcp_socket);
766
+ m_uri = s.str ();
767
+ return eConnectionStatusSuccess;
768
+ }
769
+
770
+ if (error_ptr)
771
+ error_ptr->SetErrorStringWithFormat (" invalid file descriptor: \" %s\" " ,
772
+ s.str ().c_str ());
773
+ m_io_sp.reset ();
774
+ return eConnectionStatusError;
775
+ #elif LLDB_ENABLE_POSIX
670
776
// Just passing a native file descriptor within this current process that
671
777
// is already opened (possibly from a service or other source).
672
778
int fd = -1 ;
0 commit comments