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

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

Жанры

Основы программирования в Linux
Шрифт:

#include <string.h>

int main(int argc, char *argv[]) {

 int data_processed;

 char buffer[BUFSIZ + 1];

 int file_descriptor;

 memset(buffer, '\0', sizeof(buffer));

 sscanf(argv[1], "%d", &file_descriptor);

 data_processed = read(file_descriptor, buffer, BUFSIZ);

 printf("%d — read %d bytes: %s\n", getpid, data_processed,

buffer);

 exit(EXIT_SUCCESS);

}

Выполнив pipe3

и помня о том, что она вызывает программу pipe4, вы получите вывод, аналогичный приведенному далее:

$ ./pipe3

22460 - wrote 3 bytes

22461 - read 3 bytes: 123

Как это работает

Программа pipe3 начинается как предыдущий пример, используя вызов

pipe
для создания канала и затем вызов
fork
для создания нового процесса. Далее она применяет функцию
sprintf
для сохранения в буфере номера файлового дескриптора чтения из канала, который формирует аргумент программы pipe4.

Вызов

execl
применен для вызова программы pipe4. В нем использованы следующие аргументы:

 вызванная программа;

 

argv[0]
, принимающий имя программы;

 

argv[1]
, содержащий номер файлового дескриптора, из которого программа должна читать;

 

(char *)0
, завершающий список параметров.

Программа pipe4 извлекает номер файлового дескриптора из строки аргументов и затем читает из него данные.

Чтение закрытых каналов

Прежде чем двигаться дальше, необходимо более внимательно рассмотреть файловые дескрипторы, которые открыты. До этого момента вы разрешали читающему процессу просто читать какие-то данные и завершаться, полагая, что ОС Linux уберет файлы в ходе завершения процесса.

В большинстве программ, читающих данные из стандартного ввода, это делается несколько иначе, чем в виденных вами до сих пор примерах. Обычно программы не знают, сколько данных они должны считать, поэтому они, как правило, выполняют цикл — чтение данных, их обработка и затем снова чтение данных и так до тех пор, пока не останется данных для чтения.

Вызов

read
обычно будет задерживать выполнение процесса, т.е. он заставит процесс ждать до тех пор, пока не появятся данные. Если другой конец канала был закрыт, следовательно, нет ни одного процесса, имеющего канал для записи, и вызов
read
блокируется. Поскольку это не очень полезно, вызов
read
, пытающийся читать из канала, не открытого для записи, возвращает 0 вместо блокирования. Это позволит читающему процессу обнаружить канальный эквивалент метки "конец файла" и действовать соответствующим образом. Учтите, что это не то же самое, что чтение некорректного
дескриптора файла, которое вызов read считает ошибкой и обозначает возвратом -1.

Если вы применяете канал с вызовом

fork
, есть два файловых дескриптора, которые можно использовать для записи в канал: один в родительском, а другой в дочернем процессах. Вы должны закрыть файловые дескрипторы записи в канал в обоих этих процессах, прежде чем канал будет считаться закрытым и вызов
read
для чтения из канала завершится аварийно. Мы рассмотрим пример этого позже, когда вернемся к данной теме, для того чтобы подробно обсудить флаг
O_NONBLOCK
и каналы FIFO.

Каналы, применяемые как стандартные ввод и вывод

Теперь, когда вы знаете, как заставить вызов

read
, примененный к пустому каналу, завершиться аварийно, можно рассмотреть более простой метод соединения каналом двух процессов. Вы устраиваете так, что у одного из файловых дескрипторов канала будет известное значение, обычно стандартный ввод, 0, или стандартный вывод, 1. Его немного сложнее установить в родительском процессе, но при этом значительно упрощается программа дочернего процесса.

Одно неоспоримое достоинство заключается в том, что вы можете вызывать стандартные программы, которым не нужен файловый дескриптор как параметр. Для этого вам следует применить функцию

dup
, с которой вы встречались в главе 3. Существуют две тесно связанные версии функции
dup
, которые объявляются следующим образом:

#include <unistd.h>

int dup(int file_descriptor);

int dup2(int file_descriptor_one, int file_descriptor_two);

Назначение вызова

dup
— открыть новый дескриптор файла, немного похоже на то, как это делает вызов
open
. Разница в том, что файловый дескриптор, созданный
dup
, ссылается на тот же файл (или канал), что и существующий файловый дескриптор. В случае вызова
dup
новый файловый дескриптор всегда имеет самый маленький доступный номер, а в случае
dup2
— первый доступный дескриптор, больший чем значение параметра
file_descriptor_two
.

Примечание

Того же эффекта, что и применение вызовов

dup
и
dup2
можно добиться, применяя более общий вызов
fcntl
с командой
F_DUPFD
. Как говорилось, вызов
dup
легче использовать, поскольку он разработан специально для создания дубликатов файловых дескрипторов. Он также очень широко применяется, поэтому вы встретите его гораздо чаще в существующих программах, чем вызов
fcntl
и команду
F_DUPFD
.

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

Замена Элит. Новые Люди Креативного Государства Прфессиональный Парламент. Книга 2

Мамыченко Андрей Валентинович
Научно-образовательная:
политика
5.00
рейтинг книги
Замена Элит. Новые Люди Креативного Государства Прфессиональный Парламент. Книга 2

Хроника

Саксон Анналист
Mediaevalia: средневековые литературные памятники и источники
Научно-образовательная:
история
5.00
рейтинг книги
Хроника

Нам здесь (не) жить

Зонин Сергей
2. Насуверс
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Нам здесь (не) жить

Ночная охота (сборник)

Роллинс Джеймс
Книга-загадка, книга-бестселлер
Детективы:
триллеры
7.06
рейтинг книги
Ночная охота (сборник)

Дневники 1930-1931

Пришвин Михаил Михайлович
Документальная литература:
биографии и мемуары
4.75
рейтинг книги
Дневники 1930-1931

Клевые

Нетесова Эльмира Анатольевна
Обожженные зоной
Детективы:
боевики
5.00
рейтинг книги
Клевые

Освобождение

Лейк Кери
Любовные романы:
современные любовные романы
эро литература
4.75
рейтинг книги
Освобождение

Большая Советская Энциклопедия (МЕ)

Большая Советская Энциклопедия
Справочная литература:
энциклопедии
5.00
рейтинг книги
Большая Советская Энциклопедия (МЕ)

Бояръ-Аниме. Газлайтер. Том 34

Володин Григорий Григорьевич
34. История Телепата
Фантастика:
фэнтези
боевая фантастика
аниме
7.17
рейтинг книги
Бояръ-Аниме. Газлайтер. Том 34

Домашняя медицинская энциклопедия. Симптомы и лечение самых распространенных заболеваний

Коллектив авторов
Научно-образовательная:
медицина
5.00
рейтинг книги
Домашняя медицинская энциклопедия. Симптомы и лечение самых распространенных заболеваний

Шайтан Иван 5

Тен Эдуард
5. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
5.50
рейтинг книги
Шайтан Иван 5

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

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

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

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

"Фантастика 2024-136". Компиляция. Книги 1-24

Белогорский Евгений Александрович
Фантастика 2024. Компиляция
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Фантастика 2024-136. Компиляция. Книги 1-24