Merge 2df5f47d3d
into 9c79e2b92f
This commit is contained in:
commit
7e9f8b876e
|
@ -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
|
||||
|
||||
|
|
8
fdpass.c
8
fdpass.c
|
@ -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);
|
||||
|
||||
|
|
33
zerowrite.c
33
zerowrite.c
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue