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

на главную

Жанры

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

while (chars_read > 0) {

buffer[chars_read - 1] = '\0';

printf("Reading:-\n %s\n", buffer);

chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);

}

pclose(read_fp);

exit(EXIT_SUCCESS);

 }

 exit(EXIT_FAILURE);

}

Выполнив эту программу, вы получите следующий вывод:

$ ./popen4

Reading:-

94

Как

это работает

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

popen*.с
в список всех файлов, начинающихся с
popen
и заканчивающихся
, а также для обработки символа канала (
|
) и отправки вывода команды
cat
в команду
. Вы вызываете командную оболочку, программы
cat
и
wc
и задаете перенаправление — все в одном вызове
popen
. Программа, вызвавшая команду, видит только заключительный вывод.

Вызов pipe

Вы познакомились с высокоуровневой функцией

popen
, а теперь пойдем дальше и рассмотрим низкоуровневую функцию
pipe
. Она предоставляет средства передачи данных между двумя программами без накладных расходов на вызов командной оболочки для интерпретации запрашиваемой команды. Эта функция также позволит вам лучше управлять чтением и записью данных.

У функции

pipe
следующее объявление:

#include <unistd.h>

int pipe(int file_descriptor[2]);

Функции

pipe
передается указатель на массив из двух целочисленных файловых дескрипторов. Она заполняет массив двумя новыми файловыми дескрипторами и возвращает 0. В случае неудачи она вернет -1 и установит переменную
errno
для указания причины сбоя. В интерактивном справочном руководстве Linux на странице, посвященной функций
pipe
(в разделе 2 руководства), определены следующие ошибки:

 

EMFILE
— процесс использует слишком много файловых дескрипторов;

 

ENFILE
— системная таблица файлов полна;

 

EFAULT
— некорректный файловый дескриптор.

Два возвращаемых файловых дескриптора подсоединяются специальным образом. Любые данные, записанные в

file_descriptor[1]
, могут быть считаны обратно из
file_descriptor[0]
. Данные обрабатываются по алгоритму "первым пришел, первым обслужен", обычно обозначаемому как FIFO. Это означает, что если вы записываете байты
1
,
2
,
3
в
file_descriptor[1]
, чтение из
file_descriptor[0]
выполняется в следующем порядке:
1
,
2
,
3
. Этот способ отличается от стека, который функционирует по алгоритму "последним пришел, первым обслужен", который обычно называют сокращенно LIFO.

Примечание

Важно уяснить, что речь идет о файловых дескрипторах, а не о файловых потоках, поэтому для доступа

к данным вы должны применять низкоуровневые системные вызовы
read
и
write
вместо библиотечных функций потоков
fread
и
fwrite
.

В упражнении 13.5 приведена программа pipe1.с, которая использует вызов

pipe
для создания канала.

Упражнение 13.5 Функция
pipe

Следующий пример — программа pipe1.c. Обратите внимание на массив

file_pipes
, который передается функции
pipe
как параметр.

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

int main {

 int data_processed;

 int filepipes[2];

 const char some_data[] = "123";

 char buffer[BUFSIZ + 1];

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

 if (pipe(file_pipes) == 0) {

data_processed = write(file_pipes[1], some_data, strlen(somedata));

printf("Wrote %d bytes\n", data_processed);

data_processed = read(file_pipes[0], buffer, BUFSIZ);

printf("Read %d bytes: %s\n", data_processed, buffer);

exit(EXIT_SUCCESS);

 }

 exit(EXIT_FAILURE);

}

Если вы выполните программу, то получите следующий вывод:

$ ./pipe1

Wrote 3 bytes

Read 3 bytes: 123

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

Программа создает канал с помощью двух файловых дескрипторов из массива

file_pipes[]
. Далее она записывает данные в канал, используя файловый дескриптор
file_pipes[1]
, и считывает их обратно из
file_pipes[0]
. Учтите, что у канала есть внутренняя буферизация, позволяющая хранить данные между вызовами функций
write
и
read
.

Следует знать, что реакция на попытку писать с помощью дескриптора

file_descriptor[0]
или читать с помощью дескриптора
file_descriptor[1]
не определена, поэтому поведение программы может быть очень странным и меняться без каких-либо предупреждений. В системах авторов такие вызовы заканчивались аварийно и возвращали -1, что, по крайней мере, гарантирует легкость обнаружения такой ошибки.

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

fork
, уже открытые к этому моменту файловые дескрипторы так и остаются открытыми. Создав канал в исходном процессе и затем сформировав с помощью
fork
новый процесс, вы сможете передать данные из одного процесса в другой через канал (упражнение 13.6).

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

Генерал Империи

Ланцов Михаил Алексеевич
4. Безумный Макс
Фантастика:
альтернативная история
5.62
рейтинг книги
Генерал Империи

Отмороженный 9.0

Гарцевич Евгений Александрович
9. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 9.0

Под знаменем пророчества

Зыков Виталий Валерьевич
3. Дорога домой
Фантастика:
фэнтези
боевая фантастика
9.51
рейтинг книги
Под знаменем пророчества

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Дядя самых честных правил 8

Горбов Александр Михайлович
8. Дядя самых честных правил
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Дядя самых честных правил 8

Para bellum

Ланцов Михаил Алексеевич
4. Фрунзе
Фантастика:
попаданцы
альтернативная история
6.60
рейтинг книги
Para bellum

Идеальный мир для Лекаря 5

Сапфир Олег
5. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 5

Покоритель Звездных врат

Карелин Сергей Витальевич
1. Повелитель звездных врат
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Покоритель Звездных врат

Отборная бабушка

Мягкова Нинель
Фантастика:
фэнтези
юмористическая фантастика
7.74
рейтинг книги
Отборная бабушка

Жестокая свадьба

Тоцка Тала
Любовные романы:
современные любовные романы
4.87
рейтинг книги
Жестокая свадьба

Смертник из рода Валевских. Книга 1

Маханенко Василий Михайлович
1. Смертник из рода Валевских
Фантастика:
фэнтези
рпг
аниме
5.40
рейтинг книги
Смертник из рода Валевских. Книга 1

Сердце Дракона. Том 11

Клеванский Кирилл Сергеевич
11. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
6.50
рейтинг книги
Сердце Дракона. Том 11

Тройняшки не по плану. Идеальный генофонд

Лесневская Вероника
Роковые подмены
Любовные романы:
современные любовные романы
6.80
рейтинг книги
Тройняшки не по плану. Идеальный генофонд

Возвращение Низвергнутого

Михайлов Дем Алексеевич
5. Изгой
Фантастика:
фэнтези
9.40
рейтинг книги
Возвращение Низвергнутого