blob: eccc73810f36e58fa176a167c6c941279e079251 [file] [log] [blame]
Zachary Turnerb2df30d2014-10-08 20:38:41 +00001//===-- PipeWindows.cpp -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Host/windows/PipeWindows.h"
11
Oleksiy Vyalov4536c452015-02-05 16:29:12 +000012#include "llvm/ADT/SmallString.h"
13#include "llvm/Support/Process.h"
Zachary Turnerb2df30d2014-10-08 20:38:41 +000014#include "llvm/Support/raw_ostream.h"
15
16#include <fcntl.h>
17#include <io.h>
18
19#include <atomic>
20#include <string>
21
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000022using namespace lldb;
Zachary Turnerb2df30d2014-10-08 20:38:41 +000023using namespace lldb_private;
24
25namespace
26{
27std::atomic<uint32_t> g_pipe_serial(0);
28}
29
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000030PipeWindows::PipeWindows()
Zachary Turnerb2df30d2014-10-08 20:38:41 +000031{
32 m_read = INVALID_HANDLE_VALUE;
33 m_write = INVALID_HANDLE_VALUE;
34
35 m_read_fd = -1;
36 m_write_fd = -1;
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000037 ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
38 ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
Zachary Turnerb2df30d2014-10-08 20:38:41 +000039}
40
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000041PipeWindows::~PipeWindows()
Zachary Turnerb2df30d2014-10-08 20:38:41 +000042{
43 Close();
44}
45
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000046Error
47PipeWindows::CreateNew(bool child_process_inherit)
Zachary Turnerb2df30d2014-10-08 20:38:41 +000048{
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000049 // Even for anonymous pipes, we open a named pipe. This is because you cannot get
50 // overlapped i/o on Windows without using a named pipe. So we synthesize a unique
51 // name.
Zachary Turnerb2df30d2014-10-08 20:38:41 +000052 uint32_t serial = g_pipe_serial.fetch_add(1);
53 std::string pipe_name;
54 llvm::raw_string_ostream pipe_name_stream(pipe_name);
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000055 pipe_name_stream << "lldb.pipe." << ::GetCurrentProcessId() << "." << serial;
Zachary Turnerb2df30d2014-10-08 20:38:41 +000056 pipe_name_stream.flush();
57
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000058 return CreateNew(pipe_name.c_str(), child_process_inherit);
59}
60
61Error
62PipeWindows::CreateNew(llvm::StringRef name, bool child_process_inherit)
63{
64 if (name.empty())
65 return Error(ERROR_INVALID_PARAMETER, eErrorTypeWin32);
66
67 if (CanRead() || CanWrite())
68 return Error(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
69
70 std::string pipe_path = "\\\\.\\Pipe\\";
71 pipe_path.append(name);
72
73 // Always open for overlapped i/o. We implement blocking manually in Read and Write.
74 DWORD read_mode = FILE_FLAG_OVERLAPPED;
Zachary Turnerb2df30d2014-10-08 20:38:41 +000075 m_read =
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000076 ::CreateNamedPipe(pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
Zachary Turnerb2df30d2014-10-08 20:38:41 +000077 if (INVALID_HANDLE_VALUE == m_read)
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000078 return Error(::GetLastError(), eErrorTypeWin32);
Zachary Turnerb2df30d2014-10-08 20:38:41 +000079 m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000080 ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
81 m_read_overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
Zachary Turnerb2df30d2014-10-08 20:38:41 +000082
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000083 // Open the write end of the pipe.
84 Error result = OpenNamedPipe(name, child_process_inherit, false);
85 if (!result.Success())
Zachary Turnerb2df30d2014-10-08 20:38:41 +000086 {
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000087 CloseReadEndpoint();
88 return result;
Zachary Turnerb2df30d2014-10-08 20:38:41 +000089 }
Zachary Turner0b9d3ee2014-12-17 18:02:19 +000090
91 return result;
92}
93
94Error
Oleksiy Vyalov4536c452015-02-05 16:29:12 +000095PipeWindows::CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit, llvm::SmallVectorImpl<char>& name)
96{
97 llvm::SmallString<128> pipe_name;
98 Error error;
99 do {
100 pipe_name = prefix;
101 pipe_name += "-";
102 for (unsigned i = 0; i < 6; i++) {
103 pipe_name += "0123456789abcdef"[llvm::sys::Process::GetRandomNumber() & 15];
104 }
105 Error error = CreateNew(pipe_name, child_process_inherit);
106 } while (error.GetError() == ERROR_ALREADY_EXISTS);
107 if (error.Success())
108 name = pipe_name;
109 return error;
110}
111
112Error
Oleksiy Vyalov47718292015-01-14 01:31:27 +0000113PipeWindows::OpenAsReader(llvm::StringRef name, bool child_process_inherit)
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000114{
115 if (CanRead() || CanWrite())
116 return Error(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
117
118 return OpenNamedPipe(name, child_process_inherit, true);
119}
120
121Error
Oleksiy Vyalovd5f8b6a2015-01-13 23:19:40 +0000122PipeWindows::OpenAsWriterWithTimeout(llvm::StringRef name, bool child_process_inherit, const std::chrono::microseconds &timeout)
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000123{
124 if (CanRead() || CanWrite())
125 return Error(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
126
127 return OpenNamedPipe(name, child_process_inherit, false);
128}
129
130Error
131PipeWindows::OpenNamedPipe(llvm::StringRef name, bool child_process_inherit, bool is_read)
132{
133 if (name.empty())
134 return Error(ERROR_INVALID_PARAMETER, eErrorTypeWin32);
135
136 assert(is_read ? !CanRead() : !CanWrite());
137
138 SECURITY_ATTRIBUTES attributes = {0};
139 attributes.bInheritHandle = child_process_inherit;
140
141 std::string pipe_path = "\\\\.\\Pipe\\";
142 pipe_path.append(name);
143
144 if (is_read)
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000145 {
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000146 m_read = ::CreateFile(pipe_path.c_str(), GENERIC_READ, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
147 if (INVALID_HANDLE_VALUE == m_read)
148 return Error(::GetLastError(), eErrorTypeWin32);
149
150 m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
151
152 ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
153 m_read_overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000154 }
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000155 else
156 {
157 m_write = ::CreateFile(pipe_path.c_str(), GENERIC_WRITE, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
158 if (INVALID_HANDLE_VALUE == m_write)
159 return Error(::GetLastError(), eErrorTypeWin32);
160
161 m_write_fd = _open_osfhandle((intptr_t)m_write, _O_WRONLY);
162
163 ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
164 }
165
166 return Error();
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000167}
168
169int
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000170PipeWindows::GetReadFileDescriptor() const
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000171{
172 return m_read_fd;
173}
174
175int
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000176PipeWindows::GetWriteFileDescriptor() const
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000177{
178 return m_write_fd;
179}
180
181int
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000182PipeWindows::ReleaseReadFileDescriptor()
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000183{
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000184 if (!CanRead())
185 return -1;
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000186 int result = m_read_fd;
187 m_read_fd = -1;
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000188 if (m_read_overlapped.hEvent)
189 ::CloseHandle(m_read_overlapped.hEvent);
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000190 m_read = INVALID_HANDLE_VALUE;
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000191 ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000192 return result;
193}
194
195int
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000196PipeWindows::ReleaseWriteFileDescriptor()
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000197{
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000198 if (!CanWrite())
199 return -1;
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000200 int result = m_write_fd;
201 m_write_fd = -1;
202 m_write = INVALID_HANDLE_VALUE;
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000203 ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000204 return result;
205}
206
207void
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000208PipeWindows::CloseReadEndpoint()
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000209{
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000210 if (!CanRead())
211 return;
212
213 if (m_read_overlapped.hEvent)
214 ::CloseHandle(m_read_overlapped.hEvent);
215 _close(m_read_fd);
216 m_read = INVALID_HANDLE_VALUE;
217 m_read_fd = -1;
218 ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
219}
220
221void
222PipeWindows::CloseWriteEndpoint()
223{
224 if (!CanWrite())
225 return;
226
227 _close(m_write_fd);
228 m_write = INVALID_HANDLE_VALUE;
229 m_write_fd = -1;
230 ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
231}
232
233void
234PipeWindows::Close()
235{
236 CloseReadEndpoint();
237 CloseWriteEndpoint();
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000238}
239
Oleksiy Vyalovd5f8b6a2015-01-13 23:19:40 +0000240Error
241PipeWindows::Delete(llvm::StringRef name)
242{
243 return Error();
244}
245
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000246bool
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000247PipeWindows::CanRead() const
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000248{
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000249 return (m_read != INVALID_HANDLE_VALUE);
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000250}
251
252bool
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000253PipeWindows::CanWrite() const
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000254{
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000255 return (m_write != INVALID_HANDLE_VALUE);
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000256}
257
258HANDLE
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000259PipeWindows::GetReadNativeHandle()
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000260{
261 return m_read;
262}
263
264HANDLE
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000265PipeWindows::GetWriteNativeHandle()
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000266{
267 return m_write;
268}
269
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000270Error
Oleksiy Vyalovd5f8b6a2015-01-13 23:19:40 +0000271PipeWindows::ReadWithTimeout(void *buf, size_t size, const std::chrono::microseconds &duration, size_t &bytes_read)
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000272{
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000273 if (!CanRead())
274 return Error(ERROR_INVALID_HANDLE, eErrorTypeWin32);
275
276 bytes_read = 0;
277 DWORD sys_bytes_read = size;
278 BOOL result = ::ReadFile(m_read, buf, sys_bytes_read, &sys_bytes_read, &m_read_overlapped);
279 if (!result && GetLastError() != ERROR_IO_PENDING)
280 return Error(::GetLastError(), eErrorTypeWin32);
281
Oleksiy Vyalovd5f8b6a2015-01-13 23:19:40 +0000282 DWORD timeout = (duration == std::chrono::microseconds::zero()) ? INFINITE : duration.count() * 1000;
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000283 DWORD wait_result = ::WaitForSingleObject(m_read_overlapped.hEvent, timeout);
284 if (wait_result != WAIT_OBJECT_0)
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000285 {
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000286 // The operation probably failed. However, if it timed out, we need to cancel the I/O.
287 // Between the time we returned from WaitForSingleObject and the time we call CancelIoEx,
288 // the operation may complete. If that hapens, CancelIoEx will fail and return ERROR_NOT_FOUND.
289 // If that happens, the original operation should be considered to have been successful.
290 bool failed = true;
291 DWORD failure_error = ::GetLastError();
292 if (wait_result == WAIT_TIMEOUT)
293 {
294 BOOL cancel_result = CancelIoEx(m_read, &m_read_overlapped);
295 if (!cancel_result && GetLastError() == ERROR_NOT_FOUND)
296 failed = false;
297 }
298 if (failed)
299 return Error(failure_error, eErrorTypeWin32);
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000300 }
Zachary Turner0b9d3ee2014-12-17 18:02:19 +0000301
302 // Now we call GetOverlappedResult setting bWait to false, since we've already waited
303 // as long as we're willing to.
304 if (!GetOverlappedResult(m_read, &m_read_overlapped, &sys_bytes_read, FALSE))
305 return Error(::GetLastError(), eErrorTypeWin32);
306
307 bytes_read = sys_bytes_read;
308 return Error();
309}
310
311Error
312PipeWindows::Write(const void *buf, size_t num_bytes, size_t &bytes_written)
313{
314 if (!CanWrite())
315 return Error(ERROR_INVALID_HANDLE, eErrorTypeWin32);
316
317 DWORD sys_bytes_written = 0;
318 BOOL write_result = ::WriteFile(m_write, buf, num_bytes, &sys_bytes_written, &m_write_overlapped);
319 if (!write_result && GetLastError() != ERROR_IO_PENDING)
320 return Error(::GetLastError(), eErrorTypeWin32);
321
322 BOOL result = GetOverlappedResult(m_write, &m_write_overlapped, &sys_bytes_written, TRUE);
323 if (!result)
324 return Error(::GetLastError(), eErrorTypeWin32);
325 return Error();
Zachary Turnerb2df30d2014-10-08 20:38:41 +0000326}