xref: /minix/lib/libutil/efun.c (revision 0a6a1f1d)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: efun.c,v 1.10 2015/07/26 02:20:30 kamil Exp $	*/
20c3983b2SBen Gras 
30c3983b2SBen Gras /*-
40c3983b2SBen Gras  * Copyright (c) 2006 The NetBSD Foundation, Inc.
50c3983b2SBen Gras  * All rights reserved.
60c3983b2SBen Gras  *
70c3983b2SBen Gras  * This code is derived from software contributed to The NetBSD Foundation
80c3983b2SBen Gras  * by Christos Zoulas.
90c3983b2SBen Gras  *
100c3983b2SBen Gras  * Redistribution and use in source and binary forms, with or without
110c3983b2SBen Gras  * modification, are permitted provided that the following conditions
120c3983b2SBen Gras  * are met:
130c3983b2SBen Gras  * 1. Redistributions of source code must retain the above copyright
140c3983b2SBen Gras  *    notice, this list of conditions and the following disclaimer.
150c3983b2SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
160c3983b2SBen Gras  *    notice, this list of conditions and the following disclaimer in the
170c3983b2SBen Gras  *    documentation and/or other materials provided with the distribution.
180c3983b2SBen Gras  *
190c3983b2SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
200c3983b2SBen Gras  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
210c3983b2SBen Gras  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220c3983b2SBen Gras  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
230c3983b2SBen Gras  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
240c3983b2SBen Gras  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
250c3983b2SBen Gras  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
260c3983b2SBen Gras  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
270c3983b2SBen Gras  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
280c3983b2SBen Gras  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
290c3983b2SBen Gras  * POSSIBILITY OF SUCH DAMAGE.
300c3983b2SBen Gras  */
310c3983b2SBen Gras 
320c3983b2SBen Gras #if HAVE_NBTOOL_CONFIG_H
330c3983b2SBen Gras #include "nbtool_config.h"
340c3983b2SBen Gras #endif
350c3983b2SBen Gras 
360c3983b2SBen Gras #include <sys/cdefs.h>
370c3983b2SBen Gras #ifdef __RCSID
38*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: efun.c,v 1.10 2015/07/26 02:20:30 kamil Exp $");
390c3983b2SBen Gras #endif
400c3983b2SBen Gras 
410c3983b2SBen Gras #include <err.h>
420c3983b2SBen Gras #include <errno.h>
43*0a6a1f1dSLionel Sambuc #include <inttypes.h>
440c3983b2SBen Gras #include <string.h>
450c3983b2SBen Gras #include <stdlib.h>
460c3983b2SBen Gras #include <stdio.h>
470c3983b2SBen Gras #include <stdarg.h>
480c3983b2SBen Gras #include <util.h>
490c3983b2SBen Gras 
500c3983b2SBen Gras static void (*efunc)(int, const char *, ...) = err;
510c3983b2SBen Gras 
520c3983b2SBen Gras void (*
esetfunc(void (* ef)(int,const char *,...))530c3983b2SBen Gras esetfunc(void (*ef)(int, const char *, ...)))(int, const char *, ...)
540c3983b2SBen Gras {
550c3983b2SBen Gras 	void (*of)(int, const char *, ...) = efunc;
560c3983b2SBen Gras 	efunc = ef == NULL ? (void (*)(int, const char *, ...))exit : ef;
570c3983b2SBen Gras 	return of;
580c3983b2SBen Gras }
590c3983b2SBen Gras 
600c3983b2SBen Gras size_t
estrlcpy(char * dst,const char * src,size_t len)610c3983b2SBen Gras estrlcpy(char *dst, const char *src, size_t len)
620c3983b2SBen Gras {
630c3983b2SBen Gras 	size_t rv;
640c3983b2SBen Gras 	if ((rv = strlcpy(dst, src, len)) >= len) {
650c3983b2SBen Gras 		errno = ENAMETOOLONG;
660c3983b2SBen Gras 		(*efunc)(1,
670c3983b2SBen Gras 		    "Cannot copy string; %zu chars needed %zu provided",
680c3983b2SBen Gras 		    rv, len);
690c3983b2SBen Gras 	}
700c3983b2SBen Gras 	return rv;
710c3983b2SBen Gras }
720c3983b2SBen Gras 
730c3983b2SBen Gras size_t
estrlcat(char * dst,const char * src,size_t len)740c3983b2SBen Gras estrlcat(char *dst, const char *src, size_t len)
750c3983b2SBen Gras {
760c3983b2SBen Gras 	size_t rv;
770c3983b2SBen Gras 	if ((rv = strlcat(dst, src, len)) >= len) {
780c3983b2SBen Gras 		errno = ENAMETOOLONG;
790c3983b2SBen Gras 		(*efunc)(1,
800c3983b2SBen Gras 		    "Cannot append to string; %zu chars needed %zu provided",
810c3983b2SBen Gras 		    rv, len);
820c3983b2SBen Gras 	}
830c3983b2SBen Gras 	return rv;
840c3983b2SBen Gras }
850c3983b2SBen Gras 
860c3983b2SBen Gras char *
estrdup(const char * s)870c3983b2SBen Gras estrdup(const char *s)
880c3983b2SBen Gras {
890c3983b2SBen Gras 	char *d = strdup(s);
900c3983b2SBen Gras 	if (d == NULL)
910c3983b2SBen Gras 		(*efunc)(1, "Cannot copy string");
920c3983b2SBen Gras 	return d;
930c3983b2SBen Gras }
940c3983b2SBen Gras 
950c3983b2SBen Gras char *
estrndup(const char * s,size_t len)960c3983b2SBen Gras estrndup(const char *s, size_t len)
970c3983b2SBen Gras {
980c3983b2SBen Gras 	char *d = strndup(s, len);
990c3983b2SBen Gras 	if (d == NULL)
1000c3983b2SBen Gras 		(*efunc)(1, "Cannot copy string");
1010c3983b2SBen Gras 	return d;
1020c3983b2SBen Gras }
1030c3983b2SBen Gras 
1040c3983b2SBen Gras void *
emalloc(size_t n)1050c3983b2SBen Gras emalloc(size_t n)
1060c3983b2SBen Gras {
1070c3983b2SBen Gras 	void *p = malloc(n);
10884d9c625SLionel Sambuc 	if (p == NULL && n != 0)
1090c3983b2SBen Gras 		(*efunc)(1, "Cannot allocate %zu bytes", n);
1100c3983b2SBen Gras 	return p;
1110c3983b2SBen Gras }
1120c3983b2SBen Gras 
1130c3983b2SBen Gras void *
ecalloc(size_t n,size_t s)1140c3983b2SBen Gras ecalloc(size_t n, size_t s)
1150c3983b2SBen Gras {
1160c3983b2SBen Gras 	void *p = calloc(n, s);
11784d9c625SLionel Sambuc 	if (p == NULL && n != 0 && s != 0)
11884d9c625SLionel Sambuc 		(*efunc)(1, "Cannot allocate %zu blocks of size %zu", n, s);
1190c3983b2SBen Gras 	return p;
1200c3983b2SBen Gras }
1210c3983b2SBen Gras 
1220c3983b2SBen Gras void *
erealloc(void * p,size_t n)1230c3983b2SBen Gras erealloc(void *p, size_t n)
1240c3983b2SBen Gras {
1250c3983b2SBen Gras 	void *q = realloc(p, n);
12684d9c625SLionel Sambuc 	if (q == NULL && n != 0)
1270c3983b2SBen Gras 		(*efunc)(1, "Cannot re-allocate %zu bytes", n);
1280c3983b2SBen Gras 	return q;
1290c3983b2SBen Gras }
1300c3983b2SBen Gras 
131*0a6a1f1dSLionel Sambuc void
ereallocarr(void * p,size_t n,size_t s)132*0a6a1f1dSLionel Sambuc ereallocarr(void *p, size_t n, size_t s)
133*0a6a1f1dSLionel Sambuc {
134*0a6a1f1dSLionel Sambuc 	int rv = reallocarr(p, n, s);
135*0a6a1f1dSLionel Sambuc 	if (rv != 0) {
136*0a6a1f1dSLionel Sambuc 		errno = rv;
137*0a6a1f1dSLionel Sambuc 		(*efunc)(1, "Cannot re-allocate %zu * %zu bytes", n, s);
138*0a6a1f1dSLionel Sambuc 	}
139*0a6a1f1dSLionel Sambuc }
140*0a6a1f1dSLionel Sambuc 
1410c3983b2SBen Gras FILE *
efopen(const char * p,const char * m)1420c3983b2SBen Gras efopen(const char *p, const char *m)
1430c3983b2SBen Gras {
1440c3983b2SBen Gras 	FILE *fp = fopen(p, m);
1450c3983b2SBen Gras 	if (fp == NULL)
1460c3983b2SBen Gras 		(*efunc)(1, "Cannot open `%s'", p);
1470c3983b2SBen Gras 	return fp;
1480c3983b2SBen Gras }
1490c3983b2SBen Gras 
1500c3983b2SBen Gras int
easprintf(char ** __restrict ret,const char * __restrict format,...)1510c3983b2SBen Gras easprintf(char ** __restrict ret, const char * __restrict format, ...)
1520c3983b2SBen Gras {
1530c3983b2SBen Gras 	int rv;
1540c3983b2SBen Gras 	va_list ap;
1550c3983b2SBen Gras 	va_start(ap, format);
1560c3983b2SBen Gras 	if ((rv = vasprintf(ret, format, ap)) == -1)
1570c3983b2SBen Gras 		(*efunc)(1, "Cannot format string");
1580c3983b2SBen Gras 	va_end(ap);
1590c3983b2SBen Gras 	return rv;
1600c3983b2SBen Gras }
1610c3983b2SBen Gras 
1620c3983b2SBen Gras int
evasprintf(char ** __restrict ret,const char * __restrict format,va_list ap)1630c3983b2SBen Gras evasprintf(char ** __restrict ret, const char * __restrict format, va_list ap)
1640c3983b2SBen Gras {
1650c3983b2SBen Gras 	int rv;
1660c3983b2SBen Gras 	if ((rv = vasprintf(ret, format, ap)) == -1)
1670c3983b2SBen Gras 		(*efunc)(1, "Cannot format string");
1680c3983b2SBen Gras 	return rv;
1690c3983b2SBen Gras }
170*0a6a1f1dSLionel Sambuc 
171*0a6a1f1dSLionel Sambuc intmax_t
estrtoi(const char * nptr,int base,intmax_t lo,intmax_t hi)172*0a6a1f1dSLionel Sambuc estrtoi(const char * nptr, int base, intmax_t lo, intmax_t hi)
173*0a6a1f1dSLionel Sambuc {
174*0a6a1f1dSLionel Sambuc 	int e;
175*0a6a1f1dSLionel Sambuc 	intmax_t rv = strtoi(nptr, NULL, base, lo, hi, &e);
176*0a6a1f1dSLionel Sambuc 	if (e != 0) {
177*0a6a1f1dSLionel Sambuc 		errno = e;
178*0a6a1f1dSLionel Sambuc 		(*efunc)(1,
179*0a6a1f1dSLionel Sambuc 		    "Cannot convert string value '%s' with base %d to a number in range [%jd .. %jd]",
180*0a6a1f1dSLionel Sambuc 		    nptr, base, lo, hi);
181*0a6a1f1dSLionel Sambuc 	}
182*0a6a1f1dSLionel Sambuc 	return rv;
183*0a6a1f1dSLionel Sambuc }
184*0a6a1f1dSLionel Sambuc 
185*0a6a1f1dSLionel Sambuc uintmax_t
estrtou(const char * nptr,int base,uintmax_t lo,uintmax_t hi)186*0a6a1f1dSLionel Sambuc estrtou(const char * nptr, int base, uintmax_t lo, uintmax_t hi)
187*0a6a1f1dSLionel Sambuc {
188*0a6a1f1dSLionel Sambuc 	int e;
189*0a6a1f1dSLionel Sambuc 	uintmax_t rv = strtou(nptr, NULL, base, lo, hi, &e);
190*0a6a1f1dSLionel Sambuc 	if (e != 0) {
191*0a6a1f1dSLionel Sambuc 		errno = e;
192*0a6a1f1dSLionel Sambuc 		(*efunc)(1,
193*0a6a1f1dSLionel Sambuc 		    "Cannot convert string value '%s' with base %d to a number in range [%ju .. %ju]",
194*0a6a1f1dSLionel Sambuc 		    nptr, base, lo, hi);
195*0a6a1f1dSLionel Sambuc 	}
196*0a6a1f1dSLionel Sambuc 	return rv;
197*0a6a1f1dSLionel Sambuc }
198