ptg10805159
Section 17.3 Unique Connections 641
len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
unlink(un.sun_path); /* in case it already exists */
if (bind(fd, (struct sockaddr *)&un, len) < 0) {
rval = -2;
goto errout;
}
if (chmod(un.sun_path, CLI_PERM) < 0) {
rval = -3;
do_unlink = 1;
goto errout;
}
/* fill socket address structure with server’s address */
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, name);
len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
if (connect(fd, (struct sockaddr *)&sun, len) < 0) {
rval = -4;
do_unlink = 1;
goto errout;
}
return(fd);
errout:
err = errno;
close(fd);
if (do_unlink)
unlink(un.sun_path);
errno = err;
return(rval);
}
Figure 17.10 Thecli_connfunction
We callsocketto create the client’s end of a UNIX domain socket. We then fill in a
sockaddr_unstructurewith a client-specific name.
We don’t let the system choose a default address for us, because the server would
be unable to distinguish one client from another (if we don’t explicitly bind a name to a
UNIX domain socket, the kernel implicitly binds an address to it on our behalf and no
file is created in the file system to represent the socket). Instead, we bind our own
address — a step we usually don’t take when developing a client program that uses
sockets.
The last five characters of the pathname we bind aremade from the process ID of
the client.We callunlink,just in case the pathname already exists.We then callbind
to assign a name to the client’s socket. This creates a socket file in the file system with
the same name as the bound pathname.We callchmodto turn offall permissions other
than user-read, user-write, and user-execute. Inserv_accept,the server checks these
permissions and the user ID of the socket to verify the client’s identity.