[BACK]Return to daemon-bozo.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / libexec / httpd

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/libexec/httpd/daemon-bozo.c between version 1.1.1.5 and 1.1.1.6

version 1.1.1.5, 2009/05/23 02:21:19 version 1.1.1.6, 2010/05/10 03:30:04
Line 1 
Line 1 
 /*      $eterna: daemon-bozo.c,v 1.17 2009/05/22 21:51:38 mrg Exp $     */  /*      $eterna: daemon-bozo.c,v 1.19 2010/05/10 02:51:28 mrg Exp $     */
   
 /*  /*
  * Copyright (c) 1997-2009 Matthew R. Green   * Copyright (c) 1997-2010 Matthew R. Green
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 47 
Line 47 
   
 #include "bozohttpd.h"  #include "bozohttpd.h"
   
         char    *iflag;         /* bind address; default INADDR_ANY */  
 static  int     *sock;          /* bound sockets */  
 static  int     nsock;          /* number of above */  
 static  struct pollfd *fds;     /* current poll fd set */  
 static  int     request_times;  /* how many times this proc has processed  
                                    a request */  
   
 static  void    daemon_runchild(int);  
 static  void    sigchild(int);  /* SIGCHLD handler */  static  void    sigchild(int);  /* SIGCHLD handler */
   
 #ifndef POLLRDNORM  #ifndef POLLRDNORM
