Add sbin/sysctl

This commit is contained in:
Chris Johns 2016-05-06 15:06:08 +10:00
parent c60deba242
commit 83eb07c4d6
9 changed files with 1113 additions and 1 deletions

View File

@ -0,0 +1,165 @@
#include <machine/rtems-bsd-user-space.h>
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Copyright (c) 2011 The FreeBSD Foundation
* All rights reserved.
* Portions of this software were developed by David Chisnall
* under sponsorship from the FreeBSD Foundation.
*
* 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <inttypes.h>
#ifndef __rtems__
#include "xlocale_private.h"
#else
#define locale_t void*
#define isspace_l(_c, _l) isspace(_c)
static void* __get_locale(void) { return NULL; }
#endif /* __rtems__ */
/*
* Convert a string to an intmax_t integer.
*
* Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
intmax_t
strtoimax_l(const char * __restrict nptr, char ** __restrict endptr, int base,
locale_t locale)
{
const char *s;
uintmax_t acc;
char c;
uintmax_t cutoff;
int neg, any, cutlim;
#ifndef __rtems__
FIX_LOCALE(locale);
#else
locale = NULL;
#endif /* __rtems__ */
/*
* Skip white space and pick up leading +/- sign if any.
* If base is 0, allow 0x for hex and 0 for octal, else
* assume decimal; if base is already 16, allow 0x.
*/
s = nptr;
do {
c = *s++;
} while (isspace_l((unsigned char)c, locale));
if (c == '-') {
neg = 1;
c = *s++;
} else {
neg = 0;
if (c == '+')
c = *s++;
}
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X') &&
((s[1] >= '0' && s[1] <= '9') ||
(s[1] >= 'A' && s[1] <= 'F') ||
(s[1] >= 'a' && s[1] <= 'f'))) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
acc = any = 0;
if (base < 2 || base > 36)
goto noconv;
/*
* Compute the cutoff value between legal numbers and illegal
* numbers. That is the largest legal value, divided by the
* base. An input number that is greater than this value, if
* followed by a legal input character, is too big. One that
* is equal to this value may be valid or not; the limit
* between valid and invalid numbers is then based on the last
* digit. For instance, if the range for intmax_t is
* [-9223372036854775808..9223372036854775807] and the input base
* is 10, cutoff will be set to 922337203685477580 and cutlim to
* either 7 (neg==0) or 8 (neg==1), meaning that if we have
* accumulated a value > 922337203685477580, or equal but the
* next digit is > 7 (or 8), the number is too big, and we will
* return a range error.
*
* Set 'any' if any `digits' consumed; make it negative to indicate
* overflow.
*/
cutoff = neg ? (uintmax_t)-(INTMAX_MIN + INTMAX_MAX) + INTMAX_MAX
: INTMAX_MAX;
cutlim = cutoff % base;
cutoff /= base;
for ( ; ; c = *s++) {
if (c >= '0' && c <= '9')
c -= '0';
else if (c >= 'A' && c <= 'Z')
c -= 'A' - 10;
else if (c >= 'a' && c <= 'z')
c -= 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = neg ? INTMAX_MIN : INTMAX_MAX;
errno = ERANGE;
} else if (!any) {
noconv:
errno = EINVAL;
} else if (neg)
acc = -acc;
if (endptr != NULL)
*endptr = (char *)(any ? s - 1 : nptr);
return (acc);
}
intmax_t
strtoimax(const char * __restrict nptr, char ** __restrict endptr, int base)
{
return strtoimax_l(nptr, endptr, base, __get_locale());
}

View File

