#include "unp.h"
ssize_t read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
{
struct msghdr msg;
struct iovec iov[1];
ssize_t n;
#ifdef HAVE_MSGHDR_MSG_CONTROL
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);
#else
int newfd;
msg.msg_accrights=(caddr_t)&newfd;
msg.msg_accrightslen=sizeof(int);
#endif
msg.msg_name=NULL;
msg.msg_namelen=0;
iov[0].iov_base=ptr;
iov[0].iov_len=nbytes;
if((n=recvmsg(fd, &msg,0))<=0)
return n;
#ifdef HAVE_MSGHDR_MSG_CONTROL
if((cmptr=CMS_FIRSTHDR(&msg))!=NULL&&
cmptr->cmsg_len==CMSG_LEN(sizeof(int)))
{
if(cmptr->cmsg_level!=SOL_SOCKET)
err_quit("control level!=SOL_SOCKET");
if(cmptr->cmsg_type!=SCM_RIGHTS)
err_quit("control type!=SCM_RIGHTS");
*recvfd=*((int *) CMSG_DATA(cmptr));
}
else
*recvfd=-1;
#else
if(msg.msg_accrightslen==sizeof(int))
*recvfd=newfd;
else
*recvfd=-1;
#endif
return n;
}
read_fd function: receives data and a descriptor
#include "unp.h"
int main(int argc, char **argv)
{
int fd;
if(argc!=4)
err_quit("openfile <sockfd#> <filename> <mode>");
if((fd=open(argv[2], atoi(argv[3])))<0)
exit((errno>0)?errno:255);
if(write_fd(atoi(argv[1]),"", 1, fd)<0)
exit((errno>0)?errno:255);
return 0;
}
openfile function: opens a file and passes back the descriptor
#include "unp.h"
ssize_t write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
{
struct msghdr msg;
struct iovec iov[1];
#ifdef HAVE_MSGHDR_MSG_CONTROL
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;
#else
msg.msg_accrights=(caddr_t)&sendfd;
msg.msg_accrightslen=sizeof(int);
#endif
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);
}
write_fd function: passes a descriptor by calling sendmsg