[PATCH] flock: Add --close option

mac at mcrowe.com mac at mcrowe.com
Fri Jan 24 21:48:50 UTC 2025


From: Mike Crowe <mac at mcrowe.com>

util-linux supports closing the file descriptor for the locked file
before executing the child. It implements this by closing after fork. We
can't really do that easily in busybox, but we can call the hinted-at
close_on_exec_on() instead to ensure that the file descriptor is closed
at the point of exec(2), which ought to be enough.

Add minimal tests for this feature.

function                                             old     new   delta
flock_main                                           357     375     +18
static.flock_longopts                                 42      50      +8
.rodata                                            99802   99803      +1
packed_usage                                       34663   34659      -4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 27/-4)              Total: 23 bytes

Signed-off-by: Mike Crowe <mac at mcrowe.com>
---
 testsuite/flock/flock-close-option | 11 +++++++++++
 util-linux/flock.c                 | 12 ++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)
 create mode 100644 testsuite/flock/flock-close-option

diff --git a/testsuite/flock/flock-close-option b/testsuite/flock/flock-close-option
new file mode 100644
index 000000000..6161bef4d
--- /dev/null
+++ b/testsuite/flock/flock-close-option
@@ -0,0 +1,11 @@
+: "flock without -o means that the lock file should have an fd in the child"
+busybox flock flock-supports-close-lockfile ls -l /proc/self/fd > flock-supports-close-out
+grep flock-supports-close-lockfile flock-supports-close-out
+
+: "flock -o means that the lock file should not have an fd in the child"
+busybox flock -o flock-supports-close-lockfile ls -l /proc/self/fd > flock-supports-close-out
+if grep flock-supports-close-lockfile flock-supports-close-out; then false; fi
+
+: "flock --close means that the lock file should not have an fd in the child"
+busybox flock --close flock-supports-close-lockfile ls -l /proc/self/fd > flock-supports-close-out
+if grep flock-supports-close-lockfile flock-supports-close-out; then false; fi
diff --git a/util-linux/flock.c b/util-linux/flock.c
index ee88be5b7..30d53f668 100644
--- a/util-linux/flock.c
+++ b/util-linux/flock.c
@@ -14,13 +14,14 @@
 //kbuild:lib-$(CONFIG_FLOCK) += flock.o
 
 //usage:#define flock_trivial_usage
-//usage:       "[-sxun] FD | { FILE [-c] PROG ARGS }"
+//usage:       "[-sxuno] FD | { FILE [-c] PROG ARGS }"
 //usage:#define flock_full_usage "\n\n"
 //usage:       "[Un]lock file descriptor, or lock FILE, run PROG\n"
 //usage:     "\n	-s	Shared lock"
 //usage:     "\n	-x	Exclusive lock (default)"
 //usage:     "\n	-u	Unlock FD"
 //usage:     "\n	-n	Fail rather than wait"
+//usage:     "\n	-o	Close file descriptor before exec"
 
 #include <sys/file.h>
 #include "libbb.h"
@@ -34,7 +35,8 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
 		OPT_x = (1 << 1),
 		OPT_n = (1 << 2),
 		OPT_u = (1 << 3),
-		OPT_c = (1 << 4),
+		OPT_o = (1 << 4),
+		OPT_c = (1 << 5),
 	};
 
 #if ENABLE_LONG_OPTS
@@ -43,10 +45,11 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
 		"exclusive\0"   No_argument       "x"
 		"unlock\0"      No_argument       "u"
 		"nonblock\0"    No_argument       "n"
+		"close\0"       No_argument       "o"
 		;
 #endif
 
-	opt = getopt32long(argv, "^+" "sxnu" "\0" "-1", flock_longopts);
+	opt = getopt32long(argv, "^+" "sxnuo" "\0" "-1", flock_longopts);
 	argv += optind;
 
 	if (argv[1]) {
@@ -55,7 +58,8 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
 			fd = open(argv[0], O_RDONLY|O_NOCTTY);
 		if (fd < 0)
 			bb_perror_msg_and_die("can't open '%s'", argv[0]);
-		//TODO? close_on_exec_on(fd);
+		if (opt & OPT_o)
+			close_on_exec_on(fd);
 	} else {
 		fd = xatoi_positive(argv[0]);
 	}
-- 
2.39.5



More information about the busybox mailing list