mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-01 04:22:13 +08:00
Merge branch 'master' of ssh://git.rtems.org/data/git/rtems-libbsd
This commit is contained in:
commit
d422d0df64
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
*.d
|
||||
*.rel
|
||||
o-optimize
|
||||
copied
|
||||
libbsd.html
|
||||
|
@ -82,7 +82,10 @@ C_FILES += lib/libc/net/if_indextoname.c
|
||||
C_FILES += lib/libc/net/if_nameindex.c
|
||||
C_FILES += lib/libc/net/if_nametoindex.c
|
||||
C_FILES += lib/libc/net/linkaddr.c
|
||||
ifneq ($(DISABLE_IPV6),yes)
|
||||
C_FILES += lib/libc/net/map_v4v6.c
|
||||
endif
|
||||
# This file is not IPV6 specific
|
||||
C_FILES += lib/libc/net/name6.c
|
||||
C_FILES += lib/libc/net/rcmd.c
|
||||
C_FILES += lib/libc/net/recv.c
|
||||
@ -102,6 +105,7 @@ C_FILES += lib/libc/resolv/res_state.c
|
||||
C_FILES += lib/libc/resolv/res_update.c
|
||||
C_FILES += lib/libc/resolv/mtctxres.c
|
||||
C_FILES += lib/libc/string/strsep.c
|
||||
C_FILES += lib/libc/stdlib/strtonum.c
|
||||
|
||||
C_FILES += lib/libc/isc/ev_streams.c
|
||||
C_FILES += lib/libc/isc/ev_timers.c
|
||||
@ -168,7 +172,9 @@ C_FILES += rtems/rtems-shell.c
|
||||
|
||||
# ping command sources
|
||||
C_FILES += commands/sbin/ping/ping.c
|
||||
ifneq ($(DISABLE_IPV6),yes)
|
||||
C_FILES += commands/sbin/ping6/ping6.c
|
||||
endif
|
||||
|
||||
# route command sources
|
||||
C_FILES += commands/sbin/route/route.c
|
||||
@ -192,24 +198,26 @@ C_FILES += commands/sbin/dhclient/tables.c
|
||||
C_FILES += commands/sbin/dhclient/tree.c
|
||||
|
||||
# ifconfig command sources
|
||||
C_FILES += commands/sbin/ifconfig/af_atalk.c
|
||||
C_FILES += commands/sbin/ifconfig/af_inet.c
|
||||
C_FILES += commands/sbin/ifconfig/af_link.c
|
||||
C_FILES += commands/sbin/ifconfig/ifbridge.c
|
||||
C_FILES += commands/sbin/ifconfig/ifclone.c
|
||||
C_FILES += commands/sbin/ifconfig/ifgif.c
|
||||
C_FILES += commands/sbin/ifconfig/ifgroup.c
|
||||
C_FILES += commands/sbin/ifconfig/iflagg.c
|
||||
C_FILES += commands/sbin/ifconfig/ifmedia.c
|
||||
C_FILES += commands/sbin/ifconfig/ifvlan.c
|
||||
C_FILES += commands/sbin/ifconfig/af_inet6.c
|
||||
C_FILES += commands/sbin/ifconfig/af_nd6.c
|
||||
C_FILES += commands/sbin/ifconfig/ifcarp.c
|
||||
C_FILES += commands/sbin/ifconfig/ifconfig.c
|
||||
C_FILES += commands/sbin/ifconfig/ifgre.c
|
||||
C_FILES += commands/sbin/ifconfig/ifieee80211.c
|
||||
C_FILES += commands/sbin/ifconfig/ifmac.c
|
||||
C_FILES += commands/sbin/ifconfig/ifpfsync.c
|
||||
# UNUSED IFCONFIG_C_FILES += commands/sbin/ifconfig/af_atalk.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/af_inet.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/af_link.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifbridge.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifclone.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifgif.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifgroup.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/iflagg.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifmedia.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifvlan.c
|
||||
ifneq ($(DISABLE_IPV6),yes)
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/af_inet6.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/af_nd6.c
|
||||
endif
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifcarp.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifconfig.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifgre.c
|
||||
# UNUSED IFCONFIG_C_FILES += commands/sbin/ifconfig/ifieee80211.c
|
||||
# UNUSED IFCONFIG_C_FILES += commands/sbin/ifconfig/ifmac.c
|
||||
IFCONFIG_C_FILES += commands/sbin/ifconfig/ifpfsync.c
|
||||
|
||||
# The following two files were left out to avoid
|
||||
# porting issues. regdomain uses an xml parser
|
||||
@ -222,31 +230,46 @@ C_FILES += commands/sbin/ifconfig/ifpfsync.c
|
||||
|
||||
# netstat command sources
|
||||
# no need to support AppleTalk yet
|
||||
# C_FILES += commands/usr.bin/netstat/atalk.c
|
||||
C_FILES += commands/usr.bin/netstat/bpf.c
|
||||
C_FILES += commands/usr.bin/netstat/if.c
|
||||
C_FILES += commands/usr.bin/netstat/inet6.c
|
||||
C_FILES += commands/usr.bin/netstat/inet.c
|
||||
C_FILES += commands/usr.bin/netstat/ipsec.c
|
||||
# NETSTAT_C_FILES += commands/usr.bin/netstat/atalk.c
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/bpf.c
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/if.c
|
||||
ifneq ($(DISABLE_IPV6),yes)
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/inet6.c
|
||||
endif
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/inet.c
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/ipsec.c
|
||||
# no need to support IPX yet
|
||||
# C_FILES += commands/usr.bin/netstat/ipx.c
|
||||
C_FILES += commands/usr.bin/netstat/main.c
|
||||
# NETSTAT_C_FILES += commands/usr.bin/netstat/ipx.c
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/main.c
|
||||
# XXX does not compile yet
|
||||
C_FILES += commands/usr.bin/netstat/mbuf.c
|
||||
C_FILES += commands/usr.bin/netstat/mroute6.c
|
||||
C_FILES += commands/usr.bin/netstat/mroute.c
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/mbuf.c
|
||||
ifneq ($(DISABLE_IPV6),yes)
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/mroute6.c
|
||||
endif
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/mroute.c
|
||||
# Disable netgraph support - this is a long thread to pull
|
||||
# C_FILES += commands/usr.bin/netstat/netgraph.c
|
||||
C_FILES += commands/usr.bin/netstat/pfkey.c
|
||||
# NETSTAT_C_FILES += commands/usr.bin/netstat/netgraph.c
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/pfkey.c
|
||||
# Actually just route.c in FreeBSD
|
||||
C_FILES += commands/usr.bin/netstat/netstat_route.c
|
||||
C_FILES += commands/usr.bin/netstat/sctp.c
|
||||
C_FILES += commands/usr.bin/netstat/unix.c
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/netstat_route.c
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/sctp.c
|
||||
NETSTAT_C_FILES += commands/usr.bin/netstat/unix.c
|
||||
|
||||
C_O_FILES = $(C_FILES:%.c=%.o)
|
||||
C_D_FILES = $(C_FILES:%.c=%.d)
|
||||
|
||||
IFCONFIG_C_O_FILES = $(IFCONFIG_C_FILES:%.c=%.o)
|
||||
IFCONFIG_C_D_FILES = $(IFCONFIG_C_FILES:%.c=%.d)
|
||||
|
||||
NETSTAT_C_O_FILES = $(NETSTAT_C_FILES:%.c=%.o)
|
||||
NETSTAT_C_D_FILES = $(NETSTAT_C_FILES:%.c=%.d)
|
||||
|
||||
LIB = libbsdc.a
|
||||
IFCONFIG = commands/sbin/ifconfig/ifconfig.rel
|
||||
NETSTAT = commands/usr.bin/netstat/netstat.rel
|
||||
|
||||
COMMAND_RELS = $(NETSTAT) $(IFCONFIG)
|
||||
|
||||
GEN_FILES = include/rpc/rpcb_prot.h
|
||||
GEN_FILES += commands/sbin/route/keywords.h
|
||||
# lib/libc/net
|
||||
@ -263,9 +286,15 @@ EXTRA_CLEAN += lib/libipsec/y.tab.h
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(GEN_FILES) $(C_O_FILES)
|
||||
$(LIB): $(GEN_FILES) $(C_O_FILES) $(COMMAND_RELS)
|
||||
$(AR) rcu $@ $^
|
||||
|
||||
$(IFCONFIG): $(IFCONFIG_C_O_FILES)
|
||||
$(LD) -r -o $@ $^
|
||||
|
||||
$(NETSTAT): $(NETSTAT_C_O_FILES)
|
||||
$(LD) -r -o $@ $^
|
||||
|
||||
include/rpc/rpcb_prot.h: include/rpc/rpcb_prot.x
|
||||
rm -f include/rpc/rpcb_prot.h
|
||||
rpcgen -h -o include/rpc/rpcb_prot.h include/rpc/rpcb_prot.x
|
||||
@ -307,7 +336,9 @@ install: $(LIB)
|
||||
install -c -m 644 $(LIB) $(INSTALL_BASE)
|
||||
|
||||
clean:
|
||||
rm -f $(LIB) $(C_O_FILES) $(C_D_FILES) $(GEN_FILES) $(CLEAN_FILES)
|
||||
rm -f $(LIB) $(GEN_FILES) $(CLEAN_FILES)
|
||||
rm -f $(C_O_FILES) $(IFCONFIG_C_O_FILES) $(NETSTAT_C_O_FILES)
|
||||
rm -f $(C_D_FILES) $(IFCONFIG_C_D_FILES) $(NETSTAT_C_D_FILES)
|
||||
|
||||
-include $(C_D_FILES)
|
||||
|
||||
|
@ -167,6 +167,10 @@ main(argc, argv)
|
||||
int ch;
|
||||
#ifdef __rtems__
|
||||
struct getopt_data getopt_reent;
|
||||
#define optind getopt_reent.optind
|
||||
#define optarg getopt_reent.optarg
|
||||
#define opterr getopt_reent.opterr
|
||||
#define optopt getopt_reent.optopt
|
||||
#endif
|
||||
|
||||
if (argc < 2)
|
||||
|
@ -340,6 +340,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
break;
|
||||
#else
|
||||
he->h_name = bp;
|
||||
#ifdef INET6
|
||||
if (statp->options & RES_USE_INET6) {
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
@ -349,6 +350,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
bp += n;
|
||||
_map_v4v6_hostent(he, &bp, ep);
|
||||
}
|
||||
#endif
|
||||
RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
|
||||
return (0);
|
||||
#endif
|
||||
@ -424,8 +426,10 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
he->h_name = bp;
|
||||
bp += n;
|
||||
}
|
||||
#ifdef INET6
|
||||
if (statp->options & RES_USE_INET6)
|
||||
_map_v4v6_hostent(he, &bp, ep);
|
||||
#endif
|
||||
RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
|
||||
return (0);
|
||||
}
|
||||
@ -699,11 +703,13 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
memcpy(hed->host_addr, uaddr, len);
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
#ifdef INET6
|
||||
if (af == AF_INET && (statp->options & RES_USE_INET6)) {
|
||||
_map_v4v6_address((char*)hed->host_addr, (char*)hed->host_addr);
|
||||
he.h_addrtype = AF_INET6;
|
||||
he.h_length = NS_IN6ADDRSZ;
|
||||
}
|
||||
#endif
|
||||
if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
|
||||
*errnop = errno;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
|
@ -115,6 +115,7 @@ gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped,
|
||||
if (!(cp = strpbrk(p, " \t")))
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
#ifdef INET6
|
||||
if (inet_pton(AF_INET6, p, hed->host_addr) > 0) {
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
@ -131,6 +132,12 @@ gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped,
|
||||
} else {
|
||||
goto again;
|
||||
}
|
||||
#else
|
||||
if (inet_pton(AF_INET, p, hed->host_addr) > 0) {
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
#endif
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
he->h_addr_list = hed->h_addr_ptrs;
|
||||
@ -193,8 +200,10 @@ gethostent_r(struct hostent *hptr, char *buffer, size_t buflen,
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (-1);
|
||||
}
|
||||
#ifdef INET6
|
||||
if (gethostent_p(&he, hed, statp->options & RES_USE_INET6, statp) != 0)
|
||||
return (-1);
|
||||
#endif
|
||||
if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
@ -254,12 +263,14 @@ _ht_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
while ((error = gethostent_p(&he, hed, 0, statp)) == 0) {
|
||||
if (he.h_addrtype != af)
|
||||
continue;
|
||||
#ifdef INET6
|
||||
if (he.h_addrtype == AF_INET &&
|
||||
statp->options & RES_USE_INET6) {
|
||||
_map_v4v6_address(he.h_addr, he.h_addr);
|
||||
he.h_length = IN6ADDRSZ;
|
||||
he.h_addrtype = AF_INET6;
|
||||
}
|
||||
#endif
|
||||
if (strcasecmp(he.h_name, name) == 0)
|
||||
break;
|
||||
for (cp = he.h_aliases; *cp != 0; cp++)
|
||||
@ -317,6 +328,7 @@ _ht_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
|
||||
_sethosthtent(0, hed);
|
||||
while ((error = gethostent_p(&he, hed, 0, statp)) == 0)
|
||||
#ifdef INET6
|
||||
if (he.h_addrtype == af && !bcmp(he.h_addr, addr, len)) {
|
||||
if (he.h_addrtype == AF_INET &&
|
||||
statp->options & RES_USE_INET6) {
|
||||
@ -326,6 +338,7 @@ _ht_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
_endhosthtent(hed);
|
||||
|
||||
if (error != 0)
|
||||
|
@ -458,19 +458,23 @@ fakeaddr(const char *name, int af, struct hostent *hp, char *buf,
|
||||
}
|
||||
strncpy(hed->hostbuf, name, MAXDNAME);
|
||||
hed->hostbuf[MAXDNAME] = '\0';
|
||||
#ifdef INET6
|
||||
if (af == AF_INET && (statp->options & RES_USE_INET6) != 0U) {
|
||||
_map_v4v6_address((char *)hed->host_addr,
|
||||
(char *)hed->host_addr);
|
||||
af = AF_INET6;
|
||||
}
|
||||
#endif
|
||||
he.h_addrtype = af;
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
he.h_length = NS_INADDRSZ;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
he.h_length = NS_IN6ADDRSZ;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
|
155
freebsd-userspace/lib/libc/stdlib/strtonum.3
Normal file
155
freebsd-userspace/lib/libc/stdlib/strtonum.3
Normal file
@ -0,0 +1,155 @@
|
||||
.\" Copyright (c) 2004 Ted Unangst
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.\" $OpenBSD: strtonum.3,v 1.13 2006/04/25 05:15:42 tedu Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 29, 2004
|
||||
.Dt STRTONUM 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm strtonum
|
||||
.Nd "reliably convert string value to an integer"
|
||||
.Sh SYNOPSIS
|
||||
.In stdlib.h
|
||||
.Ft long long
|
||||
.Fo strtonum
|
||||
.Fa "const char *nptr"
|
||||
.Fa "long long minval"
|
||||
.Fa "long long maxval"
|
||||
.Fa "const char **errstr"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn strtonum
|
||||
function converts the string in
|
||||
.Fa nptr
|
||||
to a
|
||||
.Vt "long long"
|
||||
value.
|
||||
The
|
||||
.Fn strtonum
|
||||
function was designed to facilitate safe, robust programming
|
||||
and overcome the shortcomings of the
|
||||
.Xr atoi 3
|
||||
and
|
||||
.Xr strtol 3
|
||||
family of interfaces.
|
||||
.Pp
|
||||
The string may begin with an arbitrary amount of whitespace
|
||||
(as determined by
|
||||
.Xr isspace 3 )
|
||||
followed by a single optional
|
||||
.Ql +
|
||||
or
|
||||
.Ql -
|
||||
sign.
|
||||
.Pp
|
||||
The remainder of the string is converted to a
|
||||
.Vt "long long"
|
||||
value according to base 10.
|
||||
.Pp
|
||||
The value obtained is then checked against the provided
|
||||
.Fa minval
|
||||
and
|
||||
.Fa maxval
|
||||
bounds.
|
||||
If
|
||||
.Fa errstr
|
||||
is non-null,
|
||||
.Fn strtonum
|
||||
stores an error string in
|
||||
.Fa *errstr
|
||||
indicating the failure.
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn strtonum
|
||||
function returns the result of the conversion,
|
||||
unless the value would exceed the provided bounds or is invalid.
|
||||
On error, 0 is returned,
|
||||
.Va errno
|
||||
is set, and
|
||||
.Fa errstr
|
||||
will point to an error message.
|
||||
On success,
|
||||
.Fa *errstr
|
||||
will be set to
|
||||
.Dv NULL ;
|
||||
this fact can be used to differentiate
|
||||
a successful return of 0 from an error.
|
||||
.Sh EXAMPLES
|
||||
Using
|
||||
.Fn strtonum
|
||||
correctly is meant to be simpler than the alternative functions.
|
||||
.Bd -literal -offset indent
|
||||
int iterations;
|
||||
const char *errstr;
|
||||
|
||||
iterations = strtonum(optarg, 1, 64, &errstr);
|
||||
if (errstr)
|
||||
errx(1, "number of iterations is %s: %s", errstr, optarg);
|
||||
.Ed
|
||||
.Pp
|
||||
The above example will guarantee that the value of iterations is between
|
||||
1 and 64 (inclusive).
|
||||
.Sh ERRORS
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er ERANGE
|
||||
The given string was out of range.
|
||||
.It Bq Er EINVAL
|
||||
The given string did not consist solely of digit characters.
|
||||
.It Bq Er EINVAL
|
||||
The supplied
|
||||
.Fa minval
|
||||
was larger than
|
||||
.Fa maxval .
|
||||
.El
|
||||
.Pp
|
||||
If an error occurs,
|
||||
.Fa errstr
|
||||
will be set to one of the following strings:
|
||||
.Pp
|
||||
.Bl -tag -width ".Li too large" -compact
|
||||
.It Li "too large"
|
||||
The result was larger than the provided maximum value.
|
||||
.It Li "too small"
|
||||
The result was smaller than the provided minimum value.
|
||||
.It Li invalid
|
||||
The string did not consist solely of digit characters.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr atof 3 ,
|
||||
.Xr atoi 3 ,
|
||||
.Xr atol 3 ,
|
||||
.Xr atoll 3 ,
|
||||
.Xr sscanf 3 ,
|
||||
.Xr strtod 3 ,
|
||||
.Xr strtol 3 ,
|
||||
.Xr strtoul 3
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn strtonum
|
||||
function is a
|
||||
.Bx
|
||||
extension.
|
||||
The existing alternatives, such as
|
||||
.Xr atoi 3
|
||||
and
|
||||
.Xr strtol 3 ,
|
||||
are either impossible or difficult to use safely.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn strtonum
|
||||
function first appeared in
|
||||
.Ox 3.6 .
|
68
freebsd-userspace/lib/libc/stdlib/strtonum.c
Normal file
68
freebsd-userspace/lib/libc/stdlib/strtonum.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Ted Unangst and Todd Miller
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define INVALID 1
|
||||
#define TOOSMALL 2
|
||||
#define TOOLARGE 3
|
||||
|
||||
long long
|
||||
strtonum(const char *numstr, long long minval, long long maxval,
|
||||
const char **errstrp)
|
||||
{
|
||||
long long ll = 0;
|
||||
char *ep;
|
||||
int error = 0;
|
||||
struct errval {
|
||||
const char *errstr;
|
||||
int err;
|
||||
} ev[4] = {
|
||||
{ NULL, 0 },
|
||||
{ "invalid", EINVAL },
|
||||
{ "too small", ERANGE },
|
||||
{ "too large", ERANGE },
|
||||
};
|
||||
|
||||
ev[0].err = errno;
|
||||
errno = 0;
|
||||
if (minval > maxval)
|
||||
error = INVALID;
|
||||
else {
|
||||
ll = strtoll(numstr, &ep, 10);
|
||||
if (errno == EINVAL || numstr == ep || *ep != '\0')
|
||||
error = INVALID;
|
||||
else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
|
||||
error = TOOSMALL;
|
||||
else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
|
||||
error = TOOLARGE;
|
||||
}
|
||||
if (errstrp != NULL)
|
||||
*errstrp = ev[error].errstr;
|
||||
errno = ev[error].err;
|
||||
if (error)
|
||||
ll = 0;
|
||||
|
||||
return (ll);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user