UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
17-22
waitpid
status
WEXITSTATUS
openfile
errno
23
read_fd
При отправке и получении дескриптора по потоковому каналу мы всегда отправляем как минимум 1 байт данных, даже если получатель никак эти данные не обрабатывает. Иначе получатель не сможет распознать, что значит нулевое возвращаемое значение из функции read_fd: отсутствие данных (но, возможно, есть дескриптор) или конец файла.
В листинге 15.9 показана функция
readfd
recvmsg
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
HAVE_MSGHDR_MSG_CONTROL
recvmsg
msg_control
10-13
msg_control
msghdr
char
cmsghdr
malloc
27-45
recvmsg
recvfd
CMSG_DATA
cmsg_data
unsigned char
int