#include #include #include #include #include #include #include #include #include #include #include #include #define TESTSTRING "This is a test string write into the file\n" int write_fd(int socketfd, int sendfd) { struct msghdr msg; struct iovec iov[1]; char c; 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; msg.msg_name = NULL; msg.msg_namelen = 0; c = 'T'; iov[0].iov_base = &c; iov[0].iov_len = sizeof(c); msg.msg_iov = iov; msg.msg_iovlen = 1; return sendmsg(socketfd, &msg, 0); } int read_fd(int socketfd, int *recvfd) { struct msghdr msg; struct iovec iov[1]; ssize_t n; char c; union { struct cmsghdr cm; // char control[CMSG_SPACE(sizeof(int))]; char control[256]; } control_un; struct cmsghdr *cmptr; msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un.control); msg.msg_name = NULL; msg.msg_namelen = 0; /* XXX Do we have to stuff this? */ iov[0].iov_base = &c; iov[0].iov_len = sizeof(c); msg.msg_iov = iov; msg.msg_iovlen = 1; if ((n = recvmsg(socketfd, &msg, 0)) <= 0) { printf("n = %d, errno=%d\n", n, errno); return n; } if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL && (cmptr->cmsg_len == CMSG_LEN(sizeof(int)))) { if(cmptr->cmsg_level != SOL_SOCKET) { printf("cmsg_level != SOL_SOCKET"); return -1; } if(cmptr->cmsg_type != SCM_RIGHTS) { printf("cmsg_level != SOL_SOCKET"); return -1; } *recvfd = *((int *)CMSG_DATA(cmptr)); } else { printf("cmptr = %p\n", cmptr); if (cmptr) { printf("cmptr->cmsg_len = %d\n", cmptr->cmsg_len); } *recvfd = -1; } return n; } int main(int argc, char *argv[], char* envp[]) { struct sockaddr_un servaddr,cliaddr; int len,rc,status,len1,len2; int sockfd,sockfd2,connfd,filefd,child,fail,errsave; char *path="/tmp/tfsocket"; char *filepath="/dev/shmem/tmp"; unsigned char buf[128]; memset(buf,0,sizeof(buf)); sockfd = socket(AF_LOCAL, SOCK_STREAM, 0); assert(sockfd >= 0); unlink(path); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; strncpy(servaddr.sun_path, path, sizeof(servaddr.sun_path) - 1); rc=bind(sockfd, (struct sockaddr *)&servaddr, SUN_LEN(&servaddr)); assert(rc==0); rc=listen(sockfd, 4); assert(rc!=-1); child=fork(); assert(child!=-1); if (child == 0) { fail=0; filefd=-1; // children connect to UDS and receive sockfd2 = socket(AF_LOCAL, SOCK_STREAM, 0); assert(sockfd2>=0); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; strncpy(servaddr.sun_path, path, sizeof(servaddr.sun_path) - 1); rc=connect(sockfd2, (struct sockaddr *)&servaddr, SUN_LEN(&servaddr)); assert(rc!=-1); //Once we have a connection try to read in a fd rc=read_fd(sockfd2,&filefd); if (rc==-1) { printf("read_fd() failed\n"); exit(1); } if (filefd==-1) { printf("Returned -1 for fd\n"); exit(1); } if (write(filefd,TESTSTRING,strlen(TESTSTRING)+1)!=-1) { fail++; } if (read(filefd,buf,10)==-1) { fail++; } exit(fail); } //the parent unlink(filepath); filefd=open("/dev/shmem/test", O_RDONLY|O_CREAT,S_IRUSR|S_IWUSR); assert(filefd!=-1); len=sizeof(cliaddr); connfd=accept(sockfd,(struct sockaddr *)&cliaddr, &len); //once we have a connetion, write the fd out to it write_fd(connfd,filefd); //Now wait fo r the child rc=waitpid(child, &status, 0); assert(rc==child); if ((WIFEXITED(status)) && (WEXITSTATUS(status)==0)){ printf("The test is passed\n"); } else { printf("The test is failed\n"); } //And close the fds close(sockfd); close(connfd); close(filefd); exit(0); }