summaryrefslogtreecommitdiff
path: root/pipe.cpp
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2012-09-26 15:04:18 +0200
committerPeter Wu <lekensteyn@gmail.com>2012-09-26 15:04:18 +0200
commit2497c1392b81e093f4de2541a98746aebd449a7f (patch)
treedb87e59d4c70c677ddb1899d9161b004f6e454ac /pipe.cpp
downloadc-files-2497c1392b81e093f4de2541a98746aebd449a7f.tar.gz
Initial commit
Diffstat (limited to 'pipe.cpp')
-rw-r--r--pipe.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/pipe.cpp b/pipe.cpp
new file mode 100644
index 0000000..76cd19d
--- /dev/null
+++ b/pipe.cpp
@@ -0,0 +1,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;
+}