The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=679f619495f67eafc9fdb97d11381b14f2b49ccf
commit 679f619495f67eafc9fdb97d11381b14f2b49ccf Author: Kyle Evans <kev...@freebsd.org> AuthorDate: 2025-06-24 23:03:14 +0000 Commit: Kyle Evans <kev...@freebsd.org> CommitDate: 2025-07-10 17:54:20 +0000 lockf: add a -T option to terminate the child upon early abort This is useful to avoid having the command running twice in the face of the admin terminating the process. Notably, if the -p option is not in use (or can't be used, e.g., because we can't open the file for writing) then this provides a nice alternative where one simply needs to send a SIGTERM to the lockf(1) process associated with the lock file to clean it all up. Reviewed by: des Differential Revision: https://reviews.freebsd.org/D51025 --- usr.bin/lockf/lockf.1 | 18 +++++++++++++++++- usr.bin/lockf/lockf.c | 9 ++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/usr.bin/lockf/lockf.1 b/usr.bin/lockf/lockf.1 index 5832903246f1..40b4497bc80c 100644 --- a/usr.bin/lockf/lockf.1 +++ b/usr.bin/lockf/lockf.1 @@ -30,7 +30,7 @@ .Nd execute a command while holding a file lock .Sh SYNOPSIS .Nm -.Op Fl knpsw +.Op Fl knpsTw .Op Fl t Ar seconds .Ar file .Ar command @@ -136,6 +136,22 @@ This option will cause to open .Ar file for writing rather than reading. +.It Fl T +Upon receipt of a +.Dv SIGTERM , +forward a +.Dv SIGTERM +along to the +.Ar command +before cleaning up the +.Ar file +and exiting. +By default, +.Nm +effectively orphans the +.Ar command +after cleaning up the +.Ar file . .It Fl t Ar seconds Specifies a timeout for waiting for the lock. By default, diff --git a/usr.bin/lockf/lockf.c b/usr.bin/lockf/lockf.c index 19424418ed68..b0e16285998a 100644 --- a/usr.bin/lockf/lockf.c +++ b/usr.bin/lockf/lockf.c @@ -35,6 +35,7 @@ #include <limits.h> #include <signal.h> #include <stdatomic.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -64,6 +65,7 @@ static int lockfd = -1; static int keep; static int fdlock; static int status; +static bool termchild; static volatile sig_atomic_t timed_out; /* @@ -109,7 +111,7 @@ main(int argc, char **argv) silent = keep = writepid = 0; flags = O_CREAT | O_RDONLY; waitsec = -1; /* Infinite. */ - while ((ch = getopt(argc, argv, "knpst:w")) != -1) { + while ((ch = getopt(argc, argv, "knpsTt:w")) != -1) { switch (ch) { case 'k': keep = 1; @@ -120,6 +122,9 @@ main(int argc, char **argv) case 's': silent = 1; break; + case 'T': + termchild = true; + break; case 't': { const char *errstr; @@ -356,6 +361,8 @@ static void killed(int sig) { + if (termchild && child >= 0) + kill(child, sig); cleanup(); signal(sig, SIG_DFL); if (kill(getpid(), sig) == -1)