ptg10805159
Section 17.5 An Open Server,Version 1 655
char buf[10];
struct iovec iov[3];
static int fd[2] = { -1, -1 };
if (fd[0] < 0) { /* fork/exec our open server first time */
if (fd_pipe(fd) < 0) {
err_ret("fd_pipe error");
return(-1);
}
if ((pid = fork()) < 0) {
err_ret("fork error");
return(-1);
}else if (pid == 0) { /* child */
close(fd[0]);
if (fd[1] != STDIN_FILENO &&
dup2(fd[1], STDIN_FILENO) != STDIN_FILENO)
err_sys("dup2 error to stdin");
if (fd[1] != STDOUT_FILENO &&
dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO)
err_sys("dup2 error to stdout");
if (execl("./opend", "opend", (char *)0) < 0)
err_sys("execl error");
}
close(fd[1]); /* parent */
}
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; /* +1 for null at end of buf */
len = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len;
if (writev(fd[0], &iov[0], 3) != len) {
err_ret("writev error");
return(-1);
}
/* read descriptor, returned errors handled by write() */
return(recv_fd(fd[0], write));
}
Figure 17.19Thecsopenfunction, version 1
The child closes one end of the fd-pipe, and the parent closes the other.For the
server that it executes, the child also duplicates its end of the fd-pipe onto its standard
input and standardoutput. (Another option would have been to pass the ASCII
representation of the descriptorfd[1]as an argument to the server.)
The parent sends to the server the request containing the pathname and open mode.
Finally,the parent callsrecv_fdto return either the descriptor or an error.If an error is
returned by the server,writeis called to output the message to standarderror.