mirror of
https://github.com/opnsense/src.git
synced 2026-06-13 18:50:31 -04:00
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
This commit is contained in:
parent
56a3db77fd
commit
0660de8172
4 changed files with 143 additions and 0 deletions
|
|
@ -123,6 +123,7 @@ SUBDIR= alias \
|
|||
revoke \
|
||||
rpcinfo \
|
||||
rs \
|
||||
runat \
|
||||
rup \
|
||||
ruptime \
|
||||
rusers \
|
||||
|
|
|
|||
3
usr.bin/runat/Makefile
Normal file
3
usr.bin/runat/Makefile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
PROG= runat
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
63
usr.bin/runat/runat.1
Normal file
63
usr.bin/runat/runat.1
Normal file
|
|
@ -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 .
|
||||
76
usr.bin/runat/runat.c
Normal file
76
usr.bin/runat/runat.c
Normal file
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in a new issue