summaryrefslogtreecommitdiffstats
path: root/src/xmalloc.c
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:47:14 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:47:14 +0000
commit3eaf4237194e25804f221af93c269d3d97e2809d (patch)
treecdedf3fc954b0727b0b34aa9b0b211cc18f854eb /src/xmalloc.c
downloadsmartcardauth-3eaf4237194e25804f221af93c269d3d97e2809d.tar.gz
smartcardauth-3eaf4237194e25804f221af93c269d3d97e2809d.zip
Added my SmartCard login/session lock/unlock utility
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/smartcardauth@1097604 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/xmalloc.c')
-rw-r--r--src/xmalloc.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/xmalloc.c b/src/xmalloc.c
new file mode 100644
index 0000000..4d00c52
--- /dev/null
+++ b/src/xmalloc.c
@@ -0,0 +1,163 @@
+/* $Id: xmalloc.c 5381 2002-03-31 22:35:47Z rra $
+**
+** malloc routines with failure handling.
+**
+** Usage:
+**
+** extern xmalloc_handler_t memory_error;
+** extern const char *string;
+** char *buffer;
+**
+** xmalloc_error_handler = memory_error;
+** buffer = xmalloc(1024);
+** xrealloc(buffer, 2048);
+** free(buffer);
+** buffer = xcalloc(1024);
+** free(buffer);
+** buffer = xstrdup(string);
+** free(buffer);
+** buffer = xstrndup(string, 25);
+**
+** xmalloc, xcalloc, xrealloc, and xstrdup behave exactly like their C
+** library counterparts without the leading x except that they will never
+** return NULL. Instead, on error, they call xmalloc_error_handler,
+** passing it the name of the function whose memory allocation failed, the
+** amount of the allocation, and the file and line number where the
+** allocation function was invoked (from __FILE__ and __LINE__). This
+** function may do whatever it wishes, such as some action to free up
+** memory or a call to sleep to hope that system resources return. If the
+** handler returns, the interrupted memory allocation function will try its
+** allocation again (calling the handler again if it still fails).
+**
+** xstrndup behaves like xstrdup but only copies the given number of
+** characters. It allocates an additional byte over its second argument and
+** always nul-terminates the string.
+**
+** The default error handler, if none is set by the caller, prints an error
+** message to stderr and exits with exit status 1. An error handler must
+** take a const char * (function name), size_t (bytes allocated), const
+** char * (file), and int (line).
+**
+** xmalloc will return a pointer to a valid memory region on an xmalloc of 0
+** bytes, ensuring this by allocating space for one character instead of 0
+** bytes.
+**
+** The functions defined here are actually x_malloc, x_realloc, etc. The
+** header file defines macros named xmalloc, etc. that pass the file name
+** and line number to these functions.
+*/
+
+/* Used for unused parameters to silence gcc warnings. */
+#define UNUSED __attribute__((__unused__))
+
+/* Make available the bool type. */
+#if INN_HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# undef true
+# undef false
+# define true (1)
+# define false (0)
+# ifndef __cplusplus
+# define bool int
+# endif
+#endif /* INN_HAVE_STDBOOL_H */
+
+#include <stdlib.h>
+#include <string.h>
+#include <crypt.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+
+/* Failure handler takes the function, the size, the file, and the line. */
+typedef void (*xmalloc_handler_t)(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_t xmalloc_error_handler;
+
+/* The default error handler. */
+void
+xmalloc_fail(const char *function, size_t size, const char *file, int line)
+{
+ sysdie("failed to %s %lu bytes at %s line %d", function,
+ (unsigned long) size, file, line);
+}
+
+/* Assign to this variable to choose a handler other than the default. */
+xmalloc_handler_t xmalloc_error_handler = xmalloc_fail;
+
+void *
+x_malloc(size_t size, const char *file, int line)
+{
+ void *p;
+ size_t real_size;
+
+ real_size = (size > 0) ? size : 1;
+ p = malloc(real_size);
+ while (p == NULL) {
+ (*xmalloc_error_handler)("malloc", size, file, line);
+ p = malloc(real_size);
+ }
+ return p;
+}
+
+void *
+x_calloc(size_t n, size_t size, const char *file, int line)
+{
+ void *p;
+
+ n = (n > 0) ? n : 1;
+ size = (size > 0) ? size : 1;
+ p = calloc(n, size);
+ while (p == NULL) {
+ (*xmalloc_error_handler)("calloc", n * size, file, line);
+ p = calloc(n, size);
+ }
+ return p;
+}
+
+void *
+x_realloc(void *p, size_t size, const char *file, int line)
+{
+ void *newp;
+
+ newp = realloc(p, size);
+ while (newp == NULL && size > 0) {
+ (*xmalloc_error_handler)("realloc", size, file, line);
+ newp = realloc(p, size);
+ }
+ return newp;
+}
+
+char *
+x_strdup(const char *s, const char *file, int line)
+{
+ char *p;
+ size_t len;
+
+ len = strlen(s) + 1;
+ p = malloc(len);
+ while (p == NULL) {
+ (*xmalloc_error_handler)("strdup", len, file, line);
+ p = malloc(len);
+ }
+ memcpy(p, s, len);
+ return p;
+}
+
+char *
+x_strndup(const char *s, size_t size, const char *file, int line)
+{
+ char *p;
+
+ p = malloc(size + 1);
+ while (p == NULL) {
+ (*xmalloc_error_handler)("strndup", size + 1, file, line);
+ p = malloc(size + 1);
+ }
+ memcpy(p, s, size);
+ p[size] = '\0';
+ return p;
+}