Correctly shutdown the servers when the process is terminating;
authorreyk <reyk@openbsd.org>
Wed, 23 Jul 2014 13:26:39 +0000 (13:26 +0000)
committerreyk <reyk@openbsd.org>
Wed, 23 Jul 2014 13:26:39 +0000 (13:26 +0000)
prevents a crash on exit.  With debugging help from blambert@.

usr.sbin/httpd/config.c
usr.sbin/httpd/httpd.h
usr.sbin/httpd/server.c

index 230ec35..8dd395d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: config.c,v 1.2 2014/07/13 14:17:37 reyk Exp $ */
+/*     $OpenBSD: config.c,v 1.3 2014/07/23 13:26:39 reyk Exp $ */
 
 /*
  * Copyright (c) 2011 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -90,10 +90,8 @@ config_purge(struct httpd *env, u_int reset)
        what = ps->ps_what[privsep_process] & reset;
 
        if (what & CONFIG_SERVERS && env->sc_servers != NULL) {
-               while ((srv = TAILQ_FIRST(env->sc_servers)) != NULL) {
-                       TAILQ_REMOVE(env->sc_servers, srv, srv_entry);
-                       free(srv);
-               }
+               while ((srv = TAILQ_FIRST(env->sc_servers)) != NULL)
+                       server_purge(srv);
        }
 
        if (what & CONFIG_MEDIA && env->sc_mediatypes != NULL)
index 75d6e44..d23e6a8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: httpd.h,v 1.5 2014/07/23 12:01:27 reyk Exp $  */
+/*     $OpenBSD: httpd.h,v 1.6 2014/07/23 13:26:39 reyk Exp $  */
 
 /*
  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -362,6 +362,7 @@ int  cmdline_symset(char *);
 /* server.c */
 pid_t   server(struct privsep *, struct privsep_proc *);
 int     server_privinit(struct server *);
+void    server_purge(struct server *);
 int     server_socket_af(struct sockaddr_storage *, in_port_t);
 in_port_t
         server_socket_getport(struct sockaddr_storage *);
index 10f26e3..38151ea 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: server.c,v 1.6 2014/07/16 10:25:28 reyk Exp $ */
+/*     $OpenBSD: server.c,v 1.7 2014/07/23 13:26:39 reyk Exp $ */
 
 /*
  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -148,6 +148,28 @@ server_launch(void)
        }
 }
 
+void
+server_purge(struct server *srv)
+{
+       struct client   *clt;
+
+       /* shutdown and remove server */
+       if (event_initialized(&srv->srv_ev))
+               event_del(&srv->srv_ev);
+       if (evtimer_initialized(&srv->srv_evt))
+               evtimer_del(&srv->srv_evt);
+
+       close(srv->srv_s);
+       TAILQ_REMOVE(env->sc_servers, srv, srv_entry);
+
+       /* cleanup sessions */
+       while ((clt =
+           SPLAY_ROOT(&srv->srv_clients)) != NULL)
+               server_close(clt, NULL);
+
+       free(srv);
+}
+
 int
 server_socket_af(struct sockaddr_storage *ss, in_port_t port)
 {