-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreactive.hpp
68 lines (61 loc) · 1.66 KB
/
reactive.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// ref: https://atcoder.jp/contests/kupc2012/tasks/kupc2012_9
#include <algorithm>
#include <string>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
pid_t __reactive_pid;
int __reactive_input, __reactive_output;
int reactive_start(std::string command) {
int pipe_c2p[2], pipe_p2c[2]; int size;
signal(SIGPIPE, SIG_IGN);
if (pipe(pipe_c2p) < 0 || pipe(pipe_p2c) < 0) {
fprintf(stderr, "pipe: failed to open pipes\n");
return 1;
}
if ((__reactive_pid = fork()) < 0) {
fprintf(stderr, "fork: failed to fork\n");
return 1;
}
if (__reactive_pid == 0) {
close(pipe_p2c[1]); close(pipe_c2p[0]);
dup2(pipe_p2c[0], 0); dup2(pipe_c2p[1], 1);
close(pipe_p2c[0]); close(pipe_c2p[1]);
exit(system(command.c_str()) ? 1 : 0);
}
close(pipe_p2c[0]); close(pipe_c2p[1]);
__reactive_input = pipe_p2c[1];
__reactive_output = pipe_c2p[0];
return 0;
}
void reactive_end() {
int status;
close(__reactive_input);
waitpid(__reactive_pid, &status, WUNTRACED);
}
void reactive_write(std::string buf) {
write(__reactive_input, buf.c_str(), buf.size());
}
std::string reactive_read(int max_len = 100000) {
static char buf[1024]; static int len = 0; std::string result;
while (result.size() < max_len) {
if (!len) {
len = read(__reactive_output, buf,
std::min(1000, (int)(max_len - result.size())));
if (!len) return result;
}
char *pos = (char *)memchr(buf, '\n', len);
if (pos) {
result += std::string(buf, pos - buf + 1);
memmove(buf, pos + 1, len - (pos + 1 - buf));
len -= pos - buf + 1;
return result;
} else {
result += std::string(buf, len);
len = 0;
}
}
return result;
}