aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2010-02-09 16:00:04 -0800
committerRuss Allbery <rra@stanford.edu>2010-02-09 16:00:04 -0800
commitd05f66dbff10b525d37f60ee01d5b9f94bf5192e (patch)
tree36657983c619cfb7260781b2607ead4afc3ad866 /util
parentccf1cd7efa90bdcbe834e0d4ca144289cca97fd7 (diff)
Update util code and import Kerberos portability glue
Use the Kerberos portability layer from rra-c-util 3.0 and avoid Kerberos API calls deprecated on Heimdal. Break util/util.h into separate header files and update all source files accordingly. The test suite is not yet updated. That will come in subsequent commits.
Diffstat (limited to 'util')
-rw-r--r--util/concat.c3
-rw-r--r--util/concat.h36
-rw-r--r--util/macros.h17
-rw-r--r--util/messages-krb5.c74
-rw-r--r--util/messages-krb5.h39
-rw-r--r--util/messages.c29
-rw-r--r--util/messages.h96
-rw-r--r--util/util.h171
-rw-r--r--util/xmalloc.c24
-rw-r--r--util/xmalloc.h100
10 files changed, 314 insertions, 275 deletions
diff --git a/util/concat.c b/util/concat.c
index bef67db..bdbd836 100644
--- a/util/concat.c
+++ b/util/concat.c
@@ -25,7 +25,8 @@
#include <config.h>
#include <portable/system.h>
-#include <util/util.h>
+#include <util/concat.h>
+#include <util/xmalloc.h>
/* Abbreviation for cleaner code. */
#define VA_NEXT(var, type) ((var) = (type) va_arg(args, type))
diff --git a/util/concat.h b/util/concat.h
new file mode 100644
index 0000000..ef8b38d
--- /dev/null
+++ b/util/concat.h
@@ -0,0 +1,36 @@
+/*
+ * Prototypes for string concatenation with dynamic memory allocation.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * This work is hereby placed in the public domain by its author.
+ */
+
+#ifndef UTIL_CONCAT_H
+#define UTIL_CONCAT_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+BEGIN_DECLS
+
+/* Default to a hidden visibility for all util functions. */
+#pragma GCC visibility push(hidden)
+
+/* Concatenate NULL-terminated strings into a newly allocated string. */
+char *concat(const char *first, ...)
+ __attribute__((__malloc__, __nonnull__(1)));
+
+/*
+ * Given a base path and a file name, create a newly allocated path string.
+ * The name will be appended to base with a / between them. Exceptionally, if
+ * name begins with a slash, it will be strdup'd and returned as-is.
+ */
+char *concatpath(const char *base, const char *name)
+ __attribute__((__malloc__, __nonnull__(2)));
+
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
+END_DECLS
+
+#endif /* UTIL_CONCAT_H */
diff --git a/util/macros.h b/util/macros.h
new file mode 100644
index 0000000..97b2c2b
--- /dev/null
+++ b/util/macros.h
@@ -0,0 +1,17 @@
+/*
+ * Some standard helpful macros.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * This work is hereby placed in the public domain by its author.
+ */
+
+#ifndef UTIL_MACROS_H
+#define UTIL_MACROS_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+/* Used for unused parameters to silence gcc warnings. */
+#define UNUSED __attribute__((__unused__))
+
+#endif /* UTIL_MACROS_H */
diff --git a/util/messages-krb5.c b/util/messages-krb5.c
index 00f4a2e..7f35d29 100644
--- a/util/messages-krb5.c
+++ b/util/messages-krb5.c
@@ -6,76 +6,20 @@
* formatted message.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2006, 2007, 2008
+ * Copyright 2006, 2007, 2008, 2009, 2010
* Board of Trustees, Leland Stanford Jr. University
*
* See LICENSE for licensing terms.
*/
#include <config.h>
+#include <portable/krb5.h>
#include <portable/system.h>
-#include <krb5.h>
-#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) && !defined(HAVE_KRB5_GET_ERR_TEXT)
-# if defined(HAVE_IBM_SVC_KRB5_SVC_H)
-# include <ibm_svc/krb5_svc.h>
-# elif defined(HAVE_ET_COM_ERR_H)
-# include <et/com_err.h>
-# else
-# include <com_err.h>
-# endif
-#endif
-
-#include <util/util.h>
-
-/*
- * This string is returned for unknown error messages. We use a static
- * variable so that we can be sure not to free it.
- */
-static const char error_unknown[] = "unknown error";
-
-
-/*
- * Given a Kerberos error code, return the corresponding error. Prefer the
- * Kerberos interface if available since it will provide context-specific
- * error information, whereas the error_message() call will only provide a
- * fixed message.
- */
-static const char *
-get_error(krb5_context ctx UNUSED, krb5_error_code code)
-{
- const char *msg = NULL;
-
-#if defined(HAVE_KRB5_GET_ERROR_MESSAGE)
- msg = krb5_get_error_message(ctx, code);
-#elif defined(HAVE_KRB5_GET_ERR_TEXT)
- msg = krb5_get_err_text(ctx, code);
-#elif defined(HAVE_KRB5_SVC_GET_MSG)
- krb5_svc_get_msg(code, &msg);
-#else
- msg = error_message(code);
-#endif
- if (msg == NULL)
- return error_unknown;
- else
- return msg;
-}
-
-
-/*
- * Free an error string if necessary.
- */
-static void
-free_error(krb5_context ctx UNUSED, const char *msg)
-{
- if (msg == error_unknown)
- return;
-#if defined(HAVE_KRB5_FREE_ERROR_MESSAGE)
- krb5_free_error_message(ctx, msg);
-#elif defined(HAVE_KRB5_SVC_GET_MSG)
- krb5_free_string((char *) msg);
-#endif
-}
+#include <util/macros.h>
+#include <util/messages.h>
+#include <util/messages-krb5.h>
+#include <util/xmalloc.h>
/*
@@ -88,7 +32,7 @@ die_krb5(krb5_context ctx, krb5_error_code code, const char *format, ...)
char *message;
va_list args;
- k5_msg = get_error(ctx, code);
+ k5_msg = krb5_get_error_message(ctx, code);
va_start(args, format);
if (xvasprintf(&message, format, args) < 0)
die("internal error: unable to format error message");
@@ -107,12 +51,12 @@ warn_krb5(krb5_context ctx, krb5_error_code code, const char *format, ...)
char *message;
va_list args;
- k5_msg = get_error(ctx, code);
+ k5_msg = krb5_get_error_message(ctx, code);
va_start(args, format);
if (xvasprintf(&message, format, args) < 0)
die("internal error: unable to format error message");
va_end(args);
warn("%s: %s", message, k5_msg);
free(message);
- free_error(ctx, k5_msg);
+ krb5_free_error_message(ctx, k5_msg);
}
diff --git a/util/messages-krb5.h b/util/messages-krb5.h
new file mode 100644
index 0000000..3b763c8
--- /dev/null
+++ b/util/messages-krb5.h
@@ -0,0 +1,39 @@
+/*
+ * Prototypes for error handling for Kerberos.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2006, 2007, 2008, 2009, 2010
+ * Board of Trustees, Leland Stanford Jr. University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#ifndef UTIL_MESSAGES_KRB5_H
+#define UTIL_MESSAGES_KRB5_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+#include <krb5.h>
+#include <sys/types.h>
+
+BEGIN_DECLS
+
+/* Default to a hidden visibility for all util functions. */
+#pragma GCC visibility push(hidden)
+
+/*
+ * The Kerberos versions of the reporting functions. These take a context and
+ * an error code to get the Kerberos error.
+ */
+void die_krb5(krb5_context, krb5_error_code, const char *, ...)
+ __attribute__((__nonnull__, __noreturn__, __format__(printf, 3, 4)));
+void warn_krb5(krb5_context, krb5_error_code, const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 3, 4)));
+
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
+END_DECLS
+
+#endif /* UTIL_MESSAGES_KRB5_H */
diff --git a/util/messages.c b/util/messages.c
index 0a106f6..ef920b2 100644
--- a/util/messages.c
+++ b/util/messages.c
@@ -51,26 +51,13 @@
* va_list, and the applicable errno value (if any).
*
* Copyright 2008 Board of Trustees, Leland Stanford Jr. University
- * Copyright 2004, 2005, 2006
+ * Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
- * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- * 2003 by The Internet Software Consortium and Rich Salz
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * 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.
-*/
+ * See LICENSE for licensing terms.
+ */
#include <config.h>
#include <portable/system.h>
@@ -90,7 +77,9 @@
# define LOG_CRIT EVENTLOG_ERROR_TYPE
#endif
-#include <util/util.h>
+#include <util/macros.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
/* The default handler lists. */
static message_handler_func stdout_handlers[2] = {
@@ -211,7 +200,7 @@ message_log_syslog(int pri, int len, const char *fmt, va_list args, int err)
eventlog = RegisterEventSource(NULL, message_program_name);
if (eventlog != NULL) {
- ReportEvent(eventlog, pri, 0, 0, NULL, 1, 0, &buffer, NULL);
+ ReportEvent(eventlog, (WORD) pri, 0, 0, NULL, 1, 0, &buffer, NULL);
CloseEventLog(eventlog);
}
}
diff --git a/util/messages.h b/util/messages.h
new file mode 100644
index 0000000..ff86f39
--- /dev/null
+++ b/util/messages.h
@@ -0,0 +1,96 @@
+/*
+ * Prototypes for message and error reporting (possibly fatal).
+ *
+ * Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. 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.
+ */
+
+#ifndef UTIL_MESSAGES_H
+#define UTIL_MESSAGES_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+#include <stdarg.h>
+
+BEGIN_DECLS
+
+/* Default to a hidden visibility for all util functions. */
+#pragma GCC visibility push(hidden)
+
+/*
+ * The reporting functions. The ones prefaced by "sys" add a colon, a space,
+ * and the results of strerror(errno) to the output and are intended for
+ * reporting failures of system calls.
+ */
+void debug(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void notice(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void sysnotice(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void warn(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void syswarn(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void die(const char *, ...)
+ __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2)));
+void sysdie(const char *, ...)
+ __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2)));
+
+/*
+ * Set the handlers for various message functions. All of these functions
+ * take a count of the number of handlers and then function pointers for each
+ * of those handlers. These functions are not thread-safe; they set global
+ * variables.
+ */
+void message_handlers_debug(int count, ...);
+void message_handlers_notice(int count, ...);
+void message_handlers_warn(int count, ...);
+void message_handlers_die(int count, ...);
+
+/*
+ * Some useful handlers, intended to be passed to message_handlers_*. All
+ * handlers take the length of the formatted message, the format, a variadic
+ * argument list, and the errno setting if any.
+ */
+void message_log_stdout(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_stderr(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_debug(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_info(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_notice(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_warning(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_err(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_crit(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+
+/* The type of a message handler. */
+typedef void (*message_handler_func)(int, const char *, va_list, int);
+
+/* If non-NULL, called before exit and its return value passed to exit. */
+extern int (*message_fatal_cleanup)(void);
+
+/*
+ * If non-NULL, prepended (followed by ": ") to all messages printed by either
+ * message_log_stdout or message_log_stderr.
+ */
+extern const char *message_program_name;
+
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
+END_DECLS
+
+#endif /* UTIL_MESSAGES_H */
diff --git a/util/util.h b/util/util.h
deleted file mode 100644
index 6ac7fa7..0000000
--- a/util/util.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Utility functions.
- *
- * This is a variety of utility functions that are used internally by pieces
- * of remctl. Many of them came originally from INN.
- *
- * Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2005, 2006, 2007, 2008
- * Board of Trustees, Leland Stanford Jr. University
- * Copyright 2004, 2005, 2006, 2007
- * by Internet Systems Consortium, Inc. ("ISC")
- * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- * 2003 by The Internet Software Consortium and Rich Salz
- *
- * See LICENSE for licensing terms.
- */
-
-#ifndef UTIL_UTIL_H
-#define UTIL_UTIL_H 1
-
-#include <config.h>
-#include <portable/macros.h>
-
-#include <krb5.h>
-#include <stdarg.h>
-#include <sys/types.h>
-
-/* Used for unused parameters to silence gcc warnings. */
-#define UNUSED __attribute__((__unused__))
-
-BEGIN_DECLS
-
-/* Concatenate NULL-terminated strings into a newly allocated string. */
-extern char *concat(const char *first, ...);
-
-/*
- * Given a base path and a file name, create a newly allocated path string.
- * The name will be appended to base with a / between them. Exceptionally, if
- * name begins with a slash, it will be strdup'd and returned as-is.
- */
-extern char *concatpath(const char *base, const char *name);
-
-/*
- * The reporting functions. The ones prefaced by "sys" add a colon, a space,
- * and the results of strerror(errno) to the output and are intended for
- * reporting failures of system calls.
- */
-extern void debug(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void notice(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void sysnotice(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void warn(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void syswarn(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void die(const char *, ...)
- __attribute__((__noreturn__, __format__(printf, 1, 2)));
-extern void sysdie(const char *, ...)
- __attribute__((__noreturn__, __format__(printf, 1, 2)));
-
-/*
- * The Kerberos versions of the reporting functions. These take a context and
- * an error code to get the Kerberos error.
- */
-void die_krb5(krb5_context, krb5_error_code, const char *, ...)
- __attribute__((__noreturn__, __format__(printf, 3, 4)));
-void warn_krb5(krb5_context, krb5_error_code, const char *, ...)
- __attribute__((__format__(printf, 3, 4)));
-
-/*
- * Set the handlers for various message functions. All of these functions
- * take a count of the number of handlers and then function pointers for each
- * of those handlers. These functions are not thread-safe; they set global
- * variables.
- */
-extern void message_handlers_debug(int count, ...);
-extern void message_handlers_notice(int count, ...);
-extern void message_handlers_warn(int count, ...);
-extern void message_handlers_die(int count, ...);
-
-/*
- * Some useful handlers, intended to be passed to message_handlers_*. All
- * handlers take the length of the formatted message, the format, a variadic
- * argument list, and the errno setting if any.
- */
-extern void message_log_stdout(int, const char *, va_list, int);
-extern void message_log_stderr(int, const char *, va_list, int);
-extern void message_log_syslog_debug(int, const char *, va_list, int);
-extern void message_log_syslog_info(int, const char *, va_list, int);
-extern void message_log_syslog_notice(int, const char *, va_list, int);
-extern void message_log_syslog_warning(int, const char *, va_list, int);
-extern void message_log_syslog_err(int, const char *, va_list, int);
-extern void message_log_syslog_crit(int, const char *, va_list, int);
-
-/* The type of a message handler. */
-typedef void (*message_handler_func)(int, const char *, va_list, int);
-
-/* If non-NULL, called before exit and its return value passed to exit. */
-extern int (*message_fatal_cleanup)(void);
-
-/*
- * If non-NULL, prepended (followed by ": ") to all messages printed by either
- * message_log_stdout or message_log_stderr.
- */
-extern const char *message_program_name;
-
-/*
- * The functions are actually macros so that we can pick up the file and line
- * number information for debugging error messages without the user having to
- * pass those in every time.
- */
-#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__)
-#define xmalloc(size) x_malloc((size), __FILE__, __LINE__)
-#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__)
-#define xstrdup(p) x_strdup((p), __FILE__, __LINE__)
-#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__)
-#define xvasprintf(p, f, a) x_vasprintf((p), (f), (a), __FILE__, __LINE__)
-
-/*
- * asprintf is a special case since it takes variable arguments. If we have
- * support for variadic macros, we can still pass in the file and line and
- * just need to put them somewhere else in the argument list than last.
- * Otherwise, just call x_asprintf directly. This means that the number of
- * arguments x_asprintf takes must vary depending on whether variadic macros
- * are supported.
- */
-#ifdef HAVE_C99_VAMACROS
-# define xasprintf(p, f, ...) \
- x_asprintf((p), __FILE__, __LINE__, (f), __VA_ARGS__)
-#elif HAVE_GNU_VAMACROS
-# define xasprintf(p, f, args...) \
- x_asprintf((p), __FILE__, __LINE__, (f), args)
-#else
-# define xasprintf x_asprintf
-#endif
-
-/*
- * Last two arguments are always file and line number. These are internal
- * implementations that should not be called directly.
- */
-extern void *x_calloc(size_t, size_t, const char *, int);
-extern void *x_malloc(size_t, const char *, int);
-extern void *x_realloc(void *, size_t, const char *, int);
-extern char *x_strdup(const char *, const char *, int);
-extern char *x_strndup(const char *, size_t, const char *, int);
-extern int x_vasprintf(char **, const char *, va_list, const char *, int);
-
-/* asprintf special case. */
-#if HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS
-extern int x_asprintf(char **, const char *, int, const char *, ...);
-#else
-extern int x_asprintf(char **, const char *, ...);
-#endif
-
-/* Failure handler takes the function, the size, the file, and the line. */
-typedef void (*xmalloc_handler_type)(const char *, size_t, const char *, int);
-
-/* The default error handler. */
-void xmalloc_fail(const char *, size_t, const char *, int);
-
-/*
- * Assign to this variable to choose a handler other than the default, which
- * just calls sysdie.
- */
-extern xmalloc_handler_type xmalloc_error_handler;
-
-END_DECLS
-
-#endif /* UTIL_UTIL_H */
diff --git a/util/xmalloc.c b/util/xmalloc.c
index 412890e..4e05f96 100644
--- a/util/xmalloc.c
+++ b/util/xmalloc.c
@@ -55,25 +55,12 @@
* header file defines macros named xmalloc, etc. that pass the file name and
* line number to these functions.
*
- * Copyright 2004, 2005, 2006
+ * Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
- * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- * 2003 by The Internet Software Consortium and Rich Salz
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * 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.
+ * See LICENSE for licensing terms.
*/
#include <config.h>
@@ -81,7 +68,8 @@
#include <errno.h>
-#include <util/util.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
/*
diff --git a/util/xmalloc.h b/util/xmalloc.h
new file mode 100644
index 0000000..657a6bb
--- /dev/null
+++ b/util/xmalloc.h
@@ -0,0 +1,100 @@
+/*
+ * Prototypes for malloc routines with failure handling.
+ *
+ * Copyright 2010 Board of Trustees, Leland Stanford Jr. 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.
+ */
+
+#ifndef UTIL_XMALLOC_H
+#define UTIL_XMALLOC_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+#include <sys/types.h>
+
+/*
+ * The functions are actually macros so that we can pick up the file and line
+ * number information for debugging error messages without the user having to
+ * pass those in every time.
+ */
+#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__)
+#define xmalloc(size) x_malloc((size), __FILE__, __LINE__)
+#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__)
+#define xstrdup(p) x_strdup((p), __FILE__, __LINE__)
+#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__)
+#define xvasprintf(p, f, a) x_vasprintf((p), (f), (a), __FILE__, __LINE__)
+
+/*
+ * asprintf is a special case since it takes variable arguments. If we have
+ * support for variadic macros, we can still pass in the file and line and
+ * just need to put them somewhere else in the argument list than last.
+ * Otherwise, just call x_asprintf directly. This means that the number of
+ * arguments x_asprintf takes must vary depending on whether variadic macros
+ * are supported.
+ */
+#ifdef HAVE_C99_VAMACROS
+# define xasprintf(p, f, ...) \
+ x_asprintf((p), __FILE__, __LINE__, (f), __VA_ARGS__)
+#elif HAVE_GNU_VAMACROS
+# define xasprintf(p, f, args...) \
+ x_asprintf((p), __FILE__, __LINE__, (f), args)
+#else
+# define xasprintf x_asprintf
+#endif
+
+BEGIN_DECLS
+
+/* Default to a hidden visibility for all util functions. */
+#pragma GCC visibility push(hidden)
+
+/*
+ * Last two arguments are always file and line number. These are internal
+ * implementations that should not be called directly.
+ */
+void *x_calloc(size_t, size_t, const char *, int)
+ __attribute__((__alloc_size__(1, 2), __malloc__, __nonnull__));
+void *x_malloc(size_t, const char *, int)
+ __attribute__((__alloc_size__(1), __malloc__, __nonnull__));
+void *x_realloc(void *, size_t, const char *, int)
+ __attribute__((__alloc_size__(2), __malloc__, __nonnull__(3)));
+char *x_strdup(const char *, const char *, int)
+ __attribute__((__malloc__, __nonnull__));
+char *x_strndup(const char *, size_t, const char *, int)
+ __attribute__((__malloc__, __nonnull__));
+int x_vasprintf(char **, const char *, va_list, const char *, int)
+ __attribute__((__nonnull__));
+
+/* asprintf special case. */
+#if HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS
+int x_asprintf(char **, const char *, int, const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 4, 5)));
+#else
+int x_asprintf(char **, const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 2, 3)));
+#endif
+
+/* Failure handler takes the function, the size, the file, and the line. */
+typedef void (*xmalloc_handler_type)(const char *, size_t, const char *, int);
+
+/* The default error handler. */
+void xmalloc_fail(const char *, size_t, const char *, int)
+ __attribute__((__nonnull__));
+
+/*
+ * Assign to this variable to choose a handler other than the default, which
+ * just calls sysdie.
+ */
+extern xmalloc_handler_type xmalloc_error_handler;
+
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
+END_DECLS
+
+#endif /* UTIL_XMALLOC_H */