On Wed, Apr 20, 2005 at 04:57:31PM +0900, Takashi Ikebe wrote: > hmm.. most internet base services will use TCPv4 TCPv6 SCTP... > AF_UNIX can not use as inter-nodes communication.
You can send file descriptors (the actually file descriptors themselves, not their contents) to another process over a socket. A nearly ten-year old example is attached (ie. this isn't new or magical or specific to Linux).
/* sendfd.c - v. crude example of passing fds */ /* * I tested this on HPUX10 using gcc -D_XOPEN_SOURCE_EXTENDED sendfd.c -lxnet * * Expected output is "hello world" */ #include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/un.h> /* Note: msg_control may be msg_accrights, etc. */ int sendfd(int conn, int fd) { size_t len = sizeof(struct cmsghdr) + sizeof(int); struct cmsghdr *hdr = (struct cmsghdr *)malloc(len); struct msghdr msg; int rc; hdr->cmsg_len = len; hdr->cmsg_level = SOL_SOCKET; hdr->cmsg_type = SCM_RIGHTS; *(int *)CMSG_DATA(hdr) = fd; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = NULL; msg.msg_iovlen = 0; msg.msg_control = hdr; msg.msg_controllen = len; rc = sendmsg(conn, &msg, 0); free(hdr); return rc; } int recvfd(int conn) { size_t len = sizeof(struct cmsghdr) + sizeof(int); struct cmsghdr *hdr = (struct cmsghdr *)malloc(len); struct msghdr msg; int rc; msg.msg_iov = NULL; msg.msg_iovlen = 0; msg.msg_control = hdr; msg.msg_controllen = len; rc = recvmsg(conn, &msg, 0); if (rc >= 0 && hdr->cmsg_len == len && hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) { int fd = *(int *)CMSG_DATA(hdr); free(hdr); return fd; } free(hdr); return -1; } int main() { int fds[2]; int fd = -1; int rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); pid_t pid; if (rc) { perror("socketpair"); return 1; } /* punt */ system("echo hello world >testfile"); switch (pid = fork()) { case 0: // open this in the child proc fd = open("testfile",O_RDONLY); if (fd < 0) perror("open(testfile)"); rc = sendfd(fds[1], fd); if (rc) perror("sendfd"); _exit(0); case -1: perror("fork"); return 1; default: waitpid(pid,NULL,0); } fd = recvfd(fds[0]); if (fd < 0) { perror("recvfd"); return 1; } close(fds[0]); close(fds[1]); dup2(fd,0); close(fd); execl("/bin/cat","cat",NULL); }