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

на главную

Жанры

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

В упражнении 13.3 приведена программа popen3.c, читающая все данные из канала.

Упражнение 13.3. Чтение из канала данных большого объема

В этой программе вы читаете данные из вызванного процесса

ps ах
. У вас нет возможности узнать заранее, какой величины будет вывод, поэтому вы должны разрешить множественные операции чтения из канала.

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

int main {

 FILE * read_fp;

 char buffer[BUFSIZ + 1];

 int chars_read;

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

 read_fp = popen("ps ax", "r");

 if(read_fp != NULL) {

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

while (chars_read > 0) {

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

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

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

}

pclose(read_fp);

exit(EXIT_SUCCESS);

 }

 exit(EXIT_FAILURE);

}

Вывод,

отредактированный для краткости, подобен приведенному далее:

$ ./popen3

Reading 1024:-

PID TTY STAT TIME COMMAND

1 ? Ss 0:03 init [5]

2 ? SW 0:00 [kflushd]

3 ? SW 0:00 [kpiod]

4 ? SW 0:00 [kswapd]

5 ? SW< 0:00 [mdrecoveryd]

...

240 tty2 S 0:02 emacs draft1.txt

Reading 1024:-

368 tty1 S 0:00 ./popen 3

369 tty1 R 0:00 ps -ax

370 ...

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

Программа применяет функцию

popen
с параметром
"r"
аналогично программе popen1.c. В этот раз она продолжает чтение из файлового потока до тех пор, пока в нем есть данные. Учтите, что, хотя программе
ps
нужно некоторое время для выполнения, Linux так организует планирование процессов, что обе программы выполняются, когда могут. Если у читающего процесса popen3 нет входных данных, он приостанавливается до появления доступных данных. Если записывающий процесс
ps
формирует вывод, больший по объему, чем может вместить буфер, он приостанавливается до тех пор, пока считывающий процесс не обработает какой-то объем данных.

В этом примере строка

Reading:-
может не появиться второй раз. Это означает, что
BUFSIZ
больше объема вывода команды
ps
. В некоторых (самых современных) системах Linux установлен размер буфера
BUFSIZ
, равный 8192 байт или даже больше. Для того чтобы проверить корректность работы программы при считывании нескольких порций вывода, попробуйте считывать
за один раз меньше символов, чем
BUFSIZ
, может быть
BUFSIZ/10
.

Как реализован вызов popen

Вызов

popen
выполняет программу, которую вы запросили, прежде всего, вызывая командную оболочку
sh
и передавая ей командную строку как аргумент. У этого процесса две стороны: приятная и не очень.

В ОС Linux (как и во всех UNIX-подобных системах) подстановка всех параметров выполняется командной оболочкой, поэтому вызов оболочки для синтаксического анализа командной строки перед вызовом программы дает возможность командной оболочке выполнить любую подстановку, например, определить реальные файлы, на которые ссылается строка *.с до того, как программа начнет выполняться. Часто это очень полезно и позволяет запускать с помощью

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

Нежелательный эффект применения командной оболочки состоит в том, что для каждого вызова

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

В упражнении 13.4 приведена программа popen4.c, которую можно использовать для демонстрации поведения

popen
. Вы можете сосчитать количество строк во всех файлах с исходным текстом примеров семейства
popen
, применив команду
cat
к файлам и затем пересылая по каналу вывод в команду
wc -l
, которая считает количество строк. В командной строке эквивалентная команда выглядит следующим образом:

$ cat popen*.c | wc -l

Примечание

На самом деле

wc -l popen*.c
легче и гораздо эффективнее ввести с клавиатуры, но пример иллюстрирует основные принципы использования каналов.

Упражнение 13.4. Вызов
popen
запускает командную оболочку

Эта программа применяет в точности предыдущую команду, но с помощью

popen
, так что она может читать результат.

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

int main {

 FILE *read_fp;

 char buffer[BUFSIZ +1];

 int chars_read;

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

 read_fp = popen("cat popen*.с | wc -l", "r");

 if (read_fp != NULL) {

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

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

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

Ланцов Михаил Алексеевич
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
рейтинг книги
Возвращение Низвергнутого