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
This commit is contained in:
Kyle Evans
2025-06-24 18:03:14 -05:00
parent 7e8afac0cb
commit 679f619495
2 changed files with 25 additions and 2 deletions
+17 -1
View File
@@ -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,
+8 -1
View File
@@ -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)