@ -0,0 +1,143 @@
#include <machine/rtems-bsd-user-space.h>
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Copyright (c) 2011 The FreeBSD Foundation
* All rights reserved.
* Portions of this software were developed by David Chisnall
* under sponsorship from the FreeBSD Foundation.
*
* 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <inttypes.h>
#ifndef __rtems__
#include "xlocale_private.h"
#else
#define locale_t void*
#define isspace_l(_c, _l) isspace(_c)
static void* __get_locale(void) { return NULL; }
#endif /* __rtems__ */
/*
* Convert a string to a uintmax_t integer.
*
* Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
uintmax_t
strtoumax_l(const char * __restrict nptr, char ** __restrict endptr, int base,
locale_t locale)
{
const char *s;
uintmax_t acc;
char c;
uintmax_t cutoff;
int neg, any, cutlim;
#ifndef __rtems__
FIX_LOCALE(locale);
#else
locale = NULL;
#endif /* __rtems__ */
/*
* See strtoimax for comments as to the logic used.
*/
s = nptr;
do {
c = *s++;
} while (isspace_l((unsigned char)c, locale));
if (c == '-') {
neg = 1;
c = *s++;
} else {
neg = 0;
if (c == '+')
c = *s++;
}
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X') &&
((s[1] >= '0' && s[1] <= '9') ||
(s[1] >= 'A' && s[1] <= 'F') ||
(s[1] >= 'a' && s[1] <= 'f'))) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
acc = any = 0;
if (base < 2 || base > 36)
goto noconv;
cutoff = UINTMAX_MAX / base;
cutlim = UINTMAX_MAX % base;
for ( ; ; c = *s++) {
if (c >= '0' && c <= '9')
c -= '0';
else if (c >= 'A' && c <= 'Z')
c -= 'A' - 10;
else if (c >= 'a' && c <= 'z')
c -= 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = UINTMAX_MAX;
errno = ERANGE;
} else if (!any) {
noconv:
errno = EINVAL;
} else if (neg)
acc = -acc;
if (endptr != NULL)
*endptr = (char *)(any ? s - 1 : nptr);
return (acc);
}
uintmax_t
strtoumax(const char * __restrict nptr, char ** __restrict endptr, int base)
{
return strtoumax_l(nptr, endptr, base, __get_locale());
}

View File

@ -0,0 +1,784 @@
#include <machine/rtems-bsd-user-space.h>
/*
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)from: sysctl.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#ifdef __rtems__
#define __need_getopt_newlib
#include <getopt.h>
#include <machine/rtems-bsd-program.h>
#include <machine/rtems-bsd-commands.h>
#endif /* __rtems__ */
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/sys/time.h>
#include <rtems/bsd/sys/resource.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <inttypes.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int aflag, bflag, dflag, eflag, hflag, iflag;
static int Nflag, nflag, oflag, qflag, xflag, warncount;
static int oidfmt(int *, int, char *, u_int *);
static void parse(const char *);
static int show_var(int *, int);
static int sysctl_all(int *oid, int len);
static int name2oid(char *, int *);
static int set_IK(const char *, int *);
static void
usage(void)
{
(void)fprintf(stderr, "%s\n%s\n",
"usage: sysctl [-bdehiNnoqx] name[=value] ...",
" sysctl [-bdehNnoqx] -a");
exit(1);
}
#ifdef __rtems__
static int main(int argc, char **argv);
int rtems_bsd_command_sysctl(int argc, char *argv[])
{
int exit_code;
rtems_bsd_program_lock();
aflag = bflag = dflag = eflag = hflag = iflag = 0;
Nflag = nflag = oflag = qflag = xflag = warncount = 0;
exit_code = rtems_bsd_program_call_main("sysctl", main, argc, argv);
rtems_bsd_program_unlock();
return exit_code;
}
#endif /* __rtems__ */
int
main(int argc, char **argv)
{
int ch;
#ifdef __rtems__
struct getopt_data getopt_data;
memset(&getopt_data, 0, sizeof(getopt_data));
#define optind getopt_data.optind
#define optarg getopt_data.optarg
#define opterr getopt_data.opterr
#define optopt getopt_data.optopt
#define getopt(argc, argv, opt) getopt_r(argc, argv, "+" opt, &getopt_data)
#endif /* __rtems__ */
#ifndef __rtems__
setlocale(LC_NUMERIC, "");
setbuf(stdout,0);
setbuf(stderr,0);
#endif /* __rtems__ */
while ((ch = getopt(argc, argv, "AabdehiNnoqwxX")) != -1) {
switch (ch) {
case 'A':
/* compatibility */
aflag = oflag = 1;
break;
case 'a':
aflag = 1;
break;
case 'b':
bflag = 1;
break;
case 'd':
dflag = 1;
break;
case 'e':
eflag = 1;
break;
case 'h':
hflag = 1;
break;
case 'i':
iflag = 1;
break;
case 'N':
Nflag = 1;
break;
case 'n':
nflag = 1;
break;
case 'o':
oflag = 1;
break;
case 'q':
qflag = 1;
break;
case 'w':
/* compatibility */
/* ignored */
break;
case 'X':
/* compatibility */
aflag = xflag = 1;
break;
case 'x':
xflag = 1;
break;
default:
usage();
}
}
argc -= optind;
argv += optind;
if (Nflag && nflag)
usage();
if (aflag && argc == 0)
exit(sysctl_all(0, 0));
if (argc == 0)
usage();
warncount = 0;
while (argc-- > 0)
parse(*argv++);
exit(warncount);
}
/*
* Parse a name into a MIB entry.
* Lookup and print out the MIB entry if it exists.
* Set a new value if requested.
*/
static void
parse(const char *string)
{
int len, i, j;
void *newval = 0;
int intval;
unsigned int uintval;
long longval;
unsigned long ulongval;
size_t newsize = 0;
int64_t i64val;
uint64_t u64val;
int mib[CTL_MAXNAME];
char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ];
u_int kind;
cp = buf;
if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ)
errx(1, "oid too long: '%s'", string);
bufp = strsep(&cp, "=");
if (cp != NULL) {
while (isspace(*cp))
cp++;
newval = cp;
newsize = strlen(cp);
}
len = name2oid(bufp, mib);
if (len < 0) {
if (iflag)
return;
if (qflag)
exit(1);
else
errx(1, "unknown oid '%s'", bufp);
}
if (oidfmt(mib, len, fmt, &kind))
err(1, "couldn't find format of oid '%s'", bufp);
if (newval == NULL || dflag) {
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
if (dflag) {
i = show_var(mib, len);
if (!i && !bflag)
putchar('\n');
}
sysctl_all(mib, len);
} else {
i = show_var(mib, len);
if (!i && !bflag)
putchar('\n');
}
} else {
if ((kind & CTLTYPE) == CTLTYPE_NODE)
errx(1, "oid '%s' isn't a leaf node", bufp);
if (!(kind & CTLFLAG_WR)) {
if (kind & CTLFLAG_TUN) {
warnx("oid '%s' is a read only tunable", bufp);
errx(1, "Tunable values are set in /boot/loader.conf");
} else {
errx(1, "oid '%s' is read only", bufp);
}
}
if ((kind & CTLTYPE) == CTLTYPE_INT ||
(kind & CTLTYPE) == CTLTYPE_UINT ||
(kind & CTLTYPE) == CTLTYPE_LONG ||
(kind & CTLTYPE) == CTLTYPE_ULONG ||
(kind & CTLTYPE) == CTLTYPE_S64 ||
(kind & CTLTYPE) == CTLTYPE_U64) {
if (strlen(newval) == 0)
errx(1, "empty numeric value");
}
switch (kind & CTLTYPE) {
case CTLTYPE_INT:
if (strcmp(fmt, "IK") == 0) {
if (!set_IK(newval, &intval))
errx(1, "invalid value '%s'",
(char *)newval);
} else {
intval = (int)strtol(newval, &endptr,
0);
if (endptr == newval || *endptr != '\0')
errx(1, "invalid integer '%s'",
(char *)newval);
}
newval = &intval;
newsize = sizeof(intval);
break;
case CTLTYPE_UINT:
uintval = (int) strtoul(newval, &endptr, 0);
if (endptr == newval || *endptr != '\0')
errx(1, "invalid unsigned integer '%s'",
(char *)newval);
newval = &uintval;
newsize = sizeof(uintval);
break;
case CTLTYPE_LONG:
longval = strtol(newval, &endptr, 0);
if (endptr == newval || *endptr != '\0')
errx(1, "invalid long integer '%s'",
(char *)newval);
newval = &longval;
newsize = sizeof(longval);
break;
case CTLTYPE_ULONG:
ulongval = strtoul(newval, &endptr, 0);
if (endptr == newval || *endptr != '\0')
errx(1, "invalid unsigned long integer"
" '%s'", (char *)newval);
newval = &ulongval;
newsize = sizeof(ulongval);
break;
case CTLTYPE_STRING:
break;
case CTLTYPE_S64:
i64val = strtoimax(newval, &endptr, 0);
if (endptr == newval || *endptr != '\0')
errx(1, "invalid int64_t '%s'",
(char *)newval);
newval = &i64val;
newsize = sizeof(i64val);
break;
case CTLTYPE_U64:
u64val = strtoumax(newval, &endptr, 0);
if (endptr == newval || *endptr != '\0')
errx(1, "invalid uint64_t '%s'",
(char *)newval);
newval = &u64val;
newsize = sizeof(u64val);
break;
case CTLTYPE_OPAQUE:
/* FALLTHROUGH */
default:
errx(1, "oid '%s' is type %d,"
" cannot set that", bufp,
kind & CTLTYPE);
}
i = show_var(mib, len);
if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
if (!i && !bflag)
putchar('\n');
switch (errno) {
case EOPNOTSUPP:
errx(1, "%s: value is not available",
string);
case ENOTDIR:
errx(1, "%s: specification is incomplete",
string);
case ENOMEM:
errx(1, "%s: type is unknown to this program",
string);
default:
warn("%s", string);
warncount++;
return;
}
}
if (!bflag)
printf(" -> ");
i = nflag;
nflag = 1;
j = show_var(mib, len);
if (!j && !bflag)
putchar('\n');
nflag = i;
}
}
/* These functions will dump out various interesting structures. */
static int
S_clockinfo(int l2, void *p)
{
#ifndef __rtems__
struct clockinfo *ci = (struct clockinfo*)p;
if (l2 != sizeof(*ci)) {
warnx("S_clockinfo %d != %zu", l2, sizeof(*ci));
return (1);
}
printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" :
"{ hz = %d, tick = %d, profhz = %d, stathz = %d }",
ci->hz, ci->tick, ci->profhz, ci->stathz);
#endif /* __rtems__ */
return (0);
}
static int
S_loadavg(int l2, void *p)
{
struct loadavg *tv = (struct loadavg*)p;
if (l2 != sizeof(*tv)) {
warnx("S_loadavg %d != %zu", l2, sizeof(*tv));
return (1);
}
printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
(double)tv->ldavg[0]/(double)tv->fscale,
(double)tv->ldavg[1]/(double)tv->fscale,
(double)tv->ldavg[2]/(double)tv->fscale);
return (0);
}
static int
S_timeval(int l2, void *p)
{
struct timeval *tv = (struct timeval*)p;
time_t tv_sec;
char *p1, *p2;
if (l2 != sizeof(*tv)) {
warnx("S_timeval %d != %zu", l2, sizeof(*tv));
return (1);
}
printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
"{ sec = %jd, usec = %ld } ",
(intmax_t)tv->tv_sec, tv->tv_usec);
tv_sec = tv->tv_sec;
p1 = strdup(ctime(&tv_sec));
for (p2=p1; *p2 ; p2++)
if (*p2 == '\n')
*p2 = '\0';
fputs(p1, stdout);
free(p1);
return (0);
}
static int
S_vmtotal(int l2, void *p)
{
struct vmtotal *v = (struct vmtotal *)p;
int pageKilo = getpagesize() / 1024;
if (l2 != sizeof(*v)) {
warnx("S_vmtotal %d != %zu", l2, sizeof(*v));
return (1);
}
printf(
"\nSystem wide totals computed every five seconds:"
" (values in kilobytes)\n");
printf("===============================================\n");
printf(
"Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: "
"%hd Sleep: %hd)\n",
v->t_rq, v->t_dw, v->t_pw, v->t_sl);
printf(
"Virtual Memory:\t\t(Total: %dK Active: %dK)\n",
v->t_vm * pageKilo, v->t_avm * pageKilo);
printf("Real Memory:\t\t(Total: %dK Active: %dK)\n",
v->t_rm * pageKilo, v->t_arm * pageKilo);
printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n",
v->t_vmshr * pageKilo, v->t_avmshr * pageKilo);
printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n",
v->t_rmshr * pageKilo, v->t_armshr * pageKilo);
printf("Free Memory:\t%dK\n", v->t_free * pageKilo);
return (0);
}
static int
set_IK(const char *str, int *val)
{
float temp;
int len, kelv;
const char *p;
char *endptr;
if ((len = strlen(str)) == 0)
return (0);
p = &str[len - 1];
if (*p == 'C' || *p == 'F') {
temp = strtof(str, &endptr);
if (endptr == str || endptr != p)
return (0);
if (*p == 'F')
temp = (temp - 32) * 5 / 9;
kelv = temp * 10 + 2732;
} else {
kelv = (int)strtol(str, &endptr, 10);
if (endptr == str || *endptr != '\0')
return (0);
}
*val = kelv;
return (1);
}
/*
* These functions uses a presently undocumented interface to the kernel
* to walk the tree and get the type so it can print the value.
* This interface is under work and consideration, and should probably
* be killed with a big axe by the first person who can find the time.
* (be aware though, that the proper interface isn't as obvious as it
* may seem, there are various conflicting requirements.
*/
static int
name2oid(char *name, int *oidp)
{
int oid[2];
int i;
size_t j;
oid[0] = 0;
oid[1] = 3;
j = CTL_MAXNAME * sizeof(int);
i = sysctl(oid, 2, oidp, &j, name, strlen(name));
if (i < 0)
return (i);
j /= sizeof(int);
return (j);
}
static int
oidfmt(int *oid, int len, char *fmt, u_int *kind)
{
int qoid[CTL_MAXNAME+2];
u_char buf[BUFSIZ];
int i;
size_t j;
qoid[0] = 0;
qoid[1] = 4;
memcpy(qoid + 2, oid, len * sizeof(int));
j = sizeof(buf);
i = sysctl(qoid, len + 2, buf, &j, 0, 0);
if (i)
err(1, "sysctl fmt %d %zu %d", i, j, errno);
if (kind)
*kind = *(u_int *)buf;
if (fmt)
strcpy(fmt, (char *)(buf + sizeof(u_int)));
return (0);
}
static int ctl_sign[CTLTYPE+1] = {
[CTLTYPE_INT] = 1,
[CTLTYPE_LONG] = 1,
[CTLTYPE_S64] = 1,
};
static int ctl_size[CTLTYPE+1] = {
[CTLTYPE_INT] = sizeof(int),
[CTLTYPE_UINT] = sizeof(u_int),
[CTLTYPE_LONG] = sizeof(long),
[CTLTYPE_ULONG] = sizeof(u_long),
[CTLTYPE_S64] = sizeof(int64_t),
[CTLTYPE_U64] = sizeof(int64_t),
};
/*
* This formats and outputs the value of one variable
*
* Returns zero if anything was actually output.
* Returns one if didn't know what to do with this.
* Return minus one if we had errors.
*/
static int
show_var(int *oid, int nlen)
{
u_char buf[BUFSIZ], *val, *oval, *p;
char name[BUFSIZ], *fmt;
const char *sep, *sep1;
int qoid[CTL_MAXNAME+2];
uintmax_t umv;
intmax_t mv;
int i, hexlen, sign, ctltype;
size_t intlen;
size_t j, len;
u_int kind;
int (*func)(int, void *);
/* Silence GCC. */
umv = mv = intlen = 0;
bzero(buf, BUFSIZ);
bzero(name, BUFSIZ);
qoid[0] = 0;
memcpy(qoid + 2, oid, nlen * sizeof(int));
qoid[1] = 1;
j = sizeof(name);
i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
if (i || !j)
err(1, "sysctl name %d %zu %d", i, j, errno);
if (Nflag) {
printf("%s", name);
return (0);
}
if (eflag)
sep = "=";
else
sep = ": ";
if (dflag) { /* just print description */
qoid[1] = 5;
j = sizeof(buf);
i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
if (!nflag)
printf("%s%s", name, sep);
printf("%s", buf);
return (0);
}
/* find an estimate of how much we need for this var */
j = 0;
i = sysctl(oid, nlen, 0, &j, 0, 0);
j += j; /* we want to be sure :-) */
val = oval = malloc(j + 1);
if (val == NULL) {
warnx("malloc failed");
return (1);
}
len = j;
i = sysctl(oid, nlen, val, &len, 0, 0);
if (i || !len) {
free(oval);
return (1);
}
if (bflag) {
fwrite(val, 1, len, stdout);
free(oval);
return (0);
}
val[len] = '\0';
fmt = buf;
oidfmt(oid, nlen, fmt, &kind);
p = val;
ctltype = (kind & CTLTYPE);
sign = ctl_sign[ctltype];
intlen = ctl_size[ctltype];
switch (ctltype) {
case CTLTYPE_STRING:
if (!nflag)
printf("%s%s", name, sep);
printf("%.*s", (int)len, p);
free(oval);
return (0);
case CTLTYPE_INT:
case CTLTYPE_UINT:
case CTLTYPE_LONG:
case CTLTYPE_ULONG:
case CTLTYPE_S64:
case CTLTYPE_U64:
if (!nflag)
printf("%s%s", name, sep);
hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
sep1 = "";
while (len >= intlen) {
switch (kind & CTLTYPE) {
case CTLTYPE_INT:
case CTLTYPE_UINT:
umv = *(u_int *)p;
mv = *(int *)p;
break;
case CTLTYPE_LONG:
case CTLTYPE_ULONG:
umv = *(u_long *)p;
mv = *(long *)p;
break;
case CTLTYPE_S64:
case CTLTYPE_U64:
umv = *(uint64_t *)p;
mv = *(int64_t *)p;
break;
}
fputs(sep1, stdout);
if (xflag)
printf("%#0*jx", hexlen, umv);
else if (!sign)
printf(hflag ? "%'ju" : "%ju", umv);
else if (fmt[1] == 'K') {
if (mv < 0)
printf("%jd", mv);
else
printf("%.1fC", (mv - 2732.0) / 10);
} else
printf(hflag ? "%'jd" : "%jd", mv);
sep1 = " ";
len -= intlen;
p += intlen;
}
free(oval);
return (0);
case CTLTYPE_OPAQUE:
i = 0;
if (strcmp(fmt, "S,clockinfo") == 0)
func = S_clockinfo;
else if (strcmp(fmt, "S,timeval") == 0)
func = S_timeval;
else if (strcmp(fmt, "S,loadavg") == 0)
func = S_loadavg;
else if (strcmp(fmt, "S,vmtotal") == 0)
func = S_vmtotal;
else
func = NULL;
if (func) {
if (!nflag)
printf("%s%s", name, sep);
i = (*func)(len, p);
free(oval);
return (i);
}
/* FALLTHROUGH */
default:
if (!oflag && !xflag) {
free(oval);
return (1);
}
if (!nflag)
printf("%s%s", name, sep);
printf("Format:%s Length:%zu Dump:0x", fmt, len);
while (len-- && (xflag || p < val + 16))
printf("%02x", *p++);
if (!xflag && len > 16)
printf("...");
free(oval);
return (0);
}
free(oval);
return (1);
}
static int
sysctl_all(int *oid, int len)
{
int name1[22], name2[22];
int i, j;
size_t l1, l2;
name1[0] = 0;
name1[1] = 2;
l1 = 2;
if (len) {
memcpy(name1+2, oid, len * sizeof(int));
l1 += len;
} else {
name1[2] = 1;
l1++;
}
for (;;) {
l2 = sizeof(name2);
j = sysctl(name1, l1, name2, &l2, 0, 0);
if (j < 0) {
if (errno == ENOENT)
return (0);
else
err(1, "sysctl(getnext) %d %zu", j, l2);
}
l2 /= sizeof(int);
if (len < 0 || l2 < (unsigned int)len)
return (0);
for (i = 0; i < len; i++)
if (name2[i] != oid[i])
return (0);
i = show_var(name2, l2);
if (!i && !bflag)
putchar('\n');
memcpy(name1+2, name2, l2 * sizeof(int));
l1 = 2 + l2;
}
}

View File

@ -1952,7 +1952,9 @@ def user_space(mm):
'lib/libc/resolv/res_state.c',
'lib/libc/resolv/res_update.c',
'lib/libc/stdio/fgetln.c',
'lib/libc/stdlib/strtoimax.c',
'lib/libc/stdlib/strtonum.c',
'lib/libc/stdlib/strtoumax.c',
'lib/libc/string/strsep.c',
'lib/libipsec/ipsec_dump_policy.c',
'lib/libipsec/ipsec_get_policylen.c',
@ -2002,6 +2004,7 @@ def user_space(mm):
'sbin/ping6/ping6.c',
'sbin/ping/ping.c',
'sbin/route/route.c',
'sbin/sysctl/sysctl.c',
'usr.bin/netstat/atalk.c',
'usr.bin/netstat/bpf.c',
'usr.bin/netstat/if.c',

View File

@ -283,7 +283,9 @@ def build(bld):
'freebsd/lib/libc/resolv/res_state.c',
'freebsd/lib/libc/resolv/res_update.c',
'freebsd/lib/libc/stdio/fgetln.c',
'freebsd/lib/libc/stdlib/strtoimax.c',
'freebsd/lib/libc/stdlib/strtonum.c',
'freebsd/lib/libc/stdlib/strtoumax.c',
'freebsd/lib/libc/string/strsep.c',
'freebsd/lib/libipsec/ipsec_dump_policy.c',
'freebsd/lib/libipsec/ipsec_get_policylen.c',
@ -333,6 +335,7 @@ def build(bld):
'freebsd/sbin/ping/ping.c',
'freebsd/sbin/ping6/ping6.c',
'freebsd/sbin/route/route.c',
'freebsd/sbin/sysctl/sysctl.c',
'freebsd/usr.bin/netstat/atalk.c',
'freebsd/usr.bin/netstat/bpf.c',
'freebsd/usr.bin/netstat/if.c',

View File

@ -60,6 +60,8 @@ int rtems_bsd_command_dhcpcd(int argc, char **argv);
int rtems_bsd_command_tcpdump(int argc, char **argv);
int rtems_bsd_command_sysctl(int argc, char **argv);
__END_DECLS
#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_COMMANDS_H_ */

View File

@ -37,6 +37,8 @@ extern rtems_shell_cmd_t rtems_shell_HOSTNAME_Command;
extern rtems_shell_cmd_t rtems_shell_TCPDUMP_Command;
extern rtems_shell_cmd_t rtems_shell_SYSCTL_Command;
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -54,3 +54,12 @@ rtems_shell_cmd_t rtems_shell_TCPDUMP_Command = {
NULL, /* alias */
NULL /* next */
};
rtems_shell_cmd_t rtems_shell_SYSCTL_Command = {
"sysctl", /* name */
"sysctl [-bdehiNnoRTqx] [-f filename] name[=value] ...", /* usage */
"net", /* topic */
rtems_bsd_command_sysctl, /* command */
NULL, /* alias */
NULL /* next */
};

View File

@ -342,7 +342,8 @@ SYSINIT_NEED_NET_IF_VLAN;
&rtems_shell_ROUTE_Command, \
&rtems_shell_NETSTAT_Command, \
&rtems_shell_IFCONFIG_Command, \
&rtems_shell_TCPDUMP_Command
&rtems_shell_TCPDUMP_Command, \
&rtems_shell_SYSCTL_Command
#define CONFIGURE_SHELL_COMMAND_CPUUSE
#define CONFIGURE_SHELL_COMMAND_PERIODUSE