diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:47:14 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:47:14 +0000 |
commit | 3eaf4237194e25804f221af93c269d3d97e2809d (patch) | |
tree | cdedf3fc954b0727b0b34aa9b0b211cc18f854eb /src/xmalloc.c | |
download | smartcardauth-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.c | 163 |
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; +} |