Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

помещаются в массив FDS. */

 pipe(fds);

 /* порождение дочернего процесса. */

 pid = fork;

 if (pid == (pid_t)0) {

FILE* stream;

/* Это дочерний процесс. Закрываем копию входного конца

канала. */

close(fds[1]);

/* Приводим дескриптор выходного конца канала к типу FILE*

и читаем данные из канала. */

stream = fdopen(fds[0], "r");

reader(stream);

close(fds[0]);

 } else {

/* Это родительский процесс. */

FILE* stream;

/* Закрываем копию выходного конца канала. */

close(fds[0]);

/* Приводим дескриптор входного конца канала к типу FILE*

и записываем данные в канал. */

stream = fdopen(fds[1], "w");

writer("Hello, world.", 5, stream);

close(fds[1]);

 }

 return 0;

}

Сначала в программе объявляется массив

fds
, состоящий из двух целых чисел. Функция
pipe
создает канал и помещает в массив дескрипторы входного и выходного концов канала. Затем функция
fork
порождает дочерний процесс. После закрытия выходного конца канала родительский процесс начинает записывать строки в канал. Дочерний процесс читает строки из канала, предварительно закрыв его входной конец.

Обратите внимание на то. что в функции

writer
родительский процесс принудительно "выталкивает" буфер канала, вызывая функцию
fflush
. Без этого строка могла бы ""застрять" в буфере и отправиться в канал только после завершения родительского процесса.

При вызове команды

ls | less
функция fork
выполняется дважды: один раз — для дочернего процесса
ls
, второй раз — для дочернего процесса
less
. Оба процесса наследуют копии дескрипторов канала, поэтому могут общаться друг с другом. О соединении несвязанных процессов речь пойдет ниже, в разделе 5.4.5, "Каналы FIFO".

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

16

Команда

sort
читает строки текста ил стандартного входного потока, сортирует их в алфавитном порядке и записывает в стандартный выходной поток.

#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.\n");

fprintf(stream, "Hello, world.\n");

fprintf(stream, "My dog has fleas.\n");

fprintf(stream, "This program is great.\n");

fprintf(stream, "One fish, two fish.\n");

fflush(stream);

close(fds[1]);

/* Дожидаемся завершения дочернего процесса. */

waitpid(pid, NULL, 0);

 }

 return 0;

}

5.4.4. Функции popen и pclose

Поделиться:
Популярные книги

Мужчина моей судьбы

Ардова Алиса
2. Мужчина не моей мечты
Любовные романы:
любовно-фантастические романы
8.03
рейтинг книги
Мужчина моей судьбы

Курс 1. Сентябрь

Фокс Гарри
1. Маркатис
Фантастика:
аниме
фэнтези
сказочная фантастика
5.00
рейтинг книги
Курс 1. Сентябрь

Афганский рубеж 2

Дорин Михаил
2. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Афганский рубеж 2

Ботаник 2

Щепетнов Евгений Владимирович
2. Ботаник
Фантастика:
фэнтези
боевая фантастика
6.00
рейтинг книги
Ботаник 2

Эммануэль

Арсан Эммануэль
1. Эммануэль
Любовные романы:
эро литература
7.38
рейтинг книги
Эммануэль

Матабар. II

Клеванский Кирилл Сергеевич
2. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар. II

Путь к бессмертию 1

Покинтелица Евгений
1. Девятихвостый Богатырь
Фантастика:
попаданцы
сказочная фантастика
фэнтези
5.00
рейтинг книги
Путь к бессмертию 1

Наследие Маозари 5

Панежин Евгений
5. Наследие Маозари
Фантастика:
фэнтези
юмористическое фэнтези
5.00
рейтинг книги
Наследие Маозари 5

Диверсант

Вайс Александр
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Диверсант

Журнал «Если», 2002 № 08

Андерсон Кевин Джей
114. Журнал Если
Фантастика:
научная фантастика
5.00
рейтинг книги
Журнал «Если», 2002 № 08

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

Убивать чтобы жить 7

Бор Жорж
7. УЧЖ
Фантастика:
героическая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 7

На границе империй. Том 10. Часть 3

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 3

Анти-Ксенонская Инициатива

Вайс Александр
7. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Анти-Ксенонская Инициатива