#include "apue.h"
#include <sys/un.h>
#include <errno.h>
#include <sys/socket.h>
#define CLI_PATH "/var/tmp/"
#define CLI_PERM S_IRWXU
int cli_conn(const char *name)
{
int fd, len,err,rval;
struct sockaddr_un un,sun;
int do_unlink=0;
if(strlen(name)>=sizeof(un.sun_path))
{
errno=ENAMETOOLONG;
return -1;
}
if((fd=socket(AF_UNIX, SOCK_STREAM, 0))<0)
{
return -1;
}
memset(&un, 0, sizeof(un));
un.sun_family=AF_UNIX;
sprintf(un.sun_path, "%s%05ld", CLI_PATH, (long)getpid());
len=offsetof(struct sockaddr_un ,sun_path)+strlen(un.sun_path);
unlink(un.sun_path);
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;
}
memset(&sun,0,sizeof(sum));
sun.sun_family=AF_UNIX;
strcpy(sun.sun_path, name);
len=offsetof((struct sockaddr *)&sun, len)<0);
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;
}
The cli_conn function
We call socket to create the client’s end of a UNIX domain socket. We then fill in a sockaddr_un structure with a client-specific name.
Passing File Descriptors
Passing an open file descriptor between processes is a powerful technique. It can lead to different ways of designing client–server applications. It allows one process (typically a server) to do everything that is required to open a file (involving such details as translating a network name to a network address, dialing a modem, and negotiating locks for the file) and simply pass back to the calling process a descriptor that can be used with all the I/O functions. All the details involved in opening the file or device are hidden from the client.
#include "apue.h"
int send_fd(int fd, int fd_to_send);
int send_err(int fd, int status, const char *errmsg);
int recv_fd(int fd, ssize_t (*userfunc)(int, const void *, size_t));
A process (normally a server) that wants to pass a descriptor to another process calls either send_fd or send_err. The process waiting to receive the descriptor (the client) calls recv_fd.
The send_fd function sends the descriptor fd_to_send across using the UNIX domain socket represented by fd. The send_err function sends the errmsg using fd, followed by the status byte. The value of status must be in the range −1 through −255.