|
29 | 29 | // suspicious means of sending raw JavaScript commands to be executed on other
|
30 | 30 | // clients.
|
31 | 31 |
|
32 |
| -// Same as ws_test, but uses the poll() method. |
| 32 | +// Same as ws_test, but uses the poll() method and a separate epoll set to |
| 33 | +// demonstrate how Seasocks can be used with another polling system. |
33 | 34 |
|
34 | 35 | #include "seasocks/PrintfLogger.h"
|
35 | 36 | #include "seasocks/Server.h"
|
|
43 | 44 | #include <set>
|
44 | 45 | #include <sstream>
|
45 | 46 | #include <string>
|
| 47 | +#include <fcntl.h> |
| 48 | +#include <unistd.h> |
| 49 | +#include <sys/epoll.h> |
46 | 50 |
|
47 | 51 | using namespace seasocks;
|
48 | 52 | using namespace std;
|
@@ -114,10 +118,53 @@ int main(int argc, const char* argv[]) {
|
114 | 118 | cerr << "couldn't start listening" << endl;
|
115 | 119 | return 1;
|
116 | 120 | }
|
| 121 | + int myEpoll = epoll_create(10); |
| 122 | + epoll_event wakeSeasocks = { EPOLLIN|EPOLLOUT|EPOLLERR, { &server } }; |
| 123 | + epoll_ctl(myEpoll, EPOLL_CTL_ADD, server.fd(), &wakeSeasocks); |
| 124 | + |
| 125 | + // Also poll stdin |
| 126 | + epoll_event wakeStdin = { EPOLLIN, { nullptr } }; |
| 127 | + epoll_ctl(myEpoll, EPOLL_CTL_ADD, STDIN_FILENO, &wakeStdin); |
| 128 | + auto prevFlags = fcntl(STDIN_FILENO, F_GETFL, 0); |
| 129 | + fcntl(STDIN_FILENO, F_SETFL, prevFlags | O_NONBLOCK); |
| 130 | + |
| 131 | + cout << "Will echo anything typed in stdin: " << flush; |
117 | 132 | while (true) {
|
118 |
| - auto result = server.poll(100); |
119 |
| - if (result == Server::PollResult::Terminated) return 0; |
120 |
| - if (result == Server::PollResult::Error) return 1; |
| 133 | + constexpr auto maxEvents = 2; |
| 134 | + epoll_event events[maxEvents]; |
| 135 | + auto res = epoll_wait(myEpoll, events, maxEvents, -1); |
| 136 | + if (res < 0) { |
| 137 | + cerr << "epoll returned an error" << endl; |
| 138 | + return 1; |
| 139 | + } |
| 140 | + for (auto i = 0; i < res; ++i) { |
| 141 | + if (events[i].data.ptr == &server) { |
| 142 | + auto seasocksResult = server.poll(0); |
| 143 | + if (seasocksResult == Server::PollResult::Terminated) return 0; |
| 144 | + if (seasocksResult == Server::PollResult::Error) return 1; |
| 145 | + } else if (events[i].data.ptr == nullptr) { |
| 146 | + // Echo stdin to stdout to show we can read from that too. |
| 147 | + for (;;) { |
| 148 | + char buf[1024]; |
| 149 | + auto numRead = ::read(STDIN_FILENO, buf, sizeof(buf)); |
| 150 | + if (numRead < 0) { |
| 151 | + if (errno != EWOULDBLOCK && errno != EAGAIN) { |
| 152 | + cerr << "Error reading stdin" << endl; |
| 153 | + return 1; |
| 154 | + } |
| 155 | + break; |
| 156 | + } else if (numRead > 0) { |
| 157 | + auto written = write(STDOUT_FILENO, buf, numRead); |
| 158 | + if (written != numRead) { |
| 159 | + cerr << "Truncated write" << endl; |
| 160 | + } |
| 161 | + } else if (numRead == 0) { |
| 162 | + cerr << "EOF on stdin" << endl; |
| 163 | + return 0; |
| 164 | + } |
| 165 | + } |
| 166 | + } |
| 167 | + } |
121 | 168 | }
|
122 | 169 | return 0;
|
123 | 170 | }
|
0 commit comments