на главную | войти | регистрация | DMCA | контакты | справка | donate |      

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я


моя полка | жанры | рекомендуем | рейтинг книг | рейтинг авторов | впечатления | новое | форум | сборники | читалки | авторам | добавить



Листинг 4.5. Клиент-сервер с использованием popen

//pipe/mainpopen.c

1  #include "unpipc.h"

2  int

3  main(int argc, char **argv)

4  {

5   size_t n;

6   char buff[MAXLINE], command[MAXLINE];

7   FILE *fp;

8   /* считывание полного имени */

9   Fgets(buff, MAXLINE, stdin);

10  n = strlen(buff); /* fgets() гарантирует завершающий ноль */

11  if (buff[n-1] == '\n')

12   n--; /* удаление перевода строки из возврата fgets() */

13  snprintf(command, sizeof(command), "cat %s", buff);

14  fp = Popen(command, "r");

15  /* копирование из канала в стандартный вывод */

16  while(Fgets(buff, MAXLINE, fp) != NULL)

17   Fputs(buff, stdout);

18  Pclose(fp);

19  exit(0);

20 }

8-17 Полное имя файла считывается из стандартного потока ввода, как и в программе в листинге 4.2. Формируется командная строка, которая передается popen. Вывод интерпретатора команд или команды cat копируется в стандартный поток вывода.

Одним из отличий этой реализации от приведенной в листинге 4.1 является отсутствие возможности формировать собственные сообщения об ошибках. Теперь мы целиком зависим от программы cat, а выводимые ею сообщения не всегда адекватны. Например, в системе Solaris 2.6 при попытке считать данные из файла, доступ на чтение к которому для нас запрещен, будет выведена следующая ошибка:

solaris % cat/etc/shadow

cat: cannot open /etc/shadow 

А в BSD/OS 3.1 мы получим более информативное сообщение в аналогичной ситуации:

bsdi % cat /etc/master.passwd

cat: /etc/master.passwd: cannot open [Permission denied]

Обратите также внимание на тот факт, что вызов popen в данном случае оказывается успешным, однако при первом же вызове fgets будет возвращен символ конца файла (EOF). Программа cat записывает сообщение об ошибке в стандартный поток сообщений об ошибках (stderr), а popen с этим потоком не связывается — к создаваемому каналу подключается только стандартный поток вывода.


Пример | UNIX: взаимодействие процессов | 4.6. Именованные каналы (FIFO)