]> git.ipfire.org Git - thirdparty/squid.git/blame - src/main.cc
disable full histograms on counter output
[thirdparty/squid.git] / src / main.cc
CommitLineData
a47b9029 1
30a4f2a8 2/*
7021844c 3 * $Id: main.cc,v 1.231 1998/03/03 00:31:08 rousskov Exp $
30a4f2a8 4 *
5 * DEBUG: section 1 Startup and Main Loop
6 * AUTHOR: Harvest Derived
7 *
42c04c16 8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
30a4f2a8 9 * --------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by
14 * the National Science Foundation.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 */
31
32/*
33 * Copyright (c) 1994, 1995. All rights reserved.
34 *
35 * The Harvest software was developed by the Internet Research Task
36 * Force Research Group on Resource Discovery (IRTF-RD):
37 *
38 * Mic Bowman of Transarc Corporation.
39 * Peter Danzig of the University of Southern California.
40 * Darren R. Hardy of the University of Colorado at Boulder.
41 * Udi Manber of the University of Arizona.
42 * Michael F. Schwartz of the University of Colorado at Boulder.
43 * Duane Wessels of the University of Colorado at Boulder.
44 *
45 * This copyright notice applies to software in the Harvest
46 * ``src/'' directory only. Users should consult the individual
47 * copyright notices in the ``components/'' subdirectories for
48 * copyright information about other software bundled with the
49 * Harvest source code distribution.
50 *
51 * TERMS OF USE
52 *
53 * The Harvest software may be used and re-distributed without
54 * charge, provided that the software origin and research team are
55 * cited in any use of the system. Most commonly this is
56 * accomplished by including a link to the Harvest Home Page
57 * (http://harvest.cs.colorado.edu/) from the query page of any
58 * Broker you deploy, as well as in the query result pages. These
59 * links are generated automatically by the standard Broker
60 * software distribution.
61 *
62 * The Harvest software is provided ``as is'', without express or
63 * implied warranty, and with no support nor obligation to assist
64 * in its use, correction, modification or enhancement. We assume
65 * no liability with respect to the infringement of copyrights,
66 * trade secrets, or any patents, and are not responsible for
67 * consequential damages. Proper use of the Harvest software is
68 * entirely the responsibility of the user.
69 *
70 * DERIVATIVE WORKS
71 *
72 * Users may make derivative works from the Harvest software, subject
73 * to the following constraints:
74 *
75 * - You must include the above copyright notice and these
76 * accompanying paragraphs in all forms of derivative works,
77 * and any documentation and other materials related to such
78 * distribution and use acknowledge that the software was
79 * developed at the above institutions.
80 *
81 * - You must notify IRTF-RD regarding your distribution of
82 * the derivative work.
83 *
84 * - You must clearly notify users that your are distributing
85 * a modified version and not the original Harvest software.
86 *
87 * - Any derivative product is also subject to these copyright
88 * and use restrictions.
89 *
90 * Note that the Harvest software is NOT in the public domain. We
91 * retain copyright, as specified above.
92 *
93 * HISTORY OF FREE SOFTWARE STATUS
94 *
95 * Originally we required sites to license the software in cases
96 * where they were going to build commercial products/services
97 * around Harvest. In June 1995 we changed this policy. We now
98 * allow people to use the core Harvest software (the code found in
99 * the Harvest ``src/'' directory) for free. We made this change
100 * in the interest of encouraging the widest possible deployment of
101 * the technology. The Harvest software is really a reference
102 * implementation of a set of protocols and formats, some of which
103 * we intend to standardize. We encourage commercial
104 * re-implementations of code complying to this set of standards.
105 */
44a47c6e 106
107#include "squid.h"
108
30a4f2a8 109/* for error reporting from xmalloc and friends */
ea3a2a69 110extern void (*failure_notify) (const char *);
30a4f2a8 111
f1dc9b30 112static int opt_send_signal = -1;
f95b8144 113static int opt_no_daemon = 0;
67508012 114static volatile int rotate_pending = 0; /* set by SIGUSR1 handler */
30a4f2a8 115static int httpPortNumOverride = 1;
116static int icpPortNumOverride = 1; /* Want to detect "-u 0" */
117#if MALLOC_DBG
4d64d74a 118static int malloc_debug_level = 0;
30a4f2a8 119#endif
4d7add01 120
b984c445 121static SIGHDLR rotate_logs;
122static SIGHDLR reconfigure;
123#if ALARM_UPDATES_TIME
124static SIGHDLR time_tick;
125#endif
f5b8bbc4 126static void mainInitialize(void);
127static void mainReconfigure(void);
128static void usage(void);
129static void mainParseOptions(int, char **);
130static void sendSignal(void);
131static void serverConnectionsOpen(void);
bbe199dc 132static void watch_child(char **);
85407535 133static void setEffectiveUser(void);
fff6ad65 134static void normal_shutdown(void);
36a97e19 135#if MEM_GEN_TRACE
136extern void log_trace_done();
137extern void log_trace_init(char *);
138#endif
85407535 139
b8d8561b 140static void
0673c0ba 141usage(void)
ccff9601 142{
0ee4272b 143 fprintf(stderr,
969c39b9 144 "Usage: %s [-dhsvzCDFNRVYX] [-f config-file] [-[au] port] [-k signal]\n"
15df8349 145 " -a port Specify HTTP port number (default: %d).\n"
b6157f5e 146 " -d level Write debugging to stderr also.\n"
0ee4272b 147 " -f file Use given config-file instead of\n"
148 " %s\n"
149 " -h Print help message.\n"
0ee4272b 150 " -k reconfigure|rotate|shutdown|interrupt|kill|debug|check\n"
151 " Send signal to running copy and exit.\n"
152 " -s Enable logging to syslog.\n"
153 " -u port Specify ICP port number (default: %d), disable with 0.\n"
154 " -v Print version.\n"
85407535 155 " -z Create swap directories\n"
0ee4272b 156 " -C Do not catch fatal signals.\n"
157 " -D Disable initial DNS tests.\n"
158 " -F Foreground fast store rebuild.\n"
969c39b9 159 " -N No daemon mode.\n"
0ee4272b 160 " -R Do not set REUSEADDR on port.\n"
0ee4272b 161 " -V Virtual host httpd-accelerator.\n"
3013ac6d 162 " -X Force full debugging.\n"
429fdbec 163 " -Y Only return UDP_HIT or UDP_MISS_NOFETCH during fast reload.\n",
30a4f2a8 164 appname, CACHE_HTTP_PORT, DefaultConfigFile, CACHE_ICP_PORT);
77ffc99f 165 exit(1);
ccff9601 166}
167
b8d8561b 168static void
169mainParseOptions(int argc, char *argv[])
090089c4 170{
090089c4 171 extern char *optarg;
4d64d74a 172 int c;
090089c4 173
723e8aa3 174 while ((c = getopt(argc, argv, "CDFNRSVYXa:d:f:hk:m::su:vz?")) != -1) {
090089c4 175 switch (c) {
090089c4 176 case 'C':
1758c627 177 opt_catch_signals = 0;
090089c4 178 break;
179 case 'D':
30a4f2a8 180 opt_dns_tests = 0;
090089c4 181 break;
30a4f2a8 182 case 'F':
183 opt_foreground_rebuild = 1;
090089c4 184 break;
f95b8144 185 case 'N':
186 opt_no_daemon = 1;
9e2225aa 187 break;
090089c4 188 case 'R':
3b4be6a6 189 opt_reuseaddr = 0;
090089c4 190 break;
b109de6b 191 case 'S':
192 opt_store_doublecheck = 1;
193 break;
30a4f2a8 194 case 'V':
195 vhost_mode = 1;
196 break;
e924600d 197 case 'X':
198 /* force full debugging */
199 sigusr2_handle(SIGUSR2);
200 break;
30a4f2a8 201 case 'Y':
202 opt_reload_hit_only = 1;
203 break;
204 case 'a':
205 httpPortNumOverride = atoi(optarg);
206 break;
0d90407c 207 case 'd':
723e8aa3 208 opt_debug_stderr = atoi(optarg);
0d90407c 209 break;
090089c4 210 case 'f':
00fac1f8 211 xfree(ConfigFile);
212 ConfigFile = xstrdup(optarg);
090089c4 213 break;
30a4f2a8 214 case 'h':
215 usage();
090089c4 216 break;
7690e8eb 217 case 'k':
24382924 218 if ((int) strlen(optarg) < 1)
7690e8eb 219 usage();
220 if (!strncmp(optarg, "reconfigure", strlen(optarg)))
221 opt_send_signal = SIGHUP;
222 else if (!strncmp(optarg, "rotate", strlen(optarg)))
223 opt_send_signal = SIGUSR1;
224 else if (!strncmp(optarg, "debug", strlen(optarg)))
225 opt_send_signal = SIGUSR2;
226 else if (!strncmp(optarg, "shutdown", strlen(optarg)))
227 opt_send_signal = SIGTERM;
6759a5fb 228 else if (!strncmp(optarg, "interrupt", strlen(optarg)))
229 opt_send_signal = SIGINT;
7690e8eb 230 else if (!strncmp(optarg, "kill", strlen(optarg)))
231 opt_send_signal = SIGKILL;
232 else if (!strncmp(optarg, "check", strlen(optarg)))
fedac7e5 233 opt_send_signal = 0; /* SIGNULL */
7690e8eb 234 else
235 usage();
236 break;
090089c4 237 case 'm':
33ab18e8 238 if (optarg) {
30a4f2a8 239#if MALLOC_DBG
33ab18e8 240 malloc_debug_level = atoi(optarg);
241 /* NOTREACHED */
242 break;
30a4f2a8 243#else
33ab18e8 244 fatal("Need to add -DMALLOC_DBG when compiling to use -mX option");
245 /* NOTREACHED */
246#endif
247 } else {
248#if XMALLOC_TRACE
249 xmalloc_trace = !xmalloc_trace;
250#else
251 fatal("Need to configure --enable-xmalloc-debug-trace to use -m option");
30a4f2a8 252#endif
33ab18e8 253 }
30a4f2a8 254 case 's':
6e40f263 255 opt_syslog_enable = 1;
30a4f2a8 256 break;
257 case 'u':
258 icpPortNumOverride = atoi(optarg);
259 if (icpPortNumOverride < 0)
260 icpPortNumOverride = 0;
261 break;
262 case 'v':
263 printf("Squid Cache: Version %s\n", version_string);
264 exit(0);
265 /* NOTREACHED */
090089c4 266 case 'z':
85407535 267 opt_create_swap_dirs = 1;
090089c4 268 break;
269 case '?':
090089c4 270 default:
ccff9601 271 usage();
090089c4 272 break;
273 }
090089c4 274 }
4d64d74a 275}
090089c4 276
7a2f978b 277/* ARGSUSED */
b8d8561b 278static void
279rotate_logs(int sig)
30a4f2a8 280{
a3d5953d 281 debug(1, 1) ("rotate_logs: SIGUSR1 received.\n");
30a4f2a8 282 rotate_pending = 1;
283#if !HAVE_SIGACTION
284 signal(sig, rotate_logs);
285#endif
286}
287
b984c445 288#if ALARM_UPDATES_TIME
97c03d3c 289static void
290time_tick(int sig)
291{
292 getCurrentTime();
293 alarm(1);
294#if !HAVE_SIGACTION
295 signal(sig, time_tick);
296#endif
297}
38d04788 298
b984c445 299#endif
97c03d3c 300
7a2f978b 301/* ARGSUSED */
b8d8561b 302static void
303reconfigure(int sig)
30a4f2a8 304{
dbe4fd8e 305 reconfigure_pending = 1;
30a4f2a8 306#if !HAVE_SIGACTION
307 signal(sig, reconfigure);
308#endif
309}
310
b8d8561b 311void
312shut_down(int sig)
30a4f2a8 313{
f3753518 314 shutdown_pending = sig == SIGINT ? -1 : 1;
f2908497 315 debug(1, 1) ("Preparing for shutdown after %d requests\n",
316 Counter.client_http.requests);
a3d5953d 317 debug(1, 1) ("Waiting %d seconds for active connections to finish\n",
5c5783a2 318 shutdown_pending > 0 ? Config.shutdownLifetime : 0);
cadc2d55 319#ifdef KILL_PARENT_OPT
88738790 320 {
321 pid_t ppid = getppid();
322 if (ppid > 1) {
1c2c5abc 323 debug(1, 1) ("Killing RunCache, pid %d\n", ppid);
88738790 324 kill(ppid, sig);
325 }
326 }
cadc2d55 327#endif
6e40f263 328#if SA_RESETHAND == 0
329 signal(SIGTERM, SIG_DFL);
330 signal(SIGINT, SIG_DFL);
331#endif
30a4f2a8 332}
333
24382924 334static void
0673c0ba 335serverConnectionsOpen(void)
4d64d74a 336{
15df8349 337 clientHttpConnectionsOpen();
338 icpConnectionsOpen();
678c6099 339#ifdef SQUID_SNMP
3265e68d 340 snmpConnectionOpen();
2bbd722b 341#endif
5ecceaa4 342 clientdbInit();
16b204c4 343 icmpOpen();
67508012 344 netdbInit();
f899fac1 345 asnInit();
85034133 346 peerSelectInit();
5f3f8d0e 347}
348
b8d8561b 349void
0673c0ba 350serverConnectionsClose(void)
5f3f8d0e 351{
dc835977 352 /*
353 * NOTE, this function will be called repeatedly while shutdown
354 * is pending
355 */
c0fbae16 356 clientHttpConnectionsClose();
17e6c0a1 357 icpConnectionShutdown();
c0fbae16 358 icmpClose();
15df8349 359#ifdef SQUID_SNMP
17e6c0a1 360 snmpConnectionShutdown();
15df8349 361#endif
5f3f8d0e 362}
363
b8d8561b 364static void
dbe4fd8e 365mainReconfigure(void)
5f3f8d0e 366{
a3d5953d 367 debug(1, 0) ("Restarting Squid Cache (version %s)...\n", version_string);
0ffd22bc 368 /* Already called serverConnectionsClose and ipcacheShutdownServers() */
15df8349 369 serverConnectionsClose();
17e6c0a1 370 icpConnectionClose();
371#ifdef SQUID_SNMP
372 snmpConnectionClose();
373#endif
15df8349 374 dnsShutdownServers();
53ad48e6 375 asnCleanup();
15df8349 376 redirectShutdownServers();
2db68ce5 377 storeDirCloseSwapLogs();
53ad48e6 378 errorFree();
00fac1f8 379 parseConfigFile(ConfigFile);
b6f794d6 380 _db_init(Config.Log.log, Config.debugOptions);
53ad48e6 381 asnAclInitialize(Config.aclList); /* reload network->AS database */
429fdbec 382 ipcache_restart(); /* clear stuck entries */
383 fqdncache_restart(); /* sigh, fqdncache too */
53ad48e6 384 errorInitialize(); /* reload error pages */
f88bb09c 385 dnsOpenServers();
d2af9477 386 redirectOpenServers();
0ffd22bc 387 serverConnectionsOpen();
17a0a4ee 388 if (theOutIcpConnection >= 0 && (!Config2.Accel.on || Config.onoff.accel_with_proxy))
30a4f2a8 389 neighbors_open(theOutIcpConnection);
2db68ce5 390 storeDirOpenSwapLogs();
a3d5953d 391 debug(1, 0) ("Ready to serve requests.\n");
5f3f8d0e 392}
393
067bea91 394static void
85407535 395setEffectiveUser(void)
396{
397 leave_suid(); /* Run as non privilegied user */
398 if (geteuid() == 0) {
399 debug(0, 0) ("Squid is not safe to run as root! If you must\n");
400 debug(0, 0) ("start Squid as root, then you must configure\n");
401 debug(0, 0) ("it to run as a non-priveledged user with the\n");
402 debug(0, 0) ("'cache_effective_user' option in the config file.\n");
403 fatal("Don't run Squid as root, set 'cache_effective_user'!");
404 }
405}
406
b8d8561b 407static void
0673c0ba 408mainInitialize(void)
5f3f8d0e 409{
1758c627 410 if (opt_catch_signals) {
30a4f2a8 411 squid_signal(SIGSEGV, death, SA_NODEFER | SA_RESETHAND);
412 squid_signal(SIGBUS, death, SA_NODEFER | SA_RESETHAND);
44f99671 413 }
30a4f2a8 414 squid_signal(SIGPIPE, SIG_IGN, SA_RESTART);
415 squid_signal(SIGCHLD, sig_child, SA_NODEFER | SA_RESTART);
44f99671 416
8407afee 417 if (!configured_once)
418 cbdataInit();
00fac1f8 419 if (ConfigFile == NULL)
420 ConfigFile = xstrdup(DefaultConfigFile);
421 parseConfigFile(ConfigFile);
5f3f8d0e 422
85407535 423 setEffectiveUser();
270b86af 424 assert(Config.Port.http);
30a4f2a8 425 if (httpPortNumOverride != 1)
270b86af 426 Config.Port.http->i = (u_short) httpPortNumOverride;
30a4f2a8 427 if (icpPortNumOverride != 1)
f2052513 428 Config.Port.icp = (u_short) icpPortNumOverride;
30a4f2a8 429
b6f794d6 430 _db_init(Config.Log.log, Config.debugOptions);
5c5783a2 431 fd_open(fileno(debug_log), FD_LOG, Config.Log.log);
71a17702 432#if MEM_GEN_TRACE
433 log_trace_init("/tmp/squid.alloc");
434#endif
a3d5953d 435 debug(1, 0) ("Starting Squid Cache version %s for %s...\n",
30a4f2a8 436 version_string,
437 CONFIG_HOST_TYPE);
70364f29 438 debug(1, 0) ("Process ID %d\n", (int) getpid());
a3d5953d 439 debug(1, 1) ("With %d file descriptors available\n", Squid_MaxFD);
5f3f8d0e 440
dbe4fd8e 441 if (!configured_once) {
3f6c0fb2 442 memInit(); /* memInit must go before at least redirect */
234967c9 443 disk_init(); /* disk_init must go before ipcache_init() */
850c4ead 444 }
5f3f8d0e 445 ipcache_init();
f88bb09c 446 fqdncache_init();
447 dnsOpenServers();
d2af9477 448 redirectOpenServers();
b012353a 449 useragentOpenLog();
2ac76861 450 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
9b312a19 451 errorInitialize();
7a2f978b 452 accessLogInit();
5f3f8d0e 453
30a4f2a8 454#if MALLOC_DBG
5f3f8d0e 455 malloc_debug(0, malloc_debug_level);
456#endif
457
dbe4fd8e 458 if (!configured_once) {
429fdbec 459 unlinkdInit();
7111c86a 460 urlInitialize();
22f3fd98 461 cachemgrInit();
a7c05555 462 statInit();
5f3f8d0e 463 storeInit();
22f3fd98 464 httpInit();
53ad48e6 465 asnAclInitialize(Config.aclList);
b6f794d6 466 if (Config.effectiveUser) {
234967c9 467 /* we were probably started as root, so cd to a swap
468 * directory in case we dump core */
641941c0 469 if (chdir(storeSwapDir(0)) < 0) {
a3d5953d 470 debug(50, 0) ("%s: %s\n", storeSwapDir(0), xstrerror());
234967c9 471 fatal_dump("Cannot cd to swap directory?");
472 }
473 }
5f3f8d0e 474 /* after this point we want to see the mallinfo() output */
475 do_mallinfo = 1;
812ed90c 476 mimeInit(Config.mimeTablePathname);
603a02fd 477 pconnInit();
5f3f8d0e 478 }
2285407f 479 serverConnectionsOpen();
17a0a4ee 480 if (theOutIcpConnection >= 0 && (!Config2.Accel.on || Config.onoff.accel_with_proxy))
30a4f2a8 481 neighbors_open(theOutIcpConnection);
482
dbe4fd8e 483 if (!configured_once)
0a5b9b32 484 writePidFile(); /* write PID file */
485
9fc0b4b8 486#if !(defined(_SQUID_LINUX_) && USE_ASYNC_IO)
30a4f2a8 487 squid_signal(SIGUSR1, rotate_logs, SA_RESTART);
488 squid_signal(SIGUSR2, sigusr2_handle, SA_RESTART);
9fc0b4b8 489#endif
30a4f2a8 490 squid_signal(SIGHUP, reconfigure, SA_RESTART);
491 squid_signal(SIGTERM, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART);
492 squid_signal(SIGINT, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART);
b984c445 493#if ALARM_UPDATES_TIME
97c03d3c 494 squid_signal(SIGALRM, time_tick, SA_RESTART);
495 alarm(1);
b984c445 496#endif
a3d5953d 497 debug(1, 0) ("Ready to serve requests.\n");
4d7add01 498
dbe4fd8e 499 if (!configured_once) {
48f44632 500 eventAdd("storeMaintain", storeMaintainSwapSpace, NULL, 1);
501 eventAdd("storeDirClean", storeDirClean, NULL, 15);
17a0a4ee 502 if (Config.onoff.announce)
e924600d 503 eventAdd("start_announce", start_announce, NULL, 3600);
582b6456 504 eventAdd("ipcache_purgelru", ipcache_purgelru, NULL, 10);
4d7add01 505 }
dbe4fd8e 506 configured_once = 1;
2bbd722b 507#ifdef SQUID_SNMP
3265e68d 508 snmpInit();
2bbd722b 509#endif
4d64d74a 510}
511
b8d8561b 512int
513main(int argc, char **argv)
4d64d74a 514{
515 int errcount = 0;
4d64d74a 516 int n; /* # of GC'd objects */
bc528c78 517 time_t loop_delay;
4d64d74a 518
88738790 519 debug_log = stderr;
e83892e9 520 if (FD_SETSIZE < Squid_MaxFD)
521 Squid_MaxFD = FD_SETSIZE;
36a97e19 522
7328e889 523 /* call mallopt() before anything else */
0b29fe44 524#if HAVE_MALLOPT
7328e889 525#ifdef M_GRAIN
526 /* Round up all sizes to a multiple of this */
527 mallopt(M_GRAIN, 16);
528#endif
529#ifdef M_MXFAST
530 /* biggest size that is considered a small block */
531 mallopt(M_MXFAST, 256);
532#endif
533#ifdef M_NBLKS
534 /* allocate this many small blocks at once */
535 mallopt(M_NLBLKS, 32);
536#endif
537#endif /* HAVE_MALLOPT */
538
30a4f2a8 539 memset(&local_addr, '\0', sizeof(struct in_addr));
429fdbec 540 safe_inet_addr(localhost, &local_addr);
28070024 541 memset(&any_addr, '\0', sizeof(struct in_addr));
429fdbec 542 safe_inet_addr("0.0.0.0", &any_addr);
28070024 543 memset(&no_addr, '\0', sizeof(struct in_addr));
429fdbec 544 safe_inet_addr("255.255.255.255", &no_addr);
88738790 545 squid_srandom(time(NULL));
4d64d74a 546
f2908497 547 getCurrentTime();
548 squid_start = current_time;
4d64d74a 549 failure_notify = fatal_dump;
550
551 mainParseOptions(argc, argv);
552
7690e8eb 553 /* send signal to running copy and exit */
554 if (opt_send_signal != -1) {
555 sendSignal();
556 /* NOTREACHED */
557 }
85407535 558 if (opt_create_swap_dirs) {
067bea91 559 if (ConfigFile == NULL)
560 ConfigFile = xstrdup(DefaultConfigFile);
561 cbdataInit();
562 parseConfigFile(ConfigFile);
563 setEffectiveUser();
564 debug(0, 0) ("Creating Swap Directories\n");
565 storeCreateSwapDirectories();
566 return 0;
567 }
f95b8144 568 if (!opt_no_daemon)
bbe199dc 569 watch_child(argv);
4d64d74a 570 setMaxFD();
571
1758c627 572 if (opt_catch_signals)
e83892e9 573 for (n = Squid_MaxFD; n > 2; n--)
30a4f2a8 574 close(n);
4d64d74a 575
4d64d74a 576 /*init comm module */
577 comm_init();
578
579 /* we have to init fdstat here. */
5c5783a2 580 fd_open(0, FD_LOG, "stdin");
581 fd_open(1, FD_LOG, "stdout");
582 fd_open(2, FD_LOG, "stderr");
4d64d74a 583
4d64d74a 584 mainInitialize();
585
090089c4 586 /* main loop */
983061ed 587 for (;;) {
15df8349 588 if (reconfigure_pending) {
969c39b9 589 mainReconfigure();
590 reconfigure_pending = 0; /* reset */
15df8349 591 } else if (rotate_pending) {
e97f40f4 592 icmpClose();
30a4f2a8 593 _db_rotate_log(); /* cache.log */
e3ef2b09 594 storeDirWriteCleanLogs(1);
595 storeLogRotate(); /* store.log */
a4394ebd 596 accessLogRotate(); /* access.log */
b012353a 597 useragentRotateLog(); /* useragent.log */
e97f40f4 598 icmpOpen();
30a4f2a8 599 rotate_pending = 0;
600 }
48f44632 601 eventRun();
602 if ((loop_delay = eventNextTime()) < 0)
4d7add01 603 loop_delay = 0;
812ed90c 604#if HAVE_POLL
605 switch (comm_poll(loop_delay)) {
606#else
9ca89c5a 607 switch (comm_select(loop_delay)) {
812ed90c 608#endif
090089c4 609 case COMM_OK:
234967c9 610 errcount = 0; /* reset if successful */
090089c4 611 break;
612 case COMM_ERROR:
613 errcount++;
a3d5953d 614 debug(1, 0) ("Select loop Error. Retry %d\n", errcount);
090089c4 615 if (errcount == 10)
4d64d74a 616 fatal_dump("Select Loop failed!");
090089c4 617 break;
4d64d74a 618 case COMM_SHUTDOWN:
43030d00 619 /* delayed close so we can transmit while shutdown pending */
17e6c0a1 620 icpConnectionClose();
d84eba42 621#ifdef SQUID_SNMP
17e6c0a1 622 snmpConnectionClose();
d84eba42 623#endif
5f3f8d0e 624 if (shutdown_pending) {
625 normal_shutdown();
15df8349 626#if 0
dbe4fd8e 627 } else if (reconfigure_pending) {
628 mainReconfigure();
629 reconfigure_pending = 0; /* reset */
15df8349 630#endif
5f3f8d0e 631 } else {
632 fatal_dump("MAIN: SHUTDOWN from comm_select, but nothing pending.");
633 }
0ffd22bc 634 break;
9ca89c5a 635 case COMM_TIMEOUT:
6c93e119 636 break;
090089c4 637 default:
6eb42cae 638 fatal_dump("MAIN: Internal error -- this should never happen.");
090089c4 639 break;
640 }
641 }
642 /* NOTREACHED */
983061ed 643 return 0;
090089c4 644}
7690e8eb 645
b8d8561b 646static void
0673c0ba 647sendSignal(void)
7690e8eb 648{
ff8d0ea6 649 pid_t pid;
fedac7e5 650 debug_log = stderr;
651 if (ConfigFile == NULL)
652 ConfigFile = xstrdup(DefaultConfigFile);
1b635117 653 cbdataInit();
fedac7e5 654 parseConfigFile(ConfigFile);
655 pid = readPidFile();
656 if (pid > 1) {
657 if (kill(pid, opt_send_signal) &&
658 /* ignore permissions if just running check */
659 !(opt_send_signal == 0 && errno == EPERM)) {
660 fprintf(stderr, "%s: ERROR: Could not send ", appname);
661 fprintf(stderr, "signal %d to process %d: %s\n",
41d30aa8 662 opt_send_signal, (int) pid, xstrerror());
7690e8eb 663 exit(1);
664 }
fedac7e5 665 } else {
666 fprintf(stderr, "%s: ERROR: No running copy\n", appname);
667 exit(1);
7690e8eb 668 }
fedac7e5 669 /* signal successfully sent */
670 exit(0);
671}
f95b8144 672
673static void
bbe199dc 674watch_child(char *argv[])
f95b8144 675{
676 char *prog;
f95b8144 677 int failcount = 0;
678 time_t start;
679 time_t stop;
680#ifdef _SQUID_NEXT_
681 union wait status;
682#else
683 int status;
684#endif
e3a3b845 685 pid_t pid;
f95b8144 686 if (*(argv[0]) == '(')
687 return;
688 for (;;) {
689 if (fork() == 0) {
690 /* child */
691 prog = xstrdup(argv[0]);
bbe199dc 692 argv[0] = xstrdup("(squid)");
693 execvp(prog, argv);
694 fatal("execvp failed");
f95b8144 695 }
696 /* parent */
697 time(&start);
e3a3b845 698 do {
0fb4fc71 699 squid_signal(SIGINT, SIG_IGN, SA_RESTART);
f95b8144 700#ifdef _SQUID_NEXT_
e3a3b845 701 pid = wait3(&status, 0, NULL);
f95b8144 702#else
e3a3b845 703 pid = waitpid(-1, &status, 0);
f95b8144 704#endif
e3a3b845 705 } while (pid > 0);
f95b8144 706 time(&stop);
707 if (stop - start < 10)
708 failcount++;
a8e69881 709 else
710 failcount = 0;
f95b8144 711 if (failcount == 5)
712 exit(1);
f95b8144 713 if (WIFEXITED(status))
714 if (WEXITSTATUS(status) == 0)
715 exit(0);
0fb4fc71 716 squid_signal(SIGINT, SIG_DFL, SA_RESTART);
f95b8144 717 sleep(3);
718 }
bbe199dc 719 /* NOTREACHED */
f95b8144 720}
fff6ad65 721
9ec1a1dc 722static void
fff6ad65 723normal_shutdown(void)
724{
725 debug(1, 1) ("Shutting down...\n");
726 if (Config.pidFilename && strcmp(Config.pidFilename, "none")) {
727 enter_suid();
728 safeunlink(Config.pidFilename, 0);
729 leave_suid();
730 }
731 releaseServerSockets();
732 unlinkdClose();
733 storeDirWriteCleanLogs(0);
734 PrintRusage();
735 dumpMallocStats();
736 storeLogClose();
737 accessLogClose();
33ab18e8 738#if PURIFY || XMALLOC_TRACE
fff6ad65 739 configFreeMemory();
740 storeFreeMemory();
741 dnsFreeMemory();
742 redirectFreeMemory();
33ab18e8 743 /*stmemFreeMemory(); */
fff6ad65 744 netdbFreeMemory();
745 ipcacheFreeMemory();
746 fqdncacheFreeMemory();
747 asnFreeMemory();
7021844c 748 httpHeaderCleanModule();
fff6ad65 749#endif
33ab18e8 750#if WHY_DO_THIS
fff6ad65 751 file_close(0);
752 file_close(1);
753 file_close(2);
33ab18e8 754#endif
fff6ad65 755 fdDumpOpen();
756 fdFreeMemory();
7021844c 757 memClean();
33ab18e8 758#if XMALLOC_TRACE
759 {
760 extern int xmalloc_total;
761 extern void xmalloc_find_leaks(void);
33ab18e8 762 xmalloc_find_leaks();
33ab18e8 763 debug(1, 0) ("Memory used after shutdown: %d\n", xmalloc_total);
764 }
765#endif
36a97e19 766#if MEM_GEN_TRACE
767 log_trace_done();
768#endif
769
fff6ad65 770 debug(1, 0) ("Squid Cache (Version %s): Exiting normally.\n",
771 version_string);
772 fclose(debug_log);
773 exit(0);
774}