Add -F option to sysctl(8) to display sysctl format.
Also add a test to ensure that it is working correctly. Submitted by: ota_j.email.ne.jp Reviewed by: mckusick Differential Revision: https://reviews.freebsd.org/D34012
This commit is contained in:
parent
57cc27a332
commit
f126d34981
@ -28,7 +28,7 @@
|
||||
.\" From: @(#)sysctl.8 8.1 (Berkeley) 6/6/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 30, 2022
|
||||
.Dd December 24, 2022
|
||||
.Dt SYSCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -36,13 +36,13 @@
|
||||
.Nd get or set kernel state
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl bdehiNnoTtqWx
|
||||
.Op Fl bdeFhilNnoTtqWx
|
||||
.Op Fl B Ar bufsize
|
||||
.Op Fl f Ar filename
|
||||
.Ar name Ns Op = Ns Ar value Ns Op , Ns Ar value
|
||||
.Ar ...
|
||||
.Nm
|
||||
.Op Fl bdehNnoTtqWx
|
||||
.Op Fl bdeFhlNnoTtqWx
|
||||
.Op Fl B Ar bufsize
|
||||
.Fl a
|
||||
.Sh DESCRIPTION
|
||||
@ -100,6 +100,10 @@ Specify a file which contains a pair of name and value in each line.
|
||||
.Nm
|
||||
reads and processes the specified file first and then processes the name
|
||||
and value pairs in the command line argument.
|
||||
.It Fl F
|
||||
Print the format of the variable.
|
||||
This is additional information to describe the type of the variable and
|
||||
most useful with struct types such as clockinfo, timeval, and loadavg.
|
||||
.It Fl h
|
||||
Format output for human, rather than machine, readability.
|
||||
.It Fl i
|
||||
@ -108,6 +112,11 @@ The purpose is to make use of
|
||||
.Nm
|
||||
for collecting data from a variety of machines (not all of which
|
||||
are necessarily running exactly the same software) easier.
|
||||
.It Fl l
|
||||
Show the length of variables along with their values.
|
||||
This option cannot be combined with the
|
||||
.Fl N
|
||||
option.
|
||||
.It Fl N
|
||||
Show only variable names, not their values.
|
||||
This is particularly useful with shells that offer programmable
|
||||
|
@ -66,6 +66,7 @@ static const char *conffile;
|
||||
|
||||
static int aflag, bflag, Bflag, dflag, eflag, hflag, iflag;
|
||||
static int Nflag, nflag, oflag, qflag, tflag, Tflag, Wflag, xflag;
|
||||
static bool Fflag, lflag;
|
||||
|
||||
static int oidfmt(int *, int, char *, u_int *);
|
||||
static int parsefile(const char *);
|
||||
@ -123,8 +124,8 @@ usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "%s\n%s\n",
|
||||
"usage: sysctl [-bdehiNnoqTtWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
|
||||
" sysctl [-bdehNnoqTtWx] [ -B <bufsize> ] -a");
|
||||
"usage: sysctl [-bdeFhilNnoqTtWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
|
||||
" sysctl [-bdeFhlNnoqTtWx] [ -B <bufsize> ] -a");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -138,7 +139,7 @@ main(int argc, char **argv)
|
||||
setbuf(stdout,0);
|
||||
setbuf(stderr,0);
|
||||
|
||||
while ((ch = getopt(argc, argv, "AabB:def:hiNnoqtTwWxX")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "AabB:def:FhilNnoqtTwWxX")) != -1) {
|
||||
switch (ch) {
|
||||
case 'A':
|
||||
/* compatibility */
|
||||
@ -162,12 +163,18 @@ main(int argc, char **argv)
|
||||
case 'f':
|
||||
conffile = optarg;
|
||||
break;
|
||||
case 'F':
|
||||
Fflag = true;
|
||||
break;
|
||||
case 'h':
|
||||
hflag = 1;
|
||||
break;
|
||||
case 'i':
|
||||
iflag = 1;
|
||||
break;
|
||||
case 'l':
|
||||
lflag = true;
|
||||
break;
|
||||
case 'N':
|
||||
Nflag = 1;
|
||||
break;
|
||||
@ -207,14 +214,15 @@ main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (Nflag && nflag)
|
||||
/* Nflag is name only and doesn't make sense to combind with these */
|
||||
/* TODO: few other combinations do not make sense but come back later */
|
||||
if (Nflag && (lflag || nflag))
|
||||
usage();
|
||||
if (aflag && argc == 0)
|
||||
exit(sysctl_all(NULL, 0));
|
||||
if (argc == 0 && conffile == NULL)
|
||||
usage();
|
||||
|
||||
warncount = 0;
|
||||
if (conffile != NULL)
|
||||
warncount += parsefile(conffile);
|
||||
|
||||
@ -949,6 +957,55 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This displays a combination of name, type, format, and/or description.
|
||||
*
|
||||
* Returns zero if anything was actually output.
|
||||
* Returns one if there is an error.
|
||||
*/
|
||||
static int
|
||||
show_info(char *name, const char *sep, int ctltype, char *fmt, int *qoid, int nlen)
|
||||
{
|
||||
u_char buf[BUFSIZ];
|
||||
const char *prntype;
|
||||
int error = 0, i;
|
||||
size_t j;
|
||||
|
||||
if (!nflag)
|
||||
printf("%s%s", name, sep);
|
||||
if (tflag) {
|
||||
if (ctl_typename[ctltype] != NULL)
|
||||
prntype = ctl_typename[ctltype];
|
||||
else {
|
||||
prntype = "unknown";
|
||||
error++;
|
||||
}
|
||||
if (Fflag || dflag)
|
||||
printf("%s%s", prntype, sep);
|
||||
else
|
||||
fputs(prntype, stdout);
|
||||
}
|
||||
if (Fflag) {
|
||||
if (!isprint(fmt[0])) /* Few codes doesn't have formats */
|
||||
fmt = "";
|
||||
if (dflag)
|
||||
printf("%s%s", fmt, sep);
|
||||
else
|
||||
fputs(fmt, stdout);
|
||||
}
|
||||
if (!dflag)
|
||||
return (error);
|
||||
|
||||
qoid[1] = CTL_SYSCTL_OIDDESCR;
|
||||
bzero(buf, BUFSIZ);
|
||||
j = sizeof(buf);
|
||||
i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
|
||||
if (i < 0)
|
||||
return (1);
|
||||
fputs(buf, stdout);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* This formats and outputs the value of one variable
|
||||
*
|
||||
@ -960,9 +1017,9 @@ static int
|
||||
show_var(int *oid, int nlen, bool honor_skip)
|
||||
{
|
||||
static int skip_len = 0, skip_oid[CTL_MAXNAME];
|
||||
u_char buf[BUFSIZ], *val, *oval, *p;
|
||||
u_char *val, *oval, *p;
|
||||
char name[BUFSIZ], fmt[BUFSIZ];
|
||||
const char *sep, *sep1, *prntype;
|
||||
const char *sep, *sep1;
|
||||
int qoid[CTL_MAXNAME+2];
|
||||
uintmax_t umv;
|
||||
intmax_t mv;
|
||||
@ -977,7 +1034,6 @@ show_var(int *oid, int nlen, bool honor_skip)
|
||||
/* Silence GCC. */
|
||||
umv = mv = intlen = 0;
|
||||
|
||||
bzero(buf, BUFSIZ);
|
||||
bzero(fmt, BUFSIZ);
|
||||
bzero(name, BUFSIZ);
|
||||
qoid[0] = CTL_SYSCTL;
|
||||
@ -1008,25 +1064,8 @@ show_var(int *oid, int nlen, bool honor_skip)
|
||||
sep = ": ";
|
||||
|
||||
ctltype = (kind & CTLTYPE);
|
||||
if (tflag || dflag) {
|
||||
if (!nflag)
|
||||
printf("%s%s", name, sep);
|
||||
if (ctl_typename[ctltype] != NULL)
|
||||
prntype = ctl_typename[ctltype];
|
||||
else
|
||||
prntype = "unknown";
|
||||
if (tflag && dflag)
|
||||
printf("%s%s", prntype, sep);
|
||||
else if (tflag) {
|
||||
printf("%s", prntype);
|
||||
return (0);
|
||||
}
|
||||
qoid[1] = CTL_SYSCTL_OIDDESCR;
|
||||
j = sizeof(buf);
|
||||
i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
|
||||
printf("%s", buf);
|
||||
return (0);
|
||||
}
|
||||
if (tflag || Fflag || dflag)
|
||||
return show_info(name, sep, ctltype, fmt, qoid, nlen);
|
||||
|
||||
/* keep track of encountered skip nodes, ignoring descendants */
|
||||
if ((skip_len == 0 || skip_len >= nlen * (int)sizeof(int)) &&
|
||||
@ -1109,6 +1148,8 @@ show_var(int *oid, int nlen, bool honor_skip)
|
||||
case CTLTYPE_STRING:
|
||||
if (!nflag)
|
||||
printf("%s%s", name, sep);
|
||||
if (lflag)
|
||||
printf("%zd%s", len, sep);
|
||||
printf("%.*s", (int)len, p);
|
||||
free(oval);
|
||||
return (0);
|
||||
@ -1127,6 +1168,8 @@ show_var(int *oid, int nlen, bool honor_skip)
|
||||
case CTLTYPE_U64:
|
||||
if (!nflag)
|
||||
printf("%s%s", name, sep);
|
||||
if (lflag)
|
||||
printf("%zd%s", len, sep);
|
||||
hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
|
||||
sep1 = "";
|
||||
while (len >= intlen) {
|
||||
@ -1197,6 +1240,8 @@ show_var(int *oid, int nlen, bool honor_skip)
|
||||
if (func) {
|
||||
if (!nflag)
|
||||
printf("%s%s", name, sep);
|
||||
if (lflag)
|
||||
printf("%zd%s", len, sep);
|
||||
i = (*func)(len, p);
|
||||
free(oval);
|
||||
return (i);
|
||||
@ -1209,6 +1254,8 @@ show_var(int *oid, int nlen, bool honor_skip)
|
||||
}
|
||||
if (!nflag)
|
||||
printf("%s%s", name, sep);
|
||||
if (lflag)
|
||||
printf("%zd%s", len, sep);
|
||||
printf("Format:%s Length:%zu Dump:0x", fmt, len);
|
||||
while (len-- && (xflag || p < val + 16))
|
||||
printf("%02x", *p++);
|
||||
|
5
sbin/sysctl/tests/Makefile
Normal file
5
sbin/sysctl/tests/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
ATF_TESTS_SH= sysctl_test
|
||||
|
||||
.include <bsd.test.mk>
|
11
sbin/sysctl/tests/Makefile.depend
Normal file
11
sbin/sysctl/tests/Makefile.depend
Normal file
@ -0,0 +1,11 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
116
sbin/sysctl/tests/sysctl_test.sh
Normal file
116
sbin/sysctl/tests/sysctl_test.sh
Normal file
@ -0,0 +1,116 @@
|
||||
# Copyright (c) 2022 Yoshihiro Ota <ota@j.email.ne.jp>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
|
||||
sysctl_name="kern.ostype"
|
||||
sysctl_value="FreeBSD"
|
||||
sysctl_type="string"
|
||||
sysctl_description="Operating system type"
|
||||
|
||||
atf_test_case sysctl_by_name
|
||||
sysctl_by_name_head()
|
||||
{
|
||||
atf_set "descr" "Verify name without any arguments"
|
||||
}
|
||||
sysctl_by_name_body()
|
||||
{
|
||||
atf_check -o "inline:${sysctl_name}: ${sysctl_value}\n" sysctl ${sysctl_name}
|
||||
}
|
||||
|
||||
|
||||
atf_test_case sysctl_nflag
|
||||
sysctl_nflag()
|
||||
{
|
||||
atf_set "descr" "Verify -n argument"
|
||||
}
|
||||
sysctl_nflag_body()
|
||||
{
|
||||
atf_check -o "inline:${sysctl_value}\n" sysctl -n ${sysctl_name}
|
||||
}
|
||||
|
||||
|
||||
atf_test_case sysctl_eflag
|
||||
sysctl_eflag()
|
||||
{
|
||||
atf_set "descr" "Verify -e argument"
|
||||
}
|
||||
sysctl_eflag_body()
|
||||
{
|
||||
atf_check -o "inline:${sysctl_name}=${sysctl_value}\n" sysctl -e ${sysctl_name}
|
||||
}
|
||||
|
||||
|
||||
atf_test_case sysctl_tflag
|
||||
sysctl_tflag()
|
||||
{
|
||||
atf_set "descr" "Verify -t argument"
|
||||
}
|
||||
sysctl_tflag_body()
|
||||
{
|
||||
atf_check -o "inline:${sysctl_name}: ${sysctl_type}\n" sysctl -t ${sysctl_name}
|
||||
}
|
||||
|
||||
|
||||
atf_test_case sysctl_dflag
|
||||
sysctl_dflag()
|
||||
{
|
||||
atf_set "descr" "Verify -d argument"
|
||||
}
|
||||
sysctl_dflag_body()
|
||||
{
|
||||
atf_check -o "inline:${sysctl_name}: ${sysctl_description}\n" sysctl -d ${sysctl_name}
|
||||
}
|
||||
|
||||
|
||||
atf_test_case sysctl_tflag_dflag
|
||||
sysctl_tflag_dflag()
|
||||
{
|
||||
atf_set "descr" "Verify -t -d arguments"
|
||||
}
|
||||
sysctl_tflag_dflag_body()
|
||||
{
|
||||
atf_check -o "inline:${sysctl_name}: ${sysctl_type}: ${sysctl_description}\n" sysctl -t -d ${sysctl_name}
|
||||
atf_check -o "inline:${sysctl_name}: ${sysctl_type}: ${sysctl_description}\n" sysctl -d -t ${sysctl_name}
|
||||
}
|
||||
|
||||
|
||||
atf_test_case sysctl_nflag_tflag_dflag
|
||||
sysctl_nflag_tflag_dflag()
|
||||
{
|
||||
atf_set "descr" "Verify -n -t -d arguments"
|
||||
}
|
||||
sysctl_nflag_tflag_dflag_body()
|
||||
{
|
||||
atf_check -o "inline:${sysctl_type}: ${sysctl_description}\n" sysctl -n -t -d ${sysctl_name}
|
||||
}
|
||||
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case sysctl_by_name
|
||||
atf_add_test_case sysctl_nflag
|
||||
atf_add_test_case sysctl_eflag
|
||||
atf_add_test_case sysctl_tflag
|
||||
atf_add_test_case sysctl_dflag
|
||||
atf_add_test_case sysctl_tflag_dflag
|
||||
atf_add_test_case sysctl_nflag_tflag_dflag
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user