ptg10805159
Section 17.6 An Open Server,Version 2 659
17.6 An Open Server,Version 2
In the previous section, we developed an open server that was invoked by aforkand
execby the client, demonstrating how we can pass file descriptors from a child to a
parent. In this section, we develop an open server as a daemon process. One server
handles all clients.We expect this design to be moreefficient, since aforkand anexec
areavoided. Weuse a UNIX domain socket connection between the client and the
server and demonstrate passing file descriptors between unrelated processes. We’ll use
the three functions serv_listen, serv_accept,and cli_conn introduced in
Section 17.3. This server also demonstrates how a single server can handle multiple
clients, using both theselectandpollfunctions from Section 14.4.
This version of the client is similar to the client from Section 17.5. Indeed, the file
main.cis identical (Figure17.18). Weadd the following line to theopen.hheader
(Figure17.17):
#define CS_OPEN "/tmp/opend.socket" /* server’s well-known name */
The fileopen.cdoes change from Figure17.19, since we now callcli_conninstead of
doing theforkandexec.This is shown in Figure17.25.
#include "open.h"
#include <sys/uio.h> /* struct iovec */
/*
*Open the file by sending the "name" and "oflag" to the
*connection server and reading a file descriptor back.
*/
int
csopen(char *name, int oflag)
{
int len;
char buf[12];
struct iovec iov[3];
static int csfd = -1;
if (csfd < 0) { /* open connection to conn server */
if ((csfd = cli_conn(CS_OPEN)) < 0) {
err_ret("cli_conn error");
return(-1);
}
}
sprintf(buf, " %d", oflag); /* oflag to ascii */
iov[0].iov_base = CL_OPEN " "; /* string concatenation */
iov[0].iov_len = strlen(CL_OPEN) + 1;
iov[1].iov_base = name;
iov[1].iov_len = strlen(name);
iov[2].iov_base = buf;
iov[2].iov_len = strlen(buf) + 1; /* null always sent */
len = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len;