git: 4bfb7cfb70e6 - main - runat: Add -h to manipulate a symlink's named attribute dir

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Mon, 02 Feb 2026 22:40:33 UTC
The branch main has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=4bfb7cfb70e62bc316de9e73cfd63a5c85541154

commit 4bfb7cfb70e62bc316de9e73cfd63a5c85541154
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2026-02-02 22:38:13 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2026-02-02 22:38:13 +0000

    runat: Add -h to manipulate a symlink's named attribute dir
    
    Lionel Cons <lionelcons1972@gmail.com> requested
    that a new option be added to runat(1) so that it could
    be used to manipulate named attributes associated with
    a symbolic link and not the file the symbolic link refers to).
    
    This patch adds the option -h/--nofollow to do this.
    
    Requested by:   Lionel Cons <lionelcons1972@gmail.com>
    Reviewed by:    kib
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D55023
---
 usr.bin/runat/runat.c | 35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/usr.bin/runat/runat.c b/usr.bin/runat/runat.c
index 99437f3472f4..eb30ef87f2f9 100644
--- a/usr.bin/runat/runat.c
+++ b/usr.bin/runat/runat.c
@@ -8,17 +8,25 @@
 #include <sys/wait.h>
 #include <err.h>
 #include <fcntl.h>
+#include <getopt.h>
 #include <paths.h>
 #include <signal.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
+static struct option longopts[] = {
+	{ "nofollow", no_argument, NULL, 'h' },
+	{ "-", no_argument, NULL, '-' },
+	{ NULL, 0, NULL, 0}
+};
+
 static void
 usage(void)
 {
-	(void)fprintf(stderr, "usage: runat <file> "
+	(void)fprintf(stderr, "usage: runat [-h/--nofollow] [--] <file> "
 	    "<shell command>\n");
 	exit(1);
 }
@@ -26,15 +34,28 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
-	int i, file_fd, nameddir_fd, outsiz;
+	int ch, file_fd, flags, i, longindex, nameddir_fd, outsiz;
 	char *buf;
 	long named_enabled;
 	size_t pos, siz;
+	bool done_args;
 
-	if (argc <= 2)
-		usage();
-	argv++;
-	argc--;
+	flags = O_RDONLY | O_CLOEXEC | O_PATH;
+	done_args = false;
+	while (!done_args && (ch = getopt_long(argc, argv, "h-", longopts,
+	    &longindex)) != -1)
+		switch (ch) {
+		case 'h':
+			flags |= O_NOFOLLOW;
+			break;
+		case '-':
+			done_args = true;
+			break;
+		default:
+			usage();
+		}
+	argv += optind;
+	argc -= optind;
 	if (argc < 2)
 		usage();
 
@@ -61,7 +82,7 @@ main(int argc, char *argv[])
 	}
 	buf[pos - 1] = '\0';
 
-	file_fd = open(argv[0], O_RDONLY | O_CLOEXEC, 0);
+	file_fd = open(argv[0], flags, 0);
 	if (file_fd < 0)
 		err(1, "Cannot open %s", argv[0]);
 	nameddir_fd = openat(file_fd, ".", O_RDONLY | O_CLOEXEC | O_NAMEDATTR,