#include <cstdlib>
#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/wait.h>
void writeToPipe(int fileDescriptor, const std::string& text) {
std::size_t totalBytesWritten = 0;
while (totalBytesWritten < text.size()) {
ssize_t bytesWritten = write(
fileDescriptor,
text.data() + totalBytesWritten,
text.size() - totalBytesWritten
);
if (bytesWritten == -1) {
perror("Ошибка записи в pipe");
exit(EXIT_FAILURE);
}
totalBytesWritten += static_cast<std::size_t>(bytesWritten);
}
}
std::string readFromPipe(int fileDescriptor) {
std::string result;
char buffer[256];
while (true) {
ssize_t bytesRead = read(fileDescriptor, buffer, sizeof(buffer));
if (bytesRead == -1) {
perror("Ошибка чтения из pipe");
exit(EXIT_FAILURE);
}
if (bytesRead == 0) {
break;
}
result.append(buffer, static_cast<std::size_t>(bytesRead));
}
return result;
}
int main(int argc, char* argv[]) {
if (argc != 2) {
std::cerr << "Использование: ./sadriev \"строка\"" << 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]);
// Получаем исходную строку от родительского процесса.
std::string input = readFromPipe(pipe_1[0]);
close(pipe_1[0]);
// В дочернем процессе fork() возвращает 0.
std::cout << "PID CHILD: " << getpid()
<< " RETPID: " << pid << std::endl;
std::string result;
for (char symbol : input) {
if (symbol >= '0' && symbol <= '9') {
result += symbol;
}
}
// Передаём результат родительскому процессу.
writeToPipe(pipe_2[1], result);
close(pipe_2[1]);
_exit(EXIT_SUCCESS);
}
// ---------------- Родительский процесс ----------------
close(pipe_1[0]);
close(pipe_2[1]);
std::string input = argv[1];
std::cout << "PID PARENT: " << getpid()
<< " RETPID: " << pid << std::endl;
// Передаём исходную строку дочернему процессу.
writeToPipe(pipe_1[1], input);
close(pipe_1[1]);
// Получаем обработанный результат от дочернего процесса.
std::string result = readFromPipe(pipe_2[0]);
close(pipe_2[0]);
// Ожидаем завершения дочернего процесса.
waitpid(pid, nullptr, 0);
std::cout << "Исходная строка: " << input << std::endl;
std::cout << "Результат: " << result << std::endl;
return EXIT_SUCCESS;
}