#include #include #include #include #include #include #include #include int manager_client (const char *sockn) { int ret = -1; int fd = socket (AF_UNIX,SOCK_STREAM,0); if (fd == -1){ perror("socket client"); }else{ struct sockaddr_un un; un.sun_family = AF_UNIX; strcpy (un.sun_path,sockn); int pid = getpid(); fcntl (fd,F_SETOWN,(void*)pid); int s = connect(fd,(struct sockaddr*)&un,sizeof(un)); if (s == -1){ perror("connect"); }else{ ret = fd; } } return ret; } int manager_server(const char *sockn) { int ret = -1; unlink (sockn); int fd = socket (AF_UNIX,SOCK_STREAM,0); if (fd == -1){ perror("socket server"); }else{ struct sockaddr_un un; un.sun_family = AF_UNIX; strcpy (un.sun_path,sockn); if (bind(fd,(struct sockaddr*)&un,sizeof(un))==-1){ perror("bind"); }else{ chmod (sockn,0666); int code = listen (fd,10); if (code == -1){ perror ("listen"); }else{ struct sockaddr_un unc; size_t len = sizeof(unc); unc.sun_family = AF_UNIX; int s = accept (fd,(struct sockaddr*)&unc,&len); if (s == -1){ perror ("accept"); }else{ ret = s; } } } } return ret; } static int manager_sendfd(int sock, int fd) { char bufctl[sizeof(struct cmsghdr)+1*sizeof(int)]; struct cmsghdr *c = (struct cmsghdr*)bufctl; c->cmsg_len = sizeof(bufctl); c->cmsg_level = SOL_SOCKET; c->cmsg_type = SCM_RIGHTS; int *fds = (int*)CMSG_DATA(c); fds[0] = fd; struct msghdr h; struct iovec iov[1]; char buf[1000]; strcpy (buf,"hellohello"); iov[0].iov_base = buf; iov[0].iov_len = 10; h.msg_name = 0; h.msg_namelen = 0; h.msg_iov = iov; h.msg_iovlen = 1; h.msg_control = (void*)bufctl; h.msg_controllen = sizeof(bufctl); h.msg_flags = 0; int ret = sendmsg (sock,&h,0); if (ret==-1){ perror ("sendmsg"); } return ret; } int main (int argc, char *argv[]) { int ret = -1; if (argc == 2){ static const char sockn[]="/tmp/test.s"; if (strcmp(argv[1],"client")==0){ int fd = manager_client(sockn); if (fd != -1){ manager_sendfd (fd,1); #if 1 for (int i=0; i<10; i++){ char buf[10]; printf (" "); fflush (stdout); fgets (buf,sizeof(buf)-1,stdin); write (fd,"hello ",6); } #endif } }else if (strcmp(argv[1],"server")==0){ int fd = manager_server(sockn); if (fd != -1){ printf ("Connect ok\n"); size_t len = 1000; char buffer[1000]; if (getpeername (fd,(struct sockaddr*)buffer,&len)!=-1){ printf ("peername %d\n",len); for (int i=0; icmsg_len = sizeof(bufctl); //c->cmsg_level = SOL_SOCKET; //c->cmsg_type = SCM_RIGHTS; h.msg_flags = 0; int len = recvmsg (fd,&h,0); if (len<=0){ perror ("recvmsg"); break; }else{ printf ("message recu flags %d len %d %d %u\n" ,h.msg_flags,len ,h.msg_controllen,sizeof(bufctl)); printf ("iov.len %d\n",iov[0].iov_len); buf[len] = '\0'; printf ("buf = :%s:\n",buf); printf ("msg_len %d msg_level %d msg_type %d\n" ,c->cmsg_len ,c->cmsg_level ,c->cmsg_type); /* On kernel 2.2, we can check that On kernel 2.0, we can only tell if there is a descriptor if it is != -1 if (c->cmsg_level == SOL_SOCKET && c->cmsg_type == SCM_RIGHTS){ */ int *fd = (int*)CMSG_DATA(c); for (int i=0; i<20 && fd[i] != -1; i++){ printf ("fd passing %d\n",fd[i]); write (fd[i],"pass\n",5); } } } #if 0 printf ("getown %d\n",fcntl(fd,F_GETOWN,0)); int n; char buf[1000]; while ((n=read(fd,buf,sizeof(buf)-1))> 0){ buf[n] = '\0'; printf ("read %d :%s:\n",n,buf); } if (n == -1){ perror ("read"); } #endif } } } return ret; }