1156707Sandre/*- 2156707Sandre * Copyright (c) 2004 Ted Unangst and Todd Miller 3156707Sandre * All rights reserved. 4156707Sandre * 5156707Sandre * Permission to use, copy, modify, and distribute this software for any 6156707Sandre * purpose with or without fee is hereby granted, provided that the above 7156707Sandre * copyright notice and this permission notice appear in all copies. 8156707Sandre * 9156707Sandre * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10156707Sandre * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11156707Sandre * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12156707Sandre * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13156707Sandre * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14156707Sandre * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15156707Sandre * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16156707Sandre * 17270033Spfg * $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ 18156707Sandre */ 19156707Sandre 20156707Sandre#include <sys/cdefs.h> 21156707Sandre__FBSDID("$FreeBSD: releng/10.3/lib/libc/stdlib/strtonum.c 270033 2014-08-16 01:03:51Z pfg $"); 22156707Sandre 23156707Sandre#include <errno.h> 24156707Sandre#include <limits.h> 25156707Sandre#include <stdlib.h> 26156707Sandre 27270033Spfg#define INVALID 1 28270033Spfg#define TOOSMALL 2 29270033Spfg#define TOOLARGE 3 30156707Sandre 31156707Sandrelong long 32156707Sandrestrtonum(const char *numstr, long long minval, long long maxval, 33156707Sandre const char **errstrp) 34156707Sandre{ 35156707Sandre long long ll = 0; 36270033Spfg int error = 0; 37156707Sandre char *ep; 38156707Sandre struct errval { 39156707Sandre const char *errstr; 40156707Sandre int err; 41156707Sandre } ev[4] = { 42156707Sandre { NULL, 0 }, 43156707Sandre { "invalid", EINVAL }, 44156707Sandre { "too small", ERANGE }, 45156707Sandre { "too large", ERANGE }, 46156707Sandre }; 47156707Sandre 48156707Sandre ev[0].err = errno; 49156707Sandre errno = 0; 50270033Spfg if (minval > maxval) { 51156707Sandre error = INVALID; 52270033Spfg } else { 53156707Sandre ll = strtoll(numstr, &ep, 10); 54156716Sache if (errno == EINVAL || numstr == ep || *ep != '\0') 55156707Sandre error = INVALID; 56156707Sandre else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) 57156707Sandre error = TOOSMALL; 58156707Sandre else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) 59156707Sandre error = TOOLARGE; 60156707Sandre } 61156707Sandre if (errstrp != NULL) 62156707Sandre *errstrp = ev[error].errstr; 63156707Sandre errno = ev[error].err; 64156707Sandre if (error) 65156707Sandre ll = 0; 66156707Sandre 67156707Sandre return (ll); 68156707Sandre} 69