Загрузка данных


#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char* argv[]) {
    // Проверяем, передана ли строка при запуске программы.
    if (argc != 2) {
        std::cerr << "Использование: ./Mezhakova \"строка\"" << std::endl;
        return EXIT_FAILURE;
    }

    int pipe_1[2]; // Передача данных от родительского процесса дочернему.
    int pipe_2[2]; // Передача результата от дочернего процесса родительскому.

    // Создаём первый канал.
    if (pipe(pipe_1) == -1) {
        perror("Ошибка создания pipe_1");
        return EXIT_FAILURE;
    }

    // Создаём второй канал.
    if (pipe(pipe_2) == -1) {
        perror("Ошибка создания pipe_2");
        return EXIT_FAILURE;
    }

    // Создаём дочерний процесс.
    pid_t pid = fork();

    if (pid == -1) {
        perror("Ошибка fork");
        return EXIT_FAILURE;
    }

    if (pid == 0) {
        // ---------------- Дочерний процесс ----------------

        // Дочерний процесс читает из pipe_1, поэтому закрываем конец записи.
        close(pipe_1[1]);

        // Дочерний процесс пишет в pipe_2, поэтому закрываем конец чтения.
        close(pipe_2[0]);

        char buffer[1024];

        // Читаем строку, переданную родительским процессом.
        ssize_t bytesRead = read(pipe_1[0], buffer, sizeof(buffer) - 1);

        if (bytesRead == -1) {
            perror("Ошибка чтения из pipe_1");
            _exit(EXIT_FAILURE);
        }

        // Добавляем завершающий символ строки.
        buffer[bytesRead] = '\0';

        std::string input(buffer);
        std::string result;

        // Оставляем только цифровые символы.
        for (char symbol : input) {
            if (symbol >= '0' && symbol <= '9') {
                result += symbol;
            }
        }

        // Передаём обработанный результат родительскому процессу.
        if (write(pipe_2[1], result.c_str(), result.size()) == -1) {
            perror("Ошибка записи в pipe_2");
            _exit(EXIT_FAILURE);
        }

        // Закрываем использованные файловые дескрипторы.
        close(pipe_1[0]);
        close(pipe_2[1]);

        _exit(EXIT_SUCCESS);
    }

    // ---------------- Родительский процесс ----------------

    // Родительский процесс пишет в pipe_1, поэтому закрываем конец чтения.
    close(pipe_1[0]);

    // Родительский процесс читает из pipe_2, поэтому закрываем конец записи.
    close(pipe_2[1]);

    std::string input = argv[1];

    // Передаём исходную строку дочернему процессу.
    if (write(pipe_1[1], input.c_str(), input.size()) == -1) {
        perror("Ошибка записи в pipe_1");
        return EXIT_FAILURE;
    }

    // После передачи данных закрываем конец записи.
    close(pipe_1[1]);

    char resultBuffer[1024];

    // Получаем результат от дочернего процесса.
    ssize_t bytesRead = read(pipe_2[0], resultBuffer, sizeof(resultBuffer) - 1);

    if (bytesRead == -1) {
        perror("Ошибка чтения из pipe_2");
        return EXIT_FAILURE;
    }

    resultBuffer[bytesRead] = '\0';

    close(pipe_2[0]);

    // Ожидаем завершения дочернего процесса.
    waitpid(pid, nullptr, 0);

    std::cout << "Исходная строка: " << input << std::endl;
    std::cout << "Результат: " << resultBuffer << std::endl;

    return EXIT_SUCCESS;
}