Teach sysctl about the new optional suffix after IK to specify

precision. Update input as well. Add IK to the manual (it was missing
completely).

Differential Revision: https://reviews.freebsd.org/D3181
This commit is contained in:
Warner Losh 2015-07-29 02:34:25 +00:00
parent 98082691bb
commit aa255ef6dd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=285994
2 changed files with 67 additions and 35 deletions

View File

@ -81,7 +81,7 @@ static int show_var(int *, int);
static int sysctl_all(int *oid, int len);
static int name2oid(const char *, int *);
static int strIKtoi(const char *, char **);
static int strIKtoi(const char *, char **, const char *);
static int ctl_sign[CTLTYPE+1] = {
[CTLTYPE_INT] = 1,
@ -336,8 +336,8 @@ parse(const char *string, int lineno)
switch (kind & CTLTYPE) {
case CTLTYPE_INT:
if (strcmp(fmt, "IK") == 0)
intval = strIKtoi(newvalstr, &endptr);
if (strncmp(fmt, "IK", 2) == 0)
intval = strIKtoi(newvalstr, &endptr, fmt);
else
intval = (int)strtol(newvalstr, &endptr,
0);
@ -666,12 +666,13 @@ S_bios_smap_xattr(size_t l2, void *p)
#endif
static int
strIKtoi(const char *str, char **endptrp)
strIKtoi(const char *str, char **endptrp, const char *fmt)
{
int kelv;
float temp;
size_t len;
const char *p;
int prec, i;
assert(errno == 0);
@ -679,16 +680,36 @@ strIKtoi(const char *str, char **endptrp)
/* caller already checked this */
assert(len > 0);
/*
* A format of "IK" is in deciKelvin. A format of "IK3" is in
* milliKelvin. The single digit following IK is log10 of the
* multiplying factor to convert Kelvin into the untis of this sysctl,
* or the dividing factor to convert the sysctl value to Kelvin. Numbers
* larger than 6 will run into precision issues with 32-bit integers.
* Characters that aren't ASCII digits after the 'K' are ignored. No
* localization is present because this is an interface from the kernel
* to this program (eg not an end-user interface), so isdigit() isn't
* used here.
*/
if (fmt[2] != '\0' && fmt[2] >= '0' && fmt[2] <= '9')
prec = fmt[2] - '0';
else
prec = 1;
p = &str[len - 1];
if (*p == 'C' || *p == 'F') {
if (*p == 'C' || *p == 'F' || *p == 'K') {
temp = strtof(str, endptrp);
if (*endptrp != str && *endptrp == p && errno == 0) {
if (*p == 'F')
temp = (temp - 32) * 5 / 9;
*endptrp = NULL;
return (temp * 10 + 2732);
if (*p != 'K')
temp += 273.15;
for (i = 0; i < prec; i++)
temp *= 10.0;
return ((int)(temp + 0.5));
}
} else {
/* No unit specified -> treat it as a raw number */
kelv = (int)strtol(str, endptrp, 10);
if (*endptrp != str && *endptrp == p && errno == 0) {
*endptrp = NULL;
@ -772,7 +793,9 @@ show_var(int *oid, int nlen)
size_t intlen;
size_t j, len;
u_int kind;
float base;
int (*func)(size_t, void *);
int prec;
/* Silence GCC. */
umv = mv = intlen = 0;
@ -893,8 +916,19 @@ show_var(int *oid, int nlen)
else if (fmt[1] == 'K') {
if (mv < 0)
printf("%jd", mv);
else
printf("%.1fC", (mv - 2732.0) / 10);
else {
/*
* See strIKtoi for details on fmt.
*/
prec = 1;
if (fmt[2] != '\0')
prec = fmt[2] - '0';
base = 1.0;
for (int i = 0; i < prec; i++)
base *= 10.0;
printf("%.*fC", prec,
(float)mv / base - 273.15);
}
} else
printf(hflag ? "%'jd" : "%jd", mv);
sep1 = " ";

View File

@ -318,35 +318,33 @@ which specifies the format of the OID in a symbolic way.
This format is used as a hint by
.Xr sysctl 8
to apply proper data formatting for display purposes.
Currently used format names are:
.Dq N
for node,
.Dq A
for
.Li "char *" ,
.Dq I
for
.Li "int" ,
.Dq IU
for
.Li "unsigned int" ,
.Dq L
for
.Li "long" ,
.Dq LU
for
.Li "unsigned long" ,
.Dq Q
for
.Li "quad_t" ,
.Dq QU
for
.Pp
Current formats:
.Bl -tag -width "S,TYPE" -compact -offset indent
.It Cm N
node
.It Cm A
.Li "char *"
.It Cm I
.Li "int"
.It Cm IK Ns Op Ar n
temperature in Kelvin, multiplied by an optional single digit
power of ten scaling factor: 1 (default) gives deciKelvin, 0 gives Kelvin, 3
gives milliKelvin
.It Cm IU
.Li "unsigned int"
.It Cm L
.Li "long"
.It Cm LU
.Li "unsigned long"
.It Cm Q
.Li "quad_t"
.It Cm QU
.Li "u_quad_t"
and
.Dq S,TYPE
for
.It Cm "S,TYPE"
.Li "struct TYPE"
structures.
structures
.El
.It Fa descr
A pointer to a textual description of the OID.
.El