UNP函数笔记十二: Unix域协议

来源:互联网 发布:ubuntu root密码忘记 编辑:程序博客网 时间:2024/06/05 15:00

第十五章  Unix域协议:

#include <sys/un.h>struct sockaddr_un {    sa_family_t  sun_family;    /* AF_LOCAL */    char         sun_path[104]; /* null-teminated pathname */};sun_path[0] means any-address#include <sys/socket.h>int socketpair(int family, int type, int protocol, int sockfd[2]);    family: AF_LOCAL    type: SOCK_STREAM, SOCK_DGRAM    protocol: 0    success return non-zero, error return -1#include <sys/socket.h>struct cmsgcred { /* cannot find in Linux */    pid_t  cmcred_pid;   /* PID of sending process */    uid_t  cmcred_uid;   /* real UID of sending process */    uid_t  cmcred_euid;  /* effective UID of sending process */    gid_t  cmcred_gid;   /* read GID of sending process */    short  cmcred_ngroups;  /* number of groups */    gid_t  cmcred_groups[CMGROUP_MAX];  /* groups */};CMGROUP_MAX is 16, cmcred_ngroups >= 1, cmcred_groups[0] is effective gid

示例:

#include <sys/socket.h>#include <sys/un.h>#include <netinet/in.h>#include "err_exit.h"#include "my_signal.h"#define PORT        9999#define ADDR        "127.0.0.1"#define MAXBACKLOG  100struct sockaddr_in  serv;pid_t               pid;int            pipefd[2];void do_parent(void);void do_child(void);int main(int argc, char ** argv){    if (argc != 1) {        printf("usage: %s\n", argv[0]);    }    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd) == -1) {        err_exit("socketpair error");    }    bzero(&serv, sizeof(serv));    serv.sin_family = AF_INET;    serv.sin_port = htons(PORT);    if (inet_pton(AF_INET, ADDR, &serv.sin_addr) <= 0) {        err_exit("inet_pton error");    }    if ((pid = fork()) < 0) {        err_exit("fork error");    }    else if (pid == 0) {        do_child();    }    else {        do_parent();    }            exit(0);}void parent_alrm(int signo){    return;  /* just interrupt blocked connect() */}void do_parent(void){    int  backlog;    int  j;    int  k;    int  junk;    int  fd[MAXBACKLOG + 1];    if (close(pipefd[0]) == -1) {        err_exit("close error");    }    if (my_signal(SIGALRM, parent_alrm) == SIG_ERR) {        err_exit("my_signal error");    }    for (backlog = 0; backlog <= 14; backlog++) {        printf("backlog = %d: ", backlog);        /* tell child value */        if (write(pipefd[1], &backlog, sizeof(int)) != sizeof(int)) {            err_exit("write error");        }        /* wait for child */        if (read(pipefd[1], &junk, sizeof(int)) < 0) {            err_exit("read error");        }        for (j = 1; j <= MAXBACKLOG; j++) {            if ((fd[j] = socket(AF_INET, SOCK_STREAM, 0)) == -1) {                err_exit("socket error");            }            alarm(2);            if (connect(fd[j], (struct sockaddr *)&serv, sizeof(serv)) < 0) {                if (errno != EINTR) {                    printf("connect error, j = %d\n", j);                    exit(1);                }                printf("timeout, %d connections completed\n", j-1);                for (k = 1; k <= j; k++) {                    if (close(fd[k]) == -1) {                        err_exit("close error");                    }                }                break;  /* next value of backlog */            }            alarm(0);        }        if (j > MAXBACKLOG) {            printf("%d connections?\n", MAXBACKLOG);        }    }    backlog = -1;  /* tell child we're all done */    if (write(pipefd[1], &backlog, sizeof(int)) != sizeof(int)) {        err_exit("write error");    }}void do_child(void){    int        listenfd;    int        backlog;    int        junk;    const int  on = 1;    if (close(pipefd[1]) == -1) {        err_exit("close error");    }    /* wait for parent */    if (read(pipefd[0], &backlog, sizeof(int)) != sizeof(int)) {        err_exit("read error");    }    while (backlog >= 0) {        if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {            err_exit("socket error");        }        if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on,                        sizeof(on)) == -1) {            err_exit("setsockopt error");        }        if (bind(listenfd, (struct sockaddr *)&serv, sizeof(serv)) == -1) {            err_exit("bind error");        }        if (listen(listenfd, backlog) == -1) {  /* start the listen */            err_exit("listen error");        }        /* tell parent */        if (write(pipefd[0], &junk, sizeof(int)) != sizeof(int)) {            err_exit("write error");        }        /* just wait for parent */        if (read(pipefd[0], &backlog, sizeof(int)) != sizeof(int)) {            err_exit("read error");        }        /* closes all queued connections, too */        if (close(listenfd) == -1) {            err_exit("close error");        }    }}
#include <sys/socket.h>#include <sys/param.h>#include "err_exit.h"#define HAVE_MSGHDR_MSG_CONTROL 1ssize_t write_fd(int fd, void * ptr, size_t nbytes, int sendfd){    struct msghdr  msg;    struct iovec   iov[1];#ifdef HAVE_MSGHDR_MSG_CONTROL    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;#else    msg.msg_accrights = (caddr_t) &sendfd;    msg.msg_accrightslen = sizeof(int);#endif    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));}
#include "err_exit.h"#include "write_fd.h"int main(int argc, char ** argv){    int  fd;    if (argc != 4) {        printf("openfile <sockfd#> <filename> <mode>\n");        exit(1);    }    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 <sys/socket.h>#include <sys/param.h>#include "err_exit.h"#define HAVE_MSGHDR_MSG_CONTROL 1ssize_t read_fd(int fd, void * ptr, size_t nbytes, int * recvfd){    struct msghdr  msg;    struct iovec   iov[1];    ssize_t        n;#ifdef HAVE_MSGHDR_MSG_CONTROL    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);#else    int                newfd;    msg.msg_accrights = (caddr_t) &newfd;    msg.msg_accrightslen = sizeof(int);#endif    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);    }#ifdef HAVE_MSGHDR_MSG_CONTROL    if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&        cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {        if (cmptr->cmsg_level != SOL_SOCKET) {            err_exit("control level != SOL_SOCKET");        }        if (cmptr->cmsg_type != SCM_RIGHTS) {            err_exit("control type != SCM_RIGHTS");        }        *recvfd = *((int *)CMSG_DATA(cmptr));    }    else {        *recvfd = -1;  /* descriptor was not passed */    }#else    if (msg.msg_accrightslen == sizeof(int)) {        *recvfd = newfd;    }    else {        *recvfd = -1;  /* descriptor was not passed */    }#endif    return(n);}
#include <sys/socket.h>#include <wait.h>#include <unistd.h>#include "err_exit.h"int my_open(const char * pathname, int mode){    int    fd;    int    sockfd[2];    int    status;    pid_t  childpid;    char   c;    char   argsockfd[10];    char   argmode[10];    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd) == -1) {        err_exit("socketpair error");    }    if ((childpid = fork()) < 0) {        err_exit("fork error");    }    else if (childpid == 0) {        if (close(sockfd[0]) == -1) {            err_exit("close error");        }        snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]);        snprintf(argmode, sizeof(argmode), "%d", mode);        execl("./openfile", "openfile", argsockfd, pathname, argmode, NULL);        err_exit("execl error");    }    if (close(sockfd[1]) == -1) {        err_exit("close error");    }    if (waitpid(childpid, &status, 0) <= 0) {        err_exit("waitpid error");    }    if (WIFEXITED(status) == 0) {        err_exit("child did not terminate");    }    if ((status = WEXITSTATUS(status)) == 0) {        if (read_fd(sockfd[0], &c, 1, &fd) <= 0) {            err_exit("read_fd error");        }    }    else {        errno = status;  /* set errno value from child's status */        fd = -1;    }    if (close(sockfd[0]) == -1) {        err_exit("close error");    }    return(fd);}
#include <fcntl.h>#include <unistd.h>#include "err_exit.h"#include "myopen.h"#define BUFFSIZE 4096int main(int argc, char ** argv){    int   fd;    int   n;    char  buff[BUFFSIZE];    if (argc != 2) {        printf("usage: mycat <pathname>\n");        exit(1);    }    if ((fd = my_open(argv[1], O_RDONLY)) < 0) {        printf("cannot open %s\n", argv[1]);        exit(1);    }    while ((n = read(fd, buff, BUFFSIZE)) > 0) {        if (write(STDOUT_FILENO, buff, n) != n) {            err_exit("write error");        }    }    if (n < 0) {        err_exit("read error");    }    exit(0);}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"int main(int argc, char ** argv){    int                 sockfd;    socklen_t           len;    struct sockaddr_un  addr1;    struct sockaddr_un  addr2;    if (argc != 2) {        printf("usage: unixbind <pathname>\n");        exit(1);    }    if ((sockfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {        err_exit("socket error");    }    unlink(argv[1]);  /* OK if this fails */    bzero(&addr1, sizeof(addr1));    addr1.sun_family = AF_LOCAL;    strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path)-1);    if (bind(sockfd, (struct sockaddr *)&addr1, SUN_LEN(&addr1)) == -1) {        err_exit("bind error");    }    len = sizeof(addr2);    if (getsockname(sockfd, (struct sockaddr *)&addr2, &len) == -1) {        err_exit("getsockname error");    }    printf("bound name = %s, returned len = %d\n", addr2.sun_path, len);        exit(0);}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"#define UNIXDG_PATH "/tmp/uinxdg"int main(int argc, char ** argv){    int                 sockfd;    struct sockaddr_un  servaddr;    struct sockaddr_un  cliaddr;    if ((sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0)) == -1) {        err_exit("socket error");    }    unlink(UNIXDG_PATH);    bzero(&servaddr, sizeof(servaddr));    servaddr.sun_family = AF_LOCAL;    strcpy(servaddr.sun_path, UNIXDG_PATH);    if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {        err_exit("bind error");    }    dg_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"#define UNIXDG_PATH "/tmp/uinxdg"int main(int argc, char ** argv){    int                 sockfd;    struct sockaddr_un  cliaddr;    struct sockaddr_un  servaddr;    if ((sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0)) == -1) {        err_exit("socket error");    }    bzero(&cliaddr, sizeof(cliaddr));  /* bind an address for us */    cliaddr.sun_family = AF_LOCAL;    strcpy(cliaddr.sun_path, tmpnam(NULL));    if (bind(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)) == -1) {        err_exit("bind error");    }    bzero(&servaddr, sizeof(servaddr));  /* fill in server's address */    servaddr.sun_family = AF_LOCAL;    strcpy(servaddr.sun_path, UNIXDG_PATH);    dg_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));    exit(0);}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"#define UNIXSTR_PATH "/tmp/unixstr"int main(int argc, char ** argv){    int                 sockfd;    struct sockaddr_un  servaddr;    if ((sockfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {        err_exit("socket error");    }    bzero(&servaddr, sizeof(servaddr));    servaddr.sun_family = AF_LOCAL;    strcpy(servaddr.sun_path, UNIXSTR_PATH);    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {        err_exit("connect error");    }    str_cli(stdin, sockfd);    exit(0);}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"#include "my_signal.h"#define LISTENQ 1024#define UNIXSTR_PATH "/tmp/unixstr"void sig_chld(int signo){    pid_t  pid;    int    stat;    while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {        printf("child %d terminated\n", pid);    }    return;}int main(int argc, char ** argv){    int                 listenfd;    int                 connfd;    pid_t               childpid;    socklen_t           clilen;    struct sockaddr_un  cliaddr;    struct sockaddr_un  servaddr;    if ((listenfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {        err_exit("socket error");    }    unlink(UNIXSTR_PATH);    bzero(&servaddr, sizeof(servaddr));    servaddr.sun_family = AF_LOCAL;    strcpy(servaddr.sun_path, UNIXSTR_PATH);    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {        err_exit("bind error");    }    if (listen(listenfd, LISTENQ) == -1) {        err_exit("listen error");    }    if (my_signal(SIGCHLD, sig_chld) == SIG_ERR) {        err_exit("my_signal error");    }    for ( ; ; ) {        clilen = sizeof(cliaddr);        if ((connfd = accept(listenfd, (struct sockaddr *)&cliaddr,                              &clilen)) < 0) {            if (errno == EINTR) {                continue;  /* back to for() */            }            else {                err_exit("accept error");            }        }        if ((childpid = fork()) < 0) {            err_exit("fork error");        }        else if (childpid == 0) {            if (close(listenfd) == -1) {                err_exit("close error");            }            str_echo(connfd);            exit(0);        }        if (close(connfd) == -1) {            err_exit("close error");        }    }}
#include <sys/socket.h>#include "err_exit.h"#define  CONTROL_LEN  (sizeof(struct cmsghdr) + sizeof(struct cmsgcred))ssize_t read_cred(int fd, void * ptr, size_t nbytes, struct cmsgcred * cmsgcredptr){    struct msghdr  msg;    struct iovec   iov[1];    char           control[CONTROL_LEN];    int            n;    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;    msg.msg_control = control;    msg.msg_controllen = sizeof(control);    msg.msg_flags = 0;    if ((n = recvmsg(fd, &msg, 0)) < 0) {        return(n);    }    cmsgcredptr->cmcred_ngroups = 0;  /* indicates no credentials returned */    if (cmsgcredptr && msg.msg_controllen > 0) {        struct cmsghdr * cmptr = (struct cmsghdr *)control;        if (cmptr->cmsg_len < CONTROL_LEN) {            printf("control length = %d\n", cmptr->cmsg_len);            exit(1);        }        if (cmptr->cmsg_level != SOL_SOCKET) {            err_exit("control level != SOL_SOCKET");        }        if (cmptr->cmsg_type != SCM_CREDS) {            err_exit("control type != SCM_CREDS");        }        memcpy(cmsgcredptr, CMSG_DATA(cmptr), sizeof(struct cmsgcred));    }    return(n);}
#include <sys/socket.h>#include "err_exit.h"#include "writen.h"#include "readcred.h"ssize_t read_cred(int, void *, size_t, struct cmsgcred *);#define MAXLINE 4096void str_echo(int sockfd){    ssize_t          n;    int              i;    char             buf[MAXLINE];    struct cmsgcred  cred;again:    while ((n = read_cred(sockfd, buf, MAXLINE, &cred)) > 0) {        if (cred.cmcred_ngroups == 0) {            printf("(no credentials returned)\n");        }        else {            printf("PID of sender = %d\n", cred.cmcred_pid);            printf("real user ID = %d\n", cred.cmcred_uid);            printf("real group ID = %d\n", cred.cmcred_gid);            printf("effective user ID = %d\n", cred.cmcred_euid);            printf("%d groups:", cred.cmcred_ngroups - 1);            for (i = 1; i < cred.cmcred_ngroups; i++) {                printf(" %d", cred.cmcred_groups[i]);            }            printf("\n");        }        if (writen(sockfd, buf, n) != n) {            err_exit("write error");        }    }    if (n < 0 && errno == EINTR) {        goto again;    }    else if (n < 0) {        err_exit("str_echo: read error");    }}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 习惯了光脚开车怎么办 遇到暴恐分子时该怎么办视频 中国人在菲律宾失踪了怎么办 高跟凉鞋前面磨脚怎么办 小孩子偷邻居家的钱怎么办 碰见美国人说叙利亚诈骗团伙怎么办 日服的火焰纹章闪退怎么办 冒险岛没潜能的怎么办 冒险岛法师运气不够怎么办 cad文件打开老是闪退白屏怎么办 上古卷轴5坏档怎么办 冒险岛2 65级后怎么办 第二次起诉离婚对方不同意怎么办 起诉离婚对方不同意离婚怎么办 我12爸妈离婚该怎么办 苹果迅雷下载的链接打不开怎么办 苹果上装的迅雷打不开怎么办 mp4进水水干了后打不开怎么办 迅雷闪退ios10.3怎么办 用辣椒辣到眼睛怎么办 辣椒辣到眼皮了怎么办 眼被辣椒辣了怎么办 老公欠银行的钱怎么办 离婚老公欠的钱怎么办 欠了几十万债怎么办 执行死刑时已怀孕怎么办 执行死刑世已经怀孕怎么办 孩子被爸爸打该怎么办 二年级的孩子逃课怎么办 龙妈和雪诺怎么办 车本扣6分怎么办 超速50扣了12分怎么办 开车超速扣12分怎么办 超速一次记12分怎么办? 驾照超速扣12分怎么办 c牌一次扣12分怎么办 超速罚500扣12分怎么办 高速超速记3分怎么办 高速超速记12分怎么办 过江隧道关闭了怎么办 高速限速60超了怎么办