]>
Commit | Line | Data |
---|---|---|
94e891ea | 1 | |
30a4f2a8 | 2 | /* |
0b6d1622 | 3 | * $Id: tools.cc,v 1.75 1996/10/19 00:13:24 wessels Exp $ |
30a4f2a8 | 4 | * |
5 | * DEBUG: section 21 Misc Functions | |
6 | * AUTHOR: Harvest Derived | |
7 | * | |
8 | * SQUID Internet Object Cache http://www.nlanr.net/Squid/ | |
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 | */ | |
019dd986 | 31 | |
32 | /* | |
30a4f2a8 | 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. | |
019dd986 | 105 | */ |
44a47c6e | 106 | |
107 | #include "squid.h" | |
108 | ||
090089c4 | 109 | int do_mallinfo = 0; /* don't do mallinfo() unless this gets set */ |
b8de7ebe | 110 | time_t squid_curtime; |
3a57089e | 111 | struct timeval current_time; |
090089c4 | 112 | |
090089c4 | 113 | #define DEAD_MSG "\ |
c5c666ab | 114 | The Squid Cache (version %s) died.\n\ |
090089c4 | 115 | \n\ |
c5c666ab | 116 | You've encountered a fatal error in the Squid Cache version %s.\n\ |
090089c4 | 117 | If a core file was created (possibly in the swap directory),\n\ |
b8de7ebe | 118 | please execute 'gdb squid core' or 'dbx squid core', then type 'where',\n\ |
234967c9 | 119 | and report the trace back to squid-bugs@nlanr.net.\n\ |
090089c4 | 120 | \n\ |
121 | Thanks!\n" | |
122 | ||
24382924 | 123 | static void fatal_common _PARAMS((char *)); |
124 | static void mail_warranty _PARAMS((void)); | |
125 | ||
b8d8561b | 126 | static char * |
0673c0ba | 127 | dead_msg(void) |
090089c4 | 128 | { |
95d659f0 | 129 | LOCAL_ARRAY(char, msg, 1024); |
8213067d | 130 | sprintf(msg, DEAD_MSG, version_string, version_string); |
090089c4 | 131 | return msg; |
132 | } | |
133 | ||
24382924 | 134 | static void |
0673c0ba | 135 | mail_warranty(void) |
090089c4 | 136 | { |
019dd986 | 137 | FILE *fp = NULL; |
6e40f263 | 138 | char *filename; |
139 | static char command[256]; | |
140 | if ((filename = tempnam(NULL, appname)) == NULL) | |
141 | return; | |
142 | if ((fp = fopen(filename, "w")) == NULL) | |
143 | return; | |
144 | fprintf(fp, "From: %s\n", appname); | |
edae7bc0 | 145 | fprintf(fp, "To: %s\n", Config.adminEmail); |
6e40f263 | 146 | fprintf(fp, "Subject: %s\n", dead_msg()); |
147 | fclose(fp); | |
edae7bc0 | 148 | sprintf(command, "mail %s < %s", Config.adminEmail, filename); |
6e40f263 | 149 | system(command); /* XXX should avoid system(3) */ |
150 | unlink(filename); | |
090089c4 | 151 | } |
152 | ||
b8d8561b | 153 | static void |
154 | dumpMallocStats(FILE * f) | |
3f43b19b | 155 | { |
156 | #if HAVE_MALLINFO | |
157 | struct mallinfo mp; | |
30a4f2a8 | 158 | int t; |
3f43b19b | 159 | if (!do_mallinfo) |
160 | return; | |
3f43b19b | 161 | mp = mallinfo(); |
30a4f2a8 | 162 | fprintf(f, "Memory usage for %s via mallinfo():\n", appname); |
163 | fprintf(f, "\ttotal space in arena: %6d KB\n", | |
164 | mp.arena >> 10); | |
165 | fprintf(f, "\tOrdinary blocks: %6d KB %6d blks\n", | |
166 | mp.uordblks >> 10, mp.ordblks); | |
167 | fprintf(f, "\tSmall blocks: %6d KB %6d blks\n", | |
168 | mp.usmblks >> 10, mp.smblks); | |
169 | fprintf(f, "\tHolding blocks: %6d KB %6d blks\n", | |
170 | mp.hblkhd >> 10, mp.hblks); | |
171 | fprintf(f, "\tFree Small blocks: %6d KB\n", | |
172 | mp.fsmblks >> 10); | |
173 | fprintf(f, "\tFree Ordinary blocks: %6d KB\n", | |
174 | mp.fordblks >> 10); | |
175 | t = mp.uordblks + mp.usmblks + mp.hblkhd; | |
176 | fprintf(f, "\tTotal in use: %6d KB %d%%\n", | |
177 | t >> 10, percent(t, mp.arena)); | |
178 | t = mp.fsmblks + mp.fordblks; | |
179 | fprintf(f, "\tTotal free: %6d KB %d%%\n", | |
180 | t >> 10, percent(t, mp.arena)); | |
181 | #ifdef WE_DONT_USE_KEEP | |
182 | fprintf(f, "\tKeep option: %6d KB\n", | |
183 | mp.keepcost >> 10); | |
184 | #endif | |
46c883ed | 185 | #if HAVE_EXT_MALLINFO |
30a4f2a8 | 186 | fprintf(f, "\tmax size of small blocks:\t%d\n", |
187 | mp.mxfast); | |
188 | fprintf(f, "\tnumber of small blocks in a holding block:\t%d\n", | |
3f43b19b | 189 | mp.nlblks); |
30a4f2a8 | 190 | fprintf(f, "\tsmall block rounding factor:\t%d\n", |
191 | mp.grain); | |
192 | fprintf(f, "\tspace (including overhead) allocated in ord. blks:\t%d\n", | |
3f43b19b | 193 | mp.uordbytes); |
30a4f2a8 | 194 | fprintf(f, "\tnumber of ordinary blocks allocated:\t%d\n", |
3f43b19b | 195 | mp.allocated); |
30a4f2a8 | 196 | fprintf(f, "\tbytes used in maintaining the free tree:\t%d\n", |
3f43b19b | 197 | mp.treeoverhead); |
46c883ed | 198 | #endif /* HAVE_EXT_MALLINFO */ |
3f43b19b | 199 | #if PRINT_MMAP |
200 | mallocmap(); | |
201 | #endif /* PRINT_MMAP */ | |
202 | #endif /* HAVE_MALLINFO */ | |
203 | } | |
30a4f2a8 | 204 | |
b8d8561b | 205 | static int |
ff8d0ea6 | 206 | PrintRusage(void (*f) (void), FILE * lf) |
f0f81709 | 207 | { |
30a4f2a8 | 208 | #if HAVE_GETRUSAGE && defined(RUSAGE_SELF) |
f0f81709 | 209 | struct rusage rusage; |
210 | getrusage(RUSAGE_SELF, &rusage); | |
30a4f2a8 | 211 | fprintf(lf, "CPU Usage: user %d sys %d\n", |
212 | (int) rusage.ru_utime.tv_sec, (int) rusage.ru_stime.tv_sec); | |
213 | fprintf(lf, "Memory Usage: rss %ld KB\n", | |
214 | rusage.ru_maxrss * getpagesize() >> 10); | |
215 | fprintf(lf, "Page faults with physical i/o: %ld\n", | |
f0f81709 | 216 | rusage.ru_majflt); |
217 | #endif | |
218 | dumpMallocStats(lf); | |
219 | if (f) | |
ff8d0ea6 | 220 | f(); |
f0f81709 | 221 | return 0; |
222 | } | |
223 | ||
b8d8561b | 224 | void |
225 | death(int sig) | |
44a47c6e | 226 | { |
0e08ce4b | 227 | if (sig == SIGSEGV) |
2c47cf74 | 228 | fprintf(debug_log, "FATAL: Received Segment Violation...dying.\n"); |
0e08ce4b | 229 | else if (sig == SIGBUS) |
6e40f263 | 230 | fprintf(debug_log, "FATAL: Received Bus Error...dying.\n"); |
0e08ce4b | 231 | else |
2c47cf74 | 232 | fprintf(debug_log, "FATAL: Received signal %d...dying.\n", sig); |
6e40f263 | 233 | #if SA_RESETHAND == 0 |
44a47c6e | 234 | signal(SIGSEGV, SIG_DFL); |
235 | signal(SIGBUS, SIG_DFL); | |
0e08ce4b | 236 | signal(sig, SIG_DFL); |
30a4f2a8 | 237 | #endif |
44a47c6e | 238 | storeWriteCleanLog(); |
2c47cf74 | 239 | PrintRusage(NULL, debug_log); |
6e40f263 | 240 | if (squid_curtime - SQUID_RELEASE_TIME < 864000) { |
241 | /* skip if more than 10 days old */ | |
edae7bc0 | 242 | if (Config.adminEmail) |
6e40f263 | 243 | mail_warranty(); |
244 | else | |
245 | puts(dead_msg()); | |
246 | } | |
44a47c6e | 247 | abort(); |
248 | } | |
249 | ||
250 | ||
b8d8561b | 251 | void |
252 | sigusr2_handle(int sig) | |
090089c4 | 253 | { |
30a4f2a8 | 254 | static int state = 0; |
255 | debug(21, 1, "sigusr2_handle: SIGUSR2 received.\n"); | |
256 | if (state == 0) { | |
b6f794d6 | 257 | _db_init(Config.Log.log, "ALL,10"); |
30a4f2a8 | 258 | state = 1; |
259 | } else { | |
b6f794d6 | 260 | _db_init(Config.Log.log, Config.debugOptions); |
30a4f2a8 | 261 | state = 0; |
262 | } | |
263 | #if !HAVE_SIGACTION | |
264 | signal(sig, sigusr2_handle); /* reinstall */ | |
090089c4 | 265 | #endif |
266 | } | |
267 | ||
b8d8561b | 268 | void |
f3753518 | 269 | setSocketShutdownLifetimes(int lft) |
30a4f2a8 | 270 | { |
271 | FD_ENTRY *f = NULL; | |
30a4f2a8 | 272 | int cur; |
273 | int i; | |
274 | for (i = fdstat_biggest_fd(); i >= 0; i--) { | |
275 | f = &fd_table[i]; | |
276 | if (!f->read_handler && !f->write_handler && !f->except_handler) | |
277 | continue; | |
278 | if (fdstatGetType(i) != FD_SOCKET) | |
279 | continue; | |
280 | cur = comm_get_fd_lifetime(i); | |
281 | if (cur > 0 && (cur - squid_curtime) <= lft) | |
282 | continue; | |
283 | comm_set_fd_lifetime(i, lft); | |
284 | } | |
285 | } | |
286 | ||
b8d8561b | 287 | void |
0673c0ba | 288 | normal_shutdown(void) |
4d64d74a | 289 | { |
290 | debug(21, 1, "Shutting down...\n"); | |
b6f794d6 | 291 | if (Config.pidFilename) { |
30a4f2a8 | 292 | enter_suid(); |
b6f794d6 | 293 | safeunlink(Config.pidFilename, 0); |
30a4f2a8 | 294 | leave_suid(); |
234967c9 | 295 | } |
4d64d74a | 296 | storeWriteCleanLog(); |
297 | PrintRusage(NULL, debug_log); | |
457bedbd | 298 | storeCloseLog(); |
299 | statCloseLog(); | |
0a21bd84 | 300 | configFreeMemory(); |
301 | diskFreeMemory(); | |
302 | storeFreeMemory(); | |
303 | commFreeMemory(); | |
304 | filemapFreeMemory(); | |
305 | dnsFreeMemory(); | |
306 | redirectFreeMemory(); | |
307 | fdstatFreeMemory(); | |
308 | errorpageFreeMemory(); | |
309 | stmemFreeMemory(); | |
e5f6c5c2 | 310 | netdbFreeMemory(); |
56e15c50 | 311 | ipcacheFreeMemory(); |
312 | fqdncacheFreeMemory(); | |
0a21bd84 | 313 | debug(21, 0, "Squid Cache (Version %s): Exiting normally.\n", |
314 | version_string); | |
c7433536 | 315 | fclose(debug_log); |
4d64d74a | 316 | exit(0); |
317 | } | |
147d3115 | 318 | |
24382924 | 319 | static void |
b8d8561b | 320 | fatal_common(char *message) |
090089c4 | 321 | { |
db40ae20 | 322 | #if HAVE_SYSLOG |
6e40f263 | 323 | if (opt_syslog_enable) |
233794cd | 324 | syslog(LOG_ALERT, "%s", message); |
db40ae20 | 325 | #endif |
2c47cf74 | 326 | fprintf(debug_log, "FATAL: %s\n", message); |
c5c666ab | 327 | fprintf(debug_log, "Squid Cache (Version %s): Terminated abnormally.\n", |
8213067d | 328 | version_string); |
2c47cf74 | 329 | fflush(debug_log); |
330 | PrintRusage(NULL, debug_log); | |
090089c4 | 331 | } |
332 | ||
333 | /* fatal */ | |
b8d8561b | 334 | void |
335 | fatal(char *message) | |
090089c4 | 336 | { |
337 | fatal_common(message); | |
338 | exit(1); | |
339 | } | |
340 | ||
341 | /* fatal with dumping core */ | |
b8d8561b | 342 | void |
343 | fatal_dump(char *message) | |
090089c4 | 344 | { |
345 | if (message) | |
346 | fatal_common(message); | |
0b6d1622 | 347 | if (!opt_catch_signals) |
090089c4 | 348 | storeWriteCleanLog(); |
349 | abort(); | |
350 | } | |
351 | ||
85b701ed | 352 | /* fatal with dumping core */ |
b8d8561b | 353 | void |
354 | _debug_trap(char *message) | |
85b701ed | 355 | { |
356 | if (opt_catch_signals) | |
357 | fatal_dump(message); | |
fedac7e5 | 358 | _db_print(0, 0, "WARNING: %s\n", message); |
85b701ed | 359 | } |
360 | ||
b8d8561b | 361 | void |
362 | sig_child(int sig) | |
090089c4 | 363 | { |
30a4f2a8 | 364 | #ifdef _SQUID_NEXT_ |
365 | union wait status; | |
366 | #else | |
090089c4 | 367 | int status; |
090089c4 | 368 | #endif |
ff8d0ea6 | 369 | pid_t pid; |
090089c4 | 370 | |
30a4f2a8 | 371 | do { |
372 | #ifdef _SQUID_NEXT_ | |
373 | pid = wait3(&status, WNOHANG, NULL); | |
090089c4 | 374 | #else |
30a4f2a8 | 375 | pid = waitpid(-1, &status, WNOHANG); |
090089c4 | 376 | #endif |
30a4f2a8 | 377 | debug(21, 3, "sig_child: Ate pid %d\n", pid); |
378 | #if HAVE_SIGACTION | |
379 | } while (pid > 0); | |
234967c9 | 380 | #else |
30a4f2a8 | 381 | } while (pid > 0 || (pid < 0 && errno == EINTR)); |
382 | signal(sig, sig_child); | |
234967c9 | 383 | #endif |
30a4f2a8 | 384 | } |
44a47c6e | 385 | |
b8d8561b | 386 | char * |
0673c0ba | 387 | getMyHostname(void) |
44a47c6e | 388 | { |
95d659f0 | 389 | LOCAL_ARRAY(char, host, SQUIDHOSTNAMELEN + 1); |
44a47c6e | 390 | static int present = 0; |
391 | struct hostent *h = NULL; | |
019dd986 | 392 | char *t = NULL; |
393 | ||
b6f794d6 | 394 | if ((t = Config.visibleHostname)) |
019dd986 | 395 | return t; |
44a47c6e | 396 | |
397 | /* Get the host name and store it in host to return */ | |
398 | if (!present) { | |
399 | host[0] = '\0'; | |
400 | if (gethostname(host, SQUIDHOSTNAMELEN) == -1) { | |
019dd986 | 401 | debug(21, 1, "getMyHostname: gethostname failed: %s\n", |
44a47c6e | 402 | xstrerror()); |
403 | return NULL; | |
404 | } else { | |
e5f6c5c2 | 405 | if ((h = gethostbyname(host)) != NULL) { |
44a47c6e | 406 | /* DNS lookup successful */ |
407 | /* use the official name from DNS lookup */ | |
408 | strcpy(host, h->h_name); | |
409 | } | |
410 | present = 1; | |
411 | } | |
412 | } | |
413 | return host; | |
414 | } | |
415 | ||
b8d8561b | 416 | int |
417 | safeunlink(char *s, int quiet) | |
44a47c6e | 418 | { |
419 | int err; | |
420 | if ((err = unlink(s)) < 0) | |
421 | if (!quiet) | |
019dd986 | 422 | debug(21, 1, "safeunlink: Couldn't delete %s. %s\n", s, xstrerror()); |
44a47c6e | 423 | return (err); |
424 | } | |
12b9e9b1 | 425 | |
30a4f2a8 | 426 | /* leave a privilegied section. (Give up any privilegies) |
427 | * Routines that need privilegies can rap themselves in enter_suid() | |
428 | * and leave_suid() | |
429 | * To give upp all posibilites to gain privilegies use no_suid() | |
12b9e9b1 | 430 | */ |
b8d8561b | 431 | void |
0673c0ba | 432 | leave_suid(void) |
12b9e9b1 | 433 | { |
434 | struct passwd *pwd = NULL; | |
435 | struct group *grp = NULL; | |
30a4f2a8 | 436 | debug(21, 3, "leave_suid: PID %d called\n", getpid()); |
12b9e9b1 | 437 | if (geteuid() != 0) |
438 | return; | |
439 | /* Started as a root, check suid option */ | |
b6f794d6 | 440 | if (Config.effectiveUser == NULL) |
12b9e9b1 | 441 | return; |
b6f794d6 | 442 | if ((pwd = getpwnam(Config.effectiveUser)) == NULL) |
12b9e9b1 | 443 | return; |
b6f794d6 | 444 | if (Config.effectiveGroup && (grp = getgrnam(Config.effectiveGroup))) { |
12b9e9b1 | 445 | setgid(grp->gr_gid); |
446 | } else { | |
447 | setgid(pwd->pw_gid); | |
448 | } | |
30a4f2a8 | 449 | debug(21, 3, "leave_suid: PID %d giving up root, becoming '%s'\n", |
450 | getpid(), pwd->pw_name); | |
234967c9 | 451 | #if HAVE_SETRESUID |
452 | setresuid(pwd->pw_uid, pwd->pw_uid, 0); | |
453 | #elif HAVE_SETEUID | |
454 | seteuid(pwd->pw_uid); | |
455 | #else | |
12b9e9b1 | 456 | setuid(pwd->pw_uid); |
234967c9 | 457 | #endif |
458 | } | |
459 | ||
30a4f2a8 | 460 | /* Enter a privilegied section */ |
b8d8561b | 461 | void |
0673c0ba | 462 | enter_suid(void) |
234967c9 | 463 | { |
30a4f2a8 | 464 | debug(21, 3, "enter_suid: PID %d taking root priveleges\n", getpid()); |
234967c9 | 465 | #if HAVE_SETRESUID |
466 | setresuid(-1, 0, -1); | |
467 | #else | |
468 | setuid(0); | |
469 | #endif | |
470 | } | |
471 | ||
30a4f2a8 | 472 | /* Give up the posibility to gain privilegies. |
473 | * this should be used before starting a sub process | |
474 | */ | |
b8d8561b | 475 | void |
0673c0ba | 476 | no_suid(void) |
234967c9 | 477 | { |
478 | uid_t uid; | |
30a4f2a8 | 479 | leave_suid(); |
234967c9 | 480 | uid = geteuid(); |
30a4f2a8 | 481 | debug(21, 3, "leave_suid: PID %d giving up root priveleges forever\n", getpid()); |
234967c9 | 482 | #if HAVE_SETRESUID |
483 | setresuid(uid, uid, uid); | |
484 | #else | |
485 | setuid(0); | |
486 | setuid(uid); | |
487 | #endif | |
12b9e9b1 | 488 | } |
ccff9601 | 489 | |
b8d8561b | 490 | void |
0673c0ba | 491 | writePidFile(void) |
ccff9601 | 492 | { |
493 | FILE *pid_fp = NULL; | |
494 | char *f = NULL; | |
495 | ||
b6f794d6 | 496 | if ((f = Config.pidFilename) == NULL) |
ccff9601 | 497 | return; |
30a4f2a8 | 498 | enter_suid(); |
499 | pid_fp = fopen(f, "w"); | |
500 | leave_suid(); | |
501 | if (pid_fp != NULL) { | |
502 | fprintf(pid_fp, "%d\n", (int) getpid()); | |
503 | fclose(pid_fp); | |
504 | } else { | |
019dd986 | 505 | debug(21, 0, "WARNING: Could not write pid file\n"); |
506 | debug(21, 0, " %s: %s\n", f, xstrerror()); | |
ccff9601 | 507 | } |
ccff9601 | 508 | } |
c4fb974e | 509 | |
510 | ||
ff8d0ea6 | 511 | pid_t |
0673c0ba | 512 | readPidFile(void) |
7690e8eb | 513 | { |
514 | FILE *pid_fp = NULL; | |
515 | char *f = NULL; | |
ff8d0ea6 | 516 | pid_t pid = -1; |
517 | int i; | |
7690e8eb | 518 | |
519 | if ((f = Config.pidFilename) == NULL) { | |
520 | fprintf(stderr, "%s: ERROR: No pid file name defined\n", appname); | |
521 | exit(1); | |
522 | } | |
523 | pid_fp = fopen(f, "r"); | |
524 | if (pid_fp != NULL) { | |
ff8d0ea6 | 525 | pid = 0; |
526 | if (fscanf(pid_fp, "%d", &i) == 1) | |
527 | pid = (pid_t) i; | |
7690e8eb | 528 | fclose(pid_fp); |
529 | } else { | |
530 | if (errno != ENOENT) { | |
531 | fprintf(stderr, "%s: ERROR: Could not read pid file\n", appname); | |
532 | fprintf(stderr, "\t%s: %s\n", f, xstrerror()); | |
533 | exit(1); | |
534 | } | |
535 | } | |
536 | return pid; | |
537 | } | |
538 | ||
539 | ||
b8d8561b | 540 | void |
0673c0ba | 541 | setMaxFD(void) |
c4fb974e | 542 | { |
234967c9 | 543 | #if HAVE_SETRLIMIT |
c4fb974e | 544 | /* try to use as many file descriptors as possible */ |
545 | /* System V uses RLIMIT_NOFILE and BSD uses RLIMIT_OFILE */ | |
546 | struct rlimit rl; | |
547 | #if defined(RLIMIT_NOFILE) | |
548 | if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { | |
a8f7d3ee | 549 | debug(21, 0, "setrlimit: RLIMIT_NOFILE: %s\n", xstrerror()); |
c4fb974e | 550 | } else { |
234967c9 | 551 | rl.rlim_cur = FD_SETSIZE; |
30a4f2a8 | 552 | if (rl.rlim_cur > rl.rlim_max) |
553 | rl.rlim_cur = rl.rlim_max; | |
c4fb974e | 554 | if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { |
234967c9 | 555 | sprintf(tmp_error_buf, "setrlimit: RLIMIT_NOFILE: %s", xstrerror()); |
556 | fatal_dump(tmp_error_buf); | |
c4fb974e | 557 | } |
558 | } | |
559 | #elif defined(RLIMIT_OFILE) | |
560 | if (getrlimit(RLIMIT_OFILE, &rl) < 0) { | |
a8f7d3ee | 561 | debug(21, 0, "setrlimit: RLIMIT_NOFILE: %s\n", xstrerror()); |
c4fb974e | 562 | } else { |
234967c9 | 563 | rl.rlim_cur = FD_SETSIZE; |
30a4f2a8 | 564 | if (rl.rlim_cur > rl.rlim_max) |
565 | rl.rlim_cur = rl.rlim_max; | |
c4fb974e | 566 | if (setrlimit(RLIMIT_OFILE, &rl) < 0) { |
234967c9 | 567 | sprintf(tmp_error_buf, "setrlimit: RLIMIT_OFILE: %s", xstrerror()); |
568 | fatal_dump(tmp_error_buf); | |
c4fb974e | 569 | } |
570 | } | |
571 | #endif | |
c4fb974e | 572 | #else /* HAVE_SETRLIMIT */ |
a8f7d3ee | 573 | debug(21, 1, "setMaxFD: Cannot increase: setrlimit() not supported on this system\n"); |
30a4f2a8 | 574 | #endif /* HAVE_SETRLIMIT */ |
575 | ||
576 | #if HAVE_SETRLIMIT && defined(RLIMIT_DATA) | |
577 | if (getrlimit(RLIMIT_DATA, &rl) < 0) { | |
a8f7d3ee | 578 | debug(21, 0, "getrlimit: RLIMIT_DATA: %s\n", xstrerror()); |
30a4f2a8 | 579 | } else { |
580 | rl.rlim_cur = rl.rlim_max; /* set it to the max */ | |
581 | if (setrlimit(RLIMIT_DATA, &rl) < 0) { | |
582 | sprintf(tmp_error_buf, "setrlimit: RLIMIT_DATA: %s", xstrerror()); | |
583 | fatal_dump(tmp_error_buf); | |
584 | } | |
585 | } | |
586 | #endif /* RLIMIT_DATA */ | |
c4fb974e | 587 | } |
3a57089e | 588 | |
b8d8561b | 589 | time_t |
0673c0ba | 590 | getCurrentTime(void) |
3a57089e | 591 | { |
94e891ea | 592 | #if GETTIMEOFDAY_NO_TZP |
30a4f2a8 | 593 | gettimeofday(¤t_time); |
594 | #else | |
d598947a | 595 | gettimeofday(¤t_time, NULL); |
5f3f8d0e | 596 | #endif |
30a4f2a8 | 597 | return squid_curtime = current_time.tv_sec; |
5f3f8d0e | 598 | } |
fe113054 | 599 | |
b8d8561b | 600 | int |
601 | percent(int a, int b) | |
30a4f2a8 | 602 | { |
603 | return b ? ((int) (100.0 * a / b + 0.5)) : 0; | |
604 | } | |
605 | ||
b8d8561b | 606 | void |
67508012 | 607 | squid_signal(int sig, void (*func) _PARAMS((int)), int flags) |
30a4f2a8 | 608 | { |
609 | #if HAVE_SIGACTION | |
610 | struct sigaction sa; | |
611 | sa.sa_handler = func; | |
612 | sa.sa_flags = flags; | |
613 | sigemptyset(&sa.sa_mask); | |
614 | if (sigaction(sig, &sa, NULL) < 0) | |
615 | debug(1, 0, "sigaction: sig=%d func=%p: %s\n", sig, func, xstrerror()); | |
616 | #else | |
617 | (void) signal(sig, func); | |
618 | #endif | |
619 | } | |
396c5745 | 620 | |
16b204c4 | 621 | struct in_addr |
622 | inaddrFromHostent(struct hostent *hp) | |
623 | { | |
cc6a9d2e | 624 | struct in_addr s; |
3c0117c9 | 625 | xmemcpy(&s.s_addr, hp->h_addr, sizeof(s.s_addr)); |
cc6a9d2e | 626 | return s; |
16b204c4 | 627 | } |