zhukov000

bebra

Nov 23rd, 2021 (edited)
599
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.92 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <setjmp.h>
  5. #include <time.h>
  6.  
  7. #define LENGTH 1000
  8.  
  9. // область памяти для запоминания состояния процесса
  10. sigjmp_buf buffer;
  11.  
  12. // счетчик количества пришедших прерываний SIGINT
  13. int count_int = 10;
  14.  
  15. int main() {
  16.  
  17.     void callBack13(); // имя функции обработки прерывания
  18.  
  19.     char data[LENGTH+1]; // буфер для считывания информации из канала
  20.    
  21.     int vv; // флаг завершения работы программы
  22.     int gg = 0;
  23.     int g[2]; // дескрипторы межпроцессного канала g[0] - для чтения, g[1] - для записи
  24.  
  25.     // обнуляем буфер для считывания информации из канала
  26.     for(int i=0; i<=LENGTH; ++i) {
  27.         data[i] = '\0';
  28.     }
  29.  
  30.     signal(SIGINT, callBack13); // уведомление, что в случаем SIGINT выполнять callBack13
  31.     sigsetjmp(buffer, 1); // сохранить текущее состояние процесса в буфер
  32.    
  33.     vv = 0;
  34.     do {
  35.         sigsetjmp(buffer, 1);
  36.         pipe(g);
  37.         if(fork() == 0) { // child
  38.             close(1);       // закрываем стандартный вывод
  39.             close(g[0]);    // закрываем межпроцессный канал на чтение
  40.             dup2(g[1], 1);  // дублирование дескриптора канала на стандартный вывод
  41.             close(g[1]);    // удалить копию
  42.            
  43.             // выполнение команды, результаты направляются в межпроцессный канал
  44.             execl("/usr/bin/w", "w", "-hs", NULL);
  45.            
  46.             exit(0); // завершить выполнение процесса-потомка
  47.         }
  48.         else { // parent
  49.             pid_t cpid = wait(NULL); // ожадение окончания процесса потомка
  50.             // вывод pid потомка и родителя
  51.             printf("Parent pid = %d, child pid = %d\n", getpid(), cpid);
  52.            
  53.             // сохранение состояния процесса
  54.             sigsetjmp(buffer, 1);
  55.             close(g[1]);
  56.  
  57.             // считывание данных из межпроцессного канала
  58.             read(g[0], data, LENGTH);
  59.            
  60.             char username[33]; // строка для хранения имени пользователя
  61.             for(int i=0; i<33; ++i) {
  62.                 username[i] = '\0';
  63.             }
  64.            
  65.             // выделяем имя пользователя из данных
  66.             int j = 0;
  67.             for(int i=0; i <= LENGTH && data[i] != '\0'; ++i) {
  68.                 if(data[i] == ' ') {
  69.                     if (username[0] != '\0') { // строка не пустая
  70.                         username[j] = '\0';
  71.                         printf("%s\n", username);   // выводим имя пользователя
  72.                         username[0] = '\0';
  73.                         sleep(1);
  74.                     }
  75.                 } else if (j < 32) {
  76.                     username[j++] = data[i];
  77.                 } else if (data[i] == '\n') {
  78.                     j = 0;
  79.                 }
  80.             }
  81.         }
  82.     } while(vv);
  83.  
  84.     sigsetjmp(buffer, 1);
  85.     printf("Good night, sweet prince!\n");
  86.  
  87.     return 0;
  88. }
  89.  
  90. // функция обработки сигнала SIGINT
  91. void callBack13() {
  92.     count_int --;
  93.     signal(SIGINT, callBack13);
  94.  
  95.     if(count_int <= 0) { // если прерывания произошли 10 раз, то выйти из программы
  96.         printf("Good bye!\n");
  97.         exit(1);
  98.     }
  99.    
  100.     time_t rawTime;
  101.     struct tm* timeInfo;
  102.  
  103.     time(&rawTime); // получить текущее время
  104.     timeInfo = localtime(&rawTime); // преобразовать его в локальный формат
  105.  
  106.     printf("Get interrupt at %s", asctime(timeInfo)); // вывести сообщение о получении прерывания
  107.     printf("%d times left\n", count_int); // сколько раз осталось
  108.  
  109.     siglongjmp(buffer, 1); // восстановить состояние процесса к последнему сохраненному
  110. }
Advertisement
Add Comment
Please, Sign In to add comment