? ChangeLog.cvs Index: src/main.c =================================================================== RCS file: /server/cvs-server/squid/squid/src/main.c,v retrieving revision 1.345.2.22 diff -u -p -r1.345.2.22 main.c --- src/main.c 19 Mar 2005 23:56:23 -0000 1.345.2.22 +++ src/main.c 5 Apr 2005 22:12:50 -0000 @@ -1021,11 +1021,7 @@ SquidShutdown(void *unused) #if MEM_GEN_TRACE log_trace_done(); #endif - if (Config.pidFilename && strcmp(Config.pidFilename, "none") != 0) { - enter_suid(); - safeunlink(Config.pidFilename, 0); - leave_suid(); - } + removePidFile(); debug(1, 1) ("Squid Cache (Version %s): Exiting normally.\n", version_string); if (debug_log) Index: src/protos.h =================================================================== RCS file: /server/cvs-server/squid/squid/src/protos.h,v retrieving revision 1.420.2.32 diff -u -p -r1.420.2.32 protos.h --- src/protos.h 3 Apr 2005 23:08:48 -0000 1.420.2.32 +++ src/protos.h 5 Apr 2005 22:12:50 -0000 @@ -1067,13 +1067,14 @@ extern void leave_suid(void); extern void enter_suid(void); extern void no_suid(void); extern void writePidFile(void); +extern pid_t readPidFile(void); +extern void removePidFile(void); extern void setSocketShutdownLifetimes(int); extern void setMaxFD(void); extern time_t getCurrentTime(void); extern int percent(int, int); extern double dpercent(double, double); extern void squid_signal(int sig, SIGHDLR *, int flags); -extern pid_t readPidFile(void); extern struct in_addr inaddrFromHostent(const struct hostent *hp); extern int intAverage(int, int, int, int); extern double doubleAverage(double, double, int, int); Index: src/tools.c =================================================================== RCS file: /server/cvs-server/squid/squid/src/tools.c,v retrieving revision 1.213.2.14 diff -u -p -r1.213.2.14 tools.c --- src/tools.c 26 Mar 2005 23:27:10 -0000 1.213.2.14 +++ src/tools.c 5 Apr 2005 22:12:50 -0000 @@ -585,6 +585,7 @@ no_suid(void) #endif } +static int pid_file_fd = -1; void writePidFile(void) { @@ -596,6 +597,9 @@ writePidFile(void) return; if (!strcmp(Config.pidFilename, "none")) return; + if (pid_file_fd > 0) + file_close(pid_file_fd); + pid_file_fd = -1; enter_suid(); old_umask = umask(022); fd = file_open(f, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT); @@ -606,9 +610,22 @@ writePidFile(void) debug_trap("Could not write pid file"); return; } +#ifdef F_SETLK + { + struct flock lk; + memset(&lk, 0, sizeof(lk)); + lk.l_type = F_WRLCK; + lk.l_whence = SEEK_SET; + if (fcntl(fd, F_SETLK, &lk) != 0) { + debug_trap("PID file in use\n"); + file_close(fd); + return; + } + } +#endif snprintf(buf, 32, "%d\n", (int) getpid()); FD_WRITE_METHOD(fd, buf, strlen(buf)); - file_close(fd); + pid_file_fd = fd; } @@ -625,21 +642,50 @@ readPidFile(void) exit(1); } pid_fp = fopen(f, "r"); - if (pid_fp != NULL) { - pid = 0; - if (fscanf(pid_fp, "%d", &i) == 1) - pid = (pid_t) i; - fclose(pid_fp); - } else { + if (pid_fp == NULL) { if (errno != ENOENT) { fprintf(stderr, "%s: ERROR: Could not read pid file\n", appname); fprintf(stderr, "\t%s: %s\n", f, xstrerror()); exit(1); } + return 0; } +#ifdef F_GETLK + { + struct flock lk; + memset(&lk, 0, sizeof(lk)); + lk.l_type = F_WRLCK; + lk.l_whence = SEEK_SET; + fcntl(fileno(pid_fp), F_GETLK, &lk); + if (lk.l_type == F_UNLCK) { + fclose(pid_fp); + return 0; + } + } +#endif + pid = 0; + if (fscanf(pid_fp, "%d", &i) == 1) + pid = (pid_t) i; + fclose(pid_fp); return pid; } +void +removePidFile(void) +{ + const char *f = NULL; + if ((f = Config.pidFilename) == NULL) + return; + if (!strcmp(Config.pidFilename, "none")) + return; + if (pid_file_fd > 0) { + file_close(pid_file_fd); + pid_file_fd = -1; + enter_suid(); + safeunlink(Config.pidFilename, 0); + leave_suid(); + } +} void setMaxFD(void)