Advertisement
Guest User

Untitled

a guest
Dec 20th, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.87 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <unistd.h>
  6. #include <sys/wait.h>
  7. #include <sys/types.h>
  8.  
  9. char *program_name;
  10.  
  11. struct parts
  12. {
  13.     char *first_half;
  14.     char *second_half;
  15. };
  16.  
  17. void usage(char *message)
  18. {
  19.     fprintf(stderr, "%s : %s\n", program_name, message);
  20.     exit(EXIT_FAILURE);
  21. }
  22.  
  23. char * getLine()
  24. {
  25.     char *line = NULL;
  26.     size_t len = 0;
  27.     getline(&line, &len, stdin);
  28.     line[strcspn(line, "\n")] = '\0';
  29.     return line;
  30. }
  31.  
  32. void split(char *input, struct parts * p)
  33. {
  34.     int len = strlen(input);
  35.     int len1 = len/2;
  36.     int len2 = len - len1;
  37.     char *s1 = malloc(len1+1);
  38.     memcpy(s1, input, len1);
  39.     s1[len1] = '\0';
  40.     char *s2 = malloc(len2+1);
  41.     memcpy(s2, input+len1, len2);
  42.     s2[len2] = '\0';
  43.     p -> first_half = s1;
  44.     p -> second_half = s2;
  45.      
  46. }
  47.  
  48. void redirectPipes(pid_t pid, int *pipe1, int *pipe2)
  49. {      
  50.     if (pid == -1)
  51.     {
  52.         exit(EXIT_FAILURE);
  53.     } else if (pid == 0)
  54.     {
  55.         close(STDIN_FILENO);
  56.         close(STDOUT_FILENO);
  57.  
  58.         dup2(pipe2[0],STDIN_FILENO);
  59.         close(pipe2[1]);
  60.         close(pipe2[0]);
  61.  
  62.         dup2(pipe1[1],STDOUT_FILENO);
  63.         close(pipe1[1]);
  64.         close(pipe1[0]);
  65.            
  66.         if((execlp(program_name,program_name,(char *)NULL)) == -1)
  67.         {
  68.             exit(EXIT_FAILURE);
  69.         }
  70.     }
  71. }
  72.  
  73. int main(int argc, char *argv[])
  74. {
  75.     program_name = argv[0];
  76.     int status = 0;
  77.     char *input;
  78.     input = getLine();
  79.     int input_length = strlen(input);
  80.    
  81.     if((input_length/2)%2 == 1 && input_length > 2)
  82.     {
  83.         usage("input must have even length");
  84.     }
  85.  
  86.     if (input_length == 1)
  87.     {
  88.         fprintf(stdout, "%s", input);
  89.     }else
  90.     {
  91.         struct parts p1;
  92.         split(input, &p1);
  93.  
  94.         //================================================== Pipe and Fork ============================================================//
  95.         // pipe - 1st child
  96.         int pipeEndsFirstChild1[2];
  97.         int pipeEndsFirstChild2[2];
  98.        
  99.         if(pipe(pipeEndsFirstChild1) == -1)
  100.         {  
  101.             exit(EXIT_FAILURE);
  102.         }
  103.         if(pipe(pipeEndsFirstChild2) == -1)
  104.         {  
  105.             exit(EXIT_FAILURE);
  106.         }
  107.  
  108.         // fork - 1st child
  109.         pid_t pid1 = fork();
  110.         redirectPipes(pid1, pipeEndsFirstChild1, pipeEndsFirstChild2);
  111.        
  112.         // close unnecessary
  113.         if(close(pipeEndsFirstChild1[1]) == -1)
  114.         {
  115.             exit(EXIT_FAILURE);
  116.         }
  117.         if(close(pipeEndsFirstChild2[0]) == -1)
  118.         {
  119.             exit(EXIT_FAILURE);
  120.         }
  121.  
  122.         // pipe - 2nd child
  123.         int pipeEndsSecondChild1[2];
  124.         int pipeEndsSecondChild2[2];
  125.        
  126.         if(pipe(pipeEndsSecondChild1) == -1)
  127.         {  
  128.             exit(EXIT_FAILURE);
  129.         }
  130.         if(pipe(pipeEndsSecondChild2) == -1)
  131.         {  
  132.             exit(EXIT_FAILURE);
  133.         }
  134.        
  135.         // fork - 2nd child
  136.         pid_t pid2 = fork();
  137.         redirectPipes(pid2, pipeEndsSecondChild1, pipeEndsSecondChild2);
  138.        
  139.         // close unnecessary
  140.         if(close(pipeEndsSecondChild1[1]) == -1)
  141.         {
  142.             exit(EXIT_FAILURE);
  143.         }
  144.         if(close(pipeEndsSecondChild2[0]) == -1)
  145.         {
  146.             exit(EXIT_FAILURE);
  147.         }
  148.  
  149.    
  150.        
  151.         // write to 1st and 2nd child
  152.         write(pipeEndsFirstChild2[1], p1.first_half,  strlen(p1.first_half));
  153.         write(pipeEndsSecondChild2[1],  p1.second_half,  strlen(p1.second_half));
  154.  
  155.         // close pipes
  156.         if(close(pipeEndsFirstChild2[1]) == -1){
  157.             exit(EXIT_FAILURE);
  158.         }
  159.  
  160.         if(close(pipeEndsSecondChild2[1]) == -1){
  161.         exit(EXIT_FAILURE);
  162.         }
  163.  
  164.         // reading from 1st and 2nd child
  165.         char readBufFirstChild[128];
  166.         char readBufSecondChild[128];
  167.  
  168.         // open output fd of 1st child
  169.         FILE *filePointer1 = fdopen(pipeEndsFirstChild1[0], "r");
  170.  
  171.         if(filePointer1 == NULL)
  172.         {
  173.             exit(EXIT_FAILURE);
  174.         }
  175.  
  176.         // put output into readBufFirstChild
  177.         fgets(readBufFirstChild,sizeof(readBufFirstChild),filePointer1);
  178.        
  179.         // open output fd of 2nd child
  180.         FILE *filePointer2 = fdopen(pipeEndsSecondChild1[0], "r");
  181.  
  182.         if(filePointer2 == NULL){
  183.             exit(EXIT_FAILURE);
  184.         }
  185.  
  186.         // open output fd of 2st child
  187.         fgets(readBufSecondChild,sizeof(readBufSecondChild),filePointer2);
  188.  
  189.        //concat results
  190.        char *result = malloc(strlen(readBufFirstChild) + strlen(readBufSecondChild) + 1);
  191.        strcpy(result, readBufFirstChild);
  192.        strcat(result, readBufSecondChild);
  193.  
  194.         fprintf(stderr, "result ->\n%s\n", result);
  195.        
  196.         if(wait(&status) == -1){
  197.             exit(EXIT_FAILURE);
  198.         }
  199.  
  200.         exit(EXIT_SUCCESS);
  201.     }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement