The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/lib/kstrtox.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Convert integer string representation to an integer.
    3  * If an integer doesn't fit into specified type, -E is returned.
    4  *
    5  * Integer starts with optional sign.
    6  * kstrtou*() functions do not accept sign "-".
    7  *
    8  * Radix 0 means autodetection: leading "0x" implies radix 16,
    9  * leading "" implies radix 8, otherwise radix is 10.
   10  * Autodetection hints work after optional sign, but not before.
   11  *
   12  * If -E is returned, result is not touched.
   13  */
   14 #include <linux/ctype.h>
   15 #include <linux/errno.h>
   16 #include <linux/kernel.h>
   17 #include <linux/math64.h>
   18 #include <linux/export.h>
   19 #include <linux/types.h>
   20 #include <asm/uaccess.h>
   21 #include "kstrtox.h"
   22 
   23 const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
   24 {
   25         if (*base == 0) {
   26                 if (s[0] == '') {
   27                         if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
   28                                 *base = 16;
   29                         else
   30                                 *base = 8;
   31                 } else
   32                         *base = 10;
   33         }
   34         if (*base == 16 && s[0] == '' && _tolower(s[1]) == 'x')
   35                 s += 2;
   36         return s;
   37 }
   38 
   39 /*
   40  * Convert non-negative integer string representation in explicitly given radix
   41  * to an integer.
   42  * Return number of characters consumed maybe or-ed with overflow bit.
   43  * If overflow occurs, result integer (incorrect) is still returned.
   44  *
   45  * Don't you dare use this function.
   46  */
   47 unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
   48 {
   49         unsigned long long res;
   50         unsigned int rv;
   51         int overflow;
   52 
   53         res = 0;
   54         rv = 0;
   55         overflow = 0;
   56         while (*s) {
   57                 unsigned int val;
   58 
   59                 if ('' <= *s && *s <= '9')
   60                         val = *s - '';
   61                 else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f')
   62                         val = _tolower(*s) - 'a' + 10;
   63                 else
   64                         break;
   65 
   66                 if (val >= base)
   67                         break;
   68                 /*
   69                  * Check for overflow only if we are within range of
   70                  * it in the max base we support (16)
   71                  */
   72                 if (unlikely(res & (~0ull << 60))) {
   73                         if (res > div_u64(ULLONG_MAX - val, base))
   74                                 overflow = 1;
   75                 }
   76                 res = res * base + val;
   77                 rv++;
   78                 s++;
   79         }
   80         *p = res;
   81         if (overflow)
   82                 rv |= KSTRTOX_OVERFLOW;
   83         return rv;
   84 }
   85 
   86 static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
   87 {
   88         unsigned long long _res;
   89         unsigned int rv;
   90 
   91         s = _parse_integer_fixup_radix(s, &base);
   92         rv = _parse_integer(s, base, &_res);
   93         if (rv & KSTRTOX_OVERFLOW)
   94                 return -ERANGE;
   95         rv &= ~KSTRTOX_OVERFLOW;
   96         if (rv == 0)
   97                 return -EINVAL;
   98         s += rv;
   99         if (*s == '\n')
  100                 s++;
  101         if (*s)
  102                 return -EINVAL;
  103         *res = _res;
  104         return 0;
  105 }
  106 
  107 /**
  108  * kstrtoull - convert a string to an unsigned long long
  109  * @s: The start of the string. The string must be null-terminated, and may also
  110  *  include a single newline before its terminating null. The first character
  111  *  may also be a plus sign, but not a minus sign.
  112  * @base: The number base to use. The maximum supported base is 16. If base is
  113  *  given as 0, then the base of the string is automatically detected with the
  114  *  conventional semantics - If it begins with 0x the number will be parsed as a
  115  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
  116  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
  117  * @res: Where to write the result of the conversion on success.
  118  *
  119  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
  120  * Used as a replacement for the obsolete simple_strtoull. Return code must
  121  * be checked.
  122  */
  123 int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
  124 {
  125         if (s[0] == '+')
  126                 s++;
  127         return _kstrtoull(s, base, res);
  128 }
  129 EXPORT_SYMBOL(kstrtoull);
  130 
  131 /**
  132  * kstrtoll - convert a string to a long long
  133  * @s: The start of the string. The string must be null-terminated, and may also
  134  *  include a single newline before its terminating null. The first character
  135  *  may also be a plus sign or a minus sign.
  136  * @base: The number base to use. The maximum supported base is 16. If base is
  137  *  given as 0, then the base of the string is automatically detected with the
  138  *  conventional semantics - If it begins with 0x the number will be parsed as a
  139  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
  140  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
  141  * @res: Where to write the result of the conversion on success.
  142  *
  143  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
  144  * Used as a replacement for the obsolete simple_strtoull. Return code must
  145  * be checked.
  146  */
  147 int kstrtoll(const char *s, unsigned int base, long long *res)
  148 {
  149         unsigned long long tmp;
  150         int rv;
  151 
  152         if (s[0] == '-') {
  153                 rv = _kstrtoull(s + 1, base, &tmp);
  154                 if (rv < 0)
  155                         return rv;
  156                 if ((long long)(-tmp) >= 0)
  157                         return -ERANGE;
  158                 *res = -tmp;
  159         } else {
  160                 rv = kstrtoull(s, base, &tmp);
  161                 if (rv < 0)
  162                         return rv;
  163                 if ((long long)tmp < 0)
  164                         return -ERANGE;
  165                 *res = tmp;
  166         }
  167         return 0;
  168 }
  169 EXPORT_SYMBOL(kstrtoll);
  170 
  171 /* Internal, do not use. */
  172 int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
  173 {
  174         unsigned long long tmp;
  175         int rv;
  176 
  177         rv = kstrtoull(s, base, &tmp);
  178         if (rv < 0)
  179                 return rv;
  180         if (tmp != (unsigned long long)(unsigned long)tmp)
  181                 return -ERANGE;
  182         *res = tmp;
  183         return 0;
  184 }
  185 EXPORT_SYMBOL(_kstrtoul);
  186 
  187 /* Internal, do not use. */
  188 int _kstrtol(const char *s, unsigned int base, long *res)
  189 {
  190         long long tmp;
  191         int rv;
  192 
  193         rv = kstrtoll(s, base, &tmp);
  194         if (rv < 0)
  195                 return rv;
  196         if (tmp != (long long)(long)tmp)
  197                 return -ERANGE;
  198         *res = tmp;
  199         return 0;
  200 }
  201 EXPORT_SYMBOL(_kstrtol);
  202 
  203 /**
  204  * kstrtouint - convert a string to an unsigned int
  205  * @s: The start of the string. The string must be null-terminated, and may also
  206  *  include a single newline before its terminating null. The first character
  207  *  may also be a plus sign, but not a minus sign.
  208  * @base: The number base to use. The maximum supported base is 16. If base is
  209  *  given as 0, then the base of the string is automatically detected with the
  210  *  conventional semantics - If it begins with 0x the number will be parsed as a
  211  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
  212  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
  213  * @res: Where to write the result of the conversion on success.
  214  *
  215  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
  216  * Used as a replacement for the obsolete simple_strtoull. Return code must
  217  * be checked.
  218  */
  219 int kstrtouint(const char *s, unsigned int base, unsigned int *res)
  220 {
  221         unsigned long long tmp;
  222         int rv;
  223 
  224         rv = kstrtoull(s, base, &tmp);
  225         if (rv < 0)
  226                 return rv;
  227         if (tmp != (unsigned long long)(unsigned int)tmp)
  228                 return -ERANGE;
  229         *res = tmp;
  230         return 0;
  231 }
  232 EXPORT_SYMBOL(kstrtouint);
  233 
  234 /**
  235  * kstrtoint - convert a string to an int
  236  * @s: The start of the string. The string must be null-terminated, and may also
  237  *  include a single newline before its terminating null. The first character
  238  *  may also be a plus sign or a minus sign.
  239  * @base: The number base to use. The maximum supported base is 16. If base is
  240  *  given as 0, then the base of the string is automatically detected with the
  241  *  conventional semantics - If it begins with 0x the number will be parsed as a
  242  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
  243  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
  244  * @res: Where to write the result of the conversion on success.
  245  *
  246  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
  247  * Used as a replacement for the obsolete simple_strtoull. Return code must
  248  * be checked.
  249  */
  250 int kstrtoint(const char *s, unsigned int base, int *res)
  251 {
  252         long long tmp;
  253         int rv;
  254 
  255         rv = kstrtoll(s, base, &tmp);
  256         if (rv < 0)
  257                 return rv;
  258         if (tmp != (long long)(int)tmp)
  259                 return -ERANGE;
  260         *res = tmp;
  261         return 0;
  262 }
  263 EXPORT_SYMBOL(kstrtoint);
  264 
  265 int kstrtou16(const char *s, unsigned int base, u16 *res)
  266 {
  267         unsigned long long tmp;
  268         int rv;
  269 
  270         rv = kstrtoull(s, base, &tmp);
  271         if (rv < 0)
  272                 return rv;
  273         if (tmp != (unsigned long long)(u16)tmp)
  274                 return -ERANGE;
  275         *res = tmp;
  276         return 0;
  277 }
  278 EXPORT_SYMBOL(kstrtou16);
  279 
  280 int kstrtos16(const char *s, unsigned int base, s16 *res)
  281 {
  282         long long tmp;
  283         int rv;
  284 
  285         rv = kstrtoll(s, base, &tmp);
  286         if (rv < 0)
  287                 return rv;
  288         if (tmp != (long long)(s16)tmp)
  289                 return -ERANGE;
  290         *res = tmp;
  291         return 0;
  292 }
  293 EXPORT_SYMBOL(kstrtos16);
  294 
  295 int kstrtou8(const char *s, unsigned int base, u8 *res)
  296 {
  297         unsigned long long tmp;
  298         int rv;
  299 
  300         rv = kstrtoull(s, base, &tmp);
  301         if (rv < 0)
  302                 return rv;
  303         if (tmp != (unsigned long long)(u8)tmp)
  304                 return -ERANGE;
  305         *res = tmp;
  306         return 0;
  307 }
  308 EXPORT_SYMBOL(kstrtou8);
  309 
  310 int kstrtos8(const char *s, unsigned int base, s8 *res)
  311 {
  312         long long tmp;
  313         int rv;
  314 
  315         rv = kstrtoll(s, base, &tmp);
  316         if (rv < 0)
  317                 return rv;
  318         if (tmp != (long long)(s8)tmp)
  319                 return -ERANGE;
  320         *res = tmp;
  321         return 0;
  322 }
  323 EXPORT_SYMBOL(kstrtos8);
  324 
  325 #define kstrto_from_user(f, g, type)                                    \
  326 int f(const char __user *s, size_t count, unsigned int base, type *res) \
  327 {                                                                       \
  328         /* sign, base 2 representation, newline, terminator */          \
  329         char buf[1 + sizeof(type) * 8 + 1 + 1];                         \
  330                                                                         \
  331         count = min(count, sizeof(buf) - 1);                            \
  332         if (copy_from_user(buf, s, count))                              \
  333                 return -EFAULT;                                         \
  334         buf[count] = '\0';                                              \
  335         return g(buf, base, res);                                       \
  336 }                                                                       \
  337 EXPORT_SYMBOL(f)
  338 
  339 kstrto_from_user(kstrtoull_from_user,   kstrtoull,      unsigned long long);
  340 kstrto_from_user(kstrtoll_from_user,    kstrtoll,       long long);
  341 kstrto_from_user(kstrtoul_from_user,    kstrtoul,       unsigned long);
  342 kstrto_from_user(kstrtol_from_user,     kstrtol,        long);
  343 kstrto_from_user(kstrtouint_from_user,  kstrtouint,     unsigned int);
  344 kstrto_from_user(kstrtoint_from_user,   kstrtoint,      int);
  345 kstrto_from_user(kstrtou16_from_user,   kstrtou16,      u16);
  346 kstrto_from_user(kstrtos16_from_user,   kstrtos16,      s16);
  347 kstrto_from_user(kstrtou8_from_user,    kstrtou8,       u8);
  348 kstrto_from_user(kstrtos8_from_user,    kstrtos8,       s8);

Cache object: 08a02dee6d5e7151b802615a772b6d8a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.