父子进程间分发FD

int fd_pair(int fd[2])
{
    return socketpair(AF_UNIX, SOCK_DGRAM, 0, fd);
}

int fd_send(int sockfd, int fd, int type)
{
    int data;
    struct iovec iov_data;
    struct msghdr msg_hdr;
    struct cmsghdr *cmsg_hdr;
    char msg_ctrl[CMSG_SPACE(1*sizeof(int))];
    memset(msg_ctrl, 0, CMSG_SPACE(1*sizeof(int)));

    data = type;
    iov_data.iov_base = &data;
    iov_data.iov_len = sizeof(int);

    msg_hdr.msg_name = NULL;
    msg_hdr.msg_namelen = 0;
    msg_hdr.msg_iov = &iov_data;
    msg_hdr.msg_iovlen = 1;
    msg_hdr.msg_control = msg_ctrl;
    msg_hdr.msg_controllen = CMSG_SPACE(1*sizeof(int));
    msg_hdr.msg_flags = 0;

    cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr);
    cmsg_hdr->cmsg_len = CMSG_LEN(1*sizeof(int));
    cmsg_hdr->cmsg_level = SOL_SOCKET;
    cmsg_hdr->cmsg_type = SCM_RIGHTS;
    ((int*)CMSG_DATA(cmsg_hdr))[0] = fd;

    return sendmsg(sockfd, &msg_hdr, 0);
}

int fd_recv(int sockfd, int *fd, int *type)
{
    int ret;
    int data;
    struct iovec iov_data;
    struct msghdr msg_hdr;
    struct cmsghdr *cmsg_hdr;
    char msg_ctrl[CMSG_SPACE(1*sizeof(int))];
    memset(msg_ctrl, 0, CMSG_SPACE(1*sizeof(int)));

    iov_data.iov_base = &data;
    iov_data.iov_len = sizeof(int);

    msg_hdr.msg_name = NULL;
    msg_hdr.msg_namelen = 0;
    msg_hdr.msg_iov = &iov_data;
    msg_hdr.msg_iovlen = 1;
    msg_hdr.msg_control = msg_ctrl;
    msg_hdr.msg_controllen = CMSG_SPACE(1*sizeof(int));
    msg_hdr.msg_flags = 0;

    cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr);
    cmsg_hdr->cmsg_len = CMSG_LEN(1*sizeof(int));
    cmsg_hdr->cmsg_level = SOL_SOCKET;
    cmsg_hdr->cmsg_type = SCM_RIGHTS;
    ((int *)CMSG_DATA(cmsg_hdr))[0] = -1;

    if((ret = recvmsg(sockfd, &msg_hdr, 0)) <= 0)
        return ret;

    if(fd) *fd = ((int*)CMSG_DATA(cmsg_hdr))[0];
    if(type) *type = data;
    return ret;
}

void fd_close(int fd)
{
    if(fd > 0)
        close(fd);
}

你可能感兴趣的:(父子进程间分发FD)