Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/include/linux/kstrtox.h
| Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| return (strtol(cp, endp, base)); | return (strtol(cp, endp, base)); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtoul(const char *cp, unsigned int base, unsigned long *res) | kstrtoul(const char *cp, unsigned int base, unsigned long *res) | ||||
| { | { | ||||
| char *end; | char *end; | ||||
| unsigned long temp; | |||||
| *res = strtoul(cp, &end, base); | temp = strtoul(cp, &end, base); | ||||
| /* skip newline character, if any */ | /* skip newline character, if any */ | ||||
| if (*end == '\n') | if (*end == '\n') | ||||
bz: This may also take a leading + but no minus according to the documentation (unrelated to this… | |||||
Not Done Inline ActionsForgive me. kstrtoul*l* does, not the one with just one 'l'. The double-ll is further down and would need the check before calling into the other one. bz: Forgive me. kstrtoul*l* does, not the one with just one 'l'. The double-ll is further down and… | |||||
Done Inline ActionsI think perhaps someone should write a test suite for the entire family and run it on Linux, and then we can adjust our implementations to match. des: I think perhaps someone should write a test suite for the entire family and run it on Linux… | |||||
| end++; | end++; | ||||
| if (*cp == 0 || *end != 0) | if (*cp == 0 || *end != 0) | ||||
| return (-EINVAL); | return (-EINVAL); | ||||
| *res = temp; | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtol(const char *cp, unsigned int base, long *res) | kstrtol(const char *cp, unsigned int base, long *res) | ||||
| { | { | ||||
| char *end; | char *end; | ||||
| long temp; | |||||
| *res = strtol(cp, &end, base); | temp = strtol(cp, &end, base); | ||||
| /* skip newline character, if any */ | /* skip newline character, if any */ | ||||
| if (*end == '\n') | if (*end == '\n') | ||||
| end++; | end++; | ||||
| if (*cp == 0 || *end != 0) | if (*cp == 0 || *end != 0) | ||||
| return (-EINVAL); | return (-EINVAL); | ||||
| *res = temp; | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtoint(const char *cp, unsigned int base, int *res) | kstrtoint(const char *cp, unsigned int base, int *res) | ||||
| { | { | ||||
| char *end; | char *end; | ||||
| long temp; | long temp; | ||||
| *res = temp = strtol(cp, &end, base); | temp = strtol(cp, &end, base); | ||||
| /* skip newline character, if any */ | /* skip newline character, if any */ | ||||
| if (*end == '\n') | if (*end == '\n') | ||||
| end++; | end++; | ||||
| if (*cp == 0 || *end != 0) | if (*cp == 0 || *end != 0) | ||||
| return (-EINVAL); | return (-EINVAL); | ||||
| if (temp != (int)temp) | if (temp != (int)temp) | ||||
| return (-ERANGE); | return (-ERANGE); | ||||
| *res = (int)temp; | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtouint(const char *cp, unsigned int base, unsigned int *res) | kstrtouint(const char *cp, unsigned int base, unsigned int *res) | ||||
| { | { | ||||
| char *end; | char *end; | ||||
| unsigned long temp; | unsigned long temp; | ||||
| *res = temp = strtoul(cp, &end, base); | temp = strtoul(cp, &end, base); | ||||
| /* skip newline character, if any */ | /* skip newline character, if any */ | ||||
| if (*end == '\n') | if (*end == '\n') | ||||
| end++; | end++; | ||||
| if (*cp == 0 || *end != 0) | if (*cp == 0 || *end != 0) | ||||
| return (-EINVAL); | return (-EINVAL); | ||||
| if (temp != (unsigned int)temp) | if (temp != (unsigned int)temp) | ||||
| return (-ERANGE); | return (-ERANGE); | ||||
| *res = (unsigned int)temp; | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtou8(const char *cp, unsigned int base, uint8_t *res) | kstrtou8(const char *cp, unsigned int base, uint8_t *res) | ||||
| { | { | ||||
| char *end; | char *end; | ||||
| unsigned long temp; | unsigned long temp; | ||||
| *res = temp = strtoul(cp, &end, base); | temp = strtoul(cp, &end, base); | ||||
| /* skip newline character, if any */ | /* skip newline character, if any */ | ||||
| if (*end == '\n') | if (*end == '\n') | ||||
| end++; | end++; | ||||
| if (*cp == 0 || *end != 0) | if (*cp == 0 || *end != 0) | ||||
| return (-EINVAL); | return (-EINVAL); | ||||
| if (temp != (uint8_t)temp) | if (temp != (uint8_t)temp) | ||||
| return (-ERANGE); | return (-ERANGE); | ||||
| *res = (uint8_t)temp; | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtou16(const char *cp, unsigned int base, uint16_t *res) | kstrtou16(const char *cp, unsigned int base, uint16_t *res) | ||||
| { | { | ||||
| char *end; | char *end; | ||||
| unsigned long temp; | unsigned long temp; | ||||
| *res = temp = strtoul(cp, &end, base); | temp = strtoul(cp, &end, base); | ||||
| /* skip newline character, if any */ | /* skip newline character, if any */ | ||||
| if (*end == '\n') | if (*end == '\n') | ||||
| end++; | end++; | ||||
| if (*cp == 0 || *end != 0) | if (*cp == 0 || *end != 0) | ||||
| return (-EINVAL); | return (-EINVAL); | ||||
| if (temp != (uint16_t)temp) | if (temp != (uint16_t)temp) | ||||
| return (-ERANGE); | return (-ERANGE); | ||||
| *res = (uint16_t)temp; | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtou32(const char *cp, unsigned int base, uint32_t *res) | kstrtou32(const char *cp, unsigned int base, uint32_t *res) | ||||
| { | { | ||||
| return (kstrtouint(cp, base, res)); | return (kstrtouint(cp, base, res)); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtos32(const char *cp, unsigned int base, int32_t *res) | kstrtos32(const char *cp, unsigned int base, int32_t *res) | ||||
| { | { | ||||
| return (kstrtoint(cp, base, res)); | return (kstrtoint(cp, base, res)); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtos64(const char *cp, unsigned int base, int64_t *res) | kstrtos64(const char *cp, unsigned int base, int64_t *res) | ||||
| { | { | ||||
| char *end; | char *end; | ||||
| quad_t temp; | |||||
| *res = strtoq(cp, &end, base); | temp = strtoq(cp, &end, base); | ||||
| /* skip newline character, if any */ | /* skip newline character, if any */ | ||||
| if (*end == '\n') | if (*end == '\n') | ||||
| end++; | end++; | ||||
| if (*cp == 0 || *end != 0) | if (*cp == 0 || *end != 0) | ||||
| return (-EINVAL); | return (-EINVAL); | ||||
| *res = (int64_t)temp; | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtoll(const char *cp, unsigned int base, long long *res) | kstrtoll(const char *cp, unsigned int base, long long *res) | ||||
| { | { | ||||
| return (kstrtos64(cp, base, (int64_t *)res)); | return (kstrtos64(cp, base, (int64_t *)res)); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtou64(const char *cp, unsigned int base, u64 *res) | kstrtou64(const char *cp, unsigned int base, uint64_t *res) | ||||
| { | { | ||||
| char *end; | char *end; | ||||
| u_quad_t temp; | |||||
| *res = strtouq(cp, &end, base); | temp = strtouq(cp, &end, base); | ||||
| /* skip newline character, if any */ | /* skip newline character, if any */ | ||||
| if (*end == '\n') | if (*end == '\n') | ||||
| end++; | end++; | ||||
| if (*cp == 0 || *end != 0) | if (*cp == 0 || *end != 0) | ||||
| return (-EINVAL); | return (-EINVAL); | ||||
| *res = (uint64_t)temp; | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtoull(const char *cp, unsigned int base, unsigned long long *res) | kstrtoull(const char *cp, unsigned int base, unsigned long long *res) | ||||
| { | { | ||||
| return (kstrtou64(cp, base, (uint64_t *)res)); | return (kstrtou64(cp, base, (uint64_t *)res)); | ||||
Not Done Inline ActionsThis one but not kstrtou64() may also take a leading '+'. (irrelevant to this review; sorry; see above) bz: This one but not kstrtou64() may also take a leading '+'. (irrelevant to this review; sorry… | |||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtobool(const char *s, bool *res) | kstrtobool(const char *s, bool *res) | ||||
| { | { | ||||
| int len; | size_t len; | ||||
| if (s == NULL || (len = strlen(s)) == 0 || res == NULL) | if (s == NULL || (len = strlen(s)) == 0 || res == NULL) | ||||
| return (-EINVAL); | return (-EINVAL); | ||||
| /* skip newline character, if any */ | /* skip newline character, if any */ | ||||
| if (s[len - 1] == '\n') | if (s[len - 1] == '\n') | ||||
| len--; | len--; | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | kstrtouint_from_user(const char __user *s, size_t count, unsigned int base, | ||||
| return (kstrtouint(buf, base, p)); | return (kstrtouint(buf, base, p)); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtou32_from_user(const char __user *s, size_t count, unsigned int base, | kstrtou32_from_user(const char __user *s, size_t count, unsigned int base, | ||||
| unsigned int *p) | unsigned int *p) | ||||
| { | { | ||||
| return (kstrtouint_from_user(s, count, base, p)); | return (kstrtouint_from_user(s, count, base, p)); | ||||
| } | } | ||||
| static inline int | static inline int | ||||
| kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, | kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, | ||||
| uint8_t *p) | uint8_t *p) | ||||
| { | { | ||||
| char buf[8] = {}; | char buf[8] = {}; | ||||
| Show All 11 Lines | |||||
This may also take a leading + but no minus according to the documentation (unrelated to this fix). Just in case someone wants to do a follow-up.