1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
/* **************************** */
/* Memory management functions. */
/* **************************** */
/* ***************************************************************** */
/* Created by Kevin Locke (from numerous canonical examples). */
/* */
/* Adapted for use by smenu. */
/* */
/* I hereby place this file in the public domain. It may be freely */
/* reproduced, distributed, used, modified, built upon, or otherwise */
/* employed by anyone for any purpose without restriction. */
/* ***************************************************************** */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "config.h"
#include "xmalloc.h"
/* The following rpl_* function are necessary for AIX which doesn't */
/* provide 'GNU compatible' allocation functions. */
/* Every call to malloc()/realloc() is then replaced by a call to */
/* rpl_malloc()/rpl_realloc() as defined in the GNU generated config.h. */
/* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
#ifdef malloc
#undef malloc
extern void *malloc(size_t);
void *
rpl_malloc(size_t size)
{
if (!size)
size++;
return malloc(size);
}
#undef realloc
extern void *
realloc(void *, size_t);
void *
rpl_realloc(void *ptr, size_t size)
{
if (!size)
size++;
return (ptr ? realloc(ptr, size) : malloc(size));
}
#endif
/* ================================================================== */
/* Customized malloc. */
/* Displays an error message and exits gracefully if an error occurs. */
/* ================================================================== */
void *
xmalloc(size_t size)
{
void *allocated;
size_t real_size;
real_size = (size > 0) ? size : 1;
allocated = malloc(real_size);
if (allocated == NULL)
{
fprintf(stderr,
"Error: Insufficient memory (attempt to malloc %zu bytes)\n",
size);
exit(EXIT_FAILURE);
}
return allocated;
}
/* ================================================================== */
/* Customized calloc. */
/* Displays an error message and exits gracefully if an error occurs. */
/* ================================================================== */
void *
xcalloc(size_t n, size_t size)
{
void *allocated;
n = (n > 0) ? n : 1;
size = (size > 0) ? size : 1;
allocated = calloc(n, size);
if (allocated == NULL)
{
fprintf(stderr,
"Error: Insufficient memory (attempt to calloc %zu bytes)\n",
size);
exit(EXIT_FAILURE);
}
return allocated;
}
/* ================================================================== */
/* Customized realloc. */
/* Displays an error message and exits gracefully if an error occurs. */
/* ================================================================== */
void *
xrealloc(void *p, size_t size)
{
void *allocated;
allocated = realloc(p, size);
if (allocated == NULL && size > 0)
{
fprintf(stderr,
"Error: Insufficient memory (attempt to realloc %zu bytes)\n",
size);
exit(EXIT_FAILURE);
}
return allocated;
}
/* ================================================================== */
/* strdup implementation using xmalloc. */
/* Displays an error message and exits gracefully if an error occurs. */
/* ================================================================== */
char *
xstrdup(const char *str)
{
char *p;
p = malloc(strlen(str) + 1);
if (p == NULL)
{
fprintf(stderr, "Error: Insufficient memory for xstrdup.\n");
exit(EXIT_FAILURE);
}
strcpy(p, str);
return p;
}
/* ================================================================== */
/* strndup implementation using xmalloc. */
/* This version guarantees that there is a final '\0'. */
/* Displays an error message and exits gracefully if an error occurs. */
/* ================================================================== */
char *
xstrndup(const char *str, size_t len)
{
char *p;
p = memchr(str, '\0', len);
if (p != NULL)
len = p - str;
p = malloc(len + 1);
if (p == NULL)
{
fprintf(stderr, "Error: Insufficient memory for xstrndup.\n");
exit(EXIT_FAILURE);
}
memcpy(p, str, len);
p[len] = '\0';
return p;
}
|