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