Advertisement
romko11l

Untitled

Nov 23rd, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.69 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/wait.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <signal.h>
  10.  
  11.  
  12.  
  13. const int n = 5; // на сколько элементов выделится память (символов) при заполнении строки (read_line) (не делать меньше 3)
  14. const int m = 5; // на сколько элементов (символов) выделится память в функции strtok
  15. const int t = 5; // на сколько строк выделится память в функции parcer
  16.  
  17. void freedom (char **base)
  18. {
  19.     int pos=0;
  20.     while (base[pos])
  21.     {
  22.         free(base[pos]);
  23.         pos++;
  24.     }
  25.     free(base);
  26. }
  27.  
  28. void Sighndlr ()
  29. {
  30.     printf("Не удалось запустить программу\n");
  31. }
  32.  
  33. //чтение одной строки из заданного ввода
  34. char *read_line(int fd, int *check) // в check-е вернется 1, если в строке обнаружен EOF
  35. {
  36.     int pos=0, size;
  37.     char *str, *temp, c, k;
  38.     size=n;
  39.     str=malloc(sizeof(char)*size);
  40.     *check=0;
  41.    
  42.     if (!str)
  43.     {
  44.         printf("memory allocation error\n");
  45.         exit(1);
  46.     }
  47.    
  48.     while (1)
  49.     {
  50.         k=read(fd,&c,sizeof(char));
  51.         if ((k==0)||(c=='\n'))
  52.         {
  53.             str[pos]='\0';
  54.             if (k==0)
  55.             {
  56.                 *check=1;
  57.             }
  58.             return str;
  59.         }
  60.         else
  61.         {
  62.             str[pos]=c;
  63.             pos++;
  64.         }
  65.    
  66.         if (pos==size)
  67.         {
  68.             size=size+n;
  69.             temp=str;
  70.             str=realloc(str,size*sizeof(char));
  71.             if (!str)
  72.             {
  73.                 free(temp);
  74.                 printf("memory allocation error\n");
  75.                 exit(1);
  76.             }
  77.         }
  78.     }
  79.    
  80. }
  81.  
  82. //вычленение лексем из строки (выводит по лексеме в виде полноценной строки)
  83. char *mystrtok (char *line, int *check, int *num) //вернет 1 в случае нахождения конца строки
  84. {
  85.     int size, pos=0, hpos=0, pos1, hpos1;
  86.     char *str, *temp;
  87.     size=m;
  88.     str=malloc(sizeof(char)*size);
  89.     if (!str)
  90.     {
  91.         printf("memory allocation error\n");
  92.         *check=2;
  93.         free(str);
  94.         return NULL;
  95.     }
  96.    
  97.     while (1)
  98.     {
  99.         // Обработка кавычек
  100.         if (line[pos]=='"')
  101.         {
  102.             pos1=pos+1;
  103.             hpos1=hpos;
  104.             while (1)
  105.             {
  106.                 if (line[pos1]=='"')
  107.                 {
  108.                     hpos=hpos1;
  109.                     pos=pos1+1;
  110.                     break;
  111.                 }
  112.                 if ((line[pos1]==EOF)||(line[pos1]=='\0'))
  113.                 {
  114.                     break; // не найдено парной кавычки -> кавычка должна считаться как обычный символ
  115.                 }
  116.                 str[hpos1]=line[pos1];
  117.                 hpos1++;
  118.                 pos1++;
  119.                 if (hpos1==size)
  120.                 {
  121.                     temp=str;
  122.                     size=size+m;
  123.                     str=realloc(str,size*sizeof(char));
  124.                     if (!str)
  125.                     {
  126.                         free(temp);
  127.                         printf("memory allocation error\n");
  128.                         *check=2;
  129.                         return NULL;
  130.                     }
  131.                 }
  132.             }
  133.         }
  134.         // Обработка иных случаев
  135.         if (line[pos]==' ')
  136.         {
  137.             if (hpos==0)
  138.             {
  139.                 pos++;
  140.             }
  141.             else
  142.             {
  143.                 str[hpos]='\0';
  144.                 *check=0;
  145.                 *num=pos; // чтобы в следующий раз отправить в эту функцию другую строку
  146.                 return str;
  147.                
  148.             }
  149.         }
  150.         else
  151.         {
  152.             if (line[pos]=='\0')
  153.             {
  154.                 if (hpos==0)
  155.                 {
  156.                     *check=1;
  157.                     free(str);
  158.                     return NULL;
  159.                 }
  160.                 else
  161.                 {
  162.                     str[hpos]='\0';
  163.                     *check=1;
  164.                     return str;
  165.                 }
  166.             }
  167.             else // обнаружен элемент, который можно записать в строку
  168.             {
  169.                 // Обрабатываем спецсимволы
  170.                 if ((line[pos]=='|')||(line[pos]=='&')||(line[pos]=='>')||(line[pos]=='<')||(line[pos]==';')||(line[pos]==')')||(line[pos]=='('))
  171.                 {
  172.                     if (hpos>0) //до этого уже сформирована строка
  173.                     {
  174.                         str[hpos]='\0';
  175.                         *check=0;
  176.                         *num=pos;
  177.                         return str;
  178.                     }
  179.                     else // строка еще не сформирована (hpos==0)
  180.                     {
  181.                         // |
  182.                         if (line[pos]=='|')
  183.                         {
  184.                             if (line[pos+1]=='|')
  185.                             {
  186.                                 str[0]='|';
  187.                                 str[1]='|';
  188.                                 str[2]='\0';
  189.                                 *check=0;
  190.                                 *num=pos+2;
  191.                                 return str;
  192.                             }
  193.                             else
  194.                             {
  195.                                 str[0]='|';
  196.                                 str[1]='\0';
  197.                                 *check=0;
  198.                                 *num=pos+1;
  199.                                 return str;
  200.                             }
  201.                         }
  202.                         // &
  203.                         if (line[pos]=='&')
  204.                         {
  205.                             if (line[pos+1]=='&')
  206.                             {
  207.                                 str[0]='&';
  208.                                 str[1]='&';
  209.                                 str[2]='\0';
  210.                                 *check=0;
  211.                                 *num=pos+2;
  212.                                 return str;
  213.                             }
  214.                             else
  215.                             {
  216.                                 str[0]='&';
  217.                                 str[1]='\0';
  218.                                 *check=0;
  219.                                 *num=pos+1;
  220.                                 return str;
  221.                             }
  222.                         }
  223.                         // >
  224.                         if (line[pos]=='>')
  225.                         {
  226.                             if (line[pos+1]=='>')
  227.                             {
  228.                                 str[0]='>';
  229.                                 str[1]='>';
  230.                                 str[2]='\0';
  231.                                 *check=0;
  232.                                 *num=pos+2;
  233.                                 return str;
  234.                             }
  235.                             else
  236.                             {
  237.                                 str[0]='>';
  238.                                 str[1]='\0';
  239.                                 *check=0;
  240.                                 *num=pos+1;
  241.                                 return str;
  242.                             }
  243.                         }
  244.                         // <
  245.                         if (line[pos]=='<')
  246.                         {
  247.                             str[0]='<';
  248.                             str[1]='\0';
  249.                             *check=0;
  250.                             *num=pos+1;
  251.                             return str;
  252.                         }
  253.                         // ;
  254.                         if (line[pos]==';')
  255.                         {
  256.                             str[0]=';';
  257.                             str[1]='\0';
  258.                             *check=0;
  259.                             *num=pos+1;
  260.                             return str;
  261.                         }
  262.                         // )
  263.                         if (line[pos]==')')
  264.                         {
  265.                             str[0]=')';
  266.                             str[1]='\0';
  267.                             *check=0;
  268.                             *num=pos+1;
  269.                             return str;
  270.                         }
  271.                         // (
  272.                         if (line[pos]=='(')
  273.                         {
  274.                             str[0]='(';
  275.                             str[1]='\0';
  276.                             *check=0;
  277.                             *num=pos+1;
  278.                             return str;
  279.                         }
  280.                     }
  281.                 }
  282.                 //Если встречен обычный символ
  283.                 str[hpos]=line[pos];
  284.                 hpos++;
  285.                 pos++;
  286.                 if (hpos==size)
  287.                 {
  288.                     temp=str;
  289.                     size=size+m;
  290.                     str=realloc(str,size*sizeof(char));
  291.                     if (!str)
  292.                     {
  293.                         free(temp);
  294.                         printf("memory allocation error\n");
  295.                         *check=2;
  296.                         return NULL;
  297.                     }
  298.                 }
  299.             }
  300.         }
  301.        
  302.     }
  303. }
  304.  
  305. // разбитие строки на лексемы
  306. char **parcer (char *line) // последний элемент массива всегда будет иметь значение NULL
  307. {
  308.     int check, pos=0, size=0, strpos=0, hstrpos=0;
  309.     char **base, **temp;
  310.    
  311.     size=t;
  312.     base=malloc(sizeof(char *)*size);
  313.     if (!base)
  314.     {
  315.         printf("memory allocation error\n");
  316.         free(line);
  317.         exit(1);
  318.     }
  319.    
  320.     while(1)
  321.     {
  322.         base[pos]=mystrtok(line+strpos, &check, &hstrpos);
  323.         if (check==2)
  324.         {
  325.             base[pos]=NULL;
  326.             freedom(base);
  327.             exit(1);
  328.         }
  329.         if (check==1)
  330.         {
  331.             if (!base[pos]) // вернулась NULL - парсинг строки завершен
  332.             {
  333.                 return base; //может быть даже такое, что первый элемент этого массива - NULL
  334.             }
  335.             else // вернулась не пустая строка, но обнаружен конец основной строки
  336.             {
  337.                 pos++;
  338.                 if (pos==size)
  339.                 {
  340.                     size=size+1;
  341.                     temp=base;
  342.                     base=realloc(base,size*sizeof(char *));
  343.                     if (!base)
  344.                     {
  345.                         free(temp[pos-1]); // т.к. на новый pos места уже нет
  346.                         temp[pos-1]=NULL;
  347.                         freedom(base);
  348.                         exit(1);
  349.                     }
  350.                 }
  351.                 base[pos]=NULL;
  352.                 return base;
  353.             }
  354.         }
  355.         if (check==0)
  356.         {
  357.             strpos+=hstrpos;
  358.             pos++;
  359.             if (pos==size)
  360.             {
  361.                 size=size+t;
  362.                 temp=base;
  363.                 base=realloc(base,size*sizeof(char *));
  364.                 if (!base)
  365.                 {
  366.                     free(temp[pos-1]); // т.к. на новый pos места уже нет
  367.                     temp[pos-1]=NULL;
  368.                     freedom(base);
  369.                     exit(1);
  370.                 }
  371.             }
  372.         }
  373.     }
  374. }
  375.  
  376. // функция смены текущей директории
  377. int cd (char *str) // проверка на корректность количества аргументов команды cd производится раньше
  378. {
  379.     int k;
  380.     if (str==NULL) //значит пользователю надо перейти в домашний каталог
  381.     {
  382.         k=chdir(getenv("HOME"));
  383.         if (k==-1)
  384.         {
  385.             printf ("В указанный каталог перейти не удалось\n");
  386.         }
  387.         return k;
  388.     }
  389.     else
  390.     {
  391.         k=chdir(str);
  392.         if (k==-1)
  393.         {
  394.             printf ("В указанный каталог перейти не удалось\n");
  395.         }
  396.         return k;
  397.     }
  398. }
  399.  
  400. //используется в конвейере, осуществляя непосредственно создание нового процесса и замену тела
  401. int function_call (char **base, int fd[2], int flag) // вернет -1 в случае неудачного fork, -2  в случае неудачного exec
  402. {   // flag=1 говорит о том, что подан последний процесс из конвейера
  403.     // base представляет из себя массив строк, заканчивающийся NULL - ссылкой
  404.     int a;
  405.     if (base[0]==NULL)
  406.     {
  407.         dup2(fd[0],0);
  408.         close(fd[0]);
  409.         close(fd[1]);
  410.         return -2;
  411.     }
  412.     a=fork();
  413.     if (a==-1)
  414.     {
  415.         printf("Не удалось породить процесс\n");
  416.         return (-1);
  417.     }
  418.     if (a>0)
  419.     {
  420.         dup2(fd[0],0);
  421.         close(fd[0]);
  422.         close(fd[1]);
  423.     }
  424.     else
  425.     {
  426.         if (flag!=1)
  427.         {
  428.             dup2(fd[1],1);
  429.         }
  430.         close(fd[1]);
  431.         close(fd[0]);
  432.         a=execvp(base[0],base);
  433.         if (a==-1)
  434.         {
  435.             //printf("Не удалось запустить программу - %s\n",base[0]);
  436.             kill(getppid(),SIGUSR1);
  437.             return -2;
  438.         }
  439.     }
  440.     return 0;
  441. }
  442.  
  443. void all_str_output (char **base)
  444. {
  445.     int pos=0;
  446.     while ((base[pos]))
  447.     {
  448.         printf("%s\n",base[pos]);
  449.         pos++;
  450.     }
  451. }
  452.  
  453. //конвейер
  454. int pipeline (char** base, int bcheck) // если bcheck==1 - то вызываемый процесс фоновый (не нужно восстанавливать реакцию на SIGINT)
  455. {
  456.     int len=0, i=0, j=0, fd[2], k;
  457.     char **lastinstr, *str;
  458.     if ((base[0]!=NULL)&&(strcmp(base[0],"cd")==0))
  459.     {
  460.         if ((base[1]!=NULL)&&(base[2]!=NULL)) //ошибки не случится, т.к. при false в первом условии проверки второго не осуществиться
  461.         {
  462.             printf("cd: Некорректное число аргументов\n");
  463.         }
  464.         else
  465.         {
  466.             cd(base[1]);
  467.         }
  468.         return 0;
  469.     }
  470.     k=fork();
  471.     if (k==-1)
  472.     {
  473.         printf("Породить процесс не удалось\n");
  474.         return -1;
  475.     }
  476.     if (k==0)
  477.     {
  478.         if (bcheck!=1)
  479.         {
  480.             signal(SIGINT,SIG_DFL);
  481.         }
  482.         lastinstr=base;
  483.         while (base[i])
  484.         {
  485.             if (strcmp(base[i],"|")==0)
  486.             {
  487.                 len++;
  488.             }
  489.             i++;
  490.         }
  491.         j=0;
  492.         i=0;
  493.         while (i<len)
  494.         {
  495.             while (strcmp(base[j],"|")!=0)
  496.             {
  497.                 j++;
  498.             }
  499.             i++;
  500.             j++;
  501.             k=pipe(fd);
  502.             if (k==-1)
  503.             {
  504.                 printf("Не удалось установить связь между процессами конвейера\n");
  505.                 return -2;
  506.                 // тут еще надо подумать
  507.             }
  508.             str=base[j-1];
  509.             base[j-1]=NULL;
  510.             k=function_call(lastinstr, fd, 0);
  511.             base[j-1]=str;
  512.             lastinstr=base+j;
  513.             if (k==-2) // возврат в теле сыновнего процесса
  514.             {
  515.                 return -2;
  516.             }
  517.             if (k==-1)
  518.             {
  519.                 while(wait(NULL)!=-1);
  520.                 return -2;
  521.             }
  522.             // k = 0 - всё хорошо
  523.         }
  524.         // на момент выхода из цикла не вызвана последняя программа из конвейера
  525.         k=pipe(fd);
  526.         if (k==-1)
  527.         {
  528.             printf("Не удалось установить связь между процессами конвейера\n");
  529.             return -2;
  530.             // тут еще надо подумать
  531.         }
  532.         k=function_call(lastinstr, fd, 1);
  533.         while(wait(NULL)!=-1);
  534.         return -2;
  535.     }
  536.     wait(NULL);
  537.     return 0;
  538. }
  539.  
  540. // обработка перенаправлений
  541. int redirection (char **base, int bcheck) // требуем, чтобы перенаправления были последними
  542. {   // если bcheck==1 - то вызываемый процесс фоновый (не нужно восстанавливать реакцию на SIGINT)
  543.     int len=0,fdrd,fdwr,hfd1,hfd2,checkrd=0,checkwr=0,res=0;
  544.     char *str;
  545.     while (base[len]) // кол-во переданных слов
  546.     {
  547.         len++;
  548.     }
  549.     hfd1=dup(1);
  550.     hfd2=dup(0);
  551.     if ((len>=4)&&(strcmp(base[len-2],">>")==0)&&(strcmp(base[len-4],">")==0)&&(strcmp(base[len-3],base[len-1])==0))
  552.     {
  553.         fdwr=open(base[len-1], O_CREAT | O_TRUNC | O_WRONLY | O_EXCL, 0666);
  554.         if (fdwr==-1)
  555.         {
  556.             fdwr=open(base[len-1], O_TRUNC | O_WRONLY); // возможно, файл уже существует
  557.             if (fdwr==-1)
  558.             {
  559.                 printf("Перенаправление вывода организовать не удалось\n");
  560.                 goto jmp;
  561.             }
  562.         }
  563.         checkwr=1;
  564.         dup2(fdwr,1);
  565.         str=base[len-4];
  566.         base[len-4]=NULL;
  567.         res=pipeline(base,bcheck);
  568.         base[len-4]=str;
  569.         goto jmp;
  570.     }
  571.     if ((len>=4)&&(strcmp(base[len-2],">>")==0)&&(strcmp(base[len-4],"<")==0)&&(strcmp(base[len-3],base[len-1])==0))
  572.     {
  573.         printf("Недопустимая конструкция (входной и выходной файлы совпадают)\n");
  574.         goto jmp;
  575.     }
  576.     if ((len>=4)&&(strcmp(base[len-2],">")==0)&&(strcmp(base[len-4],"<")==0)&&(strcmp(base[len-3],base[len-1])==0))
  577.     {
  578.         printf("Недопустимая конструкция (входной и выходной файлы совпадают)\n");
  579.         goto jmp;
  580.     }
  581.     if ((len>=4)&&(strcmp(base[len-2],"<")==0)&&(strcmp(base[len-4],">")==0)&&(strcmp(base[len-3],base[len-1])==0))
  582.     {
  583.         printf("Недопустимая конструкция (входной и выходной файлы совпадают)\n");
  584.         goto jmp;
  585.     }
  586.     if ((len>=4)&&(strcmp(base[len-2],"<")==0)&&(strcmp(base[len-4],">>")==0)&&(strcmp(base[len-3],base[len-1])==0))
  587.     {
  588.         printf("Недопустимая конструкция (входной и выходной файлы совпадают)\n");
  589.         goto jmp;
  590.     }
  591.     if (len>=2) // потому что ситуация подачи на ввод, например >> text - корректна
  592.     {
  593.         if (strcmp(base[len-2],">")==0)
  594.         {
  595.             fdwr=open(base[len-1], O_CREAT | O_TRUNC | O_WRONLY | O_EXCL, 0666);
  596.             if (fdwr==-1)
  597.             {
  598.                 fdwr=open(base[len-1], O_TRUNC | O_WRONLY); // возможно, файл уже существует
  599.                 if (fdwr==-1)
  600.                 {
  601.                     printf("Перенаправление вывода организовать не удалось\n");
  602.                     goto jmp;
  603.                 }
  604.             }
  605.             checkwr=1;
  606.             dup2(fdwr,1);
  607.         }
  608.         if (strcmp(base[len-2],">>")==0)
  609.         {
  610.             fdwr=open(base[len-1], O_CREAT | O_APPEND | O_WRONLY | O_EXCL, 0666);
  611.             if (fdwr==-1)
  612.             {
  613.                 fdwr=open(base[len-1], O_APPEND| O_WRONLY);
  614.                 if (fdwr==-1)
  615.                 {
  616.                     printf("Перенаправление вывода организовать не удалось\n");
  617.                     goto jmp;
  618.                 }
  619.             }
  620.             checkwr=1;
  621.             dup2(fdwr,1);
  622.         }
  623.         if (strcmp(base[len-2],"<")==0)
  624.         {
  625.             fdrd=open(base[len-1], O_RDONLY);
  626.             if (fdrd==-1)
  627.             {
  628.                 printf("Перенаправление ввода организовать не удалось\n");
  629.                 goto jmp;
  630.             }
  631.             checkrd=1;
  632.             dup2(fdrd,0);
  633.         }
  634.         if (len>=4)
  635.         {
  636.             if ((checkrd==1)||(checkwr==1))
  637.             {
  638.                 if ((checkrd==1)&&(strcmp(base[len-4],">")==0))
  639.                 {
  640.                     fdwr=open(base[len-3], O_CREAT | O_TRUNC | O_WRONLY | O_EXCL, 0666);
  641.                     if (fdwr==-1)
  642.                     {
  643.                         fdwr=open(base[len-3], O_TRUNC | O_WRONLY);
  644.                         if (fdwr==-1)
  645.                         {
  646.                             printf("Перенаправление вывода организовать не удалось\n");
  647.                             goto jmp;
  648.                         }
  649.                     }
  650.                     checkwr=1;
  651.                     dup2(fdwr,1);
  652.                 }
  653.                 if ((checkrd==1)&&(strcmp(base[len-4],">>")==0))
  654.                 {
  655.                     fdwr=open(base[len-3], O_CREAT | O_APPEND | O_WRONLY | O_EXCL, 0666);
  656.                     if (fdwr==-1)
  657.                     {
  658.                         fdwr=open(base[len-3], O_APPEND| O_WRONLY);
  659.                         if (fdwr==-1)
  660.                         {
  661.                             printf("Перенаправление вывода организовать не удалось\n");
  662.                             goto jmp;
  663.                         }
  664.                     }
  665.                     checkwr=1;
  666.                     dup2(fdwr,1);
  667.                 }
  668.                 if ((checkwr==1)&&(strcmp(base[len-4],"<")==0))
  669.                 {
  670.                     fdrd=open(base[len-3], O_RDONLY);
  671.                     if (fdrd==-1)
  672.                     {
  673.                         printf("Перенаправление ввода организовать не удалось\n");
  674.                         goto jmp;
  675.                     }
  676.                     checkrd=1;
  677.                     dup2(fdrd,0);
  678.                 }
  679.                 if ((checkwr==1)&&(checkrd==1))
  680.                 {
  681.                     str=base[len-4];
  682.                     base[len-4]=NULL;
  683.                     res=pipeline(base,bcheck);
  684.                     base[len-4]=str;
  685.                 }
  686.                 else
  687.                 {
  688.                     str=base[len-2];
  689.                     base[len-2]=NULL;
  690.                     res=pipeline(base,bcheck);
  691.                     base[len-2]=str;
  692.                 }
  693.             }
  694.             else
  695.             {
  696.                 res=pipeline(base,bcheck);
  697.             }
  698.         }
  699.         else // меньше 4 слов в команде
  700.         {
  701.             if ((checkrd==1)||(checkwr==1)) // только одно из перенаправлений имело место
  702.             {
  703.                 str=base[len-2];
  704.                 base[len-2]=NULL;
  705.                 res=pipeline(base,bcheck);
  706.                 base[len-2]=str;
  707.             }
  708.             else // перенаправлений не было
  709.             {
  710.                 res=pipeline(base,bcheck);
  711.             }
  712.         }
  713.     }
  714.     else // меньше 2 слов в команде
  715.     {
  716.         res=pipeline(base,bcheck);
  717.     }
  718.     jmp:
  719.     if (checkwr==1)
  720.     {
  721.         dup2(hfd1,1);;
  722.         close(fdwr);
  723.     }
  724.     if (checkrd==1)
  725.     {
  726.         dup2(hfd2,0);
  727.         close(fdrd);
  728.     }
  729.     close(hfd1);
  730.     close(hfd2);
  731.     return res;
  732. }
  733.  
  734. // обработчик фонового режима (и ;)
  735. int background (char **base)
  736. {
  737.     char **lastcom, *temp;
  738.     int i=0, a, fd[2];
  739.     lastcom=base;
  740.     jmp:
  741.     while ((base[i]!=NULL)&&(strcmp(base[i],"&")!=0)&&(strcmp(base[i],";")!=0)) // сравнения должны быть именно в таком порядке, иначе в случае strcmp(NULL,...) произойдет страшное
  742.     {
  743.         i++;
  744.     }
  745.     if ((base[i]!=NULL)&&(strcmp(base[i],"&")==0))
  746.     {
  747.         a=fork();
  748.         if (a==-1)
  749.         {
  750.             printf("Не удалось породить процесс\n");
  751.             return -2;
  752.         }
  753.         if (a==0)
  754.         {
  755.             pipe(fd);
  756.             a=fork();
  757.             if (a==-1)
  758.             {
  759.                 printf("Не удалось породить процесс\n");
  760.                 return -2;
  761.             }
  762.             if (a==0)
  763.             {
  764.                 read(fd[0],&a,sizeof(int));
  765.                 close(fd[0]);
  766.                 close(fd[1]);
  767.                 while(getppid()==a)
  768.                 {
  769.                 }
  770.                 temp=base[i];
  771.                 base[i]=NULL;
  772.                 a=open("/dev/null", O_WRONLY);
  773.                 dup2(a,0);
  774.                 redirection(lastcom,1);
  775.                 close(a);
  776.                 base[i]=temp;
  777.                 return -2;
  778.             }
  779.             // сюда может попасть только процесс-отец
  780.             a=getpid();
  781.             write(fd[1],&a,sizeof(int));
  782.             close(fd[0]);
  783.             close(fd[1]);
  784.             return -2;
  785.         }
  786.         else
  787.         {
  788.             wait(NULL); // программа основного shell
  789.         }
  790.     }
  791.     if ((base[i]!=NULL)&&(strcmp(base[i],";")==0))
  792.     {
  793.         // доделаю потом
  794.     }
  795.     if (base[i]!=NULL)
  796.     {
  797.         i++;
  798.         lastcom=base+i;
  799.         goto jmp;
  800.     }
  801.     //на данный момент не выполнился последний нефоновый процесс (ситуацию "proc &" рассматриваем как proc и пустой процесс)
  802.     return (redirection(lastcom,0));
  803. }
  804.  
  805. /*
  806. // пока что отказываемся от использования этой функции
  807. int parsing_sequence_of_commands (char **base) // в этой функции потом надо будет реализовывать фоновый режим
  808. {
  809.     int i=0,lastarg=-1;
  810.     char str[2], *hstr;
  811.     str[0]=';';
  812.     str[1]='\0';
  813.     while (base[i]!=NULL)
  814.     {
  815.         if (strcmp(base[i],str)==0)
  816.         {
  817.             hstr=base[i];
  818.             base[i]=NULL;
  819.             if (function_call(base+lastarg+1)==-2)
  820.             {
  821.                 base[i]=hstr;
  822.                 return -1; // возврат при неккоректном exec-е
  823.             } // здесь нужен будет вызов функции, которая продолжит дальнейший разбор
  824.             base[i]=hstr;
  825.             lastarg=i;
  826.         }
  827.         i++;
  828.     }
  829.     if ((lastarg+1)!=i)
  830.     {
  831.         if (function_call(base+lastarg+1)==-2)
  832.         {
  833.             return -1;
  834.         }
  835.     }
  836.     // иначе - пустая команда
  837.     return 0;
  838. } */
  839.  
  840. int main (int argc, char **argv)
  841. {
  842.     signal(SIGINT, SIG_IGN);
  843.     signal(SIGUSR1, Sighndlr);
  844.     int a, check=0, fd;
  845.     char *s, **base;
  846.     if (argc==1)
  847.     {
  848.         fd=dup(0);
  849.     }
  850.     else
  851.     {
  852.         if (argc==2)
  853.         {
  854.             fd=open(argv[1], O_RDONLY);
  855.             check=1;
  856.             if (fd==-1)
  857.             {
  858.                 printf("Нет доступа к файлу\n");
  859.                 return 0;
  860.             }
  861.         }
  862.         else
  863.         {
  864.             printf("Некорректное число аргументов командной строки\n");
  865.             return 0;
  866.         }
  867.     }
  868.    
  869.     do {
  870.         s=read_line(fd,&a);
  871.         //printf("%d\n",a);
  872.         //printf("\n");
  873.         //printf("%s\n",s);
  874.         base=parcer(s);
  875.         //printf("В массив строк занесены следующие строки\n");
  876.         //all_str_output(base);
  877.         if (background(base)==-2)
  878.         {
  879.             freedom(base);
  880.             free(s);
  881.             return 0;
  882.         }
  883.         freedom(base);
  884.         free(s);
  885.     } while (a==0);
  886.     if (check==1)
  887.     {
  888.         close(fd);
  889.     }
  890.     return 0;
  891. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement