- for (;;) {
- /*
- * If we've been told to exit, then do so,
- * even if we have data waiting.
- */
- if (do_exit) {
- DEBUG("Exiting...");
-
- /*
- * Ignore the TERM signal: we're about
- * to die.
- */
- signal(SIGTERM, SIG_IGN);
-
- /*
- * Send a TERM signal to all associated
- * processes (including us, which gets
- * ignored.)
- */
- kill(-radius_pid, SIGTERM);
-
- /*
- * FIXME: Kill child threads, and
- * clean up?
- */
-
- /*
- * FIXME: clean up any active REQUEST
- * handles.
- */
-
- /*
- * We're exiting, so we can delete the PID
- * file. (If it doesn't exist, we can ignore
- * the error returned by unlink)
- */
- if (dont_fork == FALSE) {
- unlink(mainconfig.pid_file);
- }
-
- /*
- * Free the configuration items.
- */
- free_mainconfig();
-
- /*
- * Detach any modules.
- */
- detach_modules();
-
- free(radius_dir);
-
- /*
- * SIGTERM gets do_exit=0,
- * and we want to exit cleanly.
- *
- * Other signals make us exit
- * with an error status.
- */
- exit(do_exit - 1);
- }
-
- if (need_reload) {
-#ifdef HAVE_PTHREAD_H
- /*
- * Threads: wait for all threads to stop
- * processing before re-loading the
- * config, so we don't pull the rug out
- * from under them.
- */
- int max_wait = 0;
- if (spawn_flag) for(;;) {
- /*
- * Block until there are '0' threads
- * with a REQUEST handle.
- */
- sig_hup_block = TRUE;
- if( (total_active_threads() == 0) ||
- (max_wait >= 5) ) {
- sig_hup_block = FALSE;
- break;
- }
- sleep(1);
- max_wait++;
- }
-#endif
- if (read_mainconfig(TRUE) < 0) {
- exit(1);
- }
-
- need_reload = FALSE;
- radlog(L_INFO, "Ready to process requests.");
- }
-
- FD_ZERO(&readfds);
- max_fd = 0;
-
- /*
- * Loop over all the listening FD's.
- */
- for (listener = mainconfig.listen;
- listener != NULL;
- listener = listener->next) {
- if (listener->fd < 0) continue;
-
- FD_SET(listener->fd, &readfds);
- if (listener->fd > max_fd) max_fd = listener->fd;
- }