Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 May 2025 20:38:46 GMT
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 0660de8172cd - main - runat: Add a runat(1) utility similar to the Solaris one
Message-ID:  <202505062038.546KckHj072759@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=0660de8172cd5a03affb9e87a1007cac5ba30425

commit 0660de8172cd5a03affb9e87a1007cac5ba30425
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2025-05-06 20:36:06 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2025-05-06 20:36:06 +0000

    runat: Add a runat(1) utility similar to the Solaris one
    
    Solaris has a utility called runat(1) that runs a shell
    command on a named attribute directory.  This utility
    is modelled after that one.
    
    Reviewed by:    kib (earlier version)
    Differential Revision:  https://reviews.freebsd.org/D49850
---
 usr.bin/Makefile       |  1 +
 usr.bin/runat/Makefile |  3 ++
 usr.bin/runat/runat.1  | 63 +++++++++++++++++++++++++++++++++++++++++
 usr.bin/runat/runat.c  | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 143 insertions(+)

diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index 7f35a87b0d93..e99670ec2d3e 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -123,6 +123,7 @@ SUBDIR=	alias \
 	revoke \
 	rpcinfo \
 	rs \
+	runat \
 	rup \
 	ruptime \
 	rusers \
diff --git a/usr.bin/runat/Makefile b/usr.bin/runat/Makefile
new file mode 100644
index 000000000000..6be86ce4a60b
--- /dev/null
+++ b/usr.bin/runat/Makefile
@@ -0,0 +1,3 @@
+PROG=	runat
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/runat/runat.1 b/usr.bin/runat/runat.1
new file mode 100644
index 000000000000..ceaf70ed1dba
--- /dev/null
+++ b/usr.bin/runat/runat.1
@@ -0,0 +1,63 @@
+.\"
+.\" Copyright (c) 2025 Rick Macklem
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd April 15, 2025
+.Dt RUNAT 1
+.Os
+.Sh NAME
+.Nm runat
+.Nd run a shell command on a named attribute directory
+.Sh SYNOPSIS
+.Nm
+.Op Ar file
+.Op Ar shell command
+.Sh DESCRIPTION
+The
+.Nm
+utility runs the shell command on the named attribute directory for the
+.Ar file
+argument.
+It does a
+.Xr fchdir 2
+system call to change the current working directory into the
+named attribute directory for the
+.Ar file
+argument and then performs the shell command via
+.Xr sh 1 .
+.Pp
+If a named attribute directory does not exist for
+.Ar file ,
+an empty one will be created.
+If an application needs to determine if a named attribute
+exists for the
+.Ar file ,
+.Xr pathconf 2
+with the name
+.Fa _PC_HAS_NAMEDATTR
+may be used.
+This will not create an empty named attribute directory
+if one does not exist for
+.Ar file .
+.Sh EXAMPLES
+For a
+.Ar file
+called
+.Dq myfile :
+.Bd -literal
+$ runat myfile ls -l			# lists the attributes for myfile
+$ runat myfile cp /etc/hosts attrhosts	# creates attrhosts
+$ runat myfile cat attrhosts		# displays contents of attrhosts
+.Ed
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr fchdir 2 ,
+.Xr pathconf 2 ,
+.Xr open 2 ,
+.Xr named_attribute 7
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 15.0 .
diff --git a/usr.bin/runat/runat.c b/usr.bin/runat/runat.c
new file mode 100644
index 000000000000..66f4ebadd180
--- /dev/null
+++ b/usr.bin/runat/runat.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2025 Rick Macklem
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <err.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void
+usage(void)
+{
+	(void)fprintf(stderr, "usage: runat <file> "
+	    "<shell command>\n");
+	exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int i, file_fd, nameddir_fd, outsiz;
+	char *buf;
+	long named_enabled;
+	size_t pos, siz;
+
+	if (argc <= 2)
+		usage();
+	argv++;
+	argc--;
+	if (argc < 2)
+		usage();
+
+	named_enabled = pathconf(argv[0], _PC_NAMEDATTR_ENABLED);
+	if (named_enabled <= 0)
+		errx(1, "Named attributes not enabled for %s", argv[0]);
+
+	/* Generate the command string for "sh". */
+	siz = 0;
+	for (i = 1; i < argc; i++)
+		siz += strlen(argv[i]) + 1;
+	buf = malloc(siz);
+	if (buf == NULL)
+		errx(1, "Cannot malloc");
+	pos = 0;
+	for (i = 1; i < argc; i++) {
+		outsiz = snprintf(&buf[pos], siz, "%s ", argv[i]);
+		if ((size_t)outsiz > siz)
+			errx(1, "Arguments too large");
+		pos += outsiz;
+		siz -= outsiz;
+	}
+	buf[pos - 1] = '\0';
+
+	file_fd = open(argv[0], O_RDONLY | O_CLOEXEC, 0);
+	if (file_fd < 0)
+		err(1, "Cannot open %s", argv[0]);
+	nameddir_fd = openat(file_fd, ".", O_RDONLY | O_CLOEXEC | O_NAMEDATTR,
+	    0);
+	if (nameddir_fd < 0)
+		err(1, "Cannot open named attribute directory "
+		    "for %s", argv[0]);
+
+	if (fchdir(nameddir_fd) < 0)
+		err(1, "Cannot fchdir to named attribute dir");
+
+	execl(_PATH_BSHELL, "sh", "-c", buf, NULL);
+	err(1, "Could not exec %s", _PATH_BSHELL);
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202505062038.546KckHj072759>