#include #include #include #include #include /** * Sends given file descriptior via given socket * * @param socket to be used for fd sending * @param fd to be sent * @return sendmsg result * * @note socket should be (PF_UNIX, SOCK_DGRAM) */ int send_fd(int sock, int fd){ // This function does the arcane magic for sending // file descriptors over unix domain sockets struct msghdr msg; struct iovec iov[1]; struct cmsghdr *cmsg = NULL; char ctrl_buf[CMSG_SPACE(sizeof(int))]; char data[1]; memset(&msg, 0, sizeof(struct msghdr)); memset(ctrl_buf, 0, CMSG_SPACE(sizeof(int))); data[0] = ' '; iov[0].iov_base = data; iov[0].iov_len = sizeof(data); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_controllen = CMSG_SPACE(sizeof(int)); msg.msg_control = ctrl_buf; cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int)); *((int *) CMSG_DATA(cmsg)) = fd; return sendmsg(sock, &msg, 0); } main(argc, argv) int argc; char *argv[]; { int fd, sock; struct sockaddr_un server; char buf[1024]; if (argc < 3) { printf("usage:%s ", argv[0]); exit(1); } sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) { perror("opening stream socket"); exit(1); } server.sun_family = AF_UNIX; strcpy(server.sun_path, argv[1]); if (connect(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) { close(sock); perror("connecting stream socket"); exit(1); } // Open the file descriptor we want to send fd = open(argv[2], 0); send_fd(sock, fd); close(sock); }