UNIXworkcode

 1  /*
 2   *             DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
 3   *                     Version 2, December 2004
 4   * 
 5   *  Copyright (C) 2016 Olaf Wintermann <olaf.wintermann@gmail.com>
 6   * 
 7   *  Everyone is permitted to copy and distribute verbatim or modified
 8   *  copies of this license document, and changing it is allowed as long
 9   *  as the name is changed.
10   * 
11   *             DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
12   *    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
13   * 
14   *   0. You just DO WHAT THE FUCK YOU WANT TO.
15   */
16  
17  #include <stdio.h>
18  #include <stdlib.h>
19  #include <unistd.h>
20  #include <sys/types.h>
21  #include <sys/wait.h>
22  
23  
24  int main(int argc, char** argv) {
25      int newin[2];
26      int newout[2];
27      int newerr[2];
28      
29      if(pipe(newin) || pipe(newout) || pipe(newerr)) {
30          perror("pipe");
31          return EXIT_FAILURE;
32      }
33      
34      pid_t pid = fork();
35      if(pid == 0) {
36          // child
37          
38          // we need stdin, stdout and stderr refer to the previously
39          // created pipes
40          if(dup2(newin[0], STDIN_FILENO) == -1) {
41              perror("dup2");
42              return EXIT_FAILURE;
43          }
44          if(dup2(newout[1], STDOUT_FILENO) == -1) {
45              perror("dup2");
46              return EXIT_FAILURE;
47          }
48          if(dup2(newerr[1], STDERR_FILENO) == -1) {
49              perror("dup2");
50              return EXIT_FAILURE;
51          }
52          
53          // we need to close this unused pipe
54          // otherwise stdin cannot reach EOF
55          close(newin[1]);
56          
57          // execute program
58          return execl("/usr/bin/bc", "bc", NULL);
59          // end of child process
60      } else if(pid > 0) {
61          // parent
62          
63          // close unused pipe endpoints
64          close(newout[1]);
65          close(newerr[1]);
66          
67          // write to child
68          write(newin[1], "5+2\n", 4);
69          close(newin[1]);
70          
71          // read from child
72          char buf[64];
73          ssize_t r;
74          while((r = read(newout[0], buf, 64)) > 0) {
75              write(STDOUT_FILENO, buf, r);
76          }
77          
78          int status = -1;
79          waitpid(pid, &status, 0);
80          printf("child status code: %d\n", status);
81          
82          // close all remaining pipes
83          close(newin[0]);
84          close(newout[0]);
85          close(newerr[0]);
86      } else {
87          // error
88          perror("fork");
89          return EXIT_FAILURE;
90      }
91      
92      return (EXIT_SUCCESS);
93  }
94