diff --git a/usr.bin/lockf/lockf.1 b/usr.bin/lockf/lockf.1 --- a/usr.bin/lockf/lockf.1 +++ b/usr.bin/lockf/lockf.1 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 25, 2023 +.Dd June 24, 2025 .Dt LOCKF 1 .Os .Sh NAME @@ -30,7 +30,7 @@ .Nd execute a command while holding a file lock .Sh SYNOPSIS .Nm -.Op Fl knsw +.Op Fl knpsw .Op Fl t Ar seconds .Ar file .Ar command @@ -126,6 +126,16 @@ will create .Ar file if necessary. +.It Fl p +Write the pid of the +.Ar command +to +.Ar file . +This option will cause +.Nm +to open +.Ar file +for writing rather than reading. .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 --- a/usr.bin/lockf/lockf.c +++ b/usr.bin/lockf/lockf.c @@ -91,15 +91,15 @@ int main(int argc, char **argv) { - int ch, flags, silent, status; + int ch, flags, silent, status, writepid; long long waitsec; pid_t child; union lock_subject subj; - silent = keep = 0; + silent = keep = writepid = 0; flags = O_CREAT | O_RDONLY; waitsec = -1; /* Infinite. */ - while ((ch = getopt(argc, argv, "knst:w")) != -1) { + while ((ch = getopt(argc, argv, "knpst:w")) != -1) { switch (ch) { case 'k': keep = 1; @@ -120,6 +120,9 @@ "invalid timeout \"%s\"", optarg); } break; + case 'p': + writepid = 1; + /* FALLTHROUGH */ case 'w': flags = (flags & ~O_RDONLY) | O_WRONLY; break; @@ -249,6 +252,17 @@ fclose(stdin); fclose(stdout); fclose(stderr); + + /* Write out the pid before we sleep on it. */ + if (writepid) { + char pidbuf[16]; + size_t pidlen; + + pidlen = snprintf(pidbuf, sizeof(pidbuf), "%d\n", child); + if (pidlen < sizeof(pidbuf)) + (void)write(lockfd, pidbuf, pidlen); + } + if (waitpid(child, &status, 0) == -1) exit(EX_OSERR); return (WIFEXITED(status) ? WEXITSTATUS(status) : EX_SOFTWARE);