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
|
#include <iostream>
#include <unistd.h>
#include <cstdio>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#define BS 10
int main(int argc, char **argv) {
int fds[2], fu[2];
if (argc <= 1){
std::cerr << "Usage: " << argv[0] << " program args..." << std::endl;
return 1;
}
if (pipe(fds) == -1 || pipe(fu) == -1) {
perror("pipe");
return 1;
}
pid_t p = fork();
if (p == 0) {
/*child*/
close(fu[1]);
close(fds[0]);
if (dup2(fu[0], STDIN_FILENO) == -1) perror("dup stdin");
if (dup2(fds[1], STDOUT_FILENO) == -1) perror("dup stdout");
execvp(argv[1], argv+1);
perror("Execvp");
_exit(42);
} else {
char buf[BS];
std::string in("meh\n\04");
int flags = fcntl(fds[0], F_GETFL);
fcntl(fds[0], F_SETFL, flags | O_NONBLOCK);
close(fds[1]);close(fu[0]);
do {
int r = read(fds[0], buf, BS);
if (r == -1 && errno == EWOULDBLOCK) ;
else if (r == -1) perror("read");
else if (r > 0) {
std::cout.write(buf, r);
}
if (write(fu[1], in.c_str(), in.size()) == -1) perror("write");
int status = 0;
if (waitpid(p, &status, WNOHANG) != 0) {
if (WIFEXITED(status) || WTERMSIG(status)) {
break;
}
}
} while (1);
kill(p, 15);
}
return 0;
}
|