zoukankan      html  css  js  c++  java
  • UNIX域协议之描述符传递

    一、mycat程序

    #include    <fcntl.h>
    #include    <stdlib.h>
    #include    <unistd.h>
    
    #define     BUFFSIZE    4096
    
    int my_open(const char *, int);
    void err_sys(const char *, ...); 
    void err_quit(const char *, ...);
    
    int main(int argc, char **argv)
    {
        int        fd, n;
        char    buff[BUFFSIZE];
    
        if (argc != 2) {
            err_quit("usage: mycat <pathname>");
        }
    
        if ( (fd = my_open(argv[1], O_RDONLY)) < 0) {
            err_sys("cannot open %s", argv[1]);
        }
    
        while ( (n = read(fd, buff, BUFFSIZE)) > 0) {
            write(STDOUT_FILENO, buff, n);
        }
    
        exit(0);
    }
    #include    <errno.h>
    #include    <stdio.h>
    #include    <unistd.h>
    #include    <sys/wait.h>
    #include    <sys/socket.h>
    
    void err_sys(const char *, ...);
    void err_quit(const char *, ...);
    ssize_t Read_fd(int, void *, size_t, int *);
    
    int my_open(const char *pathname, int mode)
    {
        int            fd, sockfd[2], status;
        pid_t        childpid;
        char        c, argsockfd[10], argmode[10];
    
        socketpair:
        if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd) == -1) {
            if (errno == EINTR) {
                goto socketpair;
            } else {
                err_quit("socketpair failed to create stream pipe");
            }
        }
    
        if ( (childpid = fork()) == 0) {        /* child process */
            close(sockfd[0]);
            snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]);
            snprintf(argmode, sizeof(argmode), "%d", mode);
            execl("../openfile/openfile", "openfile", argsockfd, 
                   pathname, argmode,(char *) NULL);
            err_sys("execl error");
        }
    
        close(sockfd[1]);        /* close the end we don't use */
    
        waitpid(childpid, &status, 0);
    
        if (WIFEXITED(status) == 0) {
            err_quit("child did not terminate");
        }
        if ( (status = WEXITSTATUS(status)) == 0) {
            Read_fd(sockfd[0], &c, 1, &fd);
        } else {
            errno = status;        /* set errno value from child's status */
            fd = -1;
        }
    
        close(sockfd[0]);
        return (fd);
    }
    #include    <stddef.h>
    #include    <sys/socket.h>
    
    void err_sys(const char *, ...);
    void err_quit(const char *, ...);
    
    ssize_t read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
    {
        struct msghdr    msg;
        struct iovec    iov[1];
        ssize_t            n;
    
        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);
    
        msg.msg_name = NULL;
        msg.msg_namelen = 0;
    
        iov[0].iov_base = ptr;
        iov[0].iov_len = nbytes;
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
    
        if ( (n = recvmsg(fd, &msg, 0)) <= 0) {
            return (n);
        }
    
        if ( (cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
            cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
            if (cmptr->cmsg_level != SOL_SOCKET) {
                err_quit("control level != SOL_SOCKET");
            }
            if (cmptr->cmsg_type != SCM_RIGHTS) {
                err_quit("control type != SCM_RIGHTS");
            }
            *recvfd = *((int *) CMSG_DATA(cmptr));
        } else {
            *recvfd = -1; /* descriptor was not passed */
        }
    
        return(n);
    }
    
    ssize_t Read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
    {
        ssize_t        n;
    
        if ( (n = read_fd(fd, ptr, nbytes, recvfd)) < 0) {
            err_sys("read_fd error");
        }
    
        return (n);
    }
    #include    <stdio.h>
    #include    <errno.h>
    #include    <stdlib.h>
    #include    <string.h>
    #include    <stdarg.h>        /* ANSI C header file */
    #include    <syslog.h>        /* for syslog() */
    
    #define     MAXLINE     4096
    
    int        daemon_proc;       /* set nonzero by daemon_init() */
    
    static void    err_doit(int, int, const char *, va_list);
    
    /* Nonfatal error related to system call
     * Print message and return */
    
    void err_ret(const char *fmt, ...) {
    
        va_list        ap;    
    
        va_start(ap, fmt);    
        err_doit(1, LOG_INFO, fmt, ap);
        va_end(ap);
        return;
    }
    
    /* Fatal error related to system call
     * Print message and terminate */
    
    void err_sys(const char *fmt, ...) {
    
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(1, LOG_ERR, fmt, ap);
        va_end(ap);
        exit(1);
    }
    
    /* Fatal error related to system call
     * Print message, dump core, and terminate */
    
    void err_dump(const char *fmt, ...) {
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(1, LOG_ERR, fmt, ap);
        va_end(ap);
        abort();        /* dump core and terminate */
        exit(1);        /* shouldn't get here */
    }
    
    /* Nonfatal error unrelated to system call
     * Print message and return */
    
    void err_msg(const char *fmt, ...) {
    
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(0, LOG_INFO, fmt, ap);
        va_end(ap);
        return;
    }
    
    /* Fatal error unrelated to system call
     * Print message and terminate */
    
    void err_quit(const char *fmt, ...) {
    
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(0, LOG_ERR, fmt, ap);
        va_end(ap);
        exit(1);
    }
    
    /* Print message and return to caller
     * Caller specifies "errnoflag" and "level" */
    
    static void err_doit(int errnoflag, int level, const char *fmt, va_list ap) {
    
        int        errno_save, n;
        char    buf[MAXLINE + 1];
    
        errno_save = errno;        /* value caller might want printed */
    #ifdef    HAVE_VSNPRINTF
        vsnprintf(buf, MAXLINE, fmt, ap);    /* safe */
    #else
        vsprintf(buf, fmt, ap);                /* not safe */
    #endif
        n = strlen(buf);
        if (errnoflag)
            snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
        strcat(buf, "
    ");
    
        if (daemon_proc) {
            syslog(level, buf);
        } else {
            fflush(stdout);        /* in case stdout and stderr are the same */
            fputs(buf, stderr);
            fflush(stderr);
        }
        return;
    }

    二、openfile程序

    #include    <errno.h>
    #include    <fcntl.h>
    #include    <stdlib.h>
    #include    <sys/types.h>
    
    void err_quit(const char *, ...);
    ssize_t Write_fd(int, void *, size_t, int);
    
    int main(int argc, char **argv)
    {
        int        fd;
    
        if (argc != 4) {
            err_quit("openfile <sockfd> <filename> <mode>");
        }
    
        if ( (fd = open(argv[2], atoi(argv[3]))) < 0) {
            exit( (errno > 0) ? errno : 255 );
        }
    
        if (Write_fd(atoi(argv[1]), "", 1, fd) < 0) {
            exit( (errno > 0) ? errno : 255 );
        }
    
        exit(0);
    }
    #include    <stddef.h>
    #include    <sys/socket.h>
    
    void err_sys(const char *, ...);
    
    ssize_t write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
    {
        struct msghdr    msg;
        struct iovec    iov[1];
    
        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;
    
        iov[0].iov_base = ptr;
        iov[0].iov_len = nbytes;
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
    
        return (sendmsg(fd, &msg, 0));
    }
    
    ssize_t Write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
    {
        ssize_t        n;
    
        if ( (n = write_fd(fd, ptr, nbytes, sendfd)) < 0) {
            err_sys("write_fd error");
        }
    
        return (n);
    }
    #include    <stdio.h>
    #include    <errno.h>
    #include    <stdlib.h>
    #include    <string.h>
    #include    <stdarg.h>        /* ANSI C header file */
    #include    <syslog.h>        /* for syslog() */
    
    #define     MAXLINE     4096
    
    int        daemon_proc;       /* set nonzero by daemon_init() */
    
    static void    err_doit(int, int, const char *, va_list);
    
    /* Nonfatal error related to system call
     * Print message and return */
    
    void err_ret(const char *fmt, ...) {
    
        va_list        ap;    
    
        va_start(ap, fmt);    
        err_doit(1, LOG_INFO, fmt, ap);
        va_end(ap);
        return;
    }
    
    /* Fatal error related to system call
     * Print message and terminate */
    
    void err_sys(const char *fmt, ...) {
    
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(1, LOG_ERR, fmt, ap);
        va_end(ap);
        exit(1);
    }
    
    /* Fatal error related to system call
     * Print message, dump core, and terminate */
    
    void err_dump(const char *fmt, ...) {
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(1, LOG_ERR, fmt, ap);
        va_end(ap);
        abort();        /* dump core and terminate */
        exit(1);        /* shouldn't get here */
    }
    
    /* Nonfatal error unrelated to system call
     * Print message and return */
    
    void err_msg(const char *fmt, ...) {
    
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(0, LOG_INFO, fmt, ap);
        va_end(ap);
        return;
    }
    
    /* Fatal error unrelated to system call
     * Print message and terminate */
    
    void err_quit(const char *fmt, ...) {
    
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(0, LOG_ERR, fmt, ap);
        va_end(ap);
        exit(1);
    }
    
    /* Print message and return to caller
     * Caller specifies "errnoflag" and "level" */
    
    static void err_doit(int errnoflag, int level, const char *fmt, va_list ap) {
    
        int        errno_save, n;
        char    buf[MAXLINE + 1];
    
        errno_save = errno;        /* value caller might want printed */
    #ifdef    HAVE_VSNPRINTF
        vsnprintf(buf, MAXLINE, fmt, ap);    /* safe */
    #else
        vsprintf(buf, fmt, ap);                /* not safe */
    #endif
        n = strlen(buf);
        if (errnoflag)
            snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
        strcat(buf, "
    ");
    
        if (daemon_proc) {
            syslog(level, buf);
        } else {
            fflush(stdout);        /* in case stdout and stderr are the same */
            fputs(buf, stderr);
            fflush(stderr);
        }
        return;
    }
  • 相关阅读:
    面试中AOP这样说,面试官只有一个字:服!
    Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!
    Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官!
    C#一些基础知识回顾
    关闭WiN10自动更新和后台程序。
    python脚本显示运行进程
    选择pyqt5理由
    anaconda3下64位python和32位python共存
    爬取百度搜索信息
    python尝试windows在用端口
  • 原文地址:https://www.cnblogs.com/soldierback/p/10768060.html
Copyright © 2011-2022 走看看