Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Apr 2022 16:02:14 GMT
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 287451fd0192 - main - pidfile: add pidfile_signal
Message-ID:  <202204091602.239G2ECO032937@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=287451fd019299b138bab2ee99cdf0f3be495439

commit 287451fd019299b138bab2ee99cdf0f3be495439
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2022-03-11 11:01:50 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2022-04-09 15:59:43 +0000

    pidfile: add pidfile_signal
    
    Differential Revision:  https://reviews.freebsd.org/D34681
---
 lib/libutil/libutil.h |  1 +
 lib/libutil/pidfile.c | 76 +++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 62 insertions(+), 15 deletions(-)

diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h
index 17c44de0fce7..1ca22ce40e95 100644
--- a/lib/libutil/libutil.h
+++ b/lib/libutil/libutil.h
@@ -122,6 +122,7 @@ int	openpty(int *_amaster, int *_aslave, char *_name,
 	    struct termios *_termp, struct winsize *_winp);
 int	pidfile_close(struct pidfh *_pfh);
 int	pidfile_fileno(const struct pidfh *_pfh);
+int	pidfile_signal(const char *pathp, int sig, pid_t *pidptr);
 struct pidfh *
 	pidfile_open(const char *_path, mode_t _mode, pid_t *_pidptr);
 int	pidfile_remove(struct pidfh *_pfh);
diff --git a/lib/libutil/pidfile.c b/lib/libutil/pidfile.c
index eaa9379267db..33274849f06f 100644
--- a/lib/libutil/pidfile.c
+++ b/lib/libutil/pidfile.c
@@ -30,6 +30,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/types.h>
 #include <sys/capsicum.h>
 #include <sys/file.h>
 #include <sys/stat.h>
@@ -39,6 +40,7 @@ __FBSDID("$FreeBSD$");
 #include <fcntl.h>
 #include <libgen.h>
 #include <libutil.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -74,7 +76,7 @@ pidfile_verify(const struct pidfh *pfh)
 }
 
 static int
-pidfile_read(int dirfd, const char *filename, pid_t *pidptr)
+pidfile_read_impl(int dirfd, const char *filename, pid_t *pidptr)
 {
 	char buf[16], *endptr;
 	int error, fd, i;
@@ -99,14 +101,33 @@ pidfile_read(int dirfd, const char *filename, pid_t *pidptr)
 	return (0);
 }
 
+static int
+pidfile_read(int dirfd, const char *filename, pid_t *pidptr)
+{
+	struct timespec rqtp;
+	int count;
+
+	count = 20;
+	rqtp.tv_sec = 0;
+	rqtp.tv_nsec = 5000000;
+	for (;;) {
+		errno = pidfile_read_impl(dirfd, filename, pidptr);
+		if (errno != EAGAIN || --count == 0)
+			break;
+		nanosleep(&rqtp, 0);
+	}
+	if (errno == EAGAIN)
+		*pidptr = -1;
+	return (errno);
+}
+
 struct pidfh *
 pidfile_open(const char *pathp, mode_t mode, pid_t *pidptr)
 {
 	char path[MAXPATHLEN];
 	struct pidfh *pfh;
 	struct stat sb;
-	int error, fd, dirfd, dirlen, filenamelen, count;
-	struct timespec rqtp;
+	int error, fd, dirfd, dirlen, filenamelen;
 	cap_rights_t caprights;
 
 	pfh = malloc(sizeof(*pfh));
@@ -159,18 +180,8 @@ pidfile_open(const char *pathp, mode_t mode, pid_t *pidptr)
 			if (pidptr == NULL) {
 				errno = EEXIST;
 			} else {
-				count = 20;
-				rqtp.tv_sec = 0;
-				rqtp.tv_nsec = 5000000;
-				for (;;) {
-					errno = pidfile_read(dirfd,
-					    pfh->pf_filename, pidptr);
-					if (errno != EAGAIN || --count == 0)
-						break;
-					nanosleep(&rqtp, 0);
-				}
-				if (errno == EAGAIN)
-					*pidptr = -1;
+				errno = pidfile_read(dirfd,
+				    pfh->pf_filename, pidptr);
 				if (errno == 0 || errno == EAGAIN)
 					errno = EEXIST;
 			}
@@ -330,3 +341,38 @@ pidfile_fileno(const struct pidfh *pfh)
 	}
 	return (pfh->pf_fd);
 }
+
+int
+pidfile_signal(const char *pathp, int sig, pid_t *pidptr)
+{
+	pid_t pid;
+	int fd;
+
+	fd = flopenat(AT_FDCWD, pathp,
+	    O_RDONLY | O_CLOEXEC | O_NONBLOCK);
+	if (fd >= 0) {
+		/*
+		 * The file exists but is not locked,
+		 * so the daemon is dead. Nothing to do.
+		 */
+		close(fd);
+		errno = ENOENT;
+		return (errno);
+	}
+	if (errno != EWOULDBLOCK) {
+		return (errno);
+	}
+	errno = pidfile_read(AT_FDCWD, pathp, &pid);
+	if (errno != 0)
+		return (errno);
+	/*
+	 * Refuse to send broadcast or group signals, this has
+	 * happened due to the bugs in pidfile(3).
+	 */
+	if (pid <= 0)
+		return (EDOM);
+	kill(pid, sig);
+	if (pidptr != NULL)
+		*pidptr = pid;
+	return (errno);
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202204091602.239G2ECO032937>