> I used to have a program which will fork several
> child processes, and then listen on the net waiting
> for client's requests. After the program gets a request
> it will then pass the file descriptor of the opened socket
> to one of the child processes. The program works fine
> on Sun OS 4.1.4, Solaris 2.5, and HPUX.
> After I got my own Linux box set up, I tried to port the
> program using the msghdr, cmsghdr method, however it
> seems that the child process has problem getting the
> file descriptor from the parent. Don't know what
> the problem is, have no idea whether Linux support
> this or not. Can anybody help me here?
Linux does support this. I got it working from the examples out of
Richard Stevens' "UNIX Network Programming" and "Advanced Programming in
the UNIX Environment," with the following code:
#define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(int))
#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
// sockfd is the socket between the processes.
// fd is the new file descriptor to be passed.
int send_fd(int sockfd, int fd)
{
struct iovec iov[1];
char buf[2];
struct msghdr msg;
int *ptr;
static struct cmsghdr *cmptr = NULL;
buf[0] = 'w';
buf[1] = '\0';
iov[0].iov_base = buf; // No data to send
iov[0].iov_len = 2;
if (cmptr == NULL &&
(cmptr = (struct cmsghdr *) malloc(CONTROLLEN)) == NULL)
return -1;
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
cmptr->cmsg_len = CONTROLLEN;
*(int *)CMSG_DATA(cmptr) = fd;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = (caddr_t) 0;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t) cmptr;
msg.msg_controllen = CONTROLLEN;
if (sendmsg(sockfd, &msg, 0) < 0)
return -1;
return 0;
Quote:}
// sockfd is the socket used to communicate with the other process
// returns the new file descriptor
int recv_fd(int sockfd)
{
int fd;
int *ptr;
char buf[10];
struct iovec iov[1];
struct msghdr msg;
static struct cmsghdr *cmptr = NULL;
if (cmptr == NULL &&
(cmptr = (struct cmsghdr *) malloc(CONTROLLEN)) == NULL)
return -1;
iov[0].iov_base = buf;
iov[0].iov_len = 10;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = (caddr_t) 0;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t) cmptr;
msg.msg_controllen = CONTROLLEN;
if (recvmsg(sockfd, &msg, 0) < 0)
return -1;
fd = *(int *)CMSG_DATA(cmptr);
return(fd);
Quote:}
Eric