1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
233ee3b2eSAlexey Dobriyan /*
333ee3b2eSAlexey Dobriyan * Convert integer string representation to an integer.
433ee3b2eSAlexey Dobriyan * If an integer doesn't fit into specified type, -E is returned.
533ee3b2eSAlexey Dobriyan *
633ee3b2eSAlexey Dobriyan * Integer starts with optional sign.
733ee3b2eSAlexey Dobriyan * kstrtou*() functions do not accept sign "-".
833ee3b2eSAlexey Dobriyan *
933ee3b2eSAlexey Dobriyan * Radix 0 means autodetection: leading "0x" implies radix 16,
1033ee3b2eSAlexey Dobriyan * leading "0" implies radix 8, otherwise radix is 10.
1133ee3b2eSAlexey Dobriyan * Autodetection hints work after optional sign, but not before.
1233ee3b2eSAlexey Dobriyan *
1333ee3b2eSAlexey Dobriyan * If -E is returned, result is not touched.
1433ee3b2eSAlexey Dobriyan */
1533ee3b2eSAlexey Dobriyan #include <linux/ctype.h>
1633ee3b2eSAlexey Dobriyan #include <linux/errno.h>
178bc3bcc9SPaul Gortmaker #include <linux/export.h>
184c527293SAndy Shevchenko #include <linux/kstrtox.h>
194c527293SAndy Shevchenko #include <linux/math64.h>
2033ee3b2eSAlexey Dobriyan #include <linux/types.h>
217c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
224c527293SAndy Shevchenko
231dff46d6SAlexey Dobriyan #include "kstrtox.h"
2433ee3b2eSAlexey Dobriyan
2570ac6992SAlexey Dobriyan noinline
_parse_integer_fixup_radix(const char * s,unsigned int * base)261dff46d6SAlexey Dobriyan const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
2733ee3b2eSAlexey Dobriyan {
281dff46d6SAlexey Dobriyan if (*base == 0) {
2933ee3b2eSAlexey Dobriyan if (s[0] == '0') {
3033ee3b2eSAlexey Dobriyan if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
311dff46d6SAlexey Dobriyan *base = 16;
3233ee3b2eSAlexey Dobriyan else
331dff46d6SAlexey Dobriyan *base = 8;
3433ee3b2eSAlexey Dobriyan } else
351dff46d6SAlexey Dobriyan *base = 10;
3633ee3b2eSAlexey Dobriyan }
371dff46d6SAlexey Dobriyan if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
3833ee3b2eSAlexey Dobriyan s += 2;
391dff46d6SAlexey Dobriyan return s;
401dff46d6SAlexey Dobriyan }
4133ee3b2eSAlexey Dobriyan
421dff46d6SAlexey Dobriyan /*
431dff46d6SAlexey Dobriyan * Convert non-negative integer string representation in explicitly given radix
44900fdc45SRichard Fitzgerald * to an integer. A maximum of max_chars characters will be converted.
45900fdc45SRichard Fitzgerald *
461dff46d6SAlexey Dobriyan * Return number of characters consumed maybe or-ed with overflow bit.
471dff46d6SAlexey Dobriyan * If overflow occurs, result integer (incorrect) is still returned.
481dff46d6SAlexey Dobriyan *
491dff46d6SAlexey Dobriyan * Don't you dare use this function.
501dff46d6SAlexey Dobriyan */
5170ac6992SAlexey Dobriyan noinline
_parse_integer_limit(const char * s,unsigned int base,unsigned long long * p,size_t max_chars)52900fdc45SRichard Fitzgerald unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *p,
53900fdc45SRichard Fitzgerald size_t max_chars)
541dff46d6SAlexey Dobriyan {
55690d137fSDavid Howells unsigned long long res;
561dff46d6SAlexey Dobriyan unsigned int rv;
571dff46d6SAlexey Dobriyan
58690d137fSDavid Howells res = 0;
591dff46d6SAlexey Dobriyan rv = 0;
60900fdc45SRichard Fitzgerald while (max_chars--) {
61be5f3c77SAlexey Dobriyan unsigned int c = *s;
62*3d0b7139SAndy Shevchenko unsigned int lc = _tolower(c);
6333ee3b2eSAlexey Dobriyan unsigned int val;
6433ee3b2eSAlexey Dobriyan
65be5f3c77SAlexey Dobriyan if ('0' <= c && c <= '9')
66be5f3c77SAlexey Dobriyan val = c - '0';
67be5f3c77SAlexey Dobriyan else if ('a' <= lc && lc <= 'f')
68be5f3c77SAlexey Dobriyan val = lc - 'a' + 10;
6933ee3b2eSAlexey Dobriyan else
701dff46d6SAlexey Dobriyan break;
7133ee3b2eSAlexey Dobriyan
7233ee3b2eSAlexey Dobriyan if (val >= base)
731dff46d6SAlexey Dobriyan break;
74690d137fSDavid Howells /*
75690d137fSDavid Howells * Check for overflow only if we are within range of
76690d137fSDavid Howells * it in the max base we support (16)
77690d137fSDavid Howells */
78690d137fSDavid Howells if (unlikely(res & (~0ull << 60))) {
79690d137fSDavid Howells if (res > div_u64(ULLONG_MAX - val, base))
808cfd56d4SAlexey Dobriyan rv |= KSTRTOX_OVERFLOW;
81690d137fSDavid Howells }
82690d137fSDavid Howells res = res * base + val;
831dff46d6SAlexey Dobriyan rv++;
8433ee3b2eSAlexey Dobriyan s++;
8533ee3b2eSAlexey Dobriyan }
86690d137fSDavid Howells *p = res;
871dff46d6SAlexey Dobriyan return rv;
881dff46d6SAlexey Dobriyan }
891dff46d6SAlexey Dobriyan
9070ac6992SAlexey Dobriyan noinline
_parse_integer(const char * s,unsigned int base,unsigned long long * p)91900fdc45SRichard Fitzgerald unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
92900fdc45SRichard Fitzgerald {
93900fdc45SRichard Fitzgerald return _parse_integer_limit(s, base, p, INT_MAX);
94900fdc45SRichard Fitzgerald }
95900fdc45SRichard Fitzgerald
_kstrtoull(const char * s,unsigned int base,unsigned long long * res)961dff46d6SAlexey Dobriyan static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
971dff46d6SAlexey Dobriyan {
981dff46d6SAlexey Dobriyan unsigned long long _res;
991dff46d6SAlexey Dobriyan unsigned int rv;
1001dff46d6SAlexey Dobriyan
1011dff46d6SAlexey Dobriyan s = _parse_integer_fixup_radix(s, &base);
1021dff46d6SAlexey Dobriyan rv = _parse_integer(s, base, &_res);
1031dff46d6SAlexey Dobriyan if (rv & KSTRTOX_OVERFLOW)
1041dff46d6SAlexey Dobriyan return -ERANGE;
1051dff46d6SAlexey Dobriyan if (rv == 0)
10633ee3b2eSAlexey Dobriyan return -EINVAL;
1071dff46d6SAlexey Dobriyan s += rv;
1081dff46d6SAlexey Dobriyan if (*s == '\n')
1091dff46d6SAlexey Dobriyan s++;
1101dff46d6SAlexey Dobriyan if (*s)
1111dff46d6SAlexey Dobriyan return -EINVAL;
1121dff46d6SAlexey Dobriyan *res = _res;
11333ee3b2eSAlexey Dobriyan return 0;
11433ee3b2eSAlexey Dobriyan }
11533ee3b2eSAlexey Dobriyan
1164c925d60SEldad Zack /**
1174c925d60SEldad Zack * kstrtoull - convert a string to an unsigned long long
1184c925d60SEldad Zack * @s: The start of the string. The string must be null-terminated, and may also
1194c925d60SEldad Zack * include a single newline before its terminating null. The first character
1204c925d60SEldad Zack * may also be a plus sign, but not a minus sign.
1214c925d60SEldad Zack * @base: The number base to use. The maximum supported base is 16. If base is
1224c925d60SEldad Zack * given as 0, then the base of the string is automatically detected with the
1234c925d60SEldad Zack * conventional semantics - If it begins with 0x the number will be parsed as a
1244c925d60SEldad Zack * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
1254c925d60SEldad Zack * parsed as an octal number. Otherwise it will be parsed as a decimal.
1264c925d60SEldad Zack * @res: Where to write the result of the conversion on success.
1274c925d60SEldad Zack *
1284c925d60SEldad Zack * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
129ef0f2685SKars Mulder * Preferred over simple_strtoull(). Return code must be checked.
1304c925d60SEldad Zack */
13170ac6992SAlexey Dobriyan noinline
kstrtoull(const char * s,unsigned int base,unsigned long long * res)13233ee3b2eSAlexey Dobriyan int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
13333ee3b2eSAlexey Dobriyan {
13433ee3b2eSAlexey Dobriyan if (s[0] == '+')
13533ee3b2eSAlexey Dobriyan s++;
13633ee3b2eSAlexey Dobriyan return _kstrtoull(s, base, res);
13733ee3b2eSAlexey Dobriyan }
13833ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(kstrtoull);
13933ee3b2eSAlexey Dobriyan
1404c925d60SEldad Zack /**
1414c925d60SEldad Zack * kstrtoll - convert a string to a long long
1424c925d60SEldad Zack * @s: The start of the string. The string must be null-terminated, and may also
1434c925d60SEldad Zack * include a single newline before its terminating null. The first character
1444c925d60SEldad Zack * may also be a plus sign or a minus sign.
1454c925d60SEldad Zack * @base: The number base to use. The maximum supported base is 16. If base is
1464c925d60SEldad Zack * given as 0, then the base of the string is automatically detected with the
1474c925d60SEldad Zack * conventional semantics - If it begins with 0x the number will be parsed as a
1484c925d60SEldad Zack * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
1494c925d60SEldad Zack * parsed as an octal number. Otherwise it will be parsed as a decimal.
1504c925d60SEldad Zack * @res: Where to write the result of the conversion on success.
1514c925d60SEldad Zack *
1524c925d60SEldad Zack * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
153ef0f2685SKars Mulder * Preferred over simple_strtoll(). Return code must be checked.
1544c925d60SEldad Zack */
15570ac6992SAlexey Dobriyan noinline
kstrtoll(const char * s,unsigned int base,long long * res)15633ee3b2eSAlexey Dobriyan int kstrtoll(const char *s, unsigned int base, long long *res)
15733ee3b2eSAlexey Dobriyan {
15833ee3b2eSAlexey Dobriyan unsigned long long tmp;
15933ee3b2eSAlexey Dobriyan int rv;
16033ee3b2eSAlexey Dobriyan
16133ee3b2eSAlexey Dobriyan if (s[0] == '-') {
16233ee3b2eSAlexey Dobriyan rv = _kstrtoull(s + 1, base, &tmp);
16333ee3b2eSAlexey Dobriyan if (rv < 0)
16433ee3b2eSAlexey Dobriyan return rv;
1652d2e4715SAlexey Dobriyan if ((long long)-tmp > 0)
16633ee3b2eSAlexey Dobriyan return -ERANGE;
16733ee3b2eSAlexey Dobriyan *res = -tmp;
16833ee3b2eSAlexey Dobriyan } else {
16933ee3b2eSAlexey Dobriyan rv = kstrtoull(s, base, &tmp);
17033ee3b2eSAlexey Dobriyan if (rv < 0)
17133ee3b2eSAlexey Dobriyan return rv;
17233ee3b2eSAlexey Dobriyan if ((long long)tmp < 0)
17333ee3b2eSAlexey Dobriyan return -ERANGE;
17433ee3b2eSAlexey Dobriyan *res = tmp;
17533ee3b2eSAlexey Dobriyan }
17633ee3b2eSAlexey Dobriyan return 0;
17733ee3b2eSAlexey Dobriyan }
17833ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(kstrtoll);
17933ee3b2eSAlexey Dobriyan
18033ee3b2eSAlexey Dobriyan /* Internal, do not use. */
_kstrtoul(const char * s,unsigned int base,unsigned long * res)18133ee3b2eSAlexey Dobriyan int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
18233ee3b2eSAlexey Dobriyan {
18333ee3b2eSAlexey Dobriyan unsigned long long tmp;
18433ee3b2eSAlexey Dobriyan int rv;
18533ee3b2eSAlexey Dobriyan
18633ee3b2eSAlexey Dobriyan rv = kstrtoull(s, base, &tmp);
18733ee3b2eSAlexey Dobriyan if (rv < 0)
18833ee3b2eSAlexey Dobriyan return rv;
189048e513dSAlexey Dobriyan if (tmp != (unsigned long)tmp)
19033ee3b2eSAlexey Dobriyan return -ERANGE;
19133ee3b2eSAlexey Dobriyan *res = tmp;
19233ee3b2eSAlexey Dobriyan return 0;
19333ee3b2eSAlexey Dobriyan }
19433ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(_kstrtoul);
19533ee3b2eSAlexey Dobriyan
19633ee3b2eSAlexey Dobriyan /* Internal, do not use. */
_kstrtol(const char * s,unsigned int base,long * res)19733ee3b2eSAlexey Dobriyan int _kstrtol(const char *s, unsigned int base, long *res)
19833ee3b2eSAlexey Dobriyan {
19933ee3b2eSAlexey Dobriyan long long tmp;
20033ee3b2eSAlexey Dobriyan int rv;
20133ee3b2eSAlexey Dobriyan
20233ee3b2eSAlexey Dobriyan rv = kstrtoll(s, base, &tmp);
20333ee3b2eSAlexey Dobriyan if (rv < 0)
20433ee3b2eSAlexey Dobriyan return rv;
205048e513dSAlexey Dobriyan if (tmp != (long)tmp)
20633ee3b2eSAlexey Dobriyan return -ERANGE;
20733ee3b2eSAlexey Dobriyan *res = tmp;
20833ee3b2eSAlexey Dobriyan return 0;
20933ee3b2eSAlexey Dobriyan }
21033ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(_kstrtol);
21133ee3b2eSAlexey Dobriyan
2124c925d60SEldad Zack /**
2134c925d60SEldad Zack * kstrtouint - convert a string to an unsigned int
2144c925d60SEldad Zack * @s: The start of the string. The string must be null-terminated, and may also
2154c925d60SEldad Zack * include a single newline before its terminating null. The first character
2164c925d60SEldad Zack * may also be a plus sign, but not a minus sign.
2174c925d60SEldad Zack * @base: The number base to use. The maximum supported base is 16. If base is
2184c925d60SEldad Zack * given as 0, then the base of the string is automatically detected with the
2194c925d60SEldad Zack * conventional semantics - If it begins with 0x the number will be parsed as a
2204c925d60SEldad Zack * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
2214c925d60SEldad Zack * parsed as an octal number. Otherwise it will be parsed as a decimal.
2224c925d60SEldad Zack * @res: Where to write the result of the conversion on success.
2234c925d60SEldad Zack *
2244c925d60SEldad Zack * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
225ef0f2685SKars Mulder * Preferred over simple_strtoul(). Return code must be checked.
2264c925d60SEldad Zack */
22770ac6992SAlexey Dobriyan noinline
kstrtouint(const char * s,unsigned int base,unsigned int * res)22833ee3b2eSAlexey Dobriyan int kstrtouint(const char *s, unsigned int base, unsigned int *res)
22933ee3b2eSAlexey Dobriyan {
23033ee3b2eSAlexey Dobriyan unsigned long long tmp;
23133ee3b2eSAlexey Dobriyan int rv;
23233ee3b2eSAlexey Dobriyan
23333ee3b2eSAlexey Dobriyan rv = kstrtoull(s, base, &tmp);
23433ee3b2eSAlexey Dobriyan if (rv < 0)
23533ee3b2eSAlexey Dobriyan return rv;
236048e513dSAlexey Dobriyan if (tmp != (unsigned int)tmp)
23733ee3b2eSAlexey Dobriyan return -ERANGE;
23833ee3b2eSAlexey Dobriyan *res = tmp;
23933ee3b2eSAlexey Dobriyan return 0;
24033ee3b2eSAlexey Dobriyan }
24133ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(kstrtouint);
24233ee3b2eSAlexey Dobriyan
2434c925d60SEldad Zack /**
2444c925d60SEldad Zack * kstrtoint - convert a string to an int
2454c925d60SEldad Zack * @s: The start of the string. The string must be null-terminated, and may also
2464c925d60SEldad Zack * include a single newline before its terminating null. The first character
2474c925d60SEldad Zack * may also be a plus sign or a minus sign.
2484c925d60SEldad Zack * @base: The number base to use. The maximum supported base is 16. If base is
2494c925d60SEldad Zack * given as 0, then the base of the string is automatically detected with the
2504c925d60SEldad Zack * conventional semantics - If it begins with 0x the number will be parsed as a
2514c925d60SEldad Zack * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
2524c925d60SEldad Zack * parsed as an octal number. Otherwise it will be parsed as a decimal.
2534c925d60SEldad Zack * @res: Where to write the result of the conversion on success.
2544c925d60SEldad Zack *
2554c925d60SEldad Zack * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
256ef0f2685SKars Mulder * Preferred over simple_strtol(). Return code must be checked.
2574c925d60SEldad Zack */
25870ac6992SAlexey Dobriyan noinline
kstrtoint(const char * s,unsigned int base,int * res)25933ee3b2eSAlexey Dobriyan int kstrtoint(const char *s, unsigned int base, int *res)
26033ee3b2eSAlexey Dobriyan {
26133ee3b2eSAlexey Dobriyan long long tmp;
26233ee3b2eSAlexey Dobriyan int rv;
26333ee3b2eSAlexey Dobriyan
26433ee3b2eSAlexey Dobriyan rv = kstrtoll(s, base, &tmp);
26533ee3b2eSAlexey Dobriyan if (rv < 0)
26633ee3b2eSAlexey Dobriyan return rv;
267048e513dSAlexey Dobriyan if (tmp != (int)tmp)
26833ee3b2eSAlexey Dobriyan return -ERANGE;
26933ee3b2eSAlexey Dobriyan *res = tmp;
27033ee3b2eSAlexey Dobriyan return 0;
27133ee3b2eSAlexey Dobriyan }
27233ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(kstrtoint);
27333ee3b2eSAlexey Dobriyan
27470ac6992SAlexey Dobriyan noinline
kstrtou16(const char * s,unsigned int base,u16 * res)27533ee3b2eSAlexey Dobriyan int kstrtou16(const char *s, unsigned int base, u16 *res)
27633ee3b2eSAlexey Dobriyan {
27733ee3b2eSAlexey Dobriyan unsigned long long tmp;
27833ee3b2eSAlexey Dobriyan int rv;
27933ee3b2eSAlexey Dobriyan
28033ee3b2eSAlexey Dobriyan rv = kstrtoull(s, base, &tmp);
28133ee3b2eSAlexey Dobriyan if (rv < 0)
28233ee3b2eSAlexey Dobriyan return rv;
283048e513dSAlexey Dobriyan if (tmp != (u16)tmp)
28433ee3b2eSAlexey Dobriyan return -ERANGE;
28533ee3b2eSAlexey Dobriyan *res = tmp;
28633ee3b2eSAlexey Dobriyan return 0;
28733ee3b2eSAlexey Dobriyan }
28833ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(kstrtou16);
28933ee3b2eSAlexey Dobriyan
29070ac6992SAlexey Dobriyan noinline
kstrtos16(const char * s,unsigned int base,s16 * res)29133ee3b2eSAlexey Dobriyan int kstrtos16(const char *s, unsigned int base, s16 *res)
29233ee3b2eSAlexey Dobriyan {
29333ee3b2eSAlexey Dobriyan long long tmp;
29433ee3b2eSAlexey Dobriyan int rv;
29533ee3b2eSAlexey Dobriyan
29633ee3b2eSAlexey Dobriyan rv = kstrtoll(s, base, &tmp);
29733ee3b2eSAlexey Dobriyan if (rv < 0)
29833ee3b2eSAlexey Dobriyan return rv;
299048e513dSAlexey Dobriyan if (tmp != (s16)tmp)
30033ee3b2eSAlexey Dobriyan return -ERANGE;
30133ee3b2eSAlexey Dobriyan *res = tmp;
30233ee3b2eSAlexey Dobriyan return 0;
30333ee3b2eSAlexey Dobriyan }
30433ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(kstrtos16);
30533ee3b2eSAlexey Dobriyan
30670ac6992SAlexey Dobriyan noinline
kstrtou8(const char * s,unsigned int base,u8 * res)30733ee3b2eSAlexey Dobriyan int kstrtou8(const char *s, unsigned int base, u8 *res)
30833ee3b2eSAlexey Dobriyan {
30933ee3b2eSAlexey Dobriyan unsigned long long tmp;
31033ee3b2eSAlexey Dobriyan int rv;
31133ee3b2eSAlexey Dobriyan
31233ee3b2eSAlexey Dobriyan rv = kstrtoull(s, base, &tmp);
31333ee3b2eSAlexey Dobriyan if (rv < 0)
31433ee3b2eSAlexey Dobriyan return rv;
315048e513dSAlexey Dobriyan if (tmp != (u8)tmp)
31633ee3b2eSAlexey Dobriyan return -ERANGE;
31733ee3b2eSAlexey Dobriyan *res = tmp;
31833ee3b2eSAlexey Dobriyan return 0;
31933ee3b2eSAlexey Dobriyan }
32033ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(kstrtou8);
32133ee3b2eSAlexey Dobriyan
32270ac6992SAlexey Dobriyan noinline
kstrtos8(const char * s,unsigned int base,s8 * res)32333ee3b2eSAlexey Dobriyan int kstrtos8(const char *s, unsigned int base, s8 *res)
32433ee3b2eSAlexey Dobriyan {
32533ee3b2eSAlexey Dobriyan long long tmp;
32633ee3b2eSAlexey Dobriyan int rv;
32733ee3b2eSAlexey Dobriyan
32833ee3b2eSAlexey Dobriyan rv = kstrtoll(s, base, &tmp);
32933ee3b2eSAlexey Dobriyan if (rv < 0)
33033ee3b2eSAlexey Dobriyan return rv;
331048e513dSAlexey Dobriyan if (tmp != (s8)tmp)
33233ee3b2eSAlexey Dobriyan return -ERANGE;
33333ee3b2eSAlexey Dobriyan *res = tmp;
33433ee3b2eSAlexey Dobriyan return 0;
33533ee3b2eSAlexey Dobriyan }
33633ee3b2eSAlexey Dobriyan EXPORT_SYMBOL(kstrtos8);
337c196e32aSAlexey Dobriyan
338ef951599SKees Cook /**
339ef951599SKees Cook * kstrtobool - convert common user inputs into boolean values
340ef951599SKees Cook * @s: input string
341ef951599SKees Cook * @res: result
342ef951599SKees Cook *
3430d6ea3acSJagdish Gediya * This routine returns 0 iff the first character is one of 'YyTt1NnFf0', or
344a81a5a17SKees Cook * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL. Value
345a81a5a17SKees Cook * pointed to by res is updated upon finding a match.
346ef951599SKees Cook */
34770ac6992SAlexey Dobriyan noinline
kstrtobool(const char * s,bool * res)348ef951599SKees Cook int kstrtobool(const char *s, bool *res)
349ef951599SKees Cook {
350ef951599SKees Cook if (!s)
351ef951599SKees Cook return -EINVAL;
352ef951599SKees Cook
353ef951599SKees Cook switch (s[0]) {
354ef951599SKees Cook case 'y':
355ef951599SKees Cook case 'Y':
3560d6ea3acSJagdish Gediya case 't':
3570d6ea3acSJagdish Gediya case 'T':
358ef951599SKees Cook case '1':
359ef951599SKees Cook *res = true;
360ef951599SKees Cook return 0;
361ef951599SKees Cook case 'n':
362ef951599SKees Cook case 'N':
3630d6ea3acSJagdish Gediya case 'f':
3640d6ea3acSJagdish Gediya case 'F':
365ef951599SKees Cook case '0':
366ef951599SKees Cook *res = false;
367ef951599SKees Cook return 0;
368a81a5a17SKees Cook case 'o':
369a81a5a17SKees Cook case 'O':
370a81a5a17SKees Cook switch (s[1]) {
371a81a5a17SKees Cook case 'n':
372a81a5a17SKees Cook case 'N':
373a81a5a17SKees Cook *res = true;
374a81a5a17SKees Cook return 0;
375a81a5a17SKees Cook case 'f':
376a81a5a17SKees Cook case 'F':
377a81a5a17SKees Cook *res = false;
378a81a5a17SKees Cook return 0;
379a81a5a17SKees Cook default:
380a81a5a17SKees Cook break;
381a81a5a17SKees Cook }
38236f9ff9eSGustavo A. R. Silva break;
383ef951599SKees Cook default:
384ef951599SKees Cook break;
385ef951599SKees Cook }
386ef951599SKees Cook
387ef951599SKees Cook return -EINVAL;
388ef951599SKees Cook }
389ef951599SKees Cook EXPORT_SYMBOL(kstrtobool);
390ef951599SKees Cook
391ef951599SKees Cook /*
392ef951599SKees Cook * Since "base" would be a nonsense argument, this open-codes the
393ef951599SKees Cook * _from_user helper instead of using the helper macro below.
394ef951599SKees Cook */
kstrtobool_from_user(const char __user * s,size_t count,bool * res)395ef951599SKees Cook int kstrtobool_from_user(const char __user *s, size_t count, bool *res)
396ef951599SKees Cook {
397ef951599SKees Cook /* Longest string needed to differentiate, newline, terminator */
398ef951599SKees Cook char buf[4];
399ef951599SKees Cook
400ef951599SKees Cook count = min(count, sizeof(buf) - 1);
401ef951599SKees Cook if (copy_from_user(buf, s, count))
402ef951599SKees Cook return -EFAULT;
403ef951599SKees Cook buf[count] = '\0';
404ef951599SKees Cook return kstrtobool(buf, res);
405ef951599SKees Cook }
406ef951599SKees Cook EXPORT_SYMBOL(kstrtobool_from_user);
407ef951599SKees Cook
408c196e32aSAlexey Dobriyan #define kstrto_from_user(f, g, type) \
409c196e32aSAlexey Dobriyan int f(const char __user *s, size_t count, unsigned int base, type *res) \
410c196e32aSAlexey Dobriyan { \
411c196e32aSAlexey Dobriyan /* sign, base 2 representation, newline, terminator */ \
412c196e32aSAlexey Dobriyan char buf[1 + sizeof(type) * 8 + 1 + 1]; \
413c196e32aSAlexey Dobriyan \
414c196e32aSAlexey Dobriyan count = min(count, sizeof(buf) - 1); \
415c196e32aSAlexey Dobriyan if (copy_from_user(buf, s, count)) \
416c196e32aSAlexey Dobriyan return -EFAULT; \
417c196e32aSAlexey Dobriyan buf[count] = '\0'; \
418c196e32aSAlexey Dobriyan return g(buf, base, res); \
419c196e32aSAlexey Dobriyan } \
420c196e32aSAlexey Dobriyan EXPORT_SYMBOL(f)
421c196e32aSAlexey Dobriyan
422c196e32aSAlexey Dobriyan kstrto_from_user(kstrtoull_from_user, kstrtoull, unsigned long long);
423c196e32aSAlexey Dobriyan kstrto_from_user(kstrtoll_from_user, kstrtoll, long long);
424c196e32aSAlexey Dobriyan kstrto_from_user(kstrtoul_from_user, kstrtoul, unsigned long);
425c196e32aSAlexey Dobriyan kstrto_from_user(kstrtol_from_user, kstrtol, long);
426c196e32aSAlexey Dobriyan kstrto_from_user(kstrtouint_from_user, kstrtouint, unsigned int);
427c196e32aSAlexey Dobriyan kstrto_from_user(kstrtoint_from_user, kstrtoint, int);
428c196e32aSAlexey Dobriyan kstrto_from_user(kstrtou16_from_user, kstrtou16, u16);
429c196e32aSAlexey Dobriyan kstrto_from_user(kstrtos16_from_user, kstrtos16, s16);
430c196e32aSAlexey Dobriyan kstrto_from_user(kstrtou8_from_user, kstrtou8, u8);
431c196e32aSAlexey Dobriyan kstrto_from_user(kstrtos8_from_user, kstrtos8, s8);
432