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 95