1*2ef9abdcSjv227347 /* 2*2ef9abdcSjv227347 * CDDL HEADER START 3*2ef9abdcSjv227347 * 4*2ef9abdcSjv227347 * The contents of this file are subject to the terms of the 5*2ef9abdcSjv227347 * Common Development and Distribution License (the "License"). 6*2ef9abdcSjv227347 * You may not use this file except in compliance with the License. 7*2ef9abdcSjv227347 * 8*2ef9abdcSjv227347 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2ef9abdcSjv227347 * or http://www.opensolaris.org/os/licensing. 10*2ef9abdcSjv227347 * See the License for the specific language governing permissions 11*2ef9abdcSjv227347 * and limitations under the License. 12*2ef9abdcSjv227347 * 13*2ef9abdcSjv227347 * When distributing Covered Code, include this CDDL HEADER in each 14*2ef9abdcSjv227347 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2ef9abdcSjv227347 * If applicable, add the following below this CDDL HEADER, with the 16*2ef9abdcSjv227347 * fields enclosed by brackets "[]" replaced with your own identifying 17*2ef9abdcSjv227347 * information: Portions Copyright [yyyy] [name of copyright owner] 18*2ef9abdcSjv227347 * 19*2ef9abdcSjv227347 * CDDL HEADER END 20*2ef9abdcSjv227347 */ 21*2ef9abdcSjv227347 22*2ef9abdcSjv227347 /* 23*2ef9abdcSjv227347 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*2ef9abdcSjv227347 * Use is subject to license terms. 25*2ef9abdcSjv227347 */ 26*2ef9abdcSjv227347 27*2ef9abdcSjv227347 /* Copyright (c) 1988 AT&T */ 28*2ef9abdcSjv227347 /* All Rights Reserved */ 29*2ef9abdcSjv227347 30*2ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 31*2ef9abdcSjv227347 #include <sys/errno.h> 32*2ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 33*2ef9abdcSjv227347 #if !defined(_BOOT) && !defined(_KMDB) 34*2ef9abdcSjv227347 #include "lint.h" 35*2ef9abdcSjv227347 #endif /* !_BOOT && !_KMDB */ 36*2ef9abdcSjv227347 #include <errno.h> 37*2ef9abdcSjv227347 #include <ctype.h> 38*2ef9abdcSjv227347 #include <limits.h> 39*2ef9abdcSjv227347 #include <stdlib.h> 40*2ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 41*2ef9abdcSjv227347 #include "strtolctype.h" 42*2ef9abdcSjv227347 #include <sys/types.h> 43*2ef9abdcSjv227347 44*2ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 45*2ef9abdcSjv227347 int 46*2ef9abdcSjv227347 ddi_strtoll(const char *str, char **nptr, int base, longlong_t *result) 47*2ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 48*2ef9abdcSjv227347 longlong_t 49*2ef9abdcSjv227347 strtoll(const char *str, char **nptr, int base) 50*2ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 51*2ef9abdcSjv227347 { 52*2ef9abdcSjv227347 longlong_t val; 53*2ef9abdcSjv227347 int c; 54*2ef9abdcSjv227347 int xx; 55*2ef9abdcSjv227347 int neg = 0; 56*2ef9abdcSjv227347 longlong_t multmin; 57*2ef9abdcSjv227347 longlong_t limit; 58*2ef9abdcSjv227347 const char **ptr = (const char **)nptr; 59*2ef9abdcSjv227347 const unsigned char *ustr = (const unsigned char *)str; 60*2ef9abdcSjv227347 61*2ef9abdcSjv227347 if (ptr != (const char **)0) 62*2ef9abdcSjv227347 *ptr = (char *)ustr; /* in case no number is formed */ 63*2ef9abdcSjv227347 if (base < 0 || base > MBASE || base == 1) { 64*2ef9abdcSjv227347 /* base is invalid -- should be a fatal error */ 65*2ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 66*2ef9abdcSjv227347 return (EINVAL); 67*2ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 68*2ef9abdcSjv227347 errno = EINVAL; 69*2ef9abdcSjv227347 return (0); 70*2ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 71*2ef9abdcSjv227347 } 72*2ef9abdcSjv227347 if (!isalnum(c = *ustr)) { 73*2ef9abdcSjv227347 while (isspace(c)) 74*2ef9abdcSjv227347 c = *++ustr; 75*2ef9abdcSjv227347 switch (c) { 76*2ef9abdcSjv227347 case '-': 77*2ef9abdcSjv227347 neg++; 78*2ef9abdcSjv227347 /* FALLTHROUGH */ 79*2ef9abdcSjv227347 case '+': 80*2ef9abdcSjv227347 c = *++ustr; 81*2ef9abdcSjv227347 } 82*2ef9abdcSjv227347 } 83*2ef9abdcSjv227347 if (base == 0) 84*2ef9abdcSjv227347 if (c != '0') 85*2ef9abdcSjv227347 base = 10; 86*2ef9abdcSjv227347 else if (ustr[1] == 'x' || ustr[1] == 'X') 87*2ef9abdcSjv227347 base = 16; 88*2ef9abdcSjv227347 else 89*2ef9abdcSjv227347 base = 8; 90*2ef9abdcSjv227347 /* 91*2ef9abdcSjv227347 * for any base > 10, the digits incrementally following 92*2ef9abdcSjv227347 * 9 are assumed to be "abc...z" or "ABC...Z" 93*2ef9abdcSjv227347 */ 94*2ef9abdcSjv227347 if (!lisalnum(c) || (xx = DIGIT(c)) >= base) { 95*2ef9abdcSjv227347 /* no number formed */ 96*2ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 97*2ef9abdcSjv227347 return (EINVAL); 98*2ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 99*2ef9abdcSjv227347 return (0); 100*2ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 101*2ef9abdcSjv227347 } 102*2ef9abdcSjv227347 if (base == 16 && c == '0' && (ustr[1] == 'x' || ustr[1] == 'X') && 103*2ef9abdcSjv227347 isxdigit(ustr[2])) 104*2ef9abdcSjv227347 c = *(ustr += 2); /* skip over leading "0x" or "0X" */ 105*2ef9abdcSjv227347 106*2ef9abdcSjv227347 /* this code assumes that abs(LLONG_MIN) >= abs(LLONG_MAX) */ 107*2ef9abdcSjv227347 if (neg) 108*2ef9abdcSjv227347 limit = LLONG_MIN; 109*2ef9abdcSjv227347 else 110*2ef9abdcSjv227347 limit = -LLONG_MAX; 111*2ef9abdcSjv227347 multmin = limit / (longlong_t)base; 112*2ef9abdcSjv227347 val = -DIGIT(c); 113*2ef9abdcSjv227347 for (c = *++ustr; lisalnum(c) && (xx = DIGIT(c)) < base; ) { 114*2ef9abdcSjv227347 /* accumulate neg avoids surprises near LLONG_MAX */ 115*2ef9abdcSjv227347 if (val < multmin) 116*2ef9abdcSjv227347 goto overflow; 117*2ef9abdcSjv227347 val *= base; 118*2ef9abdcSjv227347 if (val < limit + xx) 119*2ef9abdcSjv227347 goto overflow; 120*2ef9abdcSjv227347 val -= xx; 121*2ef9abdcSjv227347 c = *++ustr; 122*2ef9abdcSjv227347 } 123*2ef9abdcSjv227347 if (ptr != (const char **)0) 124*2ef9abdcSjv227347 *ptr = (char *)ustr; 125*2ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 126*2ef9abdcSjv227347 *result = neg ? val : -val; 127*2ef9abdcSjv227347 return (0); 128*2ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 129*2ef9abdcSjv227347 return (neg ? val : -val); 130*2ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 131*2ef9abdcSjv227347 132*2ef9abdcSjv227347 overflow: 133*2ef9abdcSjv227347 for (c = *++ustr; lisalnum(c) && (xx = DIGIT(c)) < base; (c = *++ustr)) 134*2ef9abdcSjv227347 ; 135*2ef9abdcSjv227347 if (ptr != (const char **)0) 136*2ef9abdcSjv227347 *ptr = (char *)ustr; 137*2ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 138*2ef9abdcSjv227347 return (ERANGE); 139*2ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 140*2ef9abdcSjv227347 errno = ERANGE; 141*2ef9abdcSjv227347 return (neg ? LLONG_MIN : LLONG_MAX); 142*2ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 143*2ef9abdcSjv227347 } 144