linux进程间传递fd备忘
====================================================
server.c
==========================================================
#include
#include
#include
#include
enum{false,true};
int send_fd(int fd,int fd_to_send);
int main()
{
int sfd,cfd,size;
struct sockaddr_un un;
un.sun_family = AF_UNIX;
strcpy(un.sun_path,"foo.socket");
sfd = socket(AF_UNIX,SOCK_STREAM,0);
size = offsetof(struct sockaddr_un,sun_path) + strlen(un.sun_path);
remove("foo.socket");
bind(sfd,(struct sockaddr *)&un,size);
listen(sfd,5);
while(true){
cfd = accept(sfd,NULL,NULL);
int fd;
fd = open("test",O_RDWR,0600);
send_fd(cfd,fd);
close(fd);
close(cfd);
}
close(sfd);
}
#define CONTROLLEN CMSG_LEN(sizeof(int))
static struct cmsghdr *cmptr = NULL;
int send_fd(int fd,int fd_to_send)
{
struct iovec iov[1];
struct msghdr msg;
char buf[0];
iov[0].iov_base = buf;
iov[0].iov_len = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
if(cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL)
return (-1);
cmptr->cmsg_len = CONTROLLEN;
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
*(int *)CMSG_DATA(cmptr)= fd_to_send;
msg.msg_control = cmptr;
msg.msg_controllen = CONTROLLEN;
sendmsg(fd,&msg,0);
return (0);
}
=========================================================================
client.c
=========================================================================
#include
#include
#include
#include
int recv_fd(int fd);
enum{false,true};
int main()
{
int fd,size;
char buf[512];
int testfd;
memset(buf,'\0',sizeof(buf));
struct sockaddr_un un;
un.sun_family = AF_UNIX;
strcpy(un.sun_path,"foo.socket");
fd = socket(AF_UNIX,SOCK_STREAM,0);
size = offsetof(struct sockaddr_un,sun_path) + strlen(un.sun_path);
connect(fd,(struct sockaddr *)&un,size);
testfd = recv_fd(fd);
read(testfd,buf,512);
printf("%s\n",buf);
close(fd);
}
#define CONTROLLEN CMSG_LEN(sizeof(int))
static struct cmsghdr *cmptr = NULL;
int recv_fd(int fd)
{
int newfd;
char buf[0];
struct iovec iov[1];
struct msghdr msg;
while(true){
iov[0].iov_base = buf;
iov[0].iov_len = 1;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
if(cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL){
return (-1);
}
msg.msg_control = cmptr;
msg.msg_controllen = CONTROLLEN;
recvmsg(fd,&msg,0);
newfd = *(int *)CMSG_DATA(cmptr);
return(newfd);
}
}