This commit is contained in:
Nicholas Rishel 2020-06-16 16:23:23 -07:00 committed by GitHub
commit 7e9f8b876e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 15 deletions

View File

@ -303,7 +303,7 @@ Can a file descriptor be passed without sending any data?
And the answer is clearly "no" -- the file descriptor is not passed And the answer is clearly "no" -- the file descriptor is not passed
when no data are included in the write. when no data are included in the write.
(update, 2019-5-8 from Yicholas Rishel) (update, 2019-5-8 from Nicholas Rishel)
This is true for SOCK_STREAM sockets, but for SOCK_SEQPACKET sockets, This is true for SOCK_STREAM sockets, but for SOCK_SEQPACKET sockets,
you *can* do zero-length writes and pass an fd. you *can* do zero-length writes and pass an fd.
@ -316,7 +316,7 @@ you *can* do zero-length writes and pass an fd.
2. failing to accept an fd in the receiver results in the fd being 2. failing to accept an fd in the receiver results in the fd being
closed by the kernel. closed by the kernel.
3. a file descriptor must be accompanied by some data. 3. a file descriptor must be accompanied by some data if sent via stream.
## Make X pass file descriptors ## Make X pass file descriptors

View File

@ -37,10 +37,15 @@ sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd, int *nfdp)
int nfd_passed, nfd; int nfd_passed, nfd;
int i; int i;
int *fd_passed; int *fd_passed;
int type;
int length;
iov.iov_base = buf; iov.iov_base = buf;
iov.iov_len = bufsize; iov.iov_len = bufsize;
length = sizeof( int );
getsockopt (sock, SOL_SOCKET, SO_TYPE, &type, &length);
msg.msg_name = NULL; msg.msg_name = NULL;
msg.msg_namelen = 0; msg.msg_namelen = 0;
msg.msg_iov = &iov; msg.msg_iov = &iov;
@ -52,7 +57,7 @@ sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd, int *nfdp)
perror ("recvmsg"); perror ("recvmsg");
exit(1); exit(1);
} }
if (size > 0 && pass.cmsghdr.cmsg_len > sizeof (struct cmsghdr)) { if ((size > 0 || type == SOCK_SEQPACKET) && pass.cmsghdr.cmsg_len > sizeof (struct cmsghdr)) {
if ((msg.msg_flags & MSG_TRUNC) || if ((msg.msg_flags & MSG_TRUNC) ||
(msg.msg_flags & MSG_CTRUNC)) { (msg.msg_flags & MSG_CTRUNC)) {
fprintf (stderr, "control message truncated"); fprintf (stderr, "control message truncated");
@ -68,7 +73,6 @@ sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd, int *nfdp)
pass.cmsghdr.cmsg_type); pass.cmsghdr.cmsg_type);
exit(1); exit(1);
} }
nfd_passed = (pass.cmsghdr.cmsg_len - sizeof (struct cmsghdr)) / sizeof (int); nfd_passed = (pass.cmsghdr.cmsg_len - sizeof (struct cmsghdr)) / sizeof (int);
fd_passed = (int *) CMSG_DATA(&pass.cmsghdr); fd_passed = (int *) CMSG_DATA(&pass.cmsghdr);

View File

@ -25,17 +25,28 @@ child(int sock)
ssize_t size; ssize_t size;
sleep(1); sleep(1);
for (;;) { size = sock_fd_read(sock, buf, sizeof(buf), NULL, NULL);
nfd = 1; if (size <= 0) {
size = sock_fd_read(sock, buf, sizeof(buf), &fd, &nfd); printf ("<=0");
if (size <= 0) return;
break;
printf ("read %d nfd %d\n", size, nfd);
if (nfd == 1) {
write(fd, "hello, world\n", 13);
close(fd);
}
} }
printf ("read %d\n", size);
nfd = 1;
size = sock_fd_read(sock, buf, sizeof(buf), &fd, &nfd);
printf ("read %d nfd %d\n", size, nfd);
if (nfd == 1) {
write(fd, "hello, world\n", 13);
close(fd);
}
size = sock_fd_read(sock, buf, sizeof(buf), NULL, NULL);
if (size <= 0) {
printf ("<=0");
return;
}
printf ("read %d\n", size);
} }
void void
@ -60,7 +71,7 @@ main(int argc, char **argv)
int sv[2]; int sv[2];
int pid; int pid;
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) < 0) { if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, sv) < 0) {
perror("socketpair"); perror("socketpair");
exit(1); exit(1);
} }