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

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

Шрифт:

27-45
Вызывается функция
recvmsg
. Если возвращаются вспомогательные данные, их формат будет таким, как показано на рис. 14.4. Мы проверяем, верны ли длина, уровень и тип, затем получаем вновь созданный дескриптор и возвращаем его через указатель вызывающего процесса
recvfd
. Макрос
CMSG_DATA
возвращает указатель на элемент
cmsg_data
объекта вспомогательных данных как указатель на элемент типа
unsigned char
. Мы преобразуем его к указателю на элемент типа
int
и получаем целочисленный дескриптор, на который указывает этот указатель.

Если поддерживается более старый элемент

msg_accrights
, то длина должна быть равна размеру целого числа, а вновь созданный дескриптор возвращается через указатель
recvfd
вызывающего процесса.

В листинге 15.10 показана программа

openfile
. Она получает три аргумента командной строки, которые должны быть переданы, и вызывает обычную функцию
open
.

Листинг 15.10. Программа openfile: открытие файла и передача дескриптора обратно

//unixdomain/openfile.c

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

4 {

5 int fd;

6 ssize_t n;

7 if (argc != 4)

8 err_quit("openfile <sockfd#> <filename> <mode>");

9 if ((fd = open(argv[2], atoi(argv[3]))) < 0)

10 exit((errno > 0) ? errno : 255);

11 if ((n = write_fd(atoi(argv[1]), "", 1, fd)) < 0)

12 exit((errno > 0) ? errno : 255);

13 exit(0);

14 }

Аргументы командной строки

6-7
Поскольку два из трех аргументов командной строки были превращены в символьные строки функцией
my_open
, они преобразуются обратно в целые числа при помощи функции
atoi
.

Открытие файла

9-10
Файл открывается с помощью функции
open
. Если встречается ошибка, статус завершения этого процесса содержит значение переменной
errno
, соответствующее ошибке функции
open
.

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

11-12
Дескриптор передается обратно функцией
write_fd
, которую мы покажем в следующем листинге. Затем этот процесс завершается, но ранее в этой главе мы сказали, что отправляющий процесс может закрыть переданный дескриптор (это происходит, когда мы вызываем функцию
exit
), поскольку ядро знает, что дескриптор находится в состоянии передачи («в полете»), и оставляет его открытым для принимающего процесса.

ПРИМЕЧАНИЕ

Статус выхода должен лежать в пределах от 0 до 255. Максимальное значение переменной errno — около 150. Альтернативный способ, при котором не требуется, чтобы значение переменной errno было меньше 256, заключается в том, чтобы передать обратно указание на ошибку в виде обычных данных при вызове функции sendmsg.

В листинге 15.11 показана последняя функция,

write_fd
, вызывающая функцию
sendmsg
для отправки дескриптора (и, возможно, еще каких-либо данных, которые мы не используем) через доменный сокет Unix.

Листинг 15.11. Функция write_fd: передача дескриптора при помощи вызова функции sendmsg

//lib/write_fd.c

1 #include "unp.h"

2 ssize_t

3 write_fd(int fd, void *ptr, size_t nbytes, int sendfd)

4 {

5 struct msghdr msg;

6 struct iovec iov[1];

7 #ifdef HAVE_MSGHDR_MSG_CONTROL

8 union {

9 struct cmsghdr cm;

10 char control[CMSG_SPACE(sizeof(int))];

11 } control_un;

12 struct cmsghdr *cmptr;

13 msg.msg_control = control_un.control;

14 msg.msg_controllen = sizeof(control_un.control);

15 cmptr = CMSG_FIRSTHDR(&msg);

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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