? 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)
