]> git.ipfire.org Git - thirdparty/squid.git/blame - src/main.cc
update
[thirdparty/squid.git] / src / main.cc
CommitLineData
30a4f2a8 1/*
004b3381 2 * $Id: main.cc,v 1.59 1996/08/14 22:57:11 wessels Exp $
30a4f2a8 3 *
4 * DEBUG: section 1 Startup and Main Loop
5 * AUTHOR: Harvest Derived
6 *
7 * SQUID Internet Object Cache http://www.nlanr.net/Squid/
8 * --------------------------------------------------------
9 *
10 * Squid is the result of efforts by numerous individuals from the
11 * Internet community. Development is led by Duane Wessels of the
12 * National Laboratory for Applied Network Research and funded by
13 * the National Science Foundation.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 */
30
31/*
32 * Copyright (c) 1994, 1995. All rights reserved.
33 *
34 * The Harvest software was developed by the Internet Research Task
35 * Force Research Group on Resource Discovery (IRTF-RD):
36 *
37 * Mic Bowman of Transarc Corporation.
38 * Peter Danzig of the University of Southern California.
39 * Darren R. Hardy of the University of Colorado at Boulder.
40 * Udi Manber of the University of Arizona.
41 * Michael F. Schwartz of the University of Colorado at Boulder.
42 * Duane Wessels of the University of Colorado at Boulder.
43 *
44 * This copyright notice applies to software in the Harvest
45 * ``src/'' directory only. Users should consult the individual
46 * copyright notices in the ``components/'' subdirectories for
47 * copyright information about other software bundled with the
48 * Harvest source code distribution.
49 *
50 * TERMS OF USE
51 *
52 * The Harvest software may be used and re-distributed without
53 * charge, provided that the software origin and research team are
54 * cited in any use of the system. Most commonly this is
55 * accomplished by including a link to the Harvest Home Page
56 * (http://harvest.cs.colorado.edu/) from the query page of any
57 * Broker you deploy, as well as in the query result pages. These
58 * links are generated automatically by the standard Broker
59 * software distribution.
60 *
61 * The Harvest software is provided ``as is'', without express or
62 * implied warranty, and with no support nor obligation to assist
63 * in its use, correction, modification or enhancement. We assume
64 * no liability with respect to the infringement of copyrights,
65 * trade secrets, or any patents, and are not responsible for
66 * consequential damages. Proper use of the Harvest software is
67 * entirely the responsibility of the user.
68 *
69 * DERIVATIVE WORKS
70 *
71 * Users may make derivative works from the Harvest software, subject
72 * to the following constraints:
73 *
74 * - You must include the above copyright notice and these
75 * accompanying paragraphs in all forms of derivative works,
76 * and any documentation and other materials related to such
77 * distribution and use acknowledge that the software was
78 * developed at the above institutions.
79 *
80 * - You must notify IRTF-RD regarding your distribution of
81 * the derivative work.
82 *
83 * - You must clearly notify users that your are distributing
84 * a modified version and not the original Harvest software.
85 *
86 * - Any derivative product is also subject to these copyright
87 * and use restrictions.
88 *
89 * Note that the Harvest software is NOT in the public domain. We
90 * retain copyright, as specified above.
91 *
92 * HISTORY OF FREE SOFTWARE STATUS
93 *
94 * Originally we required sites to license the software in cases
95 * where they were going to build commercial products/services
96 * around Harvest. In June 1995 we changed this policy. We now
97 * allow people to use the core Harvest software (the code found in
98 * the Harvest ``src/'' directory) for free. We made this change
99 * in the interest of encouraging the widest possible deployment of
100 * the technology. The Harvest software is really a reference
101 * implementation of a set of protocols and formats, some of which
102 * we intend to standardize. We encourage commercial
103 * re-implementations of code complying to this set of standards.
104 */
44a47c6e 105
106#include "squid.h"
107
b8de7ebe 108time_t squid_starttime = 0;
44a47c6e 109time_t next_cleaning = 0;
30a4f2a8 110int theHttpConnection = -1;
111int theInIcpConnection = -1;
112int theOutIcpConnection = -1;
090089c4 113int do_reuse = 1;
d68adf86 114int opt_unlink_on_reload = 0;
30a4f2a8 115int opt_reload_hit_only = 0; /* only UDP_HIT during store relaod */
090089c4 116int catch_signals = 1;
30a4f2a8 117int opt_dns_tests = 1;
118int opt_foreground_rebuild = 0;
b6f794d6 119int opt_zap_disk_store = 0;
090089c4 120int vhost_mode = 0;
16128bc7 121int unbuffered_logs = 1; /* debug and hierarhcy unbuffered by default */
5f3f8d0e 122int shutdown_pending = 0; /* set by SIGTERM handler (shut_down()) */
123int reread_pending = 0; /* set by SIGHUP handler */
30a4f2a8 124char version_string[] = SQUID_VERSION;
125char appname[] = "squid";
126char localhost[] = "127.0.0.1";
127struct in_addr local_addr;
128
129/* for error reporting from xmalloc and friends */
130extern void (*failure_notify) _PARAMS((char *));
131
132static int rotate_pending = 0; /* set by SIGUSR1 handler */
133static int httpPortNumOverride = 1;
134static int icpPortNumOverride = 1; /* Want to detect "-u 0" */
135#if MALLOC_DBG
4d64d74a 136static int malloc_debug_level = 0;
30a4f2a8 137#endif
138static void rotate_logs _PARAMS((int));
139static void reconfigure _PARAMS((int));
ccff9601 140
141static void usage()
142{
77ffc99f 143 fprintf(stderr, "\
30a4f2a8 144Usage: %s [-hsvzCDFRUVY] [-f config-file] [-[au] port]\n\
145 -a port Specify ASCII port number (default: %d).\n\
146 -f file Use given config-file instead of\n\
147 %s\n\
ccff9601 148 -h Print help message.\n\
149 -s Enable logging to syslog.\n\
30a4f2a8 150 -u port Specify UDP port number (default: %d), disable with 0.\n\
ccff9601 151 -v Print version.\n\
152 -z Zap disk storage -- deletes all objects in disk cache.\n\
153 -C Do not catch fatal signals.\n\
154 -D Disable initial DNS tests.\n\
30a4f2a8 155 -F Foreground fast store rebuild.\n\
ccff9601 156 -R Do not set REUSEADDR on port.\n\
d68adf86 157 -U Unlink expired objects on reload.\n\
30a4f2a8 158 -V Virtual host httpd-accelerator.\n\
1061b406 159 -Y Only return UDP_HIT or UDP_RELOADING during fast reload.\n",
30a4f2a8 160 appname, CACHE_HTTP_PORT, DefaultConfigFile, CACHE_ICP_PORT);
77ffc99f 161 exit(1);
ccff9601 162}
163
4d64d74a 164static void mainParseOptions(argc, argv)
090089c4 165 int argc;
4d64d74a 166 char *argv[];
090089c4 167{
090089c4 168 extern char *optarg;
4d64d74a 169 int c;
090089c4 170
30a4f2a8 171 while ((c = getopt(argc, argv, "CDFRUVYa:bf:hm:su:vz?")) != -1) {
090089c4 172 switch (c) {
090089c4 173 case 'C':
174 catch_signals = 0;
175 break;
176 case 'D':
30a4f2a8 177 opt_dns_tests = 0;
090089c4 178 break;
30a4f2a8 179 case 'F':
180 opt_foreground_rebuild = 1;
090089c4 181 break;
090089c4 182 case 'R':
183 do_reuse = 0;
184 break;
d68adf86 185 case 'U':
186 opt_unlink_on_reload = 1;
187 break;
30a4f2a8 188 case 'V':
189 vhost_mode = 1;
190 break;
191 case 'Y':
192 opt_reload_hit_only = 1;
193 break;
194 case 'a':
195 httpPortNumOverride = atoi(optarg);
196 break;
197 case 'b':
198 unbuffered_logs = 0;
199 break;
090089c4 200 case 'f':
00fac1f8 201 xfree(ConfigFile);
202 ConfigFile = xstrdup(optarg);
090089c4 203 break;
30a4f2a8 204 case 'h':
205 usage();
090089c4 206 break;
090089c4 207 case 'm':
30a4f2a8 208#if MALLOC_DBG
090089c4 209 malloc_debug_level = atoi(optarg);
34c54bb6 210 /* NOTREACHED */
090089c4 211 break;
30a4f2a8 212#else
213 fatal("Need to add -DMALLOC_DBG when compiling to use -m option");
214#endif
215 case 's':
216 syslog_enable = 0;
217 break;
218 case 'u':
219 icpPortNumOverride = atoi(optarg);
220 if (icpPortNumOverride < 0)
221 icpPortNumOverride = 0;
222 break;
223 case 'v':
224 printf("Squid Cache: Version %s\n", version_string);
225 exit(0);
226 /* NOTREACHED */
090089c4 227 case 'z':
b6f794d6 228 opt_zap_disk_store = 1;
090089c4 229 break;
230 case '?':
090089c4 231 default:
ccff9601 232 usage();
090089c4 233 break;
234 }
090089c4 235 }
4d64d74a 236}
090089c4 237
30a4f2a8 238void rotate_logs(sig)
239 int sig;
240{
241 debug(21, 1, "rotate_logs: SIGUSR1 received.\n");
242 rotate_pending = 1;
243#if !HAVE_SIGACTION
244 signal(sig, rotate_logs);
245#endif
246}
247
248void reconfigure(sig)
249 int sig;
250{
251 debug(21, 1, "reconfigure: SIGHUP received\n");
252 debug(21, 1, "Waiting %d seconds for active connections to finish\n",
b6f794d6 253 Config.lifetimeShutdown);
30a4f2a8 254 reread_pending = 1;
255#if !HAVE_SIGACTION
256 signal(sig, reconfigure);
257#endif
258}
259
260void shut_down(sig)
261 int sig;
262{
263 debug(21, 1, "Preparing for shutdown after %d connections\n",
264 ntcpconn + nudpconn);
265 debug(21, 1, "Waiting %d seconds for active connections to finish\n",
b6f794d6 266 Config.lifetimeShutdown);
30a4f2a8 267 shutdown_pending = 1;
268}
269
5f3f8d0e 270void serverConnectionsOpen()
4d64d74a 271{
30a4f2a8 272 struct in_addr addr;
273 u_short port;
234967c9 274 /* Get our real priviliges */
234967c9 275
276 /* Open server ports */
30a4f2a8 277 enter_suid();
278 theHttpConnection = comm_open(COMM_NONBLOCKING,
b6f794d6 279 Config.Addrs.tcp_incoming,
280 Config.Port.http,
30a4f2a8 281 "HTTP Port");
282 leave_suid();
283 if (theHttpConnection < 0) {
284 fatal("Cannot open HTTP Port");
090089c4 285 }
30a4f2a8 286 fd_note(theHttpConnection, "HTTP socket");
287 comm_listen(theHttpConnection);
288 comm_set_select_handler(theHttpConnection,
090089c4 289 COMM_SELECT_READ,
290 asciiHandleConn,
291 0);
30a4f2a8 292 debug(1, 1, "Accepting HTTP connections on FD %d.\n",
293 theHttpConnection);
090089c4 294
b6f794d6 295 if (!httpd_accel_mode || Config.Accel.withProxy) {
296 if ((port = Config.Port.icp) > 0) {
30a4f2a8 297 theInIcpConnection = comm_open(COMM_NONBLOCKING | COMM_DGRAM,
b6f794d6 298 Config.Addrs.udp_incoming,
30a4f2a8 299 port,
300 "ICP Port");
301 if (theInIcpConnection < 0)
302 fatal("Cannot open ICP Port");
303 fd_note(theInIcpConnection, "ICP socket");
304 comm_set_select_handler(theInIcpConnection,
090089c4 305 COMM_SELECT_READ,
306 icpHandleUdp,
307 0);
30a4f2a8 308 debug(1, 1, "Accepting ICP connections on FD %d.\n",
309 theInIcpConnection);
310
b6f794d6 311 if ((addr = Config.Addrs.udp_outgoing).s_addr != INADDR_NONE) {
30a4f2a8 312 theOutIcpConnection = comm_open(COMM_NONBLOCKING | COMM_DGRAM,
313 addr,
314 port,
315 "ICP Port");
316 if (theOutIcpConnection < 0)
317 fatal("Cannot open Outgoing ICP Port");
318 comm_set_select_handler(theOutIcpConnection,
319 COMM_SELECT_READ,
320 icpHandleUdp,
321 0);
322 debug(1, 1, "Accepting ICP connections on FD %d.\n",
323 theOutIcpConnection);
324 fd_note(theOutIcpConnection, "Outgoing ICP socket");
325 fd_note(theInIcpConnection, "Incoming ICP socket");
326 } else {
327 theOutIcpConnection = theInIcpConnection;
328 }
090089c4 329 }
330 }
5f3f8d0e 331}
332
333void serverConnectionsClose()
334{
30a4f2a8 335 /* NOTE, this function will be called repeatedly while shutdown
336 * is pending */
337 if (theHttpConnection >= 0) {
338 debug(21, 1, "FD %d Closing HTTP connection\n",
339 theHttpConnection);
340 comm_close(theHttpConnection);
341 comm_set_select_handler(theHttpConnection,
5f3f8d0e 342 COMM_SELECT_READ,
343 NULL,
344 0);
30a4f2a8 345 theHttpConnection = -1;
090089c4 346 }
30a4f2a8 347 if (theInIcpConnection >= 0) {
348 /* NOTE, don't close outgoing ICP connection, we need to write to
349 * it during shutdown */
350 debug(21, 1, "FD %d Closing ICP connection\n",
351 theInIcpConnection);
352 if (theInIcpConnection != theOutIcpConnection)
353 comm_close(theInIcpConnection);
354 comm_set_select_handler(theInIcpConnection,
5f3f8d0e 355 COMM_SELECT_READ,
356 NULL,
357 0);
30a4f2a8 358 if (theInIcpConnection != theOutIcpConnection)
359 comm_set_select_handler(theOutIcpConnection,
360 COMM_SELECT_READ,
361 NULL,
362 0);
363 theInIcpConnection = -1;
5f3f8d0e 364 }
365}
366
0ffd22bc 367static void mainReinitialize()
5f3f8d0e 368{
ad6272a1 369 debug(1, 0, "Restarting Squid Cache (version %s)...\n", version_string);
0ffd22bc 370 /* Already called serverConnectionsClose and ipcacheShutdownServers() */
5f3f8d0e 371 neighborsDestroy();
0ffd22bc 372
00fac1f8 373 parseConfigFile(ConfigFile);
b6f794d6 374 _db_init(Config.Log.log, Config.debugOptions);
0ffd22bc 375 neighbors_init();
f88bb09c 376 dnsOpenServers();
d2af9477 377 redirectOpenServers();
0ffd22bc 378 serverConnectionsOpen();
234967c9 379 (void) ftpInitialize();
b6f794d6 380 if (theOutIcpConnection >= 0 && (!httpd_accel_mode || Config.Accel.withProxy))
30a4f2a8 381 neighbors_open(theOutIcpConnection);
0ffd22bc 382 debug(1, 0, "Ready to serve requests.\n");
5f3f8d0e 383}
384
385static void mainInitialize()
386{
387 static int first_time = 1;
44f99671 388 if (catch_signals) {
30a4f2a8 389 squid_signal(SIGSEGV, death, SA_NODEFER | SA_RESETHAND);
390 squid_signal(SIGBUS, death, SA_NODEFER | SA_RESETHAND);
44f99671 391 }
30a4f2a8 392 squid_signal(SIGPIPE, SIG_IGN, SA_RESTART);
393 squid_signal(SIGCHLD, sig_child, SA_NODEFER | SA_RESTART);
44f99671 394
00fac1f8 395 if (ConfigFile == NULL)
396 ConfigFile = xstrdup(DefaultConfigFile);
397 parseConfigFile(ConfigFile);
5f3f8d0e 398
30a4f2a8 399 leave_suid(); /* Run as non privilegied user */
5f3f8d0e 400
34c54bb6 401#if USE_ASYNC_IO
402#if HAVE_AIO_INIT
403 if (first_time)
404 aio_init();
405#endif
406 squid_signal(SIGIO, aioSigHandler, SA_RESTART);
407#endif
408
30a4f2a8 409 if (httpPortNumOverride != 1)
410 setHttpPortNum((u_short) httpPortNumOverride);
411 if (icpPortNumOverride != 1)
412 setIcpPortNum((u_short) icpPortNumOverride);
413
b6f794d6 414 _db_init(Config.Log.log, Config.debugOptions);
30a4f2a8 415 fdstat_open(fileno(debug_log), FD_LOG);
b6f794d6 416 fd_note(fileno(debug_log), Config.Log.log);
5f3f8d0e 417
30a4f2a8 418 debug(1, 0, "Starting Squid Cache version %s for %s...\n",
419 version_string,
420 CONFIG_HOST_TYPE);
421 debug(1, 1, "With %d file descriptors available\n", FD_SETSIZE);
5f3f8d0e 422
850c4ead 423 if (first_time) {
94e891ea 424 stmemInit(); /* stmem must go before at least redirect */
234967c9 425 disk_init(); /* disk_init must go before ipcache_init() */
850c4ead 426 }
5f3f8d0e 427 ipcache_init();
f88bb09c 428 fqdncache_init();
429 dnsOpenServers();
d2af9477 430 redirectOpenServers();
5f3f8d0e 431 neighbors_init();
234967c9 432 (void) ftpInitialize();
5f3f8d0e 433
30a4f2a8 434#if MALLOC_DBG
5f3f8d0e 435 malloc_debug(0, malloc_debug_level);
436#endif
437
a26bdc75 438 if (first_time) {
5f3f8d0e 439 /* module initialization */
7111c86a 440 urlInitialize();
b6f794d6 441 stat_init(&CacheInfo, Config.Log.access);
5f3f8d0e 442 storeInit();
090089c4 443
b6f794d6 444 if (Config.effectiveUser) {
234967c9 445 /* we were probably started as root, so cd to a swap
446 * directory in case we dump core */
447 if (chdir(swappath(0)) < 0) {
448 debug(1, 0, "%s: %s\n", swappath(0), xstrerror());
449 fatal_dump("Cannot cd to swap directory?");
450 }
451 }
5f3f8d0e 452 /* after this point we want to see the mallinfo() output */
453 do_mallinfo = 1;
454 }
2285407f 455 serverConnectionsOpen();
b6f794d6 456 if (theOutIcpConnection >= 0 && (!httpd_accel_mode || Config.Accel.withProxy))
30a4f2a8 457 neighbors_open(theOutIcpConnection);
458
0a5b9b32 459 if (first_time)
460 writePidFile(); /* write PID file */
461
30a4f2a8 462 squid_signal(SIGUSR1, rotate_logs, SA_RESTART);
463 squid_signal(SIGUSR2, sigusr2_handle, SA_RESTART);
464 squid_signal(SIGHUP, reconfigure, SA_RESTART);
465 squid_signal(SIGTERM, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART);
466 squid_signal(SIGINT, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART);
5f3f8d0e 467 debug(1, 0, "Ready to serve requests.\n");
0a5b9b32 468 first_time = 0;
4d64d74a 469}
470
471
472int main(argc, argv)
473 int argc;
474 char **argv;
475{
476 int errcount = 0;
4d64d74a 477 int n; /* # of GC'd objects */
478 time_t last_maintain = 0;
004b3381 479 time_t last_dirclean = 0;
7d49daab 480 time_t last_announce = 0;
bc528c78 481 time_t loop_delay;
4d64d74a 482
7328e889 483 /* call mallopt() before anything else */
484#if HAVE_MALLOPT
485#ifdef M_GRAIN
486 /* Round up all sizes to a multiple of this */
487 mallopt(M_GRAIN, 16);
488#endif
489#ifdef M_MXFAST
490 /* biggest size that is considered a small block */
491 mallopt(M_MXFAST, 256);
492#endif
493#ifdef M_NBLKS
494 /* allocate this many small blocks at once */
495 mallopt(M_NLBLKS, 32);
496#endif
497#endif /* HAVE_MALLOPT */
498
30a4f2a8 499 memset(&local_addr, '\0', sizeof(struct in_addr));
500 local_addr.s_addr = inet_addr(localhost);
501
4d64d74a 502 errorInitialize();
503
b8de7ebe 504 squid_starttime = getCurrentTime();
4d64d74a 505 failure_notify = fatal_dump;
506
507 mainParseOptions(argc, argv);
508
509 setMaxFD();
510
30a4f2a8 511 if (catch_signals)
512 for (n = FD_SETSIZE; n > 2; n--)
513 close(n);
4d64d74a 514
4d64d74a 515 /*init comm module */
516 comm_init();
517
518 /* we have to init fdstat here. */
519 fdstat_init(PREOPEN_FD);
30a4f2a8 520 fdstat_open(0, FD_LOG);
521 fdstat_open(1, FD_LOG);
522 fdstat_open(2, FD_LOG);
4d64d74a 523 fd_note(0, "STDIN");
524 fd_note(1, "STDOUT");
525 fd_note(2, "STDERR");
526
4d64d74a 527 /* enable syslog by default */
528 syslog_enable = 0;
529
530 /* preinit for debug module */
531 debug_log = stderr;
532 hash_init(0);
533
4d64d74a 534 mainInitialize();
535
090089c4 536 /* main loop */
b6f794d6 537 if (Config.cleanRate > 0)
538 next_cleaning = time(NULL) + Config.cleanRate;
983061ed 539 for (;;) {
30a4f2a8 540 loop_delay = (time_t) 10;
090089c4 541 /* maintain cache storage */
b8de7ebe 542 if (squid_curtime > last_maintain) {
090089c4 543 storeMaintainSwapSpace();
b8de7ebe 544 last_maintain = squid_curtime;
090089c4 545 }
004b3381 546 if (squid_curtime - last_dirclean > 15
547 && store_rebuilding == STORE_NOT_REBUILDING) {
548 /* clean a cache directory every 15 seconds */
549 /* 15 * 16 * 256 = 17 hrs */
550 storeDirClean();
551 last_dirclean = squid_curtime;
552 }
30a4f2a8 553 if (rotate_pending) {
554 ftpServerClose();
555 _db_rotate_log(); /* cache.log */
556 storeWriteCleanLog();
557 storeRotateLog(); /* store.log */
30a4f2a8 558 stat_rotate_log(); /* access.log */
559 (void) ftpInitialize();
560 rotate_pending = 0;
561 }
bc528c78 562 /* do background processing */
563 if (doBackgroundProcessing())
564 loop_delay = (time_t) 0;
565 switch (comm_select(loop_delay, next_cleaning)) {
090089c4 566 case COMM_OK:
234967c9 567 errcount = 0; /* reset if successful */
090089c4 568 break;
569 case COMM_ERROR:
570 errcount++;
234967c9 571 debug(1, 0, "Select loop Error. Retry %d\n", errcount);
090089c4 572 if (errcount == 10)
4d64d74a 573 fatal_dump("Select Loop failed!");
090089c4 574 break;
575 case COMM_TIMEOUT:
b6f794d6 576 if (Config.cleanRate > 0 && squid_curtime >= next_cleaning) {
019dd986 577 debug(1, 1, "Performing a garbage collection...\n");
090089c4 578 n = storePurgeOld();
019dd986 579 debug(1, 1, "Garbage collection done, %d objects removed\n", n);
b6f794d6 580 next_cleaning = squid_curtime + Config.cleanRate;
090089c4 581 }
b6f794d6 582 if ((n = Config.Announce.rate) > 0) {
b8de7ebe 583 if (squid_curtime > last_announce + n)
7ba794f4 584 send_announce();
b8de7ebe 585 last_announce = squid_curtime;
7d49daab 586 }
090089c4 587 /* house keeping */
090089c4 588 break;
4d64d74a 589 case COMM_SHUTDOWN:
43030d00 590 /* delayed close so we can transmit while shutdown pending */
30a4f2a8 591 if (theOutIcpConnection > 0) {
592 comm_close(theOutIcpConnection);
593 theOutIcpConnection = -1;
43030d00 594 }
5f3f8d0e 595 if (shutdown_pending) {
596 normal_shutdown();
597 exit(0);
598 } else if (reread_pending) {
0ffd22bc 599 mainReinitialize();
5f3f8d0e 600 reread_pending = 0; /* reset */
601 } else {
602 fatal_dump("MAIN: SHUTDOWN from comm_select, but nothing pending.");
603 }
0ffd22bc 604 break;
090089c4 605 default:
6eb42cae 606 fatal_dump("MAIN: Internal error -- this should never happen.");
090089c4 607 break;
608 }
609 }
610 /* NOTREACHED */
983061ed 611 return 0;
090089c4 612}