Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

9 if ((n = Read(readfd, buff, MAXLINE)) == 0)

10 err_quit("end-of-file while reading pathname"):

11 buff[n] = '\0'; /* полное имя завершается 0 */

12 if ((fd = open(buff, O_RDONLY)) < 0) {

13 /* 4error: must tell client */

14 snprintf(buff + n, sizeof(buff) – n, ": can't open. %s\n".

15 strerror(errno)):

16 n = strlen(buff);

17 Write(writefd, buff, n);

18 } else {

19 /* файл успешно открыт и копируется в канал */

20 while ( (n = Read(fd, buff, MAXLINE)) > 0)

21 Write(writefd, buff, n);

22 Close(fd);

23 }

24 }

Считывание полного имени файла из канала

8-11 Записанное в канал клиентом имя файла считывается сервером и дополняется завершающим символом с кодом 0 (null-terminated). Обратите внимание, что функция read возвращает данные, как только они помещаются в поток, не ожидая накопления некоторого их количества (MAXLINE в данном примере).

Открытие файла, обработка возможной ошибки

12-17 Файл открывается для чтения и при возникновении ошибки сообщение о ней возвращается клиенту с помощью канала. Для получения строки с соответствующим значению переменной errno сообщением об ошибке вызывается функция strerror (в книге [24, с. 690-691] вы найдете более подробный рассказ об этой функции).

Копирование из файла в канал

18-23 При успешном завершении работы функции open содержимое файла копируется в канал.

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

solaris % mainpipe /etc/inet/ntp.conf файл, состоящий из двух строк

multicastclient 224.0.1.1

driftfile /etc/inet/ntp.drift

solaris % mainpipe /etc/shadow фaйл, на чтение которого нет разрешения

/etc/shadow: can't open. Permission denied

solaris % mainpipe /no/such/file несуществующий файл

/no/such/file: can't open. No such file or directory

4.4. Двусторонние каналы

В предыдущем разделе мы отметили, что во многих системах реализованы двусторонние каналы. В Unix SVR4 это обеспечивается самой функцией pipe, а во многих других ядрах — функцией socketpair. Но что в действительности представляет собой двусторонний канал? Представим себе сначала однонаправленный канал, изображенный на рис. 4.8.

Рис. 4.8. Односторонний канал

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

Рис. 4.9. Одна из возможных реализаций двустороннего канала (неправильная)

Такая реализация вызовет проблемы, например, в программе листинга А.14. Здесь требуется двусторонняя передача информации, причем потоки данных должны быть независимы. В противном случае некоторый процесс, записав данные в канал и перейдя затем в режим чтения из этого же канала, рискует считать обратно те же данные, которые были им только что туда записаны.

На рис. 4.10 изображена правильная реализация двустороннего канала.

Рис. 4.10. Правильная реализация двустороннего канала

Здесь двусторонний канал получается из объединения двух односторонних. Все данные, записываемые в fd[1], будут доступны для чтения из fd[0], а данные, записываемые в fd[0], будут доступны для чтения из fd[1].

Программа в листинге 4.4 иллюстрирует использование одного двустороннего канала для двусторонней передачи информации.

Листинг 4.4. Двусторонняя связь через двусторонний канал

//pipe/fduplex.c

1 #include "unpipc.h"

  • Читать дальше
  • 1
  • ...
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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