fork(12) download
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/types.h>
  4. #include <stdlib.h>
  5.  
  6. void pipeline( char * ar[], int pos, int in_fd);
  7. void error_exit(const char*);
  8. static int child = 0; /* whether it is a child process relative to main() */
  9.  
  10. int main(int argc, char * argv[]) {
  11. if(argc < 2){
  12. printf("Usage: %s option (option) ...\n", argv[0]);
  13. exit(1);
  14. }
  15. pipeline(argv, 1, STDIN_FILENO);
  16. return 0;
  17. }
  18.  
  19. void error_exit(const char *kom){
  20. perror(kom);
  21. (child ? _exit : exit)(EXIT_FAILURE);
  22. }
  23.  
  24. void pipeline(char *ar[], int pos, int in_fd){
  25. if(ar[pos+1] == NULL){ /*last command */
  26. if(in_fd != STDIN_FILENO){
  27. if(dup2(in_fd, STDIN_FILENO) != -1)
  28. close(in_fd); /*successfully redirected*/
  29. else error_exit("dup2");
  30. }
  31. execlp(ar[pos], ar[pos], NULL);
  32. error_exit("execlp last");
  33. }
  34. else{
  35. int fd[2];
  36. pid_t childpid;
  37.  
  38. if ((pipe(fd) == -1) || ((childpid = fork()) == -1)) {
  39. error_exit("Failed to setup pipeline");
  40. }
  41. if (childpid == 0){ /* child executes current command */
  42. child = 1;
  43. close(fd[0]);
  44. if (dup2(in_fd, STDIN_FILENO) == -1) /*read from in_fd */
  45. perror("Failed to redirect stdin");
  46. if (dup2(fd[1], STDOUT_FILENO) == -1) /*write to fd[1]*/
  47. perror("Failed to redirect stdout");
  48. else if ((close(fd[1]) == -1) || (close(in_fd) == - 1))
  49. perror("Failed to close extra pipe descriptors");
  50. else {
  51. execlp(ar[pos], ar[pos], NULL);
  52. error_exit("Failed to execlp");
  53. }
  54. }
  55. close(fd[1]); /* parent executes the rest of commands */
  56. close(in_fd);
  57. pipeline(ar, pos+1, fd[0]);
  58. }
  59. }
  60.  
  61.  
Runtime error #stdin #stdout 0s 2292KB
stdin
Standard input is empty
stdout
Usage: ./prog option (option) ...