Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dirent.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdbool.h>
- #include <sys/wait.h>
- #include <errno.h>
- #include <limits.h>
- typedef struct dirent DIRENT;
- typedef struct stat STAT;
- /* search func start */
- void searchFiles(const char *searchingString, const char *catalogPath, FILE *outputFilePointer, const int maxNumOfProcesses, int *currNumOfProcesses)
- {
- const int PATH_LENGTH = 255;
- DIR *dir;
- dir = opendir(catalogPath);
- if (!dir) // каталог не открылся
- {
- fprintf(stderr, "\t\t\tОшибка при открытии %s!\n", catalogPath);
- return;
- };
- struct dirent *entry;
- while ((entry = readdir(dir)) != NULL) // пока не кончатся файлы в каталоге
- {
- char fullPath[PATH_LENGTH];
- snprintf(fullPath, PATH_LENGTH, "%s/%s", catalogPath, entry->d_name);
- STAT buffer;
- stat(fullPath, &buffer);
- if (S_ISREG(buffer.st_mode)) // если текущий файл(при просмотре в каталоге) является регулярным
- {
- pid_t childPid = fork();
- if (childPid == -1) // не удалось создать процесс
- {
- fprintf(stderr, "Ошибка при создании дочернего процесса!\n");
- return;
- }
- if (childPid == 0) // процесс является дочерним
- {
- fprintf(stdout, "\tPID: %d, PPID: %d, Путь: %s, Название: %s\n", getpid(), getppid(), fullPath, entry->d_name);
- fprintf(outputFilePointer, "\tPID: %d, PPID: %d, Путь: %s, Название: %s\n", getpid(), getppid(), fullPath, entry->d_name);
- FILE *fileForCheckPointer;
- if ((fileForCheckPointer = fopen(fullPath, "rb")) == NULL) // файл не открылся для побитового чтения
- {
- fprintf(stdout, "Не удалось прочитать данные в файле %s.\n", entry->d_name);
- }
- else
- {
- char tempChar;
- int byteCounter = 0;
- bool isFound = false;
- while (!feof(fileForCheckPointer))
- {
- byteCounter++;
- tempChar = getc(fileForCheckPointer);
- if (tempChar == searchingString[0]) // если текущий выбранный символ в файле совпал с первым символом проверочной строки
- {
- int i = 1;
- isFound = true;
- while (searchingString[i] != '\0' && isFound) { //пока строка не кончается и сравниваемые символы равны
- isFound = searchingString[i] == getc(fileForCheckPointer);
- i++;
- }
- }
- }
- if (isFound)
- {
- fprintf(stdout, "\t\tФайл %s содержит строку %s. До нахождения было просмотрено %d байт.\n", entry->d_name, searchingString, byteCounter);
- fprintf(outputFilePointer, "\t\tФайл %s содержит строку %s. До нахождения было просмотрено %d байт.\n", entry->d_name, searchingString, byteCounter);
- }
- else
- {
- fprintf(stdout, "\t\tФайл %s НЕ содержит строку %s. Было просмотрено %d байт.\n", entry->d_name, searchingString, byteCounter);
- fprintf(outputFilePointer, "\t\tФайл %s НЕ содержит строку %s. Было просмотрено %d байт.\n", entry->d_name, searchingString, byteCounter);
- }
- fclose(fileForCheckPointer);
- }
- exit(0);
- }
- else // процесс является родительским
- {
- (*currNumOfProcesses)++;
- fprintf(stdout, "Родительский процесс: %d. Его дочерний - %d, а родительский - %d\n", getpid(), childPid, getppid());
- fprintf(outputFilePointer, "Родительский процесс: %d. Его дочерний - %d, а родительский - %d\n", getpid(), childPid, getppid());
- if ((*currNumOfProcesses) >= maxNumOfProcesses) // кол-во текущих процессов больше либо равно максимальному
- {
- waitpid(-1, NULL, 0);
- (*currNumOfProcesses)--;
- }
- }
- }
- }
- closedir(dir);
- while ((*currNumOfProcesses) > 0)
- {
- waitpid(-1, NULL, 0);
- (*currNumOfProcesses)--;
- }
- }
- /* search func end */
- /* print procedures start */
- void printTaskInfo()
- {
- fprintf(stdout, "\tДанная программа ищет в заданном каталоге все файлы,\n\t\t которые содержат заданную строку.\n\tРезультаты выводятся на консоль и в указанный файл.\n\n");
- }
- /* print procedures end */
- int main(int argc, char *argv[], char *envp[])
- {
- const int NUM_OF_ARGS = 5;
- printTaskInfo();
- if (argc != NUM_OF_ARGS)
- {
- fprintf(stderr, "Неверный ввод!\nФормат ввода: %s <заданный каталог> <строка для поиска> <файл вывода> <кол-во процессов>\n", argv[0]);
- fprintf(stdout, "Повторите запуск программы!\n");
- return 1;
- }
- const char *catalogPath = argv[1];
- const char *stringForSearch = argv[2];
- const char *outputFilePath = argv[3];
- int maxNumOfProcesses = atoi(argv[4]);
- int currNumOfProcesses = 0;
- FILE *outputFilePointer = fopen(outputFilePath, "w");
- if (outputFilePointer)
- {
- fprintf(stdout, "\n\t\tВывод списка найденных файлов в консоль:\n\n");
- searchFiles(stringForSearch, catalogPath, outputFilePointer, maxNumOfProcesses, &currNumOfProcesses);
- fclose(outputFilePointer);
- fprintf(stdout, "\n\t\tЗапись в файл успешно завершена!\n");
- }
- else
- {
- fprintf(stdout, "\nНе удалось открыть файл для записи! Повторите запуск программы\n");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement