1 /* Copyright 2016-present Facebook, Inc.
2 * Licensed under the Apache License, Version 2.0 */
3 #include "watchman.h"
4 #include "Pipe.h"
5
6 #include <system_error>
7
8 namespace watchman {
9
Pipe()10 Pipe::Pipe() {
11 #ifdef _WIN32
12 HANDLE readPipe;
13 HANDLE writePipe;
14 SECURITY_ATTRIBUTES sec;
15
16 memset(&sec, 0, sizeof(sec));
17 sec.nLength = sizeof(sec);
18 sec.bInheritHandle = FALSE; // O_CLOEXEC equivalent
19 constexpr DWORD kPipeSize = 64 * 1024;
20
21 if (!CreatePipe(&readPipe, &writePipe, &sec, kPipeSize)) {
22 throw std::system_error(
23 GetLastError(), std::system_category(), "CreatePipe failed");
24 }
25 read = FileDescriptor(intptr_t(readPipe));
26 write = FileDescriptor(intptr_t(writePipe));
27
28 #else
29 int fds[2];
30 int res;
31 #if HAVE_PIPE2
32 res = pipe2(fds, O_NONBLOCK | O_CLOEXEC);
33 #else
34 res = pipe(fds);
35 #endif
36
37 if (res) {
38 throw std::system_error(
39 errno,
40 std::system_category(),
41 std::string("pipe error: ") + strerror(errno));
42 }
43 read = FileDescriptor(fds[0]);
44 write = FileDescriptor(fds[1]);
45
46 #if !HAVE_PIPE2
47 read.setCloExec();
48 read.setNonBlock();
49 write.setCloExec();
50 write.setNonBlock();
51 #endif
52 #endif
53 }
54 }
55