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 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
/* xmalloc.c -- safe versions of malloc and realloc */
/* Copyright (C) 1991-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the GNU Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#include "bashtypes.h"
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "error.h"
#include "bashintl.h"
#if !defined (PTR_T)
# if defined (__STDC__)
# define PTR_T void *
# else
# define PTR_T char *
# endif /* !__STDC__ */
#endif /* !PTR_T */
#if defined (HAVE_SBRK) && !HAVE_DECL_SBRK
extern char *sbrk();
#endif
static PTR_T lbreak;
static int brkfound;
static size_t allocated;
/* **************************************************************** */
/* */
/* Memory Allocation and Deallocation. */
/* */
/* **************************************************************** */
#if defined (HAVE_SBRK)
#define FINDBRK() \
do { \
if (brkfound == 0) \
{ \
lbreak = (PTR_T)sbrk (0); \
brkfound++; \
} \
} while (0)
static size_t
findbrk ()
{
FINDBRK();
return (char *)sbrk (0) - (char *)lbreak;
}
#else
#define FINDBRK()
#endif
static void
allocerr (func, bytes)
const char *func;
size_t bytes;
{
#if defined (HAVE_SBRK)
allocated = findbrk ();
fatal_error (_("%s: cannot allocate %lu bytes (%lu bytes allocated)"), func, (unsigned long)bytes, (unsigned long)allocated);
#else
fatal_error (_("%s: cannot allocate %lu bytes"), func, (unsigned long)bytes);
#endif /* !HAVE_SBRK */
}
/* Return a pointer to free()able block of memory large enough
to hold BYTES number of bytes. If the memory cannot be allocated,
print an error message and abort. */
PTR_T
xmalloc (bytes)
size_t bytes;
{
PTR_T temp;
#if defined (DEBUG)
if (bytes == 0)
internal_warning("xmalloc: size argument is 0");
#endif
FINDBRK();
temp = malloc (bytes);
if (temp == 0)
allocerr ("xmalloc", bytes);
return (temp);
}
PTR_T
xrealloc (pointer, bytes)
PTR_T pointer;
size_t bytes;
{
PTR_T temp;
#if defined (DEBUG)
if (bytes == 0)
internal_warning("xrealloc: size argument is 0");
#endif
FINDBRK();
temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
if (temp == 0)
allocerr ("xrealloc", bytes);
return (temp);
}
/* Use this as the function to call when adding unwind protects so we
don't need to know what free() returns. */
void
xfree (string)
PTR_T string;
{
if (string)
free (string);
}
#ifdef USING_BASH_MALLOC
#include <malloc/shmalloc.h>
static void
sh_allocerr (func, bytes, file, line)
const char *func;
size_t bytes;
char *file;
int line;
{
#if defined (HAVE_SBRK)
allocated = findbrk ();
fatal_error (_("%s: %s:%d: cannot allocate %lu bytes (%lu bytes allocated)"), func, file, line, (unsigned long)bytes, (unsigned long)allocated);
#else
fatal_error (_("%s: %s:%d: cannot allocate %lu bytes"), func, file, line, (unsigned long)bytes);
#endif /* !HAVE_SBRK */
}
PTR_T
sh_xmalloc (bytes, file, line)
size_t bytes;
char *file;
int line;
{
PTR_T temp;
#if defined (DEBUG)
if (bytes == 0)
internal_warning("xmalloc: %s:%d: size argument is 0", file, line);
#endif
FINDBRK();
temp = sh_malloc (bytes, file, line);
if (temp == 0)
sh_allocerr ("xmalloc", bytes, file, line);
return (temp);
}
PTR_T
sh_xrealloc (pointer, bytes, file, line)
PTR_T pointer;
size_t bytes;
char *file;
int line;
{
PTR_T temp;
#if defined (DEBUG)
if (bytes == 0)
internal_warning("xrealloc: %s:%d: size argument is 0", file, line);
#endif
FINDBRK();
temp = pointer ? sh_realloc (pointer, bytes, file, line) : sh_malloc (bytes, file, line);
if (temp == 0)
sh_allocerr ("xrealloc", bytes, file, line);
return (temp);
}
void
sh_xfree (string, file, line)
PTR_T string;
char *file;
int line;
{
if (string)
sh_free (string, file, line);
}
#endif
|