Recv file descriptor.
Send file descriptor.
代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
ssize_t recv_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
{
struct msghdr msg;
struct iovec iov[1];
ssize_t n;
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof (int))];
} control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
if ((n = recvmsg(fd, &msg, 0)) <= 0)
return -1;
if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET)
return -1;
if (cmptr->cmsg_type != SCM_RIGHTS)
return -1;
*recvfd = *((int *) CMSG_DATA(cmptr));
} else {
*recvfd = -1;
}
return (n);
}
int main(int argc, char *argv[]) {
char c;
int fd, newfd;
struct sockaddr_un addr;
fd = socket(PF_UNIX, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sun_family = PF_UNIX;
strcpy(addr.sun_path, "/tmp/fd.socket");
unlink("/tmp/fd.socket");
bind(fd, (struct sockaddr *)&addr, sizeof(addr));
listen(fd, 10);
while((newfd = accept(fd, NULL, 0)) >= 0) {
int recvfd;
recv_fd(newfd, &c, 1, &recvfd);
close(newfd);
/* Now, we get the file descriptor. */
}
}
Send file descriptor.
代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
ssize_t send_fd(int fd, void *ptr, size_t nbytes, int sendfd)
{
struct msghdr msg;
struct iovec iov[1];
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
*((int *) CMSG_DATA(cmptr)) = sendfd;
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
return (sendmsg(fd, &msg, 0));
}
int main(int argc, char *argv[]) {
int fd, sendfd;
struct sockaddr_un addr;
fd = socket (PF_UNIX, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sun_family = PF_UNIX;
strcpy(addr.sun_path, "/tmp/fd.socket");
connect(fd, (struct sockaddr *)&addr, sizeof(addr));
sendfd = open("/etc/inittab", O_RDONLY);
/* send a file descriptor. */
send_fd(fd, "", 1, sendfd);
return 0;
}