📄 tools.c
字号:
/* * $Id: tools.c,v 1.173.2.4 1999/05/11 20:37:20 wessels Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * * Squid is the result of efforts by numerous individuals from the * Internet community. Development is led by Duane Wessels of the * National Laboratory for Applied Network Research and funded by the * National Science Foundation. Squid is Copyrighted (C) 1998 by * Duane Wessels and the University of California San Diego. Please * see the COPYRIGHT file for full details. Squid incorporates * software developed and/or copyrighted by other sources. Please 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. * */#include "squid.h"#define DEAD_MSG "\The Squid Cache (version %s) died.\n\\n\You've encountered a fatal error in the Squid Cache version %s.\n\If a core file was created (possibly in the swap directory),\n\please execute 'gdb squid core' or 'dbx squid core', then type 'where',\n\and report the trace back to squid-bugs@ircache.net.\n\\n\Thanks!\n"static void fatal_common(const char *);static void fatalvf(const char *fmt, va_list args);static void mail_warranty(void);#if USE_ASYNC_IOstatic AIOCB safeunlinkComplete;#endif#if MEM_GEN_TRACEextern void log_trace_done();extern void log_trace_init(char *);#endifvoidreleaseServerSockets(void){ int i; /* Release the main ports as early as possible */ for (i = 0; i < NHttpSockets; i++) { if (HttpSockets[i] >= 0) close(HttpSockets[i]); } if (theInIcpConnection >= 0) close(theInIcpConnection); if (theOutIcpConnection >= 0 && theOutIcpConnection != theInIcpConnection) close(theOutIcpConnection);}static char *dead_msg(void){ LOCAL_ARRAY(char, msg, 1024); snprintf(msg, 1024, DEAD_MSG, version_string, version_string); return msg;}static voidmail_warranty(void){ FILE *fp = NULL; char *filename; static char command[256]; if ((filename = tempnam(NULL, appname)) == NULL) return; if ((fp = fopen(filename, "w")) == NULL) return; fprintf(fp, "From: %s\n", appname); fprintf(fp, "To: %s\n", Config.adminEmail); fprintf(fp, "Subject: %s\n", dead_msg()); fclose(fp); snprintf(command, 256, "mail %s < %s", Config.adminEmail, filename); system(command); /* XXX should avoid system(3) */ unlink(filename);}voiddumpMallocStats(void){#if HAVE_MSTATS && HAVE_GNUMALLOC_H struct mstats ms = mstats(); fprintf(debug_log, "\ttotal space in arena: %6d KB\n", (int) (ms.bytes_total >> 10)); fprintf(debug_log, "\tTotal free: %6d KB %d%%\n", (int) (ms.bytes_free >> 10), percent(ms.bytes_free, ms.bytes_total));#elif HAVE_MALLINFO struct mallinfo mp; int t; if (!do_mallinfo) return; mp = mallinfo(); fprintf(debug_log, "Memory usage for %s via mallinfo():\n", appname); fprintf(debug_log, "\ttotal space in arena: %6d KB\n", mp.arena >> 10); fprintf(debug_log, "\tOrdinary blocks: %6d KB %6d blks\n", mp.uordblks >> 10, mp.ordblks); fprintf(debug_log, "\tSmall blocks: %6d KB %6d blks\n", mp.usmblks >> 10, mp.smblks); fprintf(debug_log, "\tHolding blocks: %6d KB %6d blks\n", mp.hblkhd >> 10, mp.hblks); fprintf(debug_log, "\tFree Small blocks: %6d KB\n", mp.fsmblks >> 10); fprintf(debug_log, "\tFree Ordinary blocks: %6d KB\n", mp.fordblks >> 10); t = mp.uordblks + mp.usmblks + mp.hblkhd; fprintf(debug_log, "\tTotal in use: %6d KB %d%%\n", t >> 10, percent(t, mp.arena)); t = mp.fsmblks + mp.fordblks; fprintf(debug_log, "\tTotal free: %6d KB %d%%\n", t >> 10, percent(t, mp.arena));#if HAVE_EXT_MALLINFO fprintf(debug_log, "\tmax size of small blocks:\t%d\n", mp.mxfast); fprintf(debug_log, "\tnumber of small blocks in a holding block:\t%d\n", mp.nlblks); fprintf(debug_log, "\tsmall block rounding factor:\t%d\n", mp.grain); fprintf(debug_log, "\tspace (including overhead) allocated in ord. blks:\t%d\n", mp.uordbytes); fprintf(debug_log, "\tnumber of ordinary blocks allocated:\t%d\n", mp.allocated); fprintf(debug_log, "\tbytes used in maintaining the free tree:\t%d\n", mp.treeoverhead);#endif /* HAVE_EXT_MALLINFO */#endif /* HAVE_MALLINFO */}voidsquid_getrusage(struct rusage *r){ memset(r, '\0', sizeof(struct rusage));#if HAVE_GETRUSAGE && defined(RUSAGE_SELF)#ifdef _SQUID_SOLARIS_ /* Solaris 2.5 has getrusage() permission bug -- Arjan de Vet */ enter_suid();#endif getrusage(RUSAGE_SELF, r);#ifdef _SQUID_SOLARIS_ leave_suid();#endif#endif}doublerusage_cputime(struct rusage *r){ return (double) r->ru_stime.tv_sec + (double) r->ru_utime.tv_sec + (double) r->ru_stime.tv_usec / 1000000.0 + (double) r->ru_utime.tv_usec / 1000000.0;}/* Hack for some HP-UX preprocessors */#ifndef HAVE_GETPAGESIZE#define HAVE_GETPAGESIZE 0#endifintrusage_maxrss(struct rusage *r){#if defined(_SQUID_SGI_) && _ABIAPI return r->ru_pad[0];#elif defined(_SQUID_SGI_) return r->ru_maxrss;#elif defined(_SQUID_OSF_) return r->ru_maxrss;#elif defined(BSD4_4) return r->ru_maxrss;#elif HAVE_GETPAGESIZE return (r->ru_maxrss * getpagesize()) >> 10;#elif defined(PAGESIZE) return (r->ru_maxrss * PAGESIZE) >> 10;#else return r->ru_maxrss;#endif}intrusage_pagefaults(struct rusage *r){#if defined(_SQUID_SGI_) && _ABIAPI return r->ru_pad[5];#else return r->ru_majflt;#endif}voidPrintRusage(void){ struct rusage rusage; squid_getrusage(&rusage); fprintf(debug_log, "CPU Usage: %.3f seconds\n", rusage_cputime(&rusage)); fprintf(debug_log, "Maximum Resident Size: %d KB\n", rusage_maxrss(&rusage)); fprintf(debug_log, "Page faults with physical i/o: %d\n", rusage_pagefaults(&rusage));}voiddeath(int sig){ if (sig == SIGSEGV) fprintf(debug_log, "FATAL: Received Segment Violation...dying.\n"); else if (sig == SIGBUS) fprintf(debug_log, "FATAL: Received Bus Error...dying.\n"); else fprintf(debug_log, "FATAL: Received signal %d...dying.\n", sig);#ifdef PRINT_STACK_TRACE#ifdef _SQUID_HPUX_ { extern void U_STACK_TRACE(void); /* link with -lcl */ fflush(debug_log); dup2(fileno(debug_log), 2); U_STACK_TRACE(); }#endif /* _SQUID_HPUX_ */#ifdef _SQUID_SOLARIS_ { /* get ftp://opcom.sun.ca/pub/tars/opcom_stack.tar.gz and */ extern void opcom_stack_trace(void); /* link with -lopcom_stack */ fflush(debug_log); dup2(fileno(debug_log), fileno(stdout)); opcom_stack_trace(); fflush(stdout); }#endif /* _SQUID_SOLARIS_ */#endif /* PRINT_STACK_TRACE */#if SA_RESETHAND == 0 signal(SIGSEGV, SIG_DFL); signal(SIGBUS, SIG_DFL); signal(sig, SIG_DFL);#endif releaseServerSockets(); storeDirWriteCleanLogs(0); PrintRusage(); dumpMallocStats(); if (squid_curtime - SQUID_RELEASE_TIME < 864000) { /* skip if more than 10 days old */ if (Config.adminEmail) mail_warranty(); else puts(dead_msg()); } abort();}voidsigusr2_handle(int sig){ static int state = 0; /* no debug() here; bad things happen if the signal is delivered during _db_print() */ if (state == 0) {#ifndef MEM_GEN_TRACE _db_init(Config.Log.log, "ALL,10");#else log_trace_done();#endif state = 1; } else {#ifndef MEM_GEN_TRACE _db_init(Config.Log.log, Config.debugOptions);#else log_trace_init("/tmp/squid.alloc");#endif state = 0; }#if !HAVE_SIGACTION signal(sig, sigusr2_handle); /* reinstall */#endif}static voidfatal_common(const char *message){#if HAVE_SYSLOG syslog(LOG_ALERT, "%s", message);#endif fprintf(debug_log, "FATAL: %s\n", message); if (opt_debug_stderr && debug_log != stderr) fprintf(stderr, "FATAL: %s\n", message); fprintf(debug_log, "Squid Cache (Version %s): Terminated abnormally.\n", version_string); fflush(debug_log); PrintRusage(); dumpMallocStats();}/* fatal */voidfatal(const char *message){ releaseServerSockets(); /* check for store_rebuilding flag because fatal() is often * used in early initialization phases, long before we ever * get to the store log. */ if (!store_rebuilding) storeDirWriteCleanLogs(0); fatal_common(message); exit(shutting_down ? 0 : 1);}/* printf-style interface for fatal */#if STDC_HEADERSvoidfatalf(const char *fmt,...){ va_list args; va_start(args, fmt);#elsevoidfatalf(va_alist) va_dcl{ va_list args; const char *fmt = NULL; va_start(args); fmt = va_arg(args, char *);#endif fatalvf(fmt, args); va_end(args);}/* used by fatalf */static voidfatalvf(const char *fmt, va_list args){ static char fatal_str[BUFSIZ]; vsnprintf(fatal_str, sizeof(fatal_str), fmt, args); fatal(fatal_str);}/* fatal with dumping core */voidfatal_dump(const char *message){ releaseServerSockets(); if (message) fatal_common(message); if (opt_catch_signals) storeDirWriteCleanLogs(0); abort();}voiddebug_trap(const char *message){ if (!opt_catch_signals) fatal_dump(message); _db_print("WARNING: %s\n", message);}voidsig_child(int sig){#ifdef _SQUID_NEXT_ union wait status;#else int status;#endif pid_t pid; do {#ifdef _SQUID_NEXT_ pid = wait3(&status, WNOHANG, NULL);#else pid = waitpid(-1, &status, WNOHANG);#endif /* no debug() here; bad things happen if the signal is delivered during _db_print() */#if HAVE_SIGACTION } while (pid > 0);#else } while (pid > 0 || (pid < 0 && errno == EINTR)); signal(sig, sig_child);#endif}const char *getMyHostname(void){ LOCAL_ARRAY(char, host, SQUIDHOSTNAMELEN + 1); static int present = 0; const struct hostent *h = NULL; char *t = NULL; if ((t = Config.visibleHostname) != NULL) return t; /* Get the host name and store it in host to return */ if (!present) { host[0] = '\0'; if (gethostname(host, SQUIDHOSTNAMELEN) == -1) { debug(50, 1) ("getMyHostname: gethostname failed: %s\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -