#include <sys_defs.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <string.h>
#include <msg.h>
#include <iostuff.h>
int unix_send_fd(int fd, int sendfd)
{
#ifdef CANT_USE_SEND_RECV_MSG
const char *myname = "unix_send_fd";
msg_warn("%s: your system has no support for file descriptor passing",
myname);
return (-1);
#else
struct msghdr msg;
struct iovec iov[1];
#if defined(CMSG_SPACE) && !defined(NO_MSGHDR_MSG_CONTROL)
union {
struct cmsghdr just_for_alignment;
char control[CMSG_SPACE(sizeof(sendfd))];
} control_un;
struct cmsghdr *cmptr;
memset((char *) &msg, 0, sizeof(msg));
msg.msg_control = control_un.control;
msg.msg_controllen = CMSG_LEN(sizeof(sendfd));
cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_len = CMSG_LEN(sizeof(sendfd));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
*(int *) CMSG_DATA(cmptr) = sendfd;
#else
msg.msg_accrights = (char *) &sendfd;
msg.msg_accrightslen = sizeof(sendfd);
#endif
msg.msg_name = 0;
msg.msg_namelen = 0;
iov->iov_base = "";
iov->iov_len = 1;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
return (sendmsg(fd, &msg, 0));
#endif
}
#ifdef TEST
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <split_at.h>
#include <connect.h>
int main(int argc, char **argv)
{
char *transport;
char *endpoint;
char *path;
int server_sock;
int client_fd;
if (argc < 3
|| (endpoint = split_at(transport = argv[1], ':')) == 0
|| *endpoint == 0 || *transport == 0)
msg_fatal("usage: %s transport:endpoint file...", argv[0]);
if (strcmp(transport, "unix") == 0) {
server_sock = unix_connect(endpoint, BLOCKING, 0);
} else {
msg_fatal("invalid transport name: %s", transport);
}
if (server_sock < 0)
msg_fatal("connect %s:%s: %m", transport, endpoint);
argv += 2;
while ((path = *argv++) != 0) {
if ((client_fd = open(path, O_RDONLY, 0)) < 0)
msg_fatal("open %s: %m", path);
msg_info("path=%s fd=%d", path, client_fd);
if (unix_send_fd(server_sock, client_fd) < 0)
msg_fatal("send file descriptor: %m");
if (close(client_fd) != 0)
msg_fatal("close(%d): %m", client_fd);
}
exit(0);
}
#endif