美文网首页LinuxLinux学习之路
APUE读书笔记-17高级进程通信(16)

APUE读书笔记-17高级进程通信(16)

作者: QuietHeart | 来源:发表于2020-08-21 17:46 被阅读0次

    服务端

    下面,我们将要看到服务进程。

    头文件opend.h,版本2

    头文件opend.h包含一些标准的头文件以及一些全局变量和函数的声明。

    如下所示:

    #include "apue.h"
    #include <errno.h>
    
    #define CS_OPEN "/home/sar/opend"   /* well-known name */
    #define CL_OPEN "open"              /* client's request for server */
    
    extern int   debug;     /* nonzero if interactive (not daemon) */
    extern char  errmsg[];  /* error message string to return to client */
    extern int   oflag;     /* open flag: O_xxx ... */
    extern char *pathname;  /* of file to open for client */
    
    typedef struct {    /* one Client struct per connected client */
      int   fd;         /* fd, or -1 if available */
      uid_t uid;
    } Client;
    
    extern Client   *client;        /* ptr to malloc'ed array */
    extern int       client_size;   /* # entries in client[] array */
    
    int      cli_args(int, char **);
    int      client_add(int, uid_t);
    void     client_del(int);
    void     loop(void);
    void     request(char *, int, int, uid_t);
    

    用来操作客户进程数组的函数

    因为服务进程处理所有的客户进程请求,它必须维护每个客户连接的状态。这个通过一个opend.h中的Client数组来做到。

    下面代码就定义了操作这个数组的三个函数:

    #include    "opend.h"
    #define NALLOC  10   /* # client structs to alloc/realloc for */
    static void client_alloc(void)   /* alloc more entries in the client[] array */
    {
        int     i;
    
        if (client == NULL)
            client = malloc(NALLOC * sizeof(Client));
        else
            client = realloc(client, (client_size+NALLOC)*sizeof(Client));
        if (client == NULL)
            err_sys("can't alloc for client array");
    
        /* initialize the new entries */
        for (i = client_size; i < client_size + NALLOC; i++)
            client[i].fd = -1;  /* fd of -1 means entry available */
    
        client_size += NALLOC;
    }
    /*
     * Called by loop() when connection request from a new client arrives.
     */
    int client_add(int fd, uid_t uid)
    {
        int     i;
    
        if (client == NULL)     /* first time we're called */
            client_alloc();
    again:
        for (i = 0; i < client_size; i++) {
            if (client[i].fd == -1) {   /* find an available entry */
                client[i].fd = fd;
                client[i].uid = uid;
                return(i);  /* return index in client[] array */
            }
        }
        /* client array full, time to realloc for more */
        client_alloc();
        goto again;     /* and search again (will work this time) */
    }
    /*
     * Called by loop() when we're done with a client.
     */
    void client_del(int fd)
    {
        int     i;
        for (i = 0; i < client_size; i++) {
            if (client[i].fd == fd) {
                client[i].fd = -1;
                return;
            }
        }
        log_quit("can't find client entry for fd %d", fd);
    }
    

    client_add第一次被调用时,会调用client_alloc给数组分配10个条目的空间。当这10个条目都被使用完了之后,后面对client_add的调用会导致realloc再次分配额外的空间。通过用这个方式动态分配额外的空间,我们不用在编译之前限制客户进程数组的数目。因为服务进程是一个守护进程,所以以上函数如果出现了错误,我们使用之前定义的log_函数来提示错误信息。

    服务进程的main函数,版本2

    下面的代码中,main函数定义了全局变量,处理了命令行选项,然后调用函数循环。如果我们使用-d选项启动服务进程,那么服务进程会以交互的方式运行而不是守护进程了。当测试服务进程的时候,这个会被使用。

    #include    "opend.h"
    #include    <syslog.h>
    
    int      debug, oflag, client_size, log_to_stderr;
    char     errmsg[MAXLINE];
    char    *pathname;
    Client  *client = NULL;
    
    int main(int argc, char *argv[])
    {
        int     c;
    
        log_open("open.serv", LOG_PID, LOG_USER);
    
        opterr = 0;     /* don't want getopt() writing to stderr */
        while ((c = getopt(argc, argv, "d")) != EOF) {
            switch (c) {
            case 'd':       /* debug */
                debug = log_to_stderr = 1;
                break;
    
            case '?':
                err_quit("unrecognized option: -%c", optopt);
            }
        }
    
        if (debug == 0)
            daemonize("opend");
    
        loop();     /* never returns */
    }
    

    相关文章

      网友评论

        本文标题:APUE读书笔记-17高级进程通信(16)

        本文链接:https://www.haomeiwen.com/subject/cwhwrktx.html