source: imaps-frontend/node_modules/@parcel/watcher/src/watchman/IPC.hh@ 0c6b92a

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 4.0 KB
Line 
1#ifndef IPC_H
2#define IPC_H
3
4#include <string>
5#include <stdlib.h>
6
7#ifdef _WIN32
8#include <winsock2.h>
9#include <windows.h>
10#else
11#include <unistd.h>
12#include <sys/socket.h>
13#include <sys/un.h>
14#endif
15
16class IPC {
17public:
18 IPC(std::string path) {
19 mStopped = false;
20 #ifdef _WIN32
21 while (true) {
22 mPipe = CreateFile(
23 path.data(), // pipe name
24 GENERIC_READ | GENERIC_WRITE, // read and write access
25 0, // no sharing
26 NULL, // default security attributes
27 OPEN_EXISTING, // opens existing pipe
28 FILE_FLAG_OVERLAPPED, // attributes
29 NULL // no template file
30 );
31
32 if (mPipe != INVALID_HANDLE_VALUE) {
33 break;
34 }
35
36 if (GetLastError() != ERROR_PIPE_BUSY) {
37 throw std::runtime_error("Could not open pipe");
38 }
39
40 // Wait for pipe to become available if it is busy
41 if (!WaitNamedPipe(path.data(), 30000)) {
42 throw std::runtime_error("Error waiting for pipe");
43 }
44 }
45
46 mReader = CreateEvent(NULL, true, false, NULL);
47 mWriter = CreateEvent(NULL, true, false, NULL);
48 #else
49 struct sockaddr_un addr;
50 memset(&addr, 0, sizeof(addr));
51 addr.sun_family = AF_UNIX;
52 strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path) - 1);
53
54 mSock = socket(AF_UNIX, SOCK_STREAM, 0);
55 if (connect(mSock, (struct sockaddr *) &addr, sizeof(struct sockaddr_un))) {
56 throw std::runtime_error("Error connecting to socket");
57 }
58 #endif
59 }
60
61 ~IPC() {
62 mStopped = true;
63 #ifdef _WIN32
64 CancelIo(mPipe);
65 CloseHandle(mPipe);
66 CloseHandle(mReader);
67 CloseHandle(mWriter);
68 #else
69 shutdown(mSock, SHUT_RDWR);
70 #endif
71 }
72
73 void write(std::string buf) {
74 #ifdef _WIN32
75 OVERLAPPED overlapped;
76 overlapped.hEvent = mWriter;
77 bool success = WriteFile(
78 mPipe, // pipe handle
79 buf.data(), // message
80 buf.size(), // message length
81 NULL, // bytes written
82 &overlapped // overlapped
83 );
84
85 if (mStopped) {
86 return;
87 }
88
89 if (!success) {
90 if (GetLastError() != ERROR_IO_PENDING) {
91 throw std::runtime_error("Write error");
92 }
93 }
94
95 DWORD written;
96 success = GetOverlappedResult(mPipe, &overlapped, &written, true);
97 if (!success) {
98 throw std::runtime_error("GetOverlappedResult failed");
99 }
100
101 if (written != buf.size()) {
102 throw std::runtime_error("Wrong number of bytes written");
103 }
104 #else
105 int r = 0;
106 for (unsigned int i = 0; i != buf.size(); i += r) {
107 r = ::write(mSock, &buf[i], buf.size() - i);
108 if (r == -1) {
109 if (errno == EAGAIN) {
110 r = 0;
111 } else if (mStopped) {
112 return;
113 } else {
114 throw std::runtime_error("Write error");
115 }
116 }
117 }
118 #endif
119 }
120
121 int read(char *buf, size_t len) {
122 #ifdef _WIN32
123 OVERLAPPED overlapped;
124 overlapped.hEvent = mReader;
125 bool success = ReadFile(
126 mPipe, // pipe handle
127 buf, // buffer to receive reply
128 len, // size of buffer
129 NULL, // number of bytes read
130 &overlapped // overlapped
131 );
132
133 if (!success && !mStopped) {
134 if (GetLastError() != ERROR_IO_PENDING) {
135 throw std::runtime_error("Read error");
136 }
137 }
138
139 DWORD read = 0;
140 success = GetOverlappedResult(mPipe, &overlapped, &read, true);
141 if (!success && !mStopped) {
142 throw std::runtime_error("GetOverlappedResult failed");
143 }
144
145 return read;
146 #else
147 int r = ::read(mSock, buf, len);
148 if (r == 0 && !mStopped) {
149 throw std::runtime_error("Socket ended unexpectedly");
150 }
151
152 if (r < 0) {
153 if (mStopped) {
154 return 0;
155 }
156
157 throw std::runtime_error(strerror(errno));
158 }
159
160 return r;
161 #endif
162 }
163
164private:
165 bool mStopped;
166 #ifdef _WIN32
167 HANDLE mPipe;
168 HANDLE mReader;
169 HANDLE mWriter;
170 #else
171 int mSock;
172 #endif
173};
174
175#endif
Note: See TracBrowser for help on using the repository browser.