summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2011-10-16 21:30:15 +0000
committerpjd <pjd@FreeBSD.org>2011-10-16 21:30:15 +0000
commit770f64229ce141801d6971ceea42082015323a53 (patch)
tree7dd9db17078c6dc0d10bafacfead86efc28d0572
parent2cd40fe2b68029b4e3872631ccfea41808316a14 (diff)
downloadFreeBSD-src-770f64229ce141801d6971ceea42082015323a53.zip
FreeBSD-src-770f64229ce141801d6971ceea42082015323a53.tar.gz
In pidfile_open(), if the pidfile is locked, but empty (PID is not stored yet)
and the caller requested other process' PID by passing non-NULL pidptr argument, we will wait at most 100ms for the PID to show up in the file and if it won't, we will store -1 in *pidptr. From now on, pidfile_open() function never sets errno to EAGAIN on failure. In collaboration with: des MFC after: 1 week
-rw-r--r--lib/libutil/pidfile.325
-rw-r--r--lib/libutil/pidfile.c24
2 files changed, 27 insertions, 22 deletions
diff --git a/lib/libutil/pidfile.3 b/lib/libutil/pidfile.3
index cc2b4bb..c42b95b 100644
--- a/lib/libutil/pidfile.3
+++ b/lib/libutil/pidfile.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 20, 2008
+.Dd October 16, 2011
.Dt PIDFILE 3
.Os
.Sh NAME
@@ -59,11 +59,14 @@ The
function opens (or creates) a file specified by the
.Fa path
argument and locks it.
-If a file can not be locked, a PID of an already running daemon is returned in
-the
+If
.Fa pidptr
-argument (if it is not
-.Dv NULL ) .
+argument is not
+.Dv NULL
+and file can not be locked, the function will use it to store a PID of an
+already running daemon or
+.Li -1
+in case daemon did not write its PID yet.
The function does not write process' PID into the file here, so it can be
used before
.Fn fork Ns ing
@@ -162,16 +165,18 @@ function will fail if:
.It Bq Er EEXIST
Some process already holds the lock on the given pidfile, meaning that a
daemon is already running.
+If
+.Fa pidptr
+argument is not
+.Dv NULL
+the function will use it to store a PID of an already running daemon or
+.Li -1
+in case daemon did not write its PID yet.
.It Bq Er ENAMETOOLONG
Specified pidfile's name is too long.
.It Bq Er EINVAL
Some process already holds the lock on the given pidfile, but PID read
from there is invalid.
-.It Bq Er EAGAIN
-Some process already holds the lock on the given pidfile, but the file
-is truncated.
-Most likely, the existing daemon is writing new PID into
-the file.
.El
.Pp
The
diff --git a/lib/libutil/pidfile.c b/lib/libutil/pidfile.c
index 6b99936..953d1e0 100644
--- a/lib/libutil/pidfile.c
+++ b/lib/libutil/pidfile.c
@@ -119,20 +119,20 @@ pidfile_open(const char *path, mode_t mode, pid_t *pidptr)
fd = flopen(pfh->pf_path,
O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, mode);
if (fd == -1) {
- count = 0;
- rqtp.tv_sec = 0;
- rqtp.tv_nsec = 5000000;
if (errno == EWOULDBLOCK && pidptr != NULL) {
- again:
- errno = pidfile_read(pfh->pf_path, pidptr);
- if (errno == 0)
- errno = EEXIST;
- else if (errno == EAGAIN) {
- if (++count <= 3) {
- nanosleep(&rqtp, 0);
- goto again;
- }
+ count = 20;
+ rqtp.tv_sec = 0;
+ rqtp.tv_nsec = 5000000;
+ for (;;) {
+ errno = pidfile_read(pfh->pf_path, pidptr);
+ if (errno != EAGAIN || --count == 0)
+ break;
+ nanosleep(&rqtp, 0);
}
+ if (errno == EAGAIN)
+ *pidptr = -1;
+ if (errno == 0 || errno == EAGAIN)
+ errno = EEXIST;
}
free(pfh);
return (NULL);
OpenPOWER on IntegriCloud