Advertisement
anticlown

Lab_7_1(search byte sequence in files in directory with processes)

Dec 2nd, 2023 (edited)
1,025
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.06 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <dirent.h>
  5. #include <sys/stat.h>
  6. #include <sys/types.h>
  7. #include <fcntl.h>
  8. #include <unistd.h>
  9. #include <stdbool.h>
  10. #include <sys/wait.h>
  11. #include <errno.h>
  12. #include <limits.h>
  13.  
  14. typedef struct dirent DIRENT;
  15. typedef struct stat STAT;
  16.  
  17. /*      search func start       */
  18. void searchFiles(const char *searchingString, const char *catalogPath, FILE *outputFilePointer, const int maxNumOfProcesses, int *currNumOfProcesses)
  19. {
  20.     const int PATH_LENGTH = 255;
  21.     DIR *dir;
  22.     dir = opendir(catalogPath);
  23.     if (!dir) // каталог не открылся
  24.     {
  25.         fprintf(stderr, "\t\t\tОшибка при открытии %s!\n", catalogPath);
  26.         return;
  27.     };
  28.  
  29.     struct dirent *entry;
  30.     while ((entry = readdir(dir)) != NULL) // пока не кончатся файлы в каталоге
  31.     {
  32.         char fullPath[PATH_LENGTH];
  33.         snprintf(fullPath, PATH_LENGTH, "%s/%s", catalogPath, entry->d_name);
  34.  
  35.         STAT buffer;
  36.         stat(fullPath, &buffer);
  37.  
  38.         if (S_ISREG(buffer.st_mode)) // если текущий файл(при просмотре в каталоге) является регулярным
  39.         {
  40.  
  41.             pid_t childPid = fork();
  42.             if (childPid == -1) // не удалось создать процесс
  43.             {
  44.                 fprintf(stderr, "Ошибка при создании дочернего процесса!\n");
  45.                 return;
  46.             }
  47.  
  48.             if (childPid == 0) // процесс является дочерним
  49.             {
  50.                 fprintf(stdout, "\tPID: %d, PPID: %d, Путь: %s, Название: %s\n", getpid(), getppid(), fullPath, entry->d_name);
  51.                 fprintf(outputFilePointer, "\tPID: %d, PPID: %d, Путь: %s, Название: %s\n", getpid(), getppid(), fullPath, entry->d_name);
  52.  
  53.                 FILE *fileForCheckPointer;
  54.                 if ((fileForCheckPointer = fopen(fullPath, "rb")) == NULL) // файл не открылся для побитового чтения
  55.                 {
  56.                     fprintf(stdout, "Не удалось прочитать данные в файле %s.\n", entry->d_name);
  57.                 }
  58.                 else
  59.                 {
  60.                     char tempChar;
  61.                     int byteCounter = 0;
  62.                     bool isFound = false;
  63.  
  64.                     while (!feof(fileForCheckPointer))
  65.                     {
  66.                         byteCounter++;
  67.                         tempChar = getc(fileForCheckPointer);
  68.                         if (tempChar == searchingString[0]) // если текущий выбранный символ в файле совпал с первым символом проверочной строки
  69.                         {
  70.                             int i = 1;
  71.                             isFound = true;
  72.                             while (searchingString[i] != '\0' && isFound) { //пока строка не кончается и сравниваемые символы равны
  73.                                 isFound = searchingString[i] == getc(fileForCheckPointer);
  74.                                 i++;
  75.                             }
  76.                         }
  77.                     }
  78.  
  79.                     if (isFound)
  80.                     {
  81.                         fprintf(stdout, "\t\tФайл %s содержит строку %s. До нахождения было просмотрено %d байт.\n", entry->d_name, searchingString, byteCounter);
  82.                         fprintf(outputFilePointer, "\t\tФайл %s содержит строку %s. До нахождения было просмотрено %d байт.\n", entry->d_name, searchingString, byteCounter);
  83.                     }
  84.                     else
  85.                     {
  86.                         fprintf(stdout, "\t\tФайл %s НЕ содержит строку %s. Было просмотрено %d байт.\n", entry->d_name, searchingString, byteCounter);
  87.                         fprintf(outputFilePointer, "\t\tФайл %s НЕ содержит строку %s. Было просмотрено %d байт.\n", entry->d_name, searchingString, byteCounter);
  88.                     }
  89.                     fclose(fileForCheckPointer);
  90.                 }
  91.  
  92.                 exit(0);
  93.             }
  94.             else // процесс является родительским
  95.             {
  96.                 (*currNumOfProcesses)++;
  97.                 fprintf(stdout, "Родительский процесс: %d. Его дочерний - %d, а родительский - %d\n", getpid(), childPid, getppid());
  98.                 fprintf(outputFilePointer, "Родительский процесс: %d. Его дочерний - %d, а родительский - %d\n", getpid(), childPid, getppid());
  99.  
  100.                 if ((*currNumOfProcesses) >= maxNumOfProcesses) // кол-во текущих процессов больше либо равно максимальному
  101.                 {
  102.                     waitpid(-1, NULL, 0);
  103.                     (*currNumOfProcesses)--;
  104.                 }
  105.             }
  106.         }
  107.     }
  108.  
  109.     closedir(dir);
  110.     while ((*currNumOfProcesses) > 0)
  111.     {
  112.         waitpid(-1, NULL, 0);
  113.         (*currNumOfProcesses)--;
  114.     }
  115. }
  116. /*      search func end       */
  117.  
  118. /*      print procedures start      */
  119. void printTaskInfo()
  120. {
  121.     fprintf(stdout, "\tДанная программа ищет в заданном каталоге все файлы,\n\t\t которые содержат заданную строку.\n\tРезультаты выводятся на консоль и в указанный файл.\n\n");
  122. }
  123. /*      print procedures end        */
  124.  
  125. int main(int argc, char *argv[], char *envp[])
  126. {
  127.     const int NUM_OF_ARGS = 5;
  128.  
  129.     printTaskInfo();
  130.     if (argc != NUM_OF_ARGS)
  131.     {
  132.         fprintf(stderr, "Неверный ввод!\nФормат ввода: %s <заданный каталог> <строка для поиска> <файл вывода> <кол-во процессов>\n", argv[0]);
  133.         fprintf(stdout, "Повторите запуск программы!\n");
  134.         return 1;
  135.     }
  136.  
  137.     const char *catalogPath = argv[1];
  138.     const char *stringForSearch = argv[2];
  139.     const char *outputFilePath = argv[3];
  140.     int maxNumOfProcesses = atoi(argv[4]);
  141.  
  142.     int currNumOfProcesses = 0;
  143.     FILE *outputFilePointer = fopen(outputFilePath, "w");
  144.  
  145.     if (outputFilePointer)
  146.     {
  147.         fprintf(stdout, "\n\t\tВывод списка найденных файлов в консоль:\n\n");
  148.         searchFiles(stringForSearch, catalogPath, outputFilePointer, maxNumOfProcesses, &currNumOfProcesses);
  149.         fclose(outputFilePointer);
  150.         fprintf(stdout, "\n\t\tЗапись в файл успешно завершена!\n");
  151.     }
  152.     else
  153.     {
  154.         fprintf(stdout, "\nНе удалось открыть файл для записи! Повторите запуск программы\n");
  155.     }
  156.  
  157.     return 0;
  158. }
  159.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement