BorrowTheProgrammer

fedoruk_lab1_11

Apr 12th, 2022 (edited)
387
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.59 KB | None | 0 0
  1. #include <sys/wait.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <signal.h>
  7. #include <ctype.h>
  8.  
  9. void reverse(char*);
  10. void changeCase(char*);
  11. void koi8er(char*);
  12. void swap(char*);
  13. void catchSignal(int);
  14. void commandToLowerCase(char*);
  15. int flag;
  16.  
  17. void reverse(char *str) {
  18.   char* end = str;
  19.   char buf;
  20.  
  21.   while (*end != '\0') end++;
  22.   end--;
  23.   str+=2;
  24.  
  25.   while (end > str) {
  26.     buf = *str;
  27.     *str = *end;
  28.     *end = buf;
  29.     str++;
  30.     end--;
  31.   }
  32. }
  33.  
  34. void swap(char *str) {
  35.   char buf;
  36.   char *ptr;
  37.  
  38.   for (int i = 0; i < 2; i++) {
  39.     if (*str != '\0') {
  40.       str++;
  41.     }
  42.   }
  43.  
  44.   while(*str != '\0') {
  45.     buf = *str;
  46.     ptr = str;
  47.     if (*(++ptr) == '\0')  break;    
  48.     *str = *ptr;
  49.     *ptr = buf;
  50.     str+=2;
  51.   }
  52. }
  53.  
  54. void koi8er(char* str) {
  55.   int len;
  56.   int dig = 0;
  57.   int i = 0;
  58.   char c;
  59.   len = (int)strlen(str);
  60.  
  61.   while ((c = str[i]) != '\0') {
  62.     if (c <= (int)'Z' && c >= (int)'A') {
  63.       str[i] = c + 32;
  64.       i++;
  65.       continue;
  66.     } else if (c <= (int)'z' && c >= (int)'a') {
  67.       str[i] = c - 32;
  68.       i++;
  69.       continue;
  70.     } else {
  71.       str[i] = c;
  72.       i++;
  73.       continue;
  74.     }
  75.   }
  76.  
  77.   for (dig = 0; dig < len; dig++) {
  78.     str[dig] += 128;
  79.   }
  80.  
  81. }
  82.  
  83. void changeCase(char *strcase) {
  84.   int len, ch=0, i=0;
  85.   char c;
  86.   char sw = strcase[1];
  87.   len = (int)strlen(strcase);
  88.  
  89.   switch (sw) {
  90.     case '1':
  91.       for (ch = 0; ch < len; ch++) {
  92.         strcase[ch] = toupper(strcase[ch]);
  93.       }  
  94.       break;
  95.     case '2':
  96.       for (ch = 0; ch < len; ch++) {
  97.         strcase[ch] = tolower(strcase[ch]);
  98.       }
  99.       break;
  100.     case '3':
  101.       while((c = strcase[i]) != '\0') {
  102.         if(c <= (int)'Z' && c >= (int)'A') {
  103.           strcase[i] = c + 32;
  104.           i++;
  105.           continue;
  106.         } else if(c <= (int)'z' && c >= (int)'a') {
  107.           strcase[i] = c - 32;
  108.           i++;
  109.           continue;
  110.         } else {
  111.           strcase[i] = c;
  112.           i++;
  113.           continue;
  114.       }
  115.     }  
  116.  }
  117. }
  118.  
  119. void commandToLowerCase(char *str) {
  120.   char *ptr = str;
  121.   char letter;
  122.   char sleshSymbol = '/';
  123.  
  124.   char *slesh = strchr(str, (int)sleshSymbol);
  125.  
  126.   if (slesh == NULL) {
  127.     *ptr = '/';
  128.     ptr++;
  129.   }
  130.  
  131.   while(*ptr != '\0') {
  132.     letter = tolower(*ptr);
  133.     *str = letter;
  134.     ptr++;
  135.   }
  136.   printf("%s\n", str);
  137. }
  138.  
  139. // Функция перехвата сигнала прерывания для ввода команд.
  140. void catchSignal(int sig) {
  141.   signal(SIGINT, catchSignal);
  142.   char userCommand[10];
  143.   char inputString[] = "\nВведите строку\n";
  144.  
  145.   printf("\n\t----------------------------------------------\n");
  146.   printf("\n\tВыберете тип преобразования сроки процессами\n\n");
  147.  
  148.   printf("%s%s%s%s%s",
  149.     "\tСписок команд для первого процесса :\n\t",
  150.     "/def1 - трансляция строки в неизменном виде;\n\t",
  151.     "/invert - инвертирование строки - первый символ становится последним и т.д.;\n\t",
  152.     "/swap - обмен соседних символов - нечетный становится на место четного и наоборот;\n\t",
  153.     "/koi8 - перевод в кодировку КОИ-8.\n"
  154.   );
  155.  
  156.   printf("%s%s%s%s%s",
  157.     "\n\tСписок команд для второго процесса :\n\t",
  158.     "/def2 - трансляция строки в неизменном виде;\n\t",
  159.     "/upreg - перевод всех символов строки в \"верхний регистр\";\n\t",
  160.     "/lowreg - перевод всех символов строки в \"нижний регистр\";\n\t",
  161.     "/swreg - смена \"регистра\" всех символов строки;\n"
  162.   );
  163.  
  164.   printf("\n\t**************************************\n");
  165.   printf("\n\t/out - завершение программы\n");
  166.   printf("\n\t**************************************\n");
  167.  
  168.   printf("Введите команду:\n");
  169.   scanf("%s", userCommand);
  170.  
  171.   if (strcmp(userCommand, "/invert") == 0) {
  172.     flag = flag % 10 + 10;
  173.     printf("%s", inputString);
  174.   }
  175.  
  176.   if (strcmp(userCommand, "/swap") == 0) {
  177.     flag = flag % 10 + 20;
  178.     printf("%s", inputString);
  179.   }
  180.  
  181.   if (strcmp(userCommand, "/koi8") == 0) {
  182.     flag = flag % 10 + 30;
  183.     printf("%s", inputString);
  184.   }
  185.  
  186.   if (strcmp(userCommand, "/def2") == 0) {
  187.     flag = (flag / 10) * 10;
  188.     printf("%s", inputString);
  189.   }
  190.  
  191.   if (strcmp(userCommand, "/upreg") == 0) {
  192.     flag = (flag / 10) * 10 + 1;
  193.     printf("%s", inputString);
  194.   }
  195.  
  196.   if (strcmp(userCommand, "/lowreg") == 0) {
  197.     flag = (flag / 10) * 10 + 2;
  198.     printf("%s", inputString);
  199.   }
  200.  
  201.   if (strcmp(userCommand, "/swreg") == 0) {
  202.     flag = (flag / 10) * 10 + 3;
  203.     printf("%s", inputString);
  204.   }
  205.  
  206.   if (strcmp(userCommand, "/out") == 0) {
  207.     flag = 44;
  208.     printf("\tВыход из программы\n");
  209.   }
  210.  
  211. }
  212.  
  213. int main(int argc, char * argv[]) {
  214.  
  215.   // дискрипторы для канала между процессами 0 и 1
  216.   int pipe01[2];
  217.  
  218.   // дискрипторы для канала между процессами 1 и 2
  219.   int pipe12[2];
  220.  
  221.   // pid для двух сыновей-процессов
  222.   pid_t pid0 = getpid(), cpid1, cpid2, ppid;
  223.  
  224.   // для кореневого процесса
  225.   char buf[50];
  226.   // для процесса 1
  227.   char inputer[50];
  228.   // для процесса 2
  229.   char final[50];
  230.   int i = 0;
  231.  
  232.   // создание канала между процессами 0 и 1
  233.   if (pipe(pipe01) < 0) {
  234.     perror("Ошибка создания канала между процессами 0 и 1!\n");
  235.     exit(-1);
  236.   }
  237.  
  238.   // создание первой копии процесса отца
  239.   cpid1 = fork();
  240.  
  241.   if (cpid1 < 0) {
  242.  
  243.     perror("Ошибка создания процесса 1!\n");
  244.     exit(-2);
  245.  
  246.   } else if (cpid1 == 0) {
  247.     // процесс сын
  248.     if (pipe(pipe12) < 0) {
  249.         perror("Ошибка создания канала между процессами 1 и 2!\n");
  250.         exit(-3);
  251.     }
  252.  
  253.     cpid2 = fork();
  254.  
  255.     if (cpid2 < 0) {
  256.         perror("Ошибка создания процесса 2!\n");
  257.         exit(-4);
  258.     }
  259.  
  260.   }
  261.  
  262.   if ((getpid() != pid0) && cpid2 != 0) {
  263.     // код для процесса 1
  264.  
  265.     // закрыть дискриптор для записи в канал 0 -> 1
  266.     close(pipe01[1]);
  267.     // закрыть дискриптор для чтения из канал 1 -> 2
  268.     close(pipe12[0]);
  269.  
  270.     // игнорировать сигнал прерывания процесса
  271.     signal(SIGINT, SIG_IGN);
  272.  
  273.     while (1) {
  274.       i = 0;
  275.       kill(getpid(), SIGSTOP);
  276.  
  277.       // читать из канало 01
  278.       while (read(pipe01[0], &buf[i], 1) && buf[i] != EOF) {
  279.         i++;
  280.       }
  281.       buf[i] = '\0';
  282.  
  283.       switch (buf[0]) {
  284.         case '1':
  285.           reverse(buf);
  286.           break;
  287.         case '2':
  288.           swap(buf);
  289.           break;
  290.         case '3':
  291.           koi8er(buf);
  292.           break;
  293.         default:
  294.           break;
  295.       }
  296.  
  297.       int m = 2;
  298.       write(1, "\tПроцесс 1 : ", 20);
  299.  
  300.       // вывод в терминал результат работы процесса 1
  301.       while (m < strlen(buf)) {
  302.         write(1, &buf[m], 1);
  303.         m++;
  304.       }
  305.  
  306.       printf("\n");
  307.  
  308.       buf[i] = EOF;
  309.       // писать в канал 1 -> 2
  310.       write(pipe12[1], buf, i + 1);
  311.       // пробудить процесс 2
  312.       kill(cpid2, SIGCONT);
  313.     }
  314.     _exit(EXIT_SUCCESS);
  315.  
  316.   } else if ((getpid() != pid0) && (cpid2 == 0)) {
  317.     // код для процесса 2
  318.  
  319.     // закрыть дискриптор для чтения из канала 0 -> 1
  320.     close(pipe01[0]);
  321.     // закрыть дискриптор для записи в канал 0 -> 1
  322.     close(pipe01[1]);
  323.     // закрыть дискриптор для записи в канал 1 -> 2
  324.     close(pipe12[1]);
  325.  
  326.     signal(SIGINT, SIG_IGN);
  327.  
  328.     while (1) {
  329.       i = 0;
  330.       kill(getpid(), SIGSTOP);
  331.  
  332.       while (read(pipe12[0], &final[i], 1) && final[i] != EOF) {
  333.         i++;
  334.       }
  335.  
  336.       final[i] = '\0';
  337.  
  338.       changeCase(final);
  339.  
  340.       i = 2;
  341.       write(1, "\tПроцесс 2 : ", 20);
  342.       while (i < strlen(final)) {
  343.         write(1, & final[i], 1);
  344.         i++;
  345.       }
  346.       printf("\n");
  347.     }
  348.   } else {
  349.     // код для корневого процесса
  350.  
  351.     // закрыть дискриптор для чтения из канала 0 -> 1
  352.     close(pipe01[0]);
  353.     // обработать сигнал прерывания процесса
  354.     signal(SIGINT, catchSignal);
  355.  
  356.     printf("Введите строку. Для смены типа обработки нажмите Ctrl + C:\n");
  357.  
  358.     inputer[0] = inputer[1] = '0';
  359.  
  360.     // читать строку из стандартного потока ввода
  361.     while (1) {
  362.       i = 2;
  363.       do {
  364.         read(0, &inputer[i], 1);
  365.         i++;
  366.       } while (inputer[i - 1] != '\n');
  367.  
  368.       char transl;
  369.       int m = 0;
  370.  
  371.       for (m = 0; m < 2; m++) {
  372.         if (!m) {
  373.           transl = flag / 10;
  374.         } else {
  375.           transl = flag % 10;
  376.         }
  377.         switch (transl) {
  378.         case 0:
  379.           inputer[m] = '0';
  380.           break;
  381.         case 1:
  382.           inputer[m] = '1';
  383.           break;
  384.         case 2:
  385.           inputer[m] = '2';
  386.           break;
  387.         case 3:
  388.           inputer[m] = '3';
  389.           break;
  390.         default:
  391.           printf(".");
  392.           break;
  393.         }
  394.       }
  395.  
  396.       if (flag == 44) {
  397.  
  398.         // если команда out - удалить два процесса-сына 1 и 2
  399.         kill(cpid1, SIGTERM);
  400.         kill(cpid2, SIGTERM);
  401.         exit(0);
  402.       }
  403.  
  404.       inputer[i - 1] = '\0';
  405.       m = 2;
  406.  
  407.       write(1, "\tПроцесс 0 : ", 20);
  408.  
  409.       // писать в поток стандартного вывода строку, введенную через поток стандартного ввода
  410.       while (m < strlen(inputer)) {
  411.         write(1, &inputer[m], 1);
  412.         m++;
  413.       }
  414.  
  415.       printf("\n");
  416.  
  417.       inputer[i - 1] = EOF;
  418.  
  419.       // передать строку в канал 0 -> 1 (запись)
  420.       write(pipe01[1], inputer, i);
  421.       // пробудить процесс 1
  422.       kill(cpid1, SIGCONT);
  423.     }
  424.     wait(NULL);
  425.     exit(EXIT_SUCCESS);
  426.   }
  427. }
Add Comment
Please, Sign In to add comment