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

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

Шрифт:

Функция

my_open
, показанная в листинге 15.8, должна выглядеть для вызывающего процесса как обычная функция Unix
open
. Она получает два аргумента — полное имя и режим открытия (например,
O_RDONLY
обозначает, что файл доступен только для чтения), открывает файл и возвращает дескриптор.

Листинг 15.8. Функция my_open: открытие файла и возвращение дескриптора

//unixdomain/myopen.c

1 #include "unp.h"

2 int

3 my_open(const char *pathname, int mode)

4 {

5 int fd, sockfd[2], status;

6 pid_t childpid;

7 char c, argsockfd[10], argmode[10];

8 Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);

9 if ((childpid = Fork) == 0) { /* дочерний процесс */

10 Close(sockfd[0]);

11 snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]);

12 snprintf(argmode, sizeof(argmode), "%d", mode);

13 execl("./openfile", "openfile", argsockfd, pathname, argmode,

14 (char*)NULL);

15 err_sys("execl error");

16 }

17 /* родительский процесс - ожидание завершения дочернего процесса */

18 Close(sockfd[1]); /* закрываем конец, который мы не используем */

19 Waitpid(childpid, &status, 0);

20 if (WIFEXITED(status) == 0)

21 err_quit("child did not terminate");

22 if ((status = WEXITSTATUS(status)) == 0)

23 Read_fd(sockfd[0], &c, 1, &fd);

24 else {

25 errno = status; /* установка значения errno в статус дочернего

процесса */

26 fd = -1;

27 }

28 Close(sockfd[0]);

29 return (fd);

30 }

Создание потокового канала

8
Функция
socketpair
создает потоковый канал. Возвращаются два дескриптора:
sockfd[0]
и
sockfd[1]
. Это состояние, которое мы показали на рис. 15.1.

Функции fork и exec

9-16
Вызывается функция
fork
, после чего дочерний процесс закрывает один конец потокового канала. Номер дескриптора другого конца потокового канала помещается в массив
argsockfd
, а режим открытия помещается в массив
argmode
. Мы вызываем функцию
snprintf
, поскольку аргументы функции exec должны быть символьными строками. Выполняется программа
openfile
. Функция
execl
возвращает управление только в том случае, если она встретит ошибку. При удачном выполнении начинает выполняться функция
main
программы
openfile
.

Родительский процесс в ожидании завершения дочернего процесса

17-22
Родительский процесс закрывает другой конец потокового канала и вызывает функцию
waitpid
для ожидания завершения дочернего процесса. Статус завершения дочернего процесса возвращается в переменной
status
, и сначала мы проверяем, что программа завершилась нормально (то есть не была завершена из-за возникновения какого-либо сигнала). Затем макрос
WEXITSTATUS
преобразует статус завершения в статус выхода, значение которого должно быть между 0 и 255. Мы вскоре увидим, что если при открытии необходимого файла программой
openfile
происходит ошибка, то эта программа завершается, причем статус ее завершения равен соответствующему значению переменной
errno
.

Получение дескриптора

23
Наша функция
read_fd
, которую мы показываем в следующем листинге, получает дескриптор потокового канала. Кроме получения дескриптора мы считываем 1 байт данных, но ничего с этими данными не делаем.

ПРИМЕЧАНИЕ

При отправке и получении дескриптора по потоковому каналу мы всегда отправляем как минимум 1 байт данных, даже если получатель никак эти данные не обрабатывает. Иначе получатель не сможет распознать, что значит нулевое возвращаемое значение из функции read_fd: отсутствие данных (но, возможно, есть дескриптор) или конец файла.

  • Читать дальше
  • 1
  • ...
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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