Changeset View
Changeset View
Standalone View
Standalone View
lib/libnv/msgio.c
Show All 30 Lines | |||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/select.h> | #include <sys/select.h> | ||||
#include <sys/time.h> | |||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
Show All 20 Lines | |||||
* To work around limitations in 32-bit emulation on 64-bit kernels, use a | * To work around limitations in 32-bit emulation on 64-bit kernels, use a | ||||
* machine-independent limit on the number of FDs per message. Each control | * machine-independent limit on the number of FDs per message. Each control | ||||
* message contains 1 FD and requires 12 bytes for the header, 4 pad bytes, | * message contains 1 FD and requires 12 bytes for the header, 4 pad bytes, | ||||
* 4 bytes for the descriptor, and another 4 pad bytes. | * 4 bytes for the descriptor, and another 4 pad bytes. | ||||
*/ | */ | ||||
#define PKG_MAX_SIZE (MCLBYTES / 24) | #define PKG_MAX_SIZE (MCLBYTES / 24) | ||||
#endif | #endif | ||||
void buf_drain(int sock); | |||||
static int | static int | ||||
msghdr_add_fd(struct cmsghdr *cmsg, int fd) | msghdr_add_fd(struct cmsghdr *cmsg, int fd) | ||||
{ | { | ||||
PJDLOG_ASSERT(fd >= 0); | PJDLOG_ASSERT(fd >= 0); | ||||
cmsg->cmsg_level = SOL_SOCKET; | cmsg->cmsg_level = SOL_SOCKET; | ||||
cmsg->cmsg_type = SCM_RIGHTS; | cmsg->cmsg_type = SCM_RIGHTS; | ||||
▲ Show 20 Lines • Show All 269 Lines • ▼ Show 20 Lines | #ifndef MSG_CMSG_CLOEXEC | ||||
for (i = 0; i < nfds; i++) { | for (i = 0; i < nfds; i++) { | ||||
(void) fcntl(fds[i], F_SETFD, FD_CLOEXEC); | (void) fcntl(fds[i], F_SETFD, FD_CLOEXEC); | ||||
} | } | ||||
#endif | #endif | ||||
ret = 0; | ret = 0; | ||||
end: | end: | ||||
serrno = errno; | serrno = errno; | ||||
if (errno == EMSGSIZE) | |||||
buf_drain(sock); | |||||
free(msg.msg_control); | free(msg.msg_control); | ||||
errno = serrno; | errno = serrno; | ||||
return (ret); | return (ret); | ||||
} | } | ||||
int | int | ||||
fd_recv(int sock, int *fds, size_t nfds) | fd_recv(int sock, int *fds, size_t nfds) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | if (done == -1) { | ||||
errno = ENOTCONN; | errno = ENOTCONN; | ||||
return (-1); | return (-1); | ||||
} | } | ||||
size -= done; | size -= done; | ||||
ptr += done; | ptr += done; | ||||
} while (size > 0); | } while (size > 0); | ||||
return (0); | return (0); | ||||
} | |||||
void | |||||
buf_drain(int sock) | |||||
{ | |||||
char buf[4096]; | |||||
fd_set fds; | |||||
struct timeval tval; | |||||
int ret; | |||||
PJDLOG_ASSERT(sock >= 0); | |||||
tval.tv_sec = 0; | |||||
tval.tv_usec = 0; | |||||
for (;;) { | |||||
FD_ZERO(&fds); | |||||
FD_SET(sock, &fds); | |||||
ret = select(sock + 1, &fds, NULL, NULL, &tval); | |||||
if (ret < 0) { | |||||
if (errno == EINTR) | |||||
continue; | |||||
return; | |||||
} else if (ret == 0) { | |||||
/* Nothing to drain; bail out */ | |||||
return; | |||||
} | |||||
(void)recv(sock, buf, sizeof(buf), 0); | |||||
} | |||||
} | } | ||||
int | int | ||||
buf_recv(int sock, void *buf, size_t size) | buf_recv(int sock, void *buf, size_t size) | ||||
{ | { | ||||
ssize_t done; | ssize_t done; | ||||
unsigned char *ptr; | unsigned char *ptr; | ||||
Show All 21 Lines |