git: 287451fd0192 - main - pidfile: add pidfile_signal
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 09 Apr 2022 16:02:14 UTC
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);
+}