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); +}