Red World

6.2.3. Каналы - легкий путь!

Если все изложенные выше изыскания кажутся слишком размытым способом создания и использования каналов, то вот альтернатива этому.

LIBRARY FUNCTION: popen();

PROTOTYPE: FILE *popen ( char *command, char *type );

RETURNS: новый файловый поток в случае успеха

NULL при неудачном fork() или pipe()

NOTES: создает канал, и выполняет fork/exec, используя command

Эта стандартная библиотечная функция создает полудуплексный канал посредством вызывания pipe() внутренне. Затем она порождает дочерний процесс, запускает Bourne shell и исполняет аргумент command внутри shell-а. Управление потоком данных определяется вторым аргументом, type. Он может быть "r" или "w" - для чтения или записи, но не может быть и то, и другое! Под Linux-ом канал будет открыт в виде, определенном первой литерой аргумента "type". Поэтому, если вы попытаетесь ввести "rw", канал будет открыт только в виде "read".

Каналы, созданные popen(), должны быть закрыты pclose(). К этому моменту вы, вероятно, уже использовали [реализовали] popen/pclose share, удивительно похожий на стандартный файловый поток I/O функций fopen() и fclose().LIBRARY FUNCTION: pclose();

PROTOTYPE: int pclose( FILE *stream )

RETURNS: выход из статуса системного вызова wait4()

-1, если "stream" некорректен или облом с wait4()

NOTES: ожидает окончания связанного каналом процесса, затем закрывает поток.

Функция pclose() выполняет wait4() над процессом, порожденным popen()-ом. Когда она возвращается, то уничтожает канал и файловый поток. Повторим еще раз, что этот эффект аналогичен эффекту, вызываемому функцией fclose() для нормального, основанного на потоке файлового ввода/вывода.

Рассмотрим пример, который открывает канал для команды сортировки и начинает сортировать массив строк:


Excerpt from "Linux Programmer's Guide - Chapter 6"

(C)opyright 1994-1995, Scott Burket


MODULE: popen1.c

#include

#define MAXSTRS 5

int main(void)

{

int cntr;

FILE *pipe_fp;

char *strings[MAXSTRS] = {"echo", "bravo", "alpha", "charlie", "delta"};

/* Создаем односторонний канал вызовом popen() */

if (( pipe_fp = popen("sort", "w")) == NULL)

{

perror("popen");

exit(1);

}

/* Цикл */

for(cntr=0;

cntr /tmp/foo", "w") popen("sort | uniq | more", "w");

В качестве другого примера popen()-а, рассмотрим маленькую программу, открывающую два канала (один - для команды ls, другой - для сортировки):


Excerpt from "Linux Programmer's Guide - Chapter 6"

(C)opyright 1994-1995, Scott Burkett


MODULE: popen2.c

#include

int main(void)

{

FILE *pipein_fp, *pipeout_fp;

char readbuf[80];

/* Создаем односторонний канал вызовом popen() */

if (( pipein_fp = popen("ls", "r")) == NULL)

{

perror("popen");

exit(1);

}

/* Создаем односторонний канал вызовом popen() */

if (( pipeout_fp = popen("sort", "w")) == NULL)

{

perror("popen");

exit(1);

}

/* Цикл */

while(fgets(readbuf, 80, pipein_fp)) fputs(readbuf, pipeout_fp);

/* Закрываем каналы */

pclose(pipein_fp);

pclose(pipeout_fp);

return(0);

}

В качестве последней демонстрации popen(), давайте создадим программу, характерную для открытия канала между отданной командой и именем файла:


Excerpt from "Linux Programmer's Guide - Chapter 6"

(C)opyright 1994-1995, Scott Burkett


MODULE: popen3.c

#include

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

{

FILE *pipe_fp, *infile;

char readbuf[80];

if( argc != 3 )

{

fpintf(stderr, "USAGE"




Сайт создан в системе uCoz