#include #include #include #include #include #include "ipc_msg.h" int file_exists(char *filename) { struct stat buffer; return (stat (filename, &buffer) == 0); } /** * @brief 发送目标文件描述符 * @param fd 传递信息的 UNIX 域 文件描述符 * @param fd_to_send 待发送的文件描述符 */ int send_fd_args_sendmsg(int fd, int fd_to_send, pid_t pid, void **ppdata, int len) { struct iovec iov[1]; struct msghdr msg; int control_len = 0; int ret = 0; memfd_data_st memfd_data; struct cmsghdr cm; /* 这是辅助数据头部结构体,文件描述符就是通过这个结构体以及后面的数据部分发送的 */ control_len = CMSG_SPACE(sizeof(memfd_data_st) + len); char * recv_buf = (char *)malloc(control_len); if(NULL != recv_buf) { return -1; } iov[0].iov_base = recv_buf; iov[0].iov_len = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; memfd_data.memfd = fd_to_send; memfd_data.pid = pid; memfd_data.data = *ppdata; memfd_data.len = len; cm.cmsg_len = control_len; /* 辅助数据的字节数,包扩头部和真正的数据 */ cm.cmsg_level = SOL_SOCKET; /* 表示原始协议级别,与 setsockopt 的 level 参数相同 */ cm.cmsg_type = SCM_RIGHTS; /* 控制信息类型,SCM_RIGHTS 表示传送的内容是访问权 */ *(memfd_data_st*)CMSG_DATA(&cm) = memfd_data;/* 设置真正数据部分为我们想发送的文件描述符 */ msg.msg_control = &cm; /* 设置辅助数据 */ msg.msg_controllen = control_len; ret = sendmsg(fd, &msg, 0); free(recv_buf); return ret; } /** * @brief 发送目标文件描述符 * @param fd 传递信息的 UNIX 域 文件描述符 * @param fd_to_send 待发送的文件描述符 */ int send_fd_sendmsg(int fd, memfd_data_st** ppmemfd_data) { memfd_data_st *ptr_memfd_data = *ppmemfd_data; return send_fd_args_sendmsg(fd, ptr_memfd_data->memfd, ptr_memfd_data->pid, &ptr_memfd_data->data, ptr_memfd_data->len); } /** * @brief 接受文件描述符 * @param fd 传递信息的 UNIX 域 文件描述符 */ int recv_fd_recvmsg(int fd, memfd_data_st** ppmemfd_data) { struct iovec iov[1]; struct msghdr msg; char recv_buf[MAX_LEN]; int ret = -1; int control_len = 0; struct cmsghdr cm; iov[0].iov_base = recv_buf; iov[0].iov_len = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; control_len = CMSG_SPACE(sizeof(memfd_data_st) + MAX_LEN); msg.msg_control = &cm; msg.msg_controllen = control_len; ret = recvmsg(fd, &msg, 0); if(ret < 0) { ret = -1; } int off = offsetof(memfd_data_st, len); int len = *(int*)((char *)CMSG_DATA(&cm) + off); control_len = CMSG_SPACE(sizeof(memfd_data_st) + len); *ppmemfd_data = (memfd_data_st *)malloc(control_len); if(*ppmemfd_data == NULL) { return -1; } memset(*ppmemfd_data, 0, control_len); memcpy(*ppmemfd_data, CMSG_DATA(&cm), control_len); return ret; }