| 1013 | #endif |
| 1014 | |
| 1015 | static int |
| 1016 | strIKtoi(const char *str, char **endptrp, const char *fmt) |
| 1017 | { |
| 1018 | int kelv; |
| 1019 | float temp; |
| 1020 | size_t len; |
| 1021 | const char *p; |
| 1022 | int prec, i; |
| 1023 | |
| 1024 | assert(errno == 0); |
| 1025 | |
| 1026 | len = strlen(str); |
| 1027 | /* caller already checked this */ |
| 1028 | assert(len > 0); |
| 1029 | |
| 1030 | /* |
| 1031 | * A format of "IK" is in deciKelvin. A format of "IK3" is in |
| 1032 | * milliKelvin. The single digit following IK is log10 of the |
| 1033 | * multiplying factor to convert Kelvin into the untis of this sysctl, |
| 1034 | * or the dividing factor to convert the sysctl value to Kelvin. Numbers |
| 1035 | * larger than 6 will run into precision issues with 32-bit integers. |
| 1036 | * Characters that aren't ASCII digits after the 'K' are ignored. No |
| 1037 | * localization is present because this is an interface from the kernel |
| 1038 | * to this program (eg not an end-user interface), so isdigit() isn't |
| 1039 | * used here. |
| 1040 | */ |
| 1041 | if (fmt[2] != '\0' && fmt[2] >= '0' && fmt[2] <= '9') |
| 1042 | prec = fmt[2] - '0'; |
| 1043 | else |
| 1044 | prec = 1; |
| 1045 | p = &str[len - 1]; |
| 1046 | if (*p == 'C' || *p == 'F' || *p == 'K') { |
| 1047 | temp = strtof(str, endptrp); |
| 1048 | if (*endptrp != str && *endptrp == p && errno == 0) { |
| 1049 | if (*p == 'F') |
| 1050 | temp = (temp - 32) * 5 / 9; |
| 1051 | *endptrp = NULL; |
| 1052 | if (*p != 'K') |
| 1053 | temp += 273.15; |
| 1054 | for (i = 0; i < prec; i++) |
| 1055 | temp *= 10.0; |
| 1056 | return ((int)(temp + 0.5)); |
| 1057 | } |
| 1058 | } else { |
| 1059 | /* No unit specified -> treat it as a raw number */ |
| 1060 | kelv = (int)strtol(str, endptrp, 10); |
| 1061 | if (*endptrp != str && *endptrp == p && errno == 0) { |
| 1062 | *endptrp = NULL; |
| 1063 | return (kelv); |
| 1064 | } |
| 1065 | } |
| 1066 | |
| 1067 | errno = ERANGE; |
| 1068 | return (0); |
| 1069 | } |
| 1070 | |
| 1071 | /* |
| 1072 | * These functions uses a presently undocumented interface to the kernel |
no test coverage detected