summaryrefslogtreecommitdiff
path: root/util/xmalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/xmalloc.c')
-rw-r--r--util/xmalloc.c62
1 files changed, 44 insertions, 18 deletions
diff --git a/util/xmalloc.c b/util/xmalloc.c
index 4e05f96..a78e31a 100644
--- a/util/xmalloc.c
+++ b/util/xmalloc.c
@@ -55,12 +55,30 @@
* header file defines macros named xmalloc, etc. that pass the file name and
* line number to these functions.
*
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Copyright 2012
+ * The Board of Trustees of the Leland Stanford Junior University
* Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
* 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * See LICENSE for licensing terms.
+ * This code is derived from software contributed to the Internet Software
+ * Consortium by Rich Salz.
+ *
+ * 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 ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC 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.
*/
#include <config.h>
@@ -149,23 +167,34 @@ x_strdup(const char *s, const char *file, int line)
}
+/*
+ * Avoid using the system strndup function since it may not exist (on Mac OS
+ * X, for example), and there's no need to introduce another portability
+ * requirement.
+ */
char *
x_strndup(const char *s, size_t size, const char *file, int line)
{
- char *p;
+ const char *p;
+ size_t length;
+ char *copy;
- p = malloc(size + 1);
- while (p == NULL) {
- (*xmalloc_error_handler)("strndup", size + 1, file, line);
- p = malloc(size + 1);
+ /* Don't assume that the source string is nul-terminated. */
+ for (p = s; (size_t) (p - s) < size && *p != '\0'; p++)
+ ;
+ length = p - s;
+ copy = malloc(length + 1);
+ while (copy == NULL) {
+ (*xmalloc_error_handler)("strndup", length + 1, file, line);
+ copy = malloc(length + 1);
}
- memcpy(p, s, size);
- p[size] = '\0';
- return p;
+ memcpy(copy, s, length);
+ copy[length] = '\0';
+ return copy;
}
-int
+void
x_vasprintf(char **strp, const char *fmt, va_list args, const char *file,
int line)
{
@@ -175,7 +204,7 @@ x_vasprintf(char **strp, const char *fmt, va_list args, const char *file,
va_copy(args_copy, args);
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
- while (status < 0 && errno == ENOMEM) {
+ while (status < 0) {
va_copy(args_copy, args);
status = vsnprintf(NULL, 0, fmt, args_copy);
va_end(args_copy);
@@ -184,12 +213,11 @@ x_vasprintf(char **strp, const char *fmt, va_list args, const char *file,
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
}
- return status;
}
#if HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS
-int
+void
x_asprintf(char **strp, const char *file, int line, const char *fmt, ...)
{
va_list args, args_copy;
@@ -199,7 +227,7 @@ x_asprintf(char **strp, const char *file, int line, const char *fmt, ...)
va_copy(args_copy, args);
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
- while (status < 0 && errno == ENOMEM) {
+ while (status < 0) {
va_copy(args_copy, args);
status = vsnprintf(NULL, 0, fmt, args_copy);
va_end(args_copy);
@@ -208,10 +236,9 @@ x_asprintf(char **strp, const char *file, int line, const char *fmt, ...)
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
}
- return status;
}
#else /* !(HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS) */
-int
+void
x_asprintf(char **strp, const char *fmt, ...)
{
va_list args, args_copy;
@@ -221,7 +248,7 @@ x_asprintf(char **strp, const char *fmt, ...)
va_copy(args_copy, args);
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
- while (status < 0 && errno == ENOMEM) {
+ while (status < 0) {
va_copy(args_copy, args);
status = vsnprintf(NULL, 0, fmt, args_copy);
va_end(args_copy);
@@ -230,6 +257,5 @@ x_asprintf(char **strp, const char *fmt, ...)
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
}
- return status;
}
#endif /* !(HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS) */