9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

sendfd.c (1672B)


      1 #include <u.h>
      2 #define NOPLAN9DEFINES
      3 #include <libc.h>
      4 #include <sys/socket.h>
      5 #include <sys/uio.h>
      6 #include <unistd.h>
      7 #include <errno.h>
      8 
      9 #ifndef CMSG_ALIGN
     10 #	ifdef __sun__
     11 #		define CMSG_ALIGN _CMSG_DATA_ALIGN
     12 #	else
     13 #		define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1))
     14 #	endif
     15 #endif
     16 
     17 #ifndef CMSG_SPACE
     18 #	define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+CMSG_ALIGN(len))
     19 #endif
     20 
     21 #ifndef CMSG_LEN
     22 #	define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+(len))
     23 #endif
     24 
     25 int
     26 sendfd(int s, int fd)
     27 {
     28 	char buf[1];
     29 	struct iovec iov;
     30 	struct msghdr msg;
     31 	struct cmsghdr *cmsg;
     32 	int n;
     33 	char cms[CMSG_SPACE(sizeof(int))];
     34 	
     35 	buf[0] = 0;
     36 	iov.iov_base = buf;
     37 	iov.iov_len = 1;
     38 
     39 	memset(&msg, 0, sizeof msg);
     40 	msg.msg_iov = &iov;
     41 	msg.msg_iovlen = 1;
     42 	msg.msg_control = (caddr_t)cms;
     43 	msg.msg_controllen = CMSG_LEN(sizeof(int));
     44 
     45 	cmsg = CMSG_FIRSTHDR(&msg);
     46 	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
     47 	cmsg->cmsg_level = SOL_SOCKET;
     48 	cmsg->cmsg_type = SCM_RIGHTS;
     49 	memmove(CMSG_DATA(cmsg), &fd, sizeof(int));
     50 
     51 	if((n=sendmsg(s, &msg, 0)) != iov.iov_len)
     52 		return -1;
     53 	return 0;
     54 }
     55 
     56 int
     57 recvfd(int s)
     58 {
     59 	int n;
     60 	int fd;
     61 	char buf[1];
     62 	struct iovec iov;
     63 	struct msghdr msg;
     64 	struct cmsghdr *cmsg;
     65 	char cms[CMSG_SPACE(sizeof(int))];
     66 
     67 	iov.iov_base = buf;
     68 	iov.iov_len = 1;
     69 
     70 	memset(&msg, 0, sizeof msg);
     71 	msg.msg_name = 0;
     72 	msg.msg_namelen = 0;
     73 	msg.msg_iov = &iov;
     74 	msg.msg_iovlen = 1;
     75 
     76 	msg.msg_control = (caddr_t)cms;
     77 	msg.msg_controllen = sizeof cms;
     78 
     79 	if((n=recvmsg(s, &msg, 0)) < 0)
     80 		return -1;
     81 	if(n == 0){
     82 		werrstr("unexpected EOF");
     83 		return -1;
     84 	}
     85 	cmsg = CMSG_FIRSTHDR(&msg);
     86 	memmove(&fd, CMSG_DATA(cmsg), sizeof(int));
     87 	return fd;
     88 }