描述符传递

前端之家收集整理的这篇文章主要介绍了描述符传递前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Example.No.1:
通过socketpair打开两个连接起来的Unix套接字,一个用于进程本身读取内容,并输出到进程本身的标准输出,另一个则用于子进程传递通过Unix套接字发送excel的一个进程打开的文件描述符,通过sendmsg的辅助数据传递

进程本身代码:

#include <stdio.h>@H_301_7@
#include <stdlib.h>@H_301_7@
#include <sys/socket.h>@H_301_7@
#include <unistd.h>@H_301_7@
#include <string.h>@H_301_7@
#include <errno.h>@H_301_7@
#include <sys/wait.h>@H_301_7@
#include <fcntl.h>@H_301_7@

#define BUFSIZE 4096@H_301_7@


int@H_301_7@ read_fd(int@H_301_7@ fd,void@H_301_7@* ptr,size_t nbytes,int@H_301_7@* recvfd ) {
    struct@H_301_7@ msghdr msg;
    struct@H_301_7@ iovec iov[1@H_301_7@];
    ssize_t n;
    union@H_301_7@ {
        struct@H_301_7@ cmsghdr cm;
        char@H_301_7@ control[CMSG_SPACE(sizeof@H_301_7@(int@H_301_7@))];
    }control_un;

    msg.msg_control = control_un.control;
    msg.msg_controllen = sizeof@H_301_7@(control_un.control);
    msg.msg_name = NULL;
    msg.msg_namelen = 0@H_301_7@;
    iov[0@H_301_7@].iov_base = ptr;
    iov[0@H_301_7@].iov_len = nbytes;
    msg.msg_iov = iov;
    msg.msg_iovlen = 1@H_301_7@;
    if@H_301_7@ ((n = recvmsg(fd,&msg,0@H_301_7@)) <= 0@H_301_7@) {
        return@H_301_7@ n;
    }
    struct@H_301_7@ cmsghdr* cmptr;
    if@H_301_7@ ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL && cmptr->cmsg_len == CMSG_LEN(sizeof@H_301_7@(int@H_301_7@))) {
        if@H_301_7@ (cmptr->cmsg_level != SOL_SOCKET) {
            printf@H_301_7@("control level != SOL_SOCKET\n"@H_301_7@);
            exit@H_301_7@(1@H_301_7@);
        }

        if@H_301_7@ (cmptr->cmsg_type != SCM_RIGHTS) {
            printf@H_301_7@("control level != SCM_RIGHTS\n"@H_301_7@);
            exit@H_301_7@(1@H_301_7@);
        }
        *recvfd = *(int@H_301_7@*)CMSG_DATA(cmptr);
    }else@H_301_7@ {
        *recvfd = -1@H_301_7@;
    }
}
int@H_301_7@ my_open(char@H_301_7@* pathname,int@H_301_7@ mode) {
    int@H_301_7@ fd,sockfd[2@H_301_7@],status;
    char@H_301_7@ c;
    if@H_301_7@ (socketpair(AF_LOCAL,SOCK_STREAM,0@H_301_7@,sockfd) < 0@H_301_7@) {
        printf@H_301_7@("setsockpair error: %s\n"@H_301_7@,strerror(errno));
        exit@H_301_7@(1@H_301_7@);
    }
    int@H_301_7@ childpid;
    if@H_301_7@ ((childpid = fork()) < 0@H_301_7@) {
        printf@H_301_7@("fork error: %s\n"@H_301_7@,strerror(errno)); 
        exit@H_301_7@(1@H_301_7@);
    }else@H_301_7@ if@H_301_7@ (childpid == 0@H_301_7@) {
        char@H_301_7@ argsockfd[10@H_301_7@],argmode[10@H_301_7@];
        snprintf@H_301_7@(argsockfd,sizeof@H_301_7@(argsockfd),"%d"@H_301_7@,sockfd[1@H_301_7@]);
        snprintf@H_301_7@(argmode,sizeof@H_301_7@(argmode),mode);
        execl("./openfile"@H_301_7@,"openfile"@H_301_7@,argsockfd,pathname,argmode,(char@H_301_7@*)NULL);
    }
    close(sockfd[1@H_301_7@]);
    if@H_301_7@ (waitpid(childpid,&status,0@H_301_7@) < 0@H_301_7@) {
        printf@H_301_7@("waitpid error: %s\n"@H_301_7@,strerror(errno));
        exit@H_301_7@(1@H_301_7@);
    }
    if@H_301_7@ (WIFEXITED(status) == 0@H_301_7@) {
        printf@H_301_7@("child process did not terminate\n"@H_301_7@);
        exit@H_301_7@(1@H_301_7@);
    }

    if@H_301_7@ ((status = WEXITSTATUS(status)) == 0@H_301_7@) {
        if@H_301_7@ (read_fd(sockfd[0@H_301_7@],&c,1@H_301_7@,&fd) < 0@H_301_7@) {
            printf@H_301_7@("read_fd error\n"@H_301_7@);
            exit@H_301_7@(1@H_301_7@);
        }
    }else@H_301_7@ {
        errno = status;
        fd = -1@H_301_7@;
    }
    close(sockfd[0@H_301_7@]);
    return@H_301_7@ fd;
}
int@H_301_7@ main(int@H_301_7@ argc,char@H_301_7@** argv) {
    if@H_301_7@ (argc != 2@H_301_7@) {
        printf@H_301_7@("please add <pathname>\n"@H_301_7@);
        exit@H_301_7@(1@H_301_7@);
    }

    int@H_301_7@ fd;
    if@H_301_7@ ((fd = my_open(argv[1@H_301_7@],O_RDONLY)) < 0@H_301_7@) {
        printf@H_301_7@("can't open %s\n"@H_301_7@,argv[1@H_301_7@]);
        exit@H_301_7@(1@H_301_7@);
    }
    char@H_301_7@ buf[BUFSIZE];
    int@H_301_7@ n;
    while@H_301_7@ ((n = read(fd,buf,BUFSIZE)) > 0@H_301_7@) {
        if@H_301_7@ (write(STDOUT_FILENO,n) != n) {
            printf@H_301_7@("write error: %s\n"@H_301_7@,strerror(errno));
            exit@H_301_7@(1@H_301_7@);
        }
    }
    return@H_301_7@ 0@H_301_7@;
}

openfile进程代码:

#include <stdio.h>@H_301_7@
#include <stdlib.h>@H_301_7@
#include <unistd.h>@H_301_7@
#include <sys/socket.h>@H_301_7@
#include <fcntl.h>@H_301_7@
#include <string.h>@H_301_7@
#include <errno.h>@H_301_7@

int@H_301_7@ write_fd(int@H_301_7@ fd,int@H_301_7@ sendfd) {
    struct@H_301_7@ msghdr msg;
    struct@H_301_7@ iovec iov[1@H_301_7@];

    union@H_301_7@ {
        struct@H_301_7@ cmsghdr cmsg;
        char@H_301_7@ controls[CMSG_SPACE(sizeof@H_301_7@(int@H_301_7@))];
    }control_un;

    msg.msg_name = NULL;
    msg.msg_namelen = 0@H_301_7@;
    msg.msg_control = control_un.controls;
    msg.msg_controllen = sizeof@H_301_7@(control_un.controls);
    struct@H_301_7@ cmsghdr* cmptr;
    cmptr = CMSG_FIRSTHDR(&msg);
    cmptr->cmsg_len = CMSG_LEN(sizeof@H_301_7@(int@H_301_7@));
    cmptr->cmsg_level = SOL_SOCKET;
    cmptr->cmsg_type = SCM_RIGHTS;
    *(int@H_301_7@*)(CMSG_DATA(cmptr)) = sendfd;
    iov[0@H_301_7@].iov_base = ptr;
    iov[0@H_301_7@].iov_len = nbytes;
    msg.msg_iov = iov;
    msg.msg_iovlen = 1@H_301_7@;
    return@H_301_7@ sendmsg(fd,0@H_301_7@);
}

int@H_301_7@ main(int@H_301_7@ argc,char@H_301_7@** argv) {
    if@H_301_7@ (argc != 4@H_301_7@) {
        printf@H_301_7@("please check your input-arguments\n"@H_301_7@);
        exit@H_301_7@(1@H_301_7@);
    }

    int@H_301_7@ fd;
    if@H_301_7@ ((fd = open(argv[2@H_301_7@],atoi(argv[3@H_301_7@]))) < 0@H_301_7@) {
        printf@H_301_7@("open %s fail: error reason: %s\n"@H_301_7@,argv[2@H_301_7@],strerror(errno));
        exit@H_301_7@(1@H_301_7@);
    }

    int@H_301_7@ n;
    if@H_301_7@ ((n = write_fd(atoi(argv[1@H_301_7@]),""@H_301_7@,fd)) < 0@H_301_7@) {
        exit@H_301_7@(n);
    }
    exit@H_301_7@(0@H_301_7@);
}

猜你在找的Bash相关文章