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

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

Шрифт:

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

readfd
, вызывающая функцию
recvmsg
для получения данных и дескриптора через доменный сокет Unix. Первые три аргумента этой функции те же, что и для функции
read
, а четвертый (
recvfd
) является указателем на целое число. После выполнения этой функции
recvfd
будет указывать на полученный дескриптор.

Листинг 15.9. Функция read_fd: получение данных и дескриптора

//lib/read_fd.c

1 #include "unp.h"

2 ssize_t

3 read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)

4 {

5 struct msghdr msg;

6 struct iovec iov[1];

7 ssize_t n;

8 int newfd;

9 #ifdef HAVE_MSGHDR_MSG_CONTROL

10 union {

11 struct cmsghdr cm;

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

13 } control_un;

14 struct cmsghdr *cmptr;

15 msg.msg_control = control_un.control;

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

17 #else

18 msg.msg_accrights = (caddr_t)&newfd;

19 msg.msg_accrightslen = sizeof(int);

20 #endif

21 msg.msg_name = NULL;

22 msg.msg_namelen = 0;

23 iov[0].iov_base = ptr;

24 iov[0].iov_len = nbytes;

25 msg.msg_iov = iov;

26 msg.msg_iovlen = 1;

27 if ((n = recvmsg(fd, &msg, 0)) <= 0)

28 return (n);

29 #ifdef HAVE_MSGHDR_MSG_CONTROL

30 if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&

31 mptr->cmsg_len == CMSG_LEN(sizeof(int))) {

32 if (cmptr->cmsg_level != SOL_SOCKET)

33 err_quit("control level != SOL_SOCKET");

34 if (cmptr->cmsg_type != SCM_RIGHTS)

35 err_quit("control type != SCM_RIGHTS");

36 *recvfd = *((int*)CMSG_DATA(cmptr));

37 } else

38 *recvfd = -1; /* дескриптор не был передан */

39 #else

40 if (msg.msg_accrightslen == sizeof(int))

41 *recvfd = newfd;

42 else

43 *recvfd = -1; /* дескриптор не был передан */

44 #endif

45 return (n);

46 }

8-26
Эта функция должна работать с обеими версиями функции
recvmsg
: с элементом
msg_control
и с элементом
msg_accrights
. Наш заголовочный файл
config.h
(см. листинг Г.2) определяет константу
HAVE_MSGHDR_MSG_CONTROL
, если поддерживается версия функции
recvmsg
с
msg_control
.

Проверка выравнивания буфера msg_control

10-13
Буфер
msg_control
должен быть выровнен в соответствии со структурой
msghdr
. Просто выделить в памяти массив типа
char
недостаточно. Здесь мы объявляем объединение, состоящее из структуры
cmsghdr
и символьного массива, что гарантирует необходимое выравнивание массива. Возможно и другое решение — вызвать функцию
malloc
, но это потребует освобождения памяти перед завершением функции.

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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