5.4.3. Перенаправление стандартных потоков ввода, вывода и ошибок
5.4.3. Перенаправление стандартных потоков ввода, вывода и ошибок
Часто требуется создать дочерний процесс и сделать один из концов канала его стандартным входным или выходным потоком. В этом случае на помощь приходит функция dup2(), которая делает один файловый дескриптор равным другому. Вот как, например, можно связать стандартный входной поток с файлом fd:
dup2(fd, STDIN_FILENO);
Символическая константа STDIN_FILENO представляет дескриптор файла, соответствующий стандартному потоку ввода (значение этого дескриптора равно 0). Показанная функция закрывает входной поток, а затем открывает его под видом файла fd. Оба дескриптора (0 и fd) будут указывать на одну и ту же позицию в файле и иметь одинаковый набор флагов состояния, т.е. дескрипторы станут взаимозаменяемыми.
Программа, представленная в листинге 5.8, с помощью функции dup2() соединяет выходной. Конец канала со входом команды sort.[16] После создания канала программа "делится" функцией fork() на два процесса. Родительский процесс записывает в канал различные строки, а дочерний процесс соединяет выходной конец канала со своим входным потоком, после чего запускает команду sort.
Листинг 5.8. (dup2.c) Перенаправление выходного потока канала с помощью функции dup2()
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
int fds[2];
pid_t pid;
/* Создание канала. Дескрипторы обоих концов канала
помещаются в массив FDS. */
pipe (fds);
/* Создание дочернего процесса. */
pid = fork();
if (pid == (pid_t)0) {
/* Это дочерний процесс. Закрываем копию входного конца
канала */
close(fds[1]);
/* Соединяем выходной конец канала со стандартным входным
потоком. */
dup2(fds[0], STDIN_FILENO);
/* Замещаем дочерний процесс программой sort. */
execlp("sort", "sort", 0);
} else {
/* Это родительский процесс. */
FILE* stream;
/* Закрываем копию выходного конца канала. */
close(fds[0]);
/* Приводим дескриптор входного конца канала к типу FILE*
и записываем данные в канал. */
stream = fdopen(fds[1], "w");
fprintf(stream, "This is a test. ");
fprintf(stream, "Hello, world. ");
fprintf(stream, "My dog has fleas. ");
fprintf(stream, "This program is great. ");
fprintf(stream, "One fish, two fish. ");
fflush(stream);
close(fds[1]);
/* Дожидаемся завершения дочернего процесса. */
waitpid(pid, NULL, 0);
}
return 0;
}