Основы программирования в Linux - Мэтью Нейл
- Дата:08.09.2024
- Категория: Компьютеры и Интернет / Интернет
- Название: Основы программирования в Linux
- Автор: Мэтью Нейл
- Просмотров:0
- Комментариев:0
Шрифт:
Интервал:
Закладка:
Эта программа применяет в точности предыдущую команду, но с помощью 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, ' ', sizeof(buffer));
read_fp = popen("cat popen*.с | wc -l", "r");
if (read_fp != NULL) {
chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
while (chars_read > 0) {
buffer[chars_read - 1] = ' ';
printf("Reading:-n %sn", buffer);
chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
}
pclose(read_fp);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}
Выполнив эту программу, вы получите следующий вывод:
$ <b>./popen4</b>
Reading:-
94
Как это работает
Программа показывает, что вызывается командная оболочка для того, чтобы развернуть popen*.с в список всех файлов, начинающихся с popen и заканчивающихся .с, а также для обработки символа канала (|) и отправки вывода команды cat в команду wс. Вы вызываете командную оболочку, программы cat и wc и задаете перенаправление — все в одном вызове popen. Программа, вызвавшая команду, видит только заключительный вывод.
Вызов pipe
Вы познакомились с высокоуровневой функцией popen, а теперь пойдем дальше и рассмотрим низкоуровневую функцию pipe. Она предоставляет средства передачи данных между двумя программами без накладных расходов на вызов командной оболочки для интерпретации запрашиваемой команды. Эта функция также позволит вам лучше управлять чтением и записью данных.
У функции pipe следующее объявление:
<b>#include <unistd.h></b>
<b>int pipe(int file_descriptor[2]);</b>
Функции 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, ' ', sizeof(buffer));
if (pipe(file_pipes) == 0) {
data_processed = write(file_pipes[1], some_data, strlen(somedata));
printf("Wrote %d bytesn", data_processed);
data_processed = read(file_pipes[0], buffer, BUFSIZ);
printf("Read %d bytes: %sn", data_processed, buffer);
- Вопросы истории: UNIX, Linux, BSD и другие - Федорчук Алексей Викторович "alv" - Прочая околокомпьтерная литература
- Linux Mint и его Cinnamon. Очерки применителя - Алексей Федорчук - Программное обеспечение
- Язык программирования C++. Пятое издание - Стенли Липпман - Программирование
- Аквариум. (Новое издание, исправленное и переработанное) - Виктор Суворов (Резун) - Шпионский детектив
- Интерфейс: новые направления в проектировании компьютерных систем - Джефф Раскин - Техническая литература