Open System Services Programmer's Guide

if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0)
{
fprintf(stderr, "bind() call failed [errno %d]\n", errno);
exit(1);
}
/* make the socket a listening socket */
if (listen(fd, 5) < 0)
{
fprintf(stderr, "listen() call failed [errno %d]\n", errno);
exit(1);
}
/* fd usage
* 0 stdin - not used by dlaunch1, set up for dserver
* 1 stdout - not used by dlaunch1, set up for dserver
* 2 stderr - used by dlaunch1 for messages, inherited by dserver
* 3 listenfd - used by dlaunch1 for connections,
* not inherited by dserver
*/
close(STDIN_FILENO);
close(STDOUT_FILENO);
listenfd = fd;
fcntl(listenfd, F_SETFD, FD_CLOEXEC); /* don't propagate fd to children */
FD_ZERO(&fdset);
/* loop until error or timeout */
while (1)
{
/* initialize timeout and bitmask for select() call */
timeval.tv_sec = IDLE_PERIOD;
timeval.tv_usec = 0;
FD_SET(listenfd, &fdset);
readycount = select(listenfd+1, &fdset, NULL, NULL, &timeval);
/* if timeout then exit */
if (readycount == 0)
{
fprintf(stderr, "dlaunch1 stopping - timeout\n");
exit(0);
}
/* accept new connection */
if ((fd = accept(listenfd,(struct sockaddr *)NULL,
(size_t *)NULL)) < 0)
{
fprintf(stderr, "accept() call failed [errno %d]\n", errno);
exit(1);
}
/* setup stdin and stdout */
dup2(fd,STDIN_FILENO); /* fd is already STDIN_FILENO */
dup2(fd,STDOUT_FILENO); /* setup stdout */
/* launch a dserver process to handle the connection */
/* note - fork and exec are expensive operations and only */
/* apply to the same cpu as the parent process */
if ((newpid = fork()) < 0)
{
fprintf(stderr, "fork() failed [errno %d]\n", errno);
exit(1);
}
else if (newpid == 0)
{
/* we are child ... create grandchild to avoid zombie processes */
if ((newpid = fork()) < 0)
{
fprintf(stderr, "fork() failed [errno %d]\n", errno);
exit(1);
}
else if (newpid == 0)
{
108 Managing Processes