diff options
Diffstat (limited to 'lib/libutil/pidfile.c')
-rw-r--r-- | lib/libutil/pidfile.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/lib/libutil/pidfile.c b/lib/libutil/pidfile.c index 983d103..ecf0fac 100644 --- a/lib/libutil/pidfile.c +++ b/lib/libutil/pidfile.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #include <fcntl.h> #include <string.h> +#include <time.h> #include <err.h> #include <errno.h> #include <libutil.h> @@ -74,6 +75,8 @@ pidfile_read(const char *path, pid_t *pidptr) close(fd); if (i == -1) return (error); + else if (i == 0) + return (EAGAIN); buf[i] = '\0'; *pidptr = strtol(buf, &endptr, 10); @@ -88,7 +91,8 @@ pidfile_open(const char *path, mode_t mode, pid_t *pidptr) { struct pidfh *pfh; struct stat sb; - int error, fd, len; + int error, fd, len, count; + struct timespec rqtp; pfh = malloc(sizeof(*pfh)); if (pfh == NULL) @@ -115,10 +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; + } + } } free(pfh); return (NULL); |