首页 > 代码库 > 在父子进程间用管道传递文件描述符
在父子进程间用管道传递文件描述符
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <sys/socket.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0) void send_fd(int sock_fd, int fd); int recv_fd(const int sock_fd); int main(int argc, const char *argv[]) { int fds[2]; socketpair(PF_UNIX, SOCK_STREAM, 0, fds); pid_t pid; pid = fork(); if(pid < 0) ERR_EXIT("fork"); else if(pid == 0){ close(fds[1]); int fd = open("test.txt", O_RDONLY); if(fd == -1) ERR_EXIT("open"); send_fd(fds[0], fd); }else{ sleep(1); close(fds[0]); int fd = recv_fd(fds[1]); char buffer[1024] = {0}; read(fd, buffer, 1024); printf("Recv msg: %s\n", buffer); } return 0; } void send_fd(int sock_fd, int fd) { int ret; struct msghdr msg; struct cmsghdr *p_cmsg; struct iovec vec; char cmsgbuf[CMSG_SPACE(sizeof(fd))]; int *p_fds; char sendchar = 0; msg.msg_control = cmsgbuf; msg.msg_controllen = sizeof(cmsgbuf); p_cmsg = CMSG_FIRSTHDR(&msg); p_cmsg->cmsg_level = SOL_SOCKET; p_cmsg->cmsg_type = SCM_RIGHTS; p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); p_fds = (int*)CMSG_DATA(p_cmsg); *p_fds = fd; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &vec; msg.msg_iovlen = 1; msg.msg_flags = 0; vec.iov_base = &sendchar; vec.iov_len = sizeof(sendchar); ret = sendmsg(sock_fd, &msg, 0); if (ret != 1) ERR_EXIT("sendmsg"); } int recv_fd(const int sock_fd) { int ret; struct msghdr msg; char recvchar; struct iovec vec; int recv_fd; char cmsgbuf[CMSG_SPACE(sizeof(recv_fd))]; struct cmsghdr *p_cmsg; int *p_fd; vec.iov_base = &recvchar; vec.iov_len = sizeof(recvchar); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &vec; msg.msg_iovlen = 1; msg.msg_control = cmsgbuf; msg.msg_controllen = sizeof(cmsgbuf); msg.msg_flags = 0; p_fd = (int*)CMSG_DATA(CMSG_FIRSTHDR(&msg)); *p_fd = -1; ret = recvmsg(sock_fd, &msg, 0); if (ret != 1) ERR_EXIT("recvmsg"); p_cmsg = CMSG_FIRSTHDR(&msg); if (p_cmsg == NULL) ERR_EXIT("no passed fd"); p_fd = (int*)CMSG_DATA(p_cmsg); recv_fd = *p_fd; if (recv_fd == -1) ERR_EXIT("no passed fd"); return recv_fd; }
在父子进程间用管道传递文件描述符
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。