Index: sbin/sysctl/sysctl.c =================================================================== --- sbin/sysctl/sysctl.c +++ sbin/sysctl/sysctl.c @@ -81,7 +81,7 @@ 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 @@ 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 @@ #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,6 +680,10 @@ /* caller already checked this */ assert(len > 0); + if (fmt[2] != '\0') + prec = fmt[2] - '0'; + else + prec = 1; p = &str[len - 1]; if (*p == 'C' || *p == 'F') { temp = strtof(str, endptrp); @@ -686,7 +691,10 @@ if (*p == 'F') temp = (temp - 32) * 5 / 9; *endptrp = NULL; - return (temp * 10 + 2732); + temp += 273.15; + for (i = 0; i < prec; i++) + temp *= 10.0; + return ((int)(temp + 0.5)); } } else { kelv = (int)strtol(str, endptrp, 10); @@ -772,7 +780,9 @@ 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 +903,24 @@ else if (fmt[1] == 'K') { if (mv < 0) printf("%jd", mv); - else - printf("%.1fC", (mv - 2732.0) / 10); + else { + /* + * fmt is IKx, where x is optional and + * specifies the precision of the + * temperature. x defaults to 1 to give + * historical behavior. Many temperature + * sources have precisions that exceed + * their accuracy, however. + */ + 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 = " "; Index: share/man/man9/sysctl.9 =================================================================== --- share/man/man9/sysctl.9 +++ share/man/man9/sysctl.9 @@ -327,6 +327,13 @@ .Dq I for .Li "int" , +.Dq IK +for +.Li "int" +temperature in Kelvin. +An optional single digit suffix, which defaults to 1, after +.Dq IK +specifies how many places to move the decimal point left, .Dq IU for .Li "unsigned int" ,