Advertisement
volkovich_maksim

ырудд_зшзу3

Dec 18th, 2016
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.13 KB | None | 0 0
  1. #include <string.h>
  2. #include <unistd.h>
  3. #include <sys/wait.h>
  4. #include <sys/types.h>
  5. #include <sys/time.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <ctype.h>
  9. #include <stdlib.h>
  10. #include <sys/resource.h>
  11. #include "util.h"
  12.  
  13. typedef struct pr_list{
  14.     char **pr_arr;
  15.     pid_t pid;
  16.     struct pr_list *next;
  17. }pr_list;
  18.  
  19. typedef struct pipe_list{
  20.     char *line;
  21.     struct pipe_list *next;
  22.     pr_list *prs;
  23. }pipe_list;
  24.  
  25. void printf_prs(char *array[]){
  26.     int i;
  27.     for (i = 0; array[i] != NULL /*&& array[i] != NULL*/; i++){
  28.         printf("%s ", array[i]);
  29.     }
  30. }
  31.  
  32. void add_pr(char *pr, char **array[]){
  33.     int i, j, len;
  34.     /*  count "non-NULL" cells  */
  35.     for (j = 0; (*array)[j] != NULL; j++);
  36.     j += 2;//j "non-NULL" + 1 "NULL" + 1 extra for a new argument
  37.     (*array) = realloc((*array), j*sizeof(char*));
  38.     /*  MOVE PR INTO CELL   */
  39.     for (i = 0; ((*array)[i]) != NULL && (i < j) ; i++);
  40.     len = strlen(pr);
  41.     ((*array)[i]) = calloc(len + 1, sizeof(char));
  42.     for (j = 0; j < len; j++){
  43.         ((*array)[i][j]) = pr[j];
  44.     }
  45.     ((*array)[i][j]) = '\0';
  46.     /*  NEXT CELL = NULL    */
  47.     ((*array)[i+1]) = NULL;
  48. }
  49.  
  50.     /*  MAIN    */
  51.  
  52. int main(int argc, char *argv[]){
  53.     int i, j, k, len, word_begin, word_end;
  54.     int status;
  55.     pid_t pid;
  56.     int not_empty, back_mode, pr_flag, error_flag;
  57.     int exited_flag = 1, next_pr = 0;
  58.     pipe_list *c_pipe, *pipes, *p_pipe;
  59.     pr_list *c_pr, *p_pr, *pr_pointer;
  60.     char *new_line, *cur_word;
  61.  
  62.     printf("Please input pipe\n");
  63.     pipes = malloc(sizeof(pipe_list));
  64.     pipes->next = NULL;
  65.     pipes->line = NULL;
  66.     pipes->prs = NULL;
  67.  
  68.     while ((new_line = getline_unlim()) != NULL){
  69.         if (!strcmp(new_line,"")) continue;
  70.         /*  WAIT BACK PROCESSES */
  71.         while ((pid = wait4(-1, &status, WNOHANG, NULL)) > 0){
  72.             p_pipe = pipes->next;
  73.             while (p_pipe){
  74.                 p_pr = p_pipe->prs;
  75.                 while (p_pr){
  76.                     if (pid == p_pr->pid){
  77.                         p_pr->pid = -1;
  78.                         printf("program \"%s\" has been completed with exit status: %d\n", p_pr->pr_arr[0], WEXITSTATUS(status));
  79.                         pr_pointer = p_pr;
  80.                         exited_flag = 1;
  81.                         while (pr_pointer){
  82.                             if (pr_pointer->pid != -1){
  83.                                 exited_flag = 0;
  84.                                 break;
  85.                             }
  86.                             pr_pointer = pr_pointer->next;
  87.                         }
  88.                         if (exited_flag){
  89.                             printf("pipe \"%s\" has been completed with exit status: %d\n", p_pipe->line, WEXITSTATUS(status));
  90.                         }
  91.                     }
  92.                     p_pr = p_pr->next;
  93.                 }
  94.                 p_pipe = p_pipe->next;
  95.             }
  96.         }
  97.        
  98.         /*  DELETE PRS WITH PID == -1   */
  99.         p_pipe = pipes->next;
  100.         while (p_pipe){
  101.             p_pr = p_pipe->prs;
  102.             while (p_pr){
  103.                 if (p_pr->pid == -1){
  104.                     if (p_pr == p_pipe->prs){
  105.                         for (i = 0; p_pr->pr_arr[i] != NULL; i++){
  106.                             if (p_pr->pr_arr[i])
  107.                                 free((p_pr->pr_arr[i]));
  108.                         }
  109.                         if (p_pr->pr_arr)
  110.                             free(p_pr->pr_arr);
  111.                         p_pipe->prs = p_pr->next;
  112.                         if (p_pr)
  113.                             free(p_pr);
  114.                         p_pr = p_pipe->prs;
  115.                     }else{
  116.                         c_pr = p_pipe->prs;
  117.                         while (c_pr->next != p_pr && c_pr->next != NULL){
  118.                             c_pr = c_pr->next;
  119.                         }
  120.                         c_pr->next = p_pr->next;
  121.                         for (i = 0; p_pr->pr_arr[i] != NULL; i++){
  122.                             if (p_pr->pr_arr[i])
  123.                                 free((p_pr->pr_arr[i]));
  124.                         }
  125.                         if (p_pr->pr_arr)
  126.                             free(p_pr->pr_arr);
  127.                         p_pipe->prs = p_pr->next;
  128.                         if (p_pr)
  129.                             free(p_pr);
  130.                         p_pr = c_pr;
  131.                     }
  132.                 }else{
  133.                     p_pr = p_pr->next;
  134.                 }
  135.             }
  136.             p_pipe = p_pipe->next;
  137.         }
  138.  
  139.  
  140.         if( !strcmp(new_line, "exit") || !strcmp(new_line, "EXIT") ){
  141.             printf("exit\n");
  142.             break;
  143.         }
  144.  
  145.         /* processing line, creating pipe */
  146.  
  147.         c_pipe = pipes;
  148.         while (c_pipe){
  149.             c_pipe = c_pipe->next;
  150.         }
  151.         /*  allocate memory for current pipe    */
  152.         c_pipe = calloc(1, sizeof(pipe_list));
  153.         c_pipe->next = NULL;
  154.         c_pipe->prs = NULL;
  155.  
  156.         len = strlen(new_line);
  157.         /*  copy new_line to current_pipe->line */
  158.         c_pipe->line = calloc(len + 1, sizeof(char));
  159.         for (i = 0; i < len + 1; i++){
  160.             c_pipe->line[i] = new_line[i];
  161.         }
  162.  
  163.         /*  allocate memory for first pr in current pipe    */
  164.         c_pipe->prs = calloc(1, sizeof(pr_list));
  165.         c_pipe->prs->pr_arr = calloc(1, sizeof(char*));
  166.         c_pipe->prs->pr_arr[0] = NULL;
  167.         c_pipe->prs->next = NULL;
  168.         c_pr = c_pipe->prs;
  169.  
  170.         p_pipe = pipes;
  171.         while (p_pipe->next){
  172.             p_pipe = p_pipe->next;
  173.         }
  174.         p_pipe->next = c_pipe;
  175.  
  176.         word_begin = 0; word_end = 0; next_pr = 0; error_flag = 0;
  177.         not_empty = 0, back_mode = 0, pr_flag = 1;
  178.         for (i = 0; i < len; i++){
  179.             if (pr_flag){
  180.                 c_pipe->prs = c_pr;
  181.                 pr_flag = 0;
  182.                 not_empty = 0;
  183.             }
  184.             if (next_pr){
  185.                 c_pr->next = calloc(1, sizeof(pr_list));
  186.                 c_pr = c_pr->next;
  187.                 c_pr->pr_arr = calloc(1, sizeof(char*));
  188.                 c_pr->next = NULL;
  189.                 next_pr = 0;
  190.                 not_empty = 0;
  191.             }
  192.  
  193.             if ( isspace(new_line[i]) || new_line[i] == '|' || new_line[i] == '&' ){
  194.                 if (new_line[i] == '|'){
  195.                     if (!not_empty) error_flag = 1;
  196.                     next_pr = 1;
  197.                     not_empty = 0;
  198.                 }
  199.                 if (new_line[i] == '&'){
  200.                     back_mode = 1;
  201.                 }
  202.                 new_line[i] = '\0';
  203.                 word_end = i;
  204.  
  205.                 k = word_end - word_begin;
  206.                 if (k != 0){
  207.                     cur_word = calloc(k, sizeof(char));
  208.                     for (j = 0; j < k; j++){
  209.                         cur_word[j] = new_line[word_begin + j];
  210.                     }
  211.                     word_begin = i + 1;
  212.                 }
  213.                 if (word_begin != word_end){
  214.                     if (strcmp(cur_word,"")){
  215.                         if (!not_empty) not_empty = 1;
  216.                         add_pr(cur_word, &(c_pr->pr_arr));
  217.                         if (cur_word)
  218.                             free(cur_word);
  219.                     }
  220.                 }
  221.             }
  222.         }
  223.         k = i - word_begin;
  224.         if (k != 0){
  225.             cur_word = calloc(k, sizeof(char));
  226.             for (j = 0; j < k; j++){
  227.                 cur_word[j] = new_line[word_begin + j];
  228.             }
  229.         }
  230.         if (word_begin != i){
  231.             if (strcmp(cur_word,"")){
  232.                 if (!not_empty) not_empty = 1;
  233.                 add_pr(cur_word, &(c_pr->pr_arr));
  234.                 if (cur_word)
  235.                     free(cur_word);
  236.             }
  237.         }
  238.  
  239.         /*  executing pipe  */
  240.             if (error_flag){
  241.                 printf("pipe was written incorrectly\n");
  242.  
  243.                 if (c_pipe){
  244.                     if (c_pipe->line)
  245.                         free(c_pipe->line);
  246.                     p_pr = c_pipe->prs;
  247.                     while (p_pr){
  248.                         for (i = 0; p_pr->pr_arr[i] != NULL; i++){
  249.                             if(p_pr->pr_arr[i])
  250.                                 free((p_pr->pr_arr[i]));
  251.                         }
  252.                         if (p_pr->pr_arr)
  253.                             free(p_pr->pr_arr);
  254.                         c_pipe->prs = p_pr->next;
  255.                         if (p_pr)
  256.                             free(p_pr);
  257.                         p_pr = c_pipe->prs;
  258.                     }
  259.                     c_pipe = NULL;
  260.                 }
  261.  
  262.             }else if (!back_mode){
  263.         /*  STANDART MODE   */
  264.                 int cnt = 0;
  265.                 p_pr = c_pipe->prs;
  266.                 while (p_pr){
  267.                     cnt++;
  268.                     if (p_pr->next == NULL) break;
  269.                     else (p_pr = p_pr->next);
  270.                 }
  271.                 p_pr = c_pipe->prs;
  272.                 int fd[cnt-1][2];
  273.                 for (i = 0; i < cnt - 1; i++){
  274.                     pipe(fd[i]);
  275.                 }
  276.                 for (i = 0; p_pr && i < cnt; i++){
  277.                     if (p_pr->pr_arr[0] != NULL){
  278.                         if ((p_pr->pid = fork()) < 0){
  279.                             perror("fork ");
  280.                             exit(1);
  281.                         }else if (p_pr->pid == 0){
  282.                             if (i < cnt - 1){
  283.                                 dup2(fd[i][1], 1);
  284.                             }
  285.                             if (i > 0){
  286.                                 dup2(fd[i-1][0], 0);
  287.                             }
  288.                             for (j = 0; j < cnt - 1; j++){
  289.                                 close(fd[j][0]);
  290.                                 close(fd[j][1]);
  291.                             }
  292.                             execvp(p_pr->pr_arr[0], p_pr->pr_arr);
  293.                             perror("exec ");
  294.                             _exit(1);
  295.                         }
  296.                         p_pr = p_pr->next;
  297.                         if (p_pr == NULL) break;
  298.                     }else break;
  299.                 }
  300.                 for (i = 0; i < cnt-1; i++){
  301.                     close(fd[i][0]);
  302.                     close(fd[i][1]);
  303.                 }
  304. //////////////////
  305.                 c_pr = c_pipe->prs;
  306.                 for (i = 0; i < cnt; i++){
  307.                     pid = waitpid(c_pr->pid, &status, 0);
  308.                     if (WIFEXITED(status)){
  309.                         p_pr = c_pipe->prs;
  310.                         while (p_pr){
  311.                             if (p_pr->pid == pid){
  312.                                 printf("program \"%s\" has been completed with exit status: %d\n", p_pr->pr_arr[0], WEXITSTATUS(status));
  313.                                 if (c_pr->next == NULL){
  314.                                     printf("pipe \"%s\" has been completed with exit status: %d\n", c_pipe->line, WEXITSTATUS(status));
  315.                                 }
  316.                                 break;
  317.                             }else{
  318.                                 p_pr = p_pr->next;
  319.                             }if (p_pr == NULL){
  320.                                 printf("there aren't process with pid == %d\n", (int)pid);
  321.                                 break;
  322.                             }
  323.                         }
  324.                     }else{
  325.                         p_pr = c_pipe->prs;
  326.                         while (p_pr){
  327.                             if (p_pr->pid == pid){
  328.                                 printf("program \"%s\" hasn't been completed\n", p_pr->pr_arr[0]);
  329.                                 if (c_pr->next == NULL){
  330.                                     printf("pipe \"%s\" hasn't been completed\n", p_pipe->line);
  331.                                 }
  332.                                 break;
  333.                             }else{
  334.                                 p_pr = p_pr->next;
  335.                             }
  336.                             if (p_pr == NULL){
  337.                                 printf("there aren't process with pid == %d\n", (int)pid);
  338.                                 break;
  339.                             }
  340.                         }
  341.                     }
  342.                     c_pr = c_pr->next;
  343.                 }
  344. ///////////////////
  345.                 /*  DELETE USED MEMORY  */
  346.                
  347.                 if (c_pipe){
  348.                     if (c_pipe->line)
  349.                         free(c_pipe->line);
  350.                     p_pr = c_pipe->prs;
  351.                     while (p_pr){
  352.                         for (i = 0; p_pr->pr_arr[i] != NULL; i++){
  353.                             if (p_pr->pr_arr[i])
  354.                                 free((p_pr->pr_arr[i]));
  355.                         }
  356.                         if (p_pr->pr_arr)
  357.                             free(p_pr->pr_arr);
  358.                         c_pipe->prs = p_pr->next;
  359.                         if (p_pr)
  360.                             free(p_pr);
  361.                         p_pr = c_pipe->prs;
  362.                     }
  363.                     c_pipe = NULL;
  364.                 }
  365. ///////////////////////////////
  366.             }else{
  367.             /*  BACKGROUND MODE */
  368.                 printf("backgroung mode\n");
  369.                 int cnt = 0;
  370.                 p_pr = c_pipe->prs;
  371.                 while (p_pr){
  372.                     cnt++;
  373.                     if (p_pr->next == NULL) break;
  374.                     else (p_pr = p_pr->next);
  375.                 }
  376.                 p_pr = c_pipe->prs;
  377.                 int fd[cnt-1][2];
  378.                 for (i = 0; i < cnt - 1; i++){
  379.                     pipe(fd[i]);
  380.                 }
  381.                 for (i = 0; p_pr && i < cnt; i++){
  382.                     if (p_pr->pr_arr[0] != NULL){
  383.                         if ((p_pr->pid = fork()) < 0){
  384.                             perror("fork ");
  385.                             exit(1);
  386.                         }else if (p_pr->pid == 0){
  387.                             if (i < cnt - 1){
  388.                                 dup2(fd[i][1], 1);
  389.                             }
  390.                             if (i > 0){
  391.                                 dup2(fd[i-1][0], 0);
  392.                             }
  393.                             for (j = 0; j < cnt - 1; j++){
  394.                                 close(fd[j][0]);
  395.                                 close(fd[j][1]);
  396.                             }
  397.                             execvp(p_pr->pr_arr[0], p_pr->pr_arr);
  398.                             perror("exec ");
  399.                             _exit(1);
  400.                         }
  401.                         p_pr = p_pr->next;
  402.                         if (p_pr == NULL) break;
  403.                     }else break;
  404.                 }
  405.                 for (i = 0; i < cnt-1; i++){
  406.                     close(fd[i][0]);
  407.                     close(fd[i][1]);
  408.                 }
  409.             }
  410.     printf("Please input pipe\n");
  411.     }
  412.     /*  WAIT BACK PROCESSES AND FREE ALL PIPES  */
  413.     p_pipe = pipes->next;
  414.     while (p_pipe){
  415.         p_pr = p_pipe->prs;
  416.         while (p_pr){
  417.             pid = waitpid(p_pr->pid, &status, 0);
  418.             if (WIFEXITED(status)){
  419.                 while (p_pr){
  420.                     if (p_pr->pid == pid){
  421.                         printf("program \"%s\" has been completed with exit status: %d\n", p_pr->pr_arr[0], WEXITSTATUS(status));
  422.                         if (p_pr->next == NULL){
  423.                             printf("pipe \"%s\" has been completed with exit status: %d\n", p_pipe->line, WEXITSTATUS(status));
  424.                         }
  425.                     }else{
  426.                         p_pr = p_pr->next;
  427.                     }if (p_pr == NULL){
  428.                         printf("there aren't process with pid == %d\n", (int)pid);
  429.                     }
  430.                     if (p_pr){
  431.                         p_pr = p_pr->next;
  432.                     }
  433.                 }
  434.             }else{
  435.                 p_pr = c_pipe->prs;
  436.                 while (p_pr){
  437.                     if (p_pr->pid == pid){
  438.                         printf("program \"%s\" hasn't been completed\n", p_pr->pr_arr[0]);
  439.                         if (p_pr->next == NULL){
  440.                             printf("pipe \"%s\" hasn't been completed\n", p_pipe->line);
  441.                         }
  442.                     }else{
  443.                         p_pr = p_pr->next;
  444.                     }
  445.                     if (p_pr == NULL){
  446.                         printf("there aren't process with pid == %d\n", (int)pid);
  447.                     }
  448.                     if (p_pr){
  449.                         p_pr = p_pr->next;
  450.                     }
  451.                 }
  452.             }
  453.             if (p_pr){
  454.                 p_pr = p_pr->next;
  455.             }
  456.         }
  457.         if (p_pipe){
  458.             p_pipe = p_pipe->next;
  459.         }
  460.     }
  461.     /*  DELETE PIPES WITHOUT PRS    */
  462.     p_pipe = pipes->next;
  463.     while (p_pipe){
  464.         if (p_pipe->prs == NULL){
  465.             if (pipes->next == p_pipe){
  466.                 pipes->next = p_pipe->next;
  467.                 if (p_pipe)
  468.                     free(p_pipe);
  469.                 p_pipe = pipes->next;
  470.             }else{
  471.                 c_pipe = pipes->next;
  472.                 while (c_pipe->next != p_pipe && c_pipe != NULL){
  473.                     c_pipe = c_pipe->next;
  474.                 }
  475.                 c_pipe->next = p_pipe->next;
  476.                 if (p_pipe)
  477.                     free(p_pipe);
  478.                 p_pipe = c_pipe;
  479.             }
  480.         }else{
  481.             p_pipe = p_pipe->next;
  482.         }
  483.         if (p_pipe){
  484.             p_pipe = p_pipe->next;
  485.         }
  486.     }
  487.     /*  DELETE ALL PIPES    */
  488.     p_pipe = pipes;
  489.     while (p_pipe->next){
  490.         if (p_pipe->next->prs){
  491.             p_pr = p_pipe->prs;
  492.             while (p_pr){
  493.                 for (i = 0; p_pr->pr_arr[i] != NULL; i++){
  494.                     if (p_pr->pr_arr[i])
  495.                         free((p_pr->pr_arr[i]));
  496.                 }
  497.                 if (p_pr->pr_arr)
  498.                     free(p_pr->pr_arr);
  499.                 p_pipe->next->prs = p_pr->next;
  500.                 if (p_pr)
  501.                     free(p_pr);
  502.                 p_pr = p_pipe->next->prs;
  503.             }          
  504.         }
  505.         p_pipe = p_pipe->next;
  506.     }
  507.     if (pipes)
  508.         free(pipes);
  509.     return 0;
  510. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement