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
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,
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
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

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 i;
int *fd_passed;
int type;
int length;
iov.iov_base = buf;
iov.iov_len = bufsize;
length = sizeof( int );
getsockopt (sock, SOL_SOCKET, SO_TYPE, &type, &length);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
@ -52,7 +57,7 @@ sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd, int *nfdp)
perror ("recvmsg");
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) ||
(msg.msg_flags & MSG_CTRUNC)) {
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);
exit(1);
}
nfd_passed = (pass.cmsghdr.cmsg_len - sizeof (struct cmsghdr)) / sizeof (int);
fd_passed = (int *) CMSG_DATA(&pass.cmsghdr);

View File

@ -25,17 +25,28 @@ child(int sock)
ssize_t size;
sleep(1);
for (;;) {
nfd = 1;
size = sock_fd_read(sock, buf, sizeof(buf), &fd, &nfd);
if (size <= 0)
break;
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);
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
@ -60,7 +71,7 @@ main(int argc, char **argv)
int sv[2];
int pid;
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) < 0) {
if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, sv) < 0) {
perror("socketpair");
exit(1);
}