Line 69  static void sigchild(int); /* SIGCHLD ha
Line 61  static void sigchild(int); /* SIGCHLD ha
   
 /* ARGSUSED */  /* ARGSUSED */
 static void  static void
 sigchild(signo)  sigchild(int signo)
         int signo;  
 {  {
         while (waitpid(-1, NULL, WNOHANG) > 0)          while (waitpid(-1, NULL, WNOHANG) > 0) {
                 ;          }
 }  }
   
 void  void
 daemon_init()  bozo_daemon_init(bozohttpd_t *httpd)
 {  {
         struct addrinfo h, *r, *r0;          struct addrinfo h, *r, *r0;
           const char      *portnum;
         int e, i, on = 1;          int e, i, on = 1;
   
         if (!bflag)          if (!httpd->background)
                 return;                  return;
   
         if (fflag == 0)          if (httpd->foreground == 0)
                 daemon(1, 0);                  daemon(1, 0);
   
         warning("started in daemon mode as `%s' port `%s' root `%s'",          portnum = (httpd->bindport) ? httpd->bindport : "http";
             myname, Iflag, slashdir);          bozo_warn(httpd, "started in daemon mode as `%s' port `%s' root `%s'",
               httpd->virthostname, portnum, httpd->slashdir);
   
         memset(&h, 0, sizeof h);          memset(&h, 0, sizeof(h));
         h.ai_family = PF_UNSPEC;          h.ai_family = PF_UNSPEC;
         h.ai_socktype = SOCK_STREAM;          h.ai_socktype = SOCK_STREAM;
         h.ai_flags = AI_PASSIVE;          h.ai_flags = AI_PASSIVE;
         e = getaddrinfo(iflag, Iflag, &h, &r0);          e = getaddrinfo(httpd->bindaddress, portnum, &h, &r0);
         if (e)          if (e)
                 error(1, "getaddrinfo([%s]:%s): %s",                  bozo_err(httpd, 1, "getaddrinfo([%s]:%s): %s",
                     iflag ? iflag : "*", Iflag, gai_strerror(e));                      httpd->bindaddress ? httpd->bindaddress : "*",
                       portnum, gai_strerror(e));
         for (r = r0; r != NULL; r = r->ai_next)          for (r = r0; r != NULL; r = r->ai_next)
                 nsock++;                  httpd->nsock++;
         sock = bozomalloc(nsock * sizeof *sock);          httpd->sock = bozomalloc(httpd, httpd->nsock * sizeof(*httpd->sock));
         fds = bozomalloc(nsock * sizeof *fds);          httpd->fds = bozomalloc(httpd, httpd->nsock * sizeof(*httpd->fds));
         for (i = 0, r = r0; r != NULL; r = r->ai_next) {          for (i = 0, r = r0; r != NULL; r = r->ai_next) {
                 sock[i] = socket(r->ai_family, SOCK_STREAM, 0);                  httpd->sock[i] = socket(r->ai_family, SOCK_STREAM, 0);
                 if (sock[i] == -1)                  if (httpd->sock[i] == -1)
                         continue;                          continue;
                 if (setsockopt(sock[i], SOL_SOCKET, SO_REUSEADDR, &on,                  if (setsockopt(httpd->sock[i], SOL_SOCKET, SO_REUSEADDR, &on,
                     sizeof(on)) == -1)                      sizeof(on)) == -1)
                         warning("setsockopt SO_REUSEADDR: %s",                          bozo_warn(httpd, "setsockopt SO_REUSEADDR: %s",
                             strerror(errno));                              strerror(errno));
                 if (bind(sock[i], r->ai_addr, r->ai_addrlen) == -1)                  if (bind(httpd->sock[i], r->ai_addr, r->ai_addrlen) == -1)
                         continue;                          continue;
                 if (listen(sock[i], SOMAXCONN) == -1)                  if (listen(httpd->sock[i], SOMAXCONN) == -1)
                         continue;                          continue;
                 fds[i].events = POLLIN | POLLPRI | POLLRDNORM |                  httpd->fds[i].events = POLLIN | POLLPRI | POLLRDNORM |
                                 POLLRDBAND | POLLERR;                                  POLLRDBAND | POLLERR;
                 fds[i].fd = sock[i];                  httpd->fds[i].fd = httpd->sock[i];
                 i++;                  i++;
         }          }
         if (i == 0)          if (i == 0)
                 error(1, "could not find any addresses to bind");                  bozo_err(httpd, 1, "could not find any addresses to bind");
         nsock = i;          httpd->nsock = i;
         freeaddrinfo(r0);          freeaddrinfo(r0);
   
         signal(SIGCHLD, sigchild);          signal(SIGCHLD, sigchild);
 }  }
   
 void  void
 daemon_closefds(void)  bozo_daemon_closefds(bozohttpd_t *httpd)
 {  {
         int i;          int i;
   
         for (i = 0; i < nsock; i++)          for (i = 0; i < httpd->nsock; i++)
                 close(sock[i]);                  close(httpd->sock[i]);
 }  }
   
 static void  static void
 daemon_runchild(int fd)  daemon_runchild(bozohttpd_t *httpd, int fd)
 {  {
   
         request_times++;          httpd->request_times++;
   
         /* setup stdin/stdout/stderr */          /* setup stdin/stdout/stderr */
         dup2(fd, 0);          dup2(fd, 0);
Line 155  daemon_runchild(int fd)
Line 149  daemon_runchild(int fd)
  * are ready to run... XXXMRG - still true in fork-lesser bozo?   * are ready to run... XXXMRG - still true in fork-lesser bozo?
  */   */
 void  void
 daemon_fork()  bozo_daemon_fork(bozohttpd_t *httpd)
 {  {
         int i;          int i;
   
         debug((DEBUG_FAT, "%s: pid %u request_times %d", __func__, getpid(),          debug((httpd, DEBUG_FAT, "%s: pid %u request_times %d",
                request_times));                  __func__, getpid(),
                   httpd->request_times));
         /* if we've handled 5 files, exit and let someone else work */          /* if we've handled 5 files, exit and let someone else work */
         if (request_times > 5 || (bflag == 2 && request_times > 0))          if (httpd->request_times > 5 ||
               (httpd->background == 2 && httpd->request_times > 0))
                 exit(0);                  exit(0);
   
         while (bflag) {          while (httpd->background) {
                 struct  sockaddr_storage ss;                  struct  sockaddr_storage ss;
                 socklen_t slen;                  socklen_t slen;
                 int fd;                  int fd;
   
                 if (nsock == 0)                  if (httpd->nsock == 0)
                         exit(0);                          exit(0);
   
                 /*                  /*
Line 180  daemon_fork()
Line 176  daemon_fork()
                  * it, for processing.                   * it, for processing.
                  */                   */
 again:  again:
                 if (poll(fds, nsock, INFTIM) == -1) {                  if (poll(httpd->fds, (unsigned)httpd->nsock, INFTIM) == -1) {
                         /* fail on programmer errors */                          /* fail on programmer errors */
                         if (errno == EFAULT ||                          if (errno == EFAULT ||
                             errno == EINVAL)                              errno == EINVAL)
                                 error(1, "poll: %s", strerror(errno));                                  bozo_err(httpd, 1, "poll: %s",
                                           strerror(errno));
   
                         /* sleep on some temporary kernel failures */                          /* sleep on some temporary kernel failures */
                         if (errno == ENOMEM ||                          if (errno == ENOMEM ||
Line 194  again:
Line 191  again:
                         goto again;                          goto again;
                 }                  }
   
                 for (i = 0; i < nsock; i++) {                  for (i = 0; i < httpd->nsock; i++) {
                         if (fds[i].revents & (POLLNVAL|POLLERR|POLLHUP)) {                          if (httpd->fds[i].revents & (POLLNVAL|POLLERR|POLLHUP)) {
                                 warning("poll on fd %d pid %d revents %d: %s",                                  bozo_warn(httpd,
                                     fds[i].fd, getpid(), fds[i].revents,                                          "poll on fd %d pid %d revents %d: %s",
                                     strerror(errno));                                          httpd->fds[i].fd, getpid(),
                                 warning("nsock = %d", nsock);                                          httpd->fds[i].revents,
                                 close(sock[i]);                                          strerror(errno));
                                 nsock--;                                  bozo_warn(httpd, "nsock = %d", httpd->nsock);
                                 warning("nsock now = %d", nsock);                                  close(httpd->sock[i]);
                                   httpd->nsock--;
                                   bozo_warn(httpd, "nsock now = %d", httpd->nsock);
                                 /* no sockets left */                                  /* no sockets left */
                                 if (nsock == 0)                                  if (httpd->nsock == 0)
                                         exit(0);                                          exit(0);
                                 /* last socket; easy case */                                  /* last socket; easy case */
                                 if (nsock == i)                                  if (httpd->nsock == i)
                                         break;                                          break;
                                 memmove(&fds[i], &fds[i+i],                                  memmove(&httpd->fds[i], &httpd->fds[i+i],
                                         (nsock - i) * sizeof(*fds));                                          (httpd->nsock - i) *
                                 memmove(&sock[i], &sock[i+i],                                                  sizeof(*httpd->fds));
                                         (nsock - i) * sizeof(*sock));                                  memmove(&httpd->sock[i], &httpd->sock[i+i],
                                           (httpd->nsock - i) *
                                                   sizeof(*httpd->sock));
                                 break;                                  break;
                         }                          }
                         if (fds[i].revents == 0)                          if (httpd->fds[i].revents == 0)
                                 continue;                                  continue;
   
                         slen = sizeof(ss);                          slen = sizeof(ss);
                         fd = accept(fds[i].fd, (struct sockaddr *)&ss, &slen);                          fd = accept(httpd->fds[i].fd,
                                           (struct sockaddr *)(void *)&ss, &slen);
                         if (fd == -1) {                          if (fd == -1) {
                                 if (errno == EFAULT ||                                  if (errno == EFAULT ||
                                     errno == EINVAL)                                      errno == EINVAL)
                                         error(1, "accept: %s", strerror(errno));                                          bozo_err(httpd, 1, "accept: %s",
                                                   strerror(errno));
   
                                 if (errno == ENOMEM ||                                  if (errno == ENOMEM ||
                                     errno == EAGAIN)                                      errno == EAGAIN)
Line 232  again:
Line 235  again:
                                 continue;                                  continue;
                         }                          }
   
                         if (request_times > 0) {                          if (httpd->request_times > 0) {
                                 daemon_runchild(fd);                                  daemon_runchild(httpd, fd);
                                 return;                                  return;
                         }                          }
   
                         switch (fork()) {                          switch (fork()) {
                         case -1: /* eep, failure */                          case -1: /* eep, failure */
                                 warning("fork() failed, sleeping for "                                  bozo_warn(httpd, "fork() failed, sleeping for "
                                         "10 seconds: %s", strerror(errno));                                          "10 seconds: %s", strerror(errno));
                                 close(fd);                                  close(fd);
                                 sleep(10);                                  sleep(10);
                                 break;                                  break;
   
                         case 0: /* child */                          case 0: /* child */
                                 daemon_runchild(fd);                                  daemon_runchild(httpd, fd);
                                 return;                                  return;
   
                         default: /* parent */                          default: /* parent */

Legend:
Removed from v.1.1.1.5  
changed lines
  Added in v.1.1.1.6

CVSweb <webmaster@jp.NetBSD.org>