summaryrefslogtreecommitdiff
path: root/pipe.cpp
blob: 76cd19d93185d5e77872e1e3129d64b157d08b4f (plain)
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;
}