12ef9abdcSjv227347 /* 22ef9abdcSjv227347 * CDDL HEADER START 32ef9abdcSjv227347 * 42ef9abdcSjv227347 * The contents of this file are subject to the terms of the 52ef9abdcSjv227347 * Common Development and Distribution License (the "License"). 62ef9abdcSjv227347 * You may not use this file except in compliance with the License. 72ef9abdcSjv227347 * 82ef9abdcSjv227347 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92ef9abdcSjv227347 * or http://www.opensolaris.org/os/licensing. 102ef9abdcSjv227347 * See the License for the specific language governing permissions 112ef9abdcSjv227347 * and limitations under the License. 122ef9abdcSjv227347 * 132ef9abdcSjv227347 * When distributing Covered Code, include this CDDL HEADER in each 142ef9abdcSjv227347 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152ef9abdcSjv227347 * If applicable, add the following below this CDDL HEADER, with the 162ef9abdcSjv227347 * fields enclosed by brackets "[]" replaced with your own identifying 172ef9abdcSjv227347 * information: Portions Copyright [yyyy] [name of copyright owner] 182ef9abdcSjv227347 * 192ef9abdcSjv227347 * CDDL HEADER END 202ef9abdcSjv227347 */ 212ef9abdcSjv227347 222ef9abdcSjv227347 /* 232ef9abdcSjv227347 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 242ef9abdcSjv227347 * Use is subject to license terms. 252ef9abdcSjv227347 */ 262ef9abdcSjv227347 272ef9abdcSjv227347 /* Copyright (c) 1988 AT&T */ 282ef9abdcSjv227347 /* All Rights Reserved */ 292ef9abdcSjv227347 302ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 31*28de4f3cSToomas Soome #include <sys/null.h> 322ef9abdcSjv227347 #include <sys/errno.h> 332ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 34*28de4f3cSToomas Soome #if !defined(_BOOT) && !defined(_KMDB) && !defined(_STANDALONE) 352ef9abdcSjv227347 #include "lint.h" 36*28de4f3cSToomas Soome #endif /* !_BOOT && !_KMDB && !_STANDALONE */ 37*28de4f3cSToomas Soome #if defined(_STANDALONE) 38*28de4f3cSToomas Soome #include <sys/cdefs.h> 39*28de4f3cSToomas Soome #include <stand.h> 40*28de4f3cSToomas Soome #include <limits.h> 41*28de4f3cSToomas Soome 42*28de4f3cSToomas Soome typedef long long longlong_t; 43*28de4f3cSToomas Soome #else 442ef9abdcSjv227347 #include <errno.h> 452ef9abdcSjv227347 #include <ctype.h> 462ef9abdcSjv227347 #include <limits.h> 472ef9abdcSjv227347 #include <stdlib.h> 48*28de4f3cSToomas Soome #endif /* _STANDALONE */ 492ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 502ef9abdcSjv227347 #include "strtolctype.h" 512ef9abdcSjv227347 #include <sys/types.h> 522ef9abdcSjv227347 532ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 542ef9abdcSjv227347 int 552ef9abdcSjv227347 ddi_strtoll(const char *str, char **nptr, int base, longlong_t *result) 562ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 572ef9abdcSjv227347 longlong_t 582ef9abdcSjv227347 strtoll(const char *str, char **nptr, int base) 592ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 602ef9abdcSjv227347 { 612ef9abdcSjv227347 longlong_t val; 622ef9abdcSjv227347 int c; 632ef9abdcSjv227347 int xx; 642ef9abdcSjv227347 int neg = 0; 652ef9abdcSjv227347 longlong_t multmin; 662ef9abdcSjv227347 longlong_t limit; 672ef9abdcSjv227347 const char **ptr = (const char **)nptr; 682ef9abdcSjv227347 const unsigned char *ustr = (const unsigned char *)str; 692ef9abdcSjv227347 70*28de4f3cSToomas Soome if (ptr != NULL) 712ef9abdcSjv227347 *ptr = (char *)ustr; /* in case no number is formed */ 722ef9abdcSjv227347 if (base < 0 || base > MBASE || base == 1) { 732ef9abdcSjv227347 /* base is invalid -- should be a fatal error */ 742ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 752ef9abdcSjv227347 return (EINVAL); 762ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 772ef9abdcSjv227347 errno = EINVAL; 782ef9abdcSjv227347 return (0); 792ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 802ef9abdcSjv227347 } 812ef9abdcSjv227347 if (!isalnum(c = *ustr)) { 822ef9abdcSjv227347 while (isspace(c)) 832ef9abdcSjv227347 c = *++ustr; 842ef9abdcSjv227347 switch (c) { 852ef9abdcSjv227347 case '-': 862ef9abdcSjv227347 neg++; 872ef9abdcSjv227347 /* FALLTHROUGH */ 882ef9abdcSjv227347 case '+': 892ef9abdcSjv227347 c = *++ustr; 902ef9abdcSjv227347 } 912ef9abdcSjv227347 } 92*28de4f3cSToomas Soome if (base == 0) { 932ef9abdcSjv227347 if (c != '0') 942ef9abdcSjv227347 base = 10; 952ef9abdcSjv227347 else if (ustr[1] == 'x' || ustr[1] == 'X') 962ef9abdcSjv227347 base = 16; 972ef9abdcSjv227347 else 982ef9abdcSjv227347 base = 8; 99*28de4f3cSToomas Soome } 1002ef9abdcSjv227347 /* 1012ef9abdcSjv227347 * for any base > 10, the digits incrementally following 1022ef9abdcSjv227347 * 9 are assumed to be "abc...z" or "ABC...Z" 1032ef9abdcSjv227347 */ 1042ef9abdcSjv227347 if (!lisalnum(c) || (xx = DIGIT(c)) >= base) { 1052ef9abdcSjv227347 /* no number formed */ 1062ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 1072ef9abdcSjv227347 return (EINVAL); 1082ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 1092ef9abdcSjv227347 return (0); 1102ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 1112ef9abdcSjv227347 } 1122ef9abdcSjv227347 if (base == 16 && c == '0' && (ustr[1] == 'x' || ustr[1] == 'X') && 1132ef9abdcSjv227347 isxdigit(ustr[2])) 1142ef9abdcSjv227347 c = *(ustr += 2); /* skip over leading "0x" or "0X" */ 1152ef9abdcSjv227347 1162ef9abdcSjv227347 /* this code assumes that abs(LLONG_MIN) >= abs(LLONG_MAX) */ 1172ef9abdcSjv227347 if (neg) 1182ef9abdcSjv227347 limit = LLONG_MIN; 1192ef9abdcSjv227347 else 1202ef9abdcSjv227347 limit = -LLONG_MAX; 1212ef9abdcSjv227347 multmin = limit / (longlong_t)base; 1222ef9abdcSjv227347 val = -DIGIT(c); 1232ef9abdcSjv227347 for (c = *++ustr; lisalnum(c) && (xx = DIGIT(c)) < base; ) { 1242ef9abdcSjv227347 /* accumulate neg avoids surprises near LLONG_MAX */ 1252ef9abdcSjv227347 if (val < multmin) 1262ef9abdcSjv227347 goto overflow; 1272ef9abdcSjv227347 val *= base; 1282ef9abdcSjv227347 if (val < limit + xx) 1292ef9abdcSjv227347 goto overflow; 1302ef9abdcSjv227347 val -= xx; 1312ef9abdcSjv227347 c = *++ustr; 1322ef9abdcSjv227347 } 133*28de4f3cSToomas Soome if (ptr != NULL) 1342ef9abdcSjv227347 *ptr = (char *)ustr; 1352ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 1362ef9abdcSjv227347 *result = neg ? val : -val; 1372ef9abdcSjv227347 return (0); 1382ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 1392ef9abdcSjv227347 return (neg ? val : -val); 1402ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 1412ef9abdcSjv227347 1422ef9abdcSjv227347 overflow: 1432ef9abdcSjv227347 for (c = *++ustr; lisalnum(c) && (xx = DIGIT(c)) < base; (c = *++ustr)) 1442ef9abdcSjv227347 ; 145*28de4f3cSToomas Soome if (ptr != NULL) 1462ef9abdcSjv227347 *ptr = (char *)ustr; 1472ef9abdcSjv227347 #if defined(_KERNEL) && !defined(_BOOT) 1482ef9abdcSjv227347 return (ERANGE); 1492ef9abdcSjv227347 #else /* _KERNEL && !_BOOT */ 1502ef9abdcSjv227347 errno = ERANGE; 1512ef9abdcSjv227347 return (neg ? LLONG_MIN : LLONG_MAX); 1522ef9abdcSjv227347 #endif /* _KERNEL && !_BOOT */ 1532ef9abdcSjv227347 } 154