守护进程常常用作服务器进程。确实,我们可以称图13-2中的syslogd进程为服务器进程,用户进程(客户进程)用UNIX域数据报套接字向其发送消息。

一般而言,服务器进程等待客户进程与其联系,提出某种类型的服务要求。图 13-2 中,由syslogd服务器进程提供的服务是将一条出错消息记录到日志文件中。

图13-2中,客户进程和服务器进程之间的通信是单向的。客户进程向服务器进程发送服务请求,服务器进程则不向客户进程回送任何消息。在下面有关进程通信的几章中,我们将见到大量客户进程和服务器进程之间双向通信的实例。客户进程向服务器进程发送请求,服务器进程则向客户进程回送应答。

在服务器进程中调用fork然后exec另一个程序来向客户进程提供服务是很常见的。这些服务器进程通常管理着多个文件描述符:通信端点、配置文件、日志文件和类似的文件。最好的情况下,让子进程中的这些文件描述符保持打开状态并无大碍,因为它们很可能不会被在子进程中执行的程序所使用,尤其是那些与服务器端无关的程序。最坏情况下,保持它们的打开状态会导致安全问题——被执行的程序可能有一些恶意行为,如更改服务器端配置文件或欺骗客户端程序使其认为正在与服务器端通信,从而获取未授权的信息。

解决此问题的一个简单方法是对所有被执行程序不需要的文件描述符设置执行时关闭(close-on-exec)标志。图13-9展示了一个可以用来在服务器端进程中执行上述工作的函数。

#include "apue.h"
#include <fcntl.h>

int
set_cloexec(int fd)
{
    int    val;

    if ((val = fcntl(fd, F_GETFD, 0)) < 0)
        return(-1);

    val |= FD_CLOEXEC;        /* enable close-on-exec */

    return(fcntl(fd, F_SETFD, val));
}

图13-9 设置执行时关闭标志

results matching ""

    No results matching ""