/*
- * $Id$
- *
- * DEBUG: section 01 Startup and Main Loop
- * AUTHOR: Harvest Derived
- *
- * SQUID Web Proxy Cache http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from
- * the Internet community; see the CONTRIBUTORS file for full
- * details. Many organizations have provided support for Squid's
- * development; see the SPONSORS file for full details. Squid is
- * Copyrighted (C) 2001 by the Regents of the University of
- * California; see the COPYRIGHT file for full details. Squid
- * incorporates software developed and/or copyrighted by other
- * sources; see the CREDITS file for full details.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
*
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
*/
+/* DEBUG: section 01 Startup and Main Loop */
+
#include "squid.h"
#include "AccessLogEntry.h"
#include "acl/Acl.h"
#include "acl/Asn.h"
+#include "AuthReg.h"
#include "base/RunnersRegistry.h"
#include "base/Subscription.h"
#include "base/TextException.h"
#include "ExternalACL.h"
#include "fd.h"
#include "format/Token.h"
-#include "forward.h"
-#include "fs/Module.h"
#include "fqdncache.h"
+#include "fs/Module.h"
+#include "FwdState.h"
+#include "globals.h"
#include "htcp.h"
#include "HttpHeader.h"
#include "HttpReply.h"
#include "icmp/net_db.h"
#include "ICP.h"
#include "ident/Ident.h"
+#include "ip/tools.h"
#include "ipc/Coordinator.h"
#include "ipc/Kids.h"
#include "ipc/Strand.h"
-#include "ip/tools.h"
-#include "Mem.h"
-#include "MemPool.h"
+#include "ipcache.h"
+#include "mime.h"
#include "neighbors.h"
+#include "parser/Tokenizer.h"
#include "pconn.h"
-#include "PeerSelectState.h"
#include "peer_sourcehash.h"
#include "peer_userhash.h"
+#include "PeerSelectState.h"
#include "profiler/Profiler.h"
-#include "protos.h"
+#include "redirect.h"
#include "refresh.h"
-#include "tools.h"
+#include "send-announce.h"
+#include "SquidConfig.h"
#include "SquidDns.h"
#include "SquidTime.h"
#include "stat.h"
#include "StatCounters.h"
-#include "StoreFileSystem.h"
#include "Store.h"
+#include "store_log.h"
+#include "StoreFileSystem.h"
#include "SwapDir.h"
+#include "tools.h"
+#include "unlinkd.h"
#include "URL.h"
#include "wccp.h"
#include "wccp2.h"
+#include "WinSvc.h"
#if USE_ADAPTATION
#include "adaptation/Config.h"
#include "LoadableModules.h"
#endif
#if USE_SSL_CRTD
-#include "ssl/helper.h"
#include "ssl/certificate_db.h"
#endif
-#if USE_SSL
+#if USE_OPENSSL
#include "ssl/context_storage.h"
+#include "ssl/helper.h"
#endif
#if ICAP_CLIENT
#include "adaptation/icap/Config.h"
#if USE_SQUID_ESI
#include "esi/Module.h"
#endif
+#if SQUID_SNMP
+#include "snmp_core.h"
+#endif
+#include <cerrno>
+#if HAVE_GETOPT_H
+#include <getopt.h>
+#endif
#if HAVE_PATHS_H
#include <paths.h>
#endif
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
#if USE_WIN32_SERVICE
-#include "squid_windows.h"
#include <process.h>
static int opt_install_service = FALSE;
static int opt_remove_service = FALSE;
-static int opt_signal_service = FALSE;
static int opt_command_line = FALSE;
-extern void WIN32_svcstatusupdate(DWORD, DWORD);
+void WIN32_svcstatusupdate(DWORD, DWORD);
void WINAPI WIN32_svcHandler(DWORD);
-
-#endif
-
-#if !defined(SQUID_BUILD_INFO)
-#define SQUID_BUILD_INFO ""
#endif
+static int opt_signal_service = FALSE;
static char *opt_syslog_facility = NULL;
-static int icpPortNumOverride = 1; /* Want to detect "-u 0" */
+static int icpPortNumOverride = 1; /* Want to detect "-u 0" */
static int configured_once = 0;
#if MALLOC_DBG
static int malloc_debug_level = 0;
static void serverConnectionsClose(void);
static void watch_child(char **);
static void setEffectiveUser(void);
-#if MEM_GEN_TRACE
-extern void log_trace_done();
-extern void log_trace_init(char *);
-#endif
static void SquidShutdown(void);
static void mainSetCwd(void);
static int checkRunningPid(void);
-#if !_SQUID_MSWIN_
+#if !_SQUID_WINDOWS_
static const char *squid_start_script = "squid_start";
#endif
{
public:
- int checkEvents(int timeout) {
+ int checkEvents(int) {
Store::Root().callback();
return EVENT_IDLE;
};
{
public:
- SignalEngine(EventLoop &evtLoop) : loop(evtLoop) {}
virtual int checkEvents(int timeout);
private:
- static void StopEventLoop(void * data) {
- static_cast<SignalEngine *>(data)->loop.stop();
+ static void StopEventLoop(void *) {
+ if (EventLoop::Running)
+ EventLoop::Running->stop();
}
void doShutdown(time_t wait);
-
- EventLoop &loop;
};
int
-SignalEngine::checkEvents(int timeout)
+SignalEngine::checkEvents(int)
{
PROF_start(SignalEngine_checkEvents);
/* detach the auth components (only do this on full shutdown) */
Auth::Scheme::FreeAll();
#endif
+
+ RunRegisteredHere(RegisteredRunner::startShutdown);
eventAdd("SquidShutdown", &StopEventLoop, this, (double) (wait + 1), 1, false);
}
usage(void)
{
fprintf(stderr,
+ "Usage: %s [-cdzCFNRVYX] [-n name] [-s | -l facility] [-f config-file] [-[au] port] [-k signal]"
#if USE_WIN32_SERVICE
- "Usage: %s [-cdhirvzCFNRVYX] [-s | -l facility] [-f config-file] [-[au] port] [-k signal] [-n name] [-O CommandLine]\n"
-#else
- "Usage: %s [-cdhvzCFNRVYX] [-s | -l facility] [-f config-file] [-[au] port] [-k signal]\n"
+ "[-ir] [-O CommandLine]"
#endif
+ "\n"
+ " -h | --help Print help message.\n"
+ " -v | --version Print version details.\n"
+ "\n"
" -a port Specify HTTP port number (default: %d).\n"
" -d level Write debugging to stderr also.\n"
" -f file Use given config-file instead of\n"
" %s\n"
- " -h Print help message.\n"
#if USE_WIN32_SERVICE
" -i Installs as a Windows Service (see -n option).\n"
#endif
- " -k reconfigure|rotate|shutdown|interrupt|kill|debug|check|parse\n"
+ " -k reconfigure|rotate|shutdown|"
+#ifdef SIGTTIN
+ "restart|"
+#endif
+ "interrupt|kill|debug|check|parse\n"
" Parse configuration file, then send signal to \n"
" running copy (except -k parse) and exit.\n"
+ " -n name Specify service name to use for service operations\n"
+ " default is: " APP_SHORTNAME ".\n"
#if USE_WIN32_SERVICE
- " -n name Specify Windows Service name to use for service operations\n"
- " default is: " _WIN_SQUID_DEFAULT_SERVICE_NAME ".\n"
" -r Removes a Windows Service (see -n option).\n"
#endif
" -s | -l facility\n"
" Enable logging to syslog.\n"
" -u port Specify ICP port number (default: %d), disable with 0.\n"
- " -v Print version.\n"
- " -z Create swap directories\n"
+ " -z Create missing swap directories and then exit.\n"
" -C Do not catch fatal signals.\n"
" -D OBSOLETE. Scheduled for removal.\n"
" -F Don't serve any requests until store is rebuilt.\n"
/**
* Parse the parameters received via command line interface.
*
- \param argc Number of options received on command line
- \param argv List of parameters received on command line
+ * \param argc Number of options received on command line
+ * \param argv List of parameters received on command line
*/
static void
mainParseOptions(int argc, char *argv[])
{
- extern char *optarg;
- int c;
+ int optIndex = 0;
+ // short options
+ const char *shortOpStr =
#if USE_WIN32_SERVICE
- while ((c = getopt(argc, argv, "CDFNO:RSVYXa:d:f:hik:m::n:rsl:u:vz?")) != -1)
-#else
- while ((c = getopt(argc, argv, "CDFNRSYXa:d:f:hk:m::sl:u:vz?")) != -1)
+ "O:Vir"
#endif
- {
+ "CDFNRSYXa:d:f:hk:m::n:sl:u:vz?";
+
+ // long options
+ static struct option squidOptions[] = {
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'v'},
+ {0, 0, 0, 0}
+ };
+
+ int c;
+ while ((c = getopt_long(argc, argv, shortOpStr, squidOptions, &optIndex)) != -1) {
switch (c) {
case 'd':
/** \par d
- * Set global option Debug::log_stderr to the number given follwoign the option */
+ * Set global option Debug::log_stderr to the number given following the option */
Debug::log_stderr = atoi(optarg);
break;
else if (!strncmp(optarg, "check", strlen(optarg)))
/** \li On check send 0 / SIGNULL. */
- opt_send_signal = 0; /* SIGNULL */
+ opt_send_signal = 0; /* SIGNULL */
else if (!strncmp(optarg, "parse", strlen(optarg)))
/** \li On parse set global flag to re-parse the config file only. */
opt_parse_cfg_only = 1;
fatal("Need to add -DMALLOC_DBG when compiling to use -mX option");
#endif
- } else {
-#if XMALLOC_TRACE
- xmalloc_trace = !xmalloc_trace;
-#else
- fatal("Need to configure --enable-xmalloc-debug-trace to use -m option");
-#endif
}
break;
-#if USE_WIN32_SERVICE
-
case 'n':
/** \par n
- * Set global option opt_signal_service (to TRUE).
- * Stores the additional parameter given in global WIN32_Service_name */
- xfree(WIN32_Service_name);
-
- WIN32_Service_name = xstrdup(optarg);
-
- opt_signal_service = TRUE;
-
+ * Set global option opt_signal_service (to true).
+ * Stores the additional parameter given in global service_name */
+ if (optarg && *optarg != '\0') {
+ const SBuf t(optarg);
+ ::Parser::Tokenizer tok(t);
+ const CharacterSet chr = CharacterSet::ALPHA+CharacterSet::DIGIT;
+ if (!tok.prefix(service_name, chr))
+ fatalf("Expected alphanumeric service name for the -n option but got: %s", optarg);
+ if (!tok.atEnd())
+ fatalf("Garbage after alphanumeric service name in the -n option value: %s", optarg);
+ if (service_name.length() > 32)
+ fatalf("Service name (-n option) must be limited to 32 characters but got %u", service_name.length());
+ opt_signal_service = true;
+ } else {
+ fatal("A service name is required for the -n option");
+ }
break;
+#if USE_WIN32_SERVICE
+
case 'r':
/** \par r
* Set global option opt_remove_service (to TRUE) */
/** \par l
* Stores the syslog facility name in global opt_syslog_facility
* then performs actions for -s option. */
+ xfree(opt_syslog_facility); // ignore any previous options sent
opt_syslog_facility = xstrdup(optarg);
case 's':
/** \par v
* Display squid version and build information. Then exit. */
printf("Squid Cache: Version %s\n" ,version_string);
+ printf("Service Name: " SQUIDSBUFPH "\n", SQUIDSBUFPRINT(service_name));
if (strlen(SQUID_BUILD_INFO))
printf("%s\n",SQUID_BUILD_INFO);
printf( "configure options: %s\n", SQUID_CONFIGURE_OPTIONS);
exit(0);
- /* NOTREACHED */
+ /* NOTREACHED */
case 'z':
/** \par z
{
do_rotate = 1;
RotateSignal = sig;
-#if !_SQUID_MSWIN_
+#if !_SQUID_WINDOWS_
#if !HAVE_SIGACTION
signal(sig, rotate_logs);
{
do_reconfigure = 1;
ReconfigureSignal = sig;
-#if !_SQUID_MSWIN_
+#if !_SQUID_WINDOWS_
#if !HAVE_SIGACTION
signal(sig, reconfigure);
{
do_shutdown = sig == SIGINT ? -1 : 1;
ShutdownSignal = sig;
-#ifdef SIGTTIN
-
+#if defined(SIGTTIN)
if (SIGTTIN == sig)
shutdown_status = 1;
-
#endif
+#if !_SQUID_WINDOWS_
const pid_t ppid = getppid();
if (!IamMasterProcess() && ppid > 1) {
" pid " << ppid << ": " << xstrerror());
}
-#if !_SQUID_MSWIN_
#if KILL_PARENT_OPT
-
if (!IamMasterProcess() && ppid > 1) {
debugs(1, DBG_IMPORTANT, "Killing master process, pid " << ppid);
if (kill(ppid, sig) < 0)
debugs(1, DBG_IMPORTANT, "kill " << ppid << ": " << xstrerror());
}
-
#endif /* KILL_PARENT_OPT */
+
#if SA_RESETHAND == 0
signal(SIGTERM, SIG_DFL);
snmpOpenPorts();
#endif
- clientdbInit();
icmpEngine.Open();
netdbInit();
asnInit();
#endif
}
if (IamWorkerProcess()) {
- clientHttpConnectionsClose();
+ clientConnectionsClose();
icpConnectionShutdown();
#if USE_HTCP
htcpSocketShutdown();
#if USE_SSL_CRTD
Ssl::Helper::GetInstance()->Shutdown();
#endif
-#if USE_SSL
+#if USE_OPENSSL
if (Ssl::CertValidationHelper::GetInstance())
Ssl::CertValidationHelper::GetInstance()->Shutdown();
Ssl::TheGlobalContextStorage.reconfigureStart();
debugs(1, 3, "finishing reconfiguring");
errorClean();
- enter_suid(); /* root to read config file */
+ enter_suid(); /* root to read config file */
// we may have disabled the need for PURGE
if (Config2.onoff.enable_purge)
if (oldWorkers != Config.workers) {
debugs(1, DBG_CRITICAL, "WARNING: Changing 'workers' (from " <<
oldWorkers << " to " << Config.workers <<
- ") is not supported and ignored");
+ ") requires a full restart. It has been ignored by reconfigure.");
Config.workers = oldWorkers;
}
+ RunRegisteredHere(RegisteredRunner::syncConfig);
+
if (IamPrimaryProcess())
CpuAffinityCheck();
CpuAffinityReconfigure();
Mem::Report();
setEffectiveUser();
_db_init(Debug::cache_log, Debug::debugOptions);
- ipcache_restart(); /* clear stuck entries */
- fqdncache_restart(); /* sigh, fqdncache too */
+ ipcache_restart(); /* clear stuck entries */
+ fqdncache_restart(); /* sigh, fqdncache too */
parseEtcHosts();
- errorInitialize(); /* reload error pages */
+ errorInitialize(); /* reload error pages */
accessLogInit();
#if USE_LOADABLE_MODULES
#if USE_SSL_CRTD
Ssl::Helper::GetInstance()->Init();
#endif
-#if USE_SSL
+#if USE_OPENSSL
if (Ssl::CertValidationHelper::GetInstance())
Ssl::CertValidationHelper::GetInstance()->Init();
#endif
mimeInit(Config.mimeTablePathname);
-#if USE_UNLINKD
if (unlinkdNeeded())
unlinkdInit();
-#endif
#if USE_DELAY_POOLS
Config.ClientDelay.finalize();
eventDelete(start_announce, NULL);
}
- writePidFile(); /* write PID file */
+ writePidFile(); /* write PID file */
reconfiguring = 0;
}
mainRotate(void)
{
icmpEngine.Close();
-#if USE_DNSHELPER
- dnsShutdown();
-#endif
redirectShutdown();
#if USE_AUTH
authenticateRotate();
#endif
externalAclShutdown();
- _db_rotate_log(); /* cache.log */
+ _db_rotate_log(); /* cache.log */
storeDirWriteCleanLogs(1);
- storeLogRotate(); /* store.log */
- accessLogRotate(); /* access.log */
+ storeLogRotate(); /* store.log */
+ accessLogRotate(); /* access.log */
#if ICAP_CLIENT
icapLogRotate(); /*icap.log*/
#endif
icmpEngine.Open();
-#if USE_DNSHELPER
- dnsInit();
-#endif
redirectInit();
#if USE_AUTH
authenticateInit(&Auth::TheConfig);
setEffectiveUser(void)
{
keepCapabilities();
- leave_suid(); /* Run as non privilegied user */
+ leave_suid(); /* Run as non privilegied user */
#if _SQUID_OS2_
return;
}
}
+/// changes working directory, providing error reporting
+static bool
+mainChangeDir(const char *dir)
+{
+ if (chdir(dir) == 0)
+ return true;
+
+ debugs(50, DBG_CRITICAL, "cannot change current directory to " << dir <<
+ ": " << xstrerror());
+ return false;
+}
+
+/// set the working directory.
static void
mainSetCwd(void)
{
- char pathbuf[MAXPATHLEN];
+ static bool chrooted = false;
+ if (Config.chroot_dir && !chrooted) {
+ chrooted = true;
+
+ if (chroot(Config.chroot_dir) != 0)
+ fatalf("chroot to %s failed: %s", Config.chroot_dir, xstrerror());
+
+ if (!mainChangeDir("/"))
+ fatalf("chdir to / after chroot to %s failed", Config.chroot_dir);
+ }
- if (Config.coredump_dir) {
- if (0 == strcmp("none", Config.coredump_dir)) {
- (void) 0;
- } else if (chdir(Config.coredump_dir) == 0) {
+ if (Config.coredump_dir && strcmp("none", Config.coredump_dir) != 0) {
+ if (mainChangeDir(Config.coredump_dir)) {
debugs(0, DBG_IMPORTANT, "Set Current Directory to " << Config.coredump_dir);
return;
- } else {
- debugs(50, DBG_CRITICAL, "chdir: " << Config.coredump_dir << ": " << xstrerror());
}
}
/* If we don't have coredump_dir or couldn't cd there, report current dir */
+ char pathbuf[MAXPATHLEN];
if (getcwd(pathbuf, MAXPATHLEN)) {
debugs(0, DBG_IMPORTANT, "Current Directory is " << pathbuf);
} else {
mainInitialize(void)
{
/* chroot if configured to run inside chroot */
-
- if (Config.chroot_dir && (chroot(Config.chroot_dir) != 0 || chdir("/") != 0)) {
- fatal("failed to chroot");
- }
+ mainSetCwd();
if (opt_catch_signals) {
squid_signal(SIGSEGV, death, SA_NODEFER | SA_RESETHAND);
fd_open(fileno(debug_log), FD_LOG, Debug::cache_log);
-#if MEM_GEN_TRACE
-
- log_trace_init("/tmp/squid.alloc");
-
-#endif
-
debugs(1, DBG_CRITICAL, "Starting Squid Cache version " << version_string << " for " << CONFIG_HOST_TYPE << "...");
+ debugs(1, DBG_CRITICAL, "Service Name: " << service_name);
#if _SQUID_WINDOWS_
if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
- debugs(1, DBG_CRITICAL, "Running as " << WIN32_Service_name << " Windows System Service on " << WIN32_OS_string);
debugs(1, DBG_CRITICAL, "Service command line is: " << WIN32_Service_Command_Line);
} else
debugs(1, DBG_CRITICAL, "Running on " << WIN32_OS_string);
setSystemLimits();
debugs(1, DBG_IMPORTANT, "With " << Squid_MaxFD << " file descriptors available");
-#if _SQUID_MSWIN_
+#if _SQUID_WINDOWS_
debugs(1, DBG_IMPORTANT, "With " << _getmaxstdio() << " CRT stdio descriptors available");
#endif
if (!configured_once)
- disk_init(); /* disk_init must go before ipcache_init() */
+ disk_init(); /* disk_init must go before ipcache_init() */
ipcache_init();
Ssl::Helper::GetInstance()->Init();
#endif
-#if USE_SSL
+#if USE_OPENSSL
+ if (!configured_once)
+ Ssl::initialize_session_cache();
+
if (Ssl::CertValidationHelper::GetInstance())
Ssl::CertValidationHelper::GetInstance()->Init();
#endif
#endif
externalAclInit();
- httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
+ httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
- httpReplyInitModule(); /* must go before accepting replies */
+ httpReplyInitModule(); /* must go before accepting replies */
errorInitialize();
#endif
if (!configured_once) {
-#if USE_UNLINKD
if (unlinkdNeeded())
unlinkdInit();
-#endif
urlInitialize();
statInit();
storeInit();
mainSetCwd();
- /* after this point we want to see the mallinfo() output */
- do_mallinfo = 1;
mimeInit(Config.mimeTablePathname);
refreshInit();
#if USE_DELAY_POOLS
no_suid();
if (!configured_once)
- writePidFile(); /* write PID file */
+ writePidFile(); /* write PID file */
#if defined(_SQUID_LINUX_THREADS_)
static int SquidMainSafe(int argc, char **argv);
#if USE_WIN32_SERVICE
-/* When USE_WIN32_SERVICE is defined, the main function is placed in win32.cc */
+/* Entry point for Windows services */
extern "C" void WINAPI
SquidWinSvcMain(int argc, char **argv)
{
SquidMainSafe(argc, argv);
}
-#else
+#endif
+
int
main(int argc, char **argv)
{
+#if USE_WIN32_SERVICE
+ SetErrorMode(SEM_NOGPFAULTERRORBOX);
+ if ((argc == 2) && strstr(argv[1], _WIN_SQUID_SERVICE_OPTION))
+ return WIN32_StartService(argc, argv);
+ else {
+ WIN32_run_mode = _WIN_SQUID_RUN_MODE_INTERACTIVE;
+ opt_no_daemon = 1;
+ }
+#endif
+
return SquidMainSafe(argc, argv);
}
-#endif
static int
SquidMainSafe(int argc, char **argv)
{
ConfigureCurrentKid(argv[0]);
-#if _SQUID_WINDOWS_
- int WIN32_init_err;
-#endif
-
-#if HAVE_SBRK
-
- sbrk_start = sbrk(0);
-#endif
-
Debug::parseOptions(NULL);
debug_log = stderr;
#endif
-#if _SQUID_WINDOWS_
+ /* NOP under non-windows */
+ int WIN32_init_err=0;
if ((WIN32_init_err = WIN32_Subsystem_Init(&argc, &argv)))
return WIN32_init_err;
-#endif
/* call mallopt() before anything else */
#if HAVE_MALLOPT
Mem::Init();
- storeFsInit(); /* required for config parsing */
+ storeFsInit(); /* required for config parsing */
/* TODO: call the FS::Clean() in shutdown to do Fs cleanups */
Fs::Init();
/* we may want the parsing process to set this up in the future */
Store::Root(new StoreController);
-#if USE_AUTH
- Auth::Init(); /* required for config parsing */
-#endif
+ Auth::Init(); /* required for config parsing. NOP if !USE_AUTH */
Ip::ProbeTransport(); // determine IPv4 or IPv6 capabilities before parsing.
Format::Token::Init(); // XXX: temporary. Use a runners registry of pre-parse runners instead.
/* send signal to running copy and exit */
if (opt_send_signal != -1) {
/* chroot if configured to run inside chroot */
-
+ mainSetCwd();
if (Config.chroot_dir) {
- if (chroot(Config.chroot_dir))
- fatal("failed to chroot");
-
no_suid();
} else {
leave_suid();
debugs(1,2, HERE << "Doing post-config initialization\n");
leave_suid();
- ActivateRegistered(rrFinalizeConfig);
- ActivateRegistered(rrClaimMemoryNeeds);
- ActivateRegistered(rrAfterConfig);
+ RunRegisteredHere(RegisteredRunner::finalizeConfig);
+ RunRegisteredHere(RegisteredRunner::claimMemoryNeeds);
+ RunRegisteredHere(RegisteredRunner::useConfig);
enter_suid();
if (!opt_no_daemon && Config.workers > 0)
if (opt_create_swap_dirs) {
/* chroot if configured to run inside chroot */
-
- if (Config.chroot_dir && chroot(Config.chroot_dir)) {
- fatal("failed to chroot");
- }
+ mainSetCwd();
setEffectiveUser();
- debugs(0, DBG_CRITICAL, "Creating Swap Directories");
+ debugs(0, DBG_CRITICAL, "Creating missing swap directories");
Store::Root().create();
return 0;
/* main loop */
EventLoop mainLoop;
- SignalEngine signalEngine(mainLoop);
+ SignalEngine signalEngine;
mainLoop.registerEngine(&signalEngine);
if (pid > 1) {
#if USE_WIN32_SERVICE
-
if (opt_signal_service) {
WIN32_sendSignal(opt_send_signal);
exit(0);
- } else
-#if _SQUID_MSWIN_
- {
+ } else {
fprintf(stderr, "%s: ERROR: Could not send ", APP_SHORTNAME);
fprintf(stderr, "signal to Squid Service:\n");
fprintf(stderr, "missing -n command line switch.\n");
exit(1);
}
-
/* NOTREACHED */
-#endif
-
#endif
if (kill(pid, opt_send_signal) &&
exit(0);
}
-#if !_SQUID_MSWIN_
+#if !_SQUID_WINDOWS_
/*
* This function is run when Squid is in daemon mode, just
* before the parent forks and starts up the child process.
}
}
-#endif /* _SQUID_MSWIN_ */
+#endif /* _SQUID_WINDOWS_ */
static int
checkRunningPid(void)
static void
watch_child(char *argv[])
{
-#if !_SQUID_MSWIN_
+#if !_SQUID_WINDOWS_
char *prog;
#if _SQUID_NEXT_
if (!TheKids.someRunning() && !TheKids.shouldRestartSome()) {
leave_suid();
- DeactivateRegistered(rrAfterConfig);
- DeactivateRegistered(rrClaimMemoryNeeds);
- DeactivateRegistered(rrFinalizeConfig);
+ // XXX: Master process has no main loop and, hence, should not call
+ // RegisteredRunner::startShutdown which promises a loop iteration.
+ RunRegisteredHere(RegisteredRunner::finishShutdown);
enter_suid();
if (TheKids.someSignaled(SIGINT) || TheKids.someSignaled(SIGTERM)) {
}
/* NOTREACHED */
-#endif /* _SQUID_MSWIN_ */
+#endif /* _SQUID_WINDOWS_ */
}
#if USE_SSL_CRTD
Ssl::Helper::GetInstance()->Shutdown();
#endif
-#if USE_SSL
+#if USE_OPENSSL
if (Ssl::CertValidationHelper::GetInstance())
Ssl::CertValidationHelper::GetInstance()->Shutdown();
#endif
#endif
Store::Root().sync(); /* Flush pending object writes/unlinks */
-#if USE_UNLINKD
- unlinkdClose(); /* after sync/flush */
-#endif
+ unlinkdClose(); /* after sync/flush. NOP if !USE_UNLINKD */
storeDirWriteCleanLogs(0);
PrintRusage();
dumpMallocStats();
- Store::Root().sync(); /* Flush log writes */
+ Store::Root().sync(); /* Flush log writes */
storeLogClose();
accessLogClose();
- Store::Root().sync(); /* Flush log close */
+ Store::Root().sync(); /* Flush log close */
StoreFileSystem::FreeAllFs();
DiskIOModule::FreeAllModules();
- DeactivateRegistered(rrAfterConfig);
- DeactivateRegistered(rrClaimMemoryNeeds);
- DeactivateRegistered(rrFinalizeConfig);
#if LEAK_CHECK_MODE && 0 /* doesn't work at the moment */
configFreeMemory();
eventFreeMemory();
mimeFreeMemory();
errorClean();
-#endif
-#if !XMALLOC_TRACE
-
- if (opt_no_daemon) {
- file_close(0);
- file_close(1);
- file_close(2);
- }
-
#endif
// clear StoreController
Store::Root(NULL);
comm_exit();
- memClean();
-
-#if XMALLOC_TRACE
-
- xmalloc_find_leaks();
-
- debugs(1, DBG_CRITICAL, "Memory used after shutdown: " << xmalloc_total);
-
-#endif
-#if MEM_GEN_TRACE
-
- log_trace_done();
+ RunRegisteredHere(RegisteredRunner::finishShutdown);
-#endif
+ memClean();
if (IamPrimaryProcess()) {
if (Config.pidFilename && strcmp(Config.pidFilename, "none") != 0) {