Open System Services Programmer's Guide
fdmsghdr.msg_iovlen = 1;
iov[0].iov_base = msg_buff; /* data ignored when passing fd */
iov[0].iov_len = sizeof(msg_buff);
fdmsghdr.msg_control = &fdadata;
fdmsghdr.msg_controllen = sizeof(fdadata);
fdadata.fdcmsghdr.cmsg_len = sizeof(fdadata);
fdadata.fdcmsghdr.cmsg_level = SOL_SOCKET;
fdadata.fdcmsghdr.cmsg_type = SCM_RIGHTS;
fdadata.fd = -1; /* set by each recvmsg() call */
/* Find a ready socket ... */
while (1)
{
/* initialize timeout and bitmask for select() call */
timeval.tv_sec = IDLE_PERIOD;
timeval.tv_usec = 0;
memcpy(&rdset, &fdset, sizeof(fdset));
readycount = select(highfd+1, &rdset, NULL, NULL, &timeval);
/* if timeout then exit */
if (readycount == 0)
{
fprintf(stderr, "sserver [cpu %d] - "
"stopping [timeout]\n",
cpu);
exit(0);
}
/* find first fd that was marked ready for reading */
for (fd = 0; !FD_ISSET(fd, &rdset); fd++)
{
; /* for loop does all the work */
}
/* if ready fd is the fd passing socket, accept new fd */
if (fd == fdpassfd)
{
if ((bytesread = recvmsg(fd, &fdmsghdr, 0)) < 0)
{
fprintf(stderr, "sserver [cpu %d] - "
"recvmsg(fd %d) failed [errno %d]\n",
cpu, fd, errno);
exit(1);
}
else if (bytesread == 0)
{
fprintf(stderr, "sserver [cpu %d] - "
"stopping [stdin unexpectedly closed]\n",
cpu);
exit(1);
}
/* add fd to set of active fds */
newfd = fdadata.fd;
FD_SET(newfd, &fdset);
fdcount++;
if (newfd > highfd)
highfd = newfd;
fprintf(stderr, "sserver [cpu %d] - "
"new connection on fd %d\n",
cpu, newfd);
}
else /* else ready fd is an existing connected socket */
{
/* read data from connected socket which is ready
* for reading */
if ((bytesread = recv(fd, msg_buff, BUFF_LEN, 0)) < 0)
{
fprintf(stderr, "sserver [cpu %d] - "
"recv(fd %d) failed [errno %d]\n",
cpu, fd, errno);
148 Managing Processes