1 |
/* xmalloc.c -- malloc with out of memory checking |
/* xmalloc.c -- malloc with out of memory checking |
2 |
Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 2000 |
|
3 |
Free Software Foundation, Inc. |
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
4 |
|
1999, 2000, 2002, 2003 Free Software Foundation, Inc. |
5 |
|
|
6 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
7 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
25 |
|
|
26 |
#if STDC_HEADERS |
#if STDC_HEADERS |
27 |
# include <stdlib.h> |
# include <stdlib.h> |
|
#endif |
|
|
|
|
|
#if ENABLE_NLS |
|
|
# include <libintl.h> |
|
|
# define _(Text) gettext (Text) |
|
28 |
#else |
#else |
29 |
# define textdomain(Domain) |
void *calloc (); |
30 |
# define _(Text) Text |
void *malloc (); |
31 |
|
void *realloc (); |
32 |
|
void free (); |
33 |
#endif |
#endif |
34 |
|
|
35 |
/* If this file fails to compile because your machine has no memset() |
#include "gettext.h" |
36 |
function, you should ensure that either HAVE_CALLOC or HAVE_BZERO |
#define _(msgid) gettext (msgid) |
37 |
are defined in config.h */ |
#define N_(msgid) msgid |
|
#if !HAVE_BZERO |
|
|
# define bzero(p, s) memset (s, 0, n) |
|
|
#endif |
|
38 |
|
|
39 |
#ifndef STDC_HEADERS |
#include "error.h" |
40 |
void *calloc (); |
#include "exitfail.h" |
41 |
void *malloc (); |
#include "xalloc.h" |
42 |
void *realloc (); |
|
43 |
void free (); |
#ifndef EXIT_FAILURE |
44 |
|
# define EXIT_FAILURE 1 |
45 |
#endif |
#endif |
46 |
|
|
47 |
/* Prototypes for functions defined here. */ |
/* The following tests require AC_PREREQ(2.54). */ |
|
static void *fixup_null_alloc (size_t n); |
|
48 |
|
|
49 |
|
#ifndef HAVE_MALLOC |
50 |
|
"you must run the autoconf test for a GNU libc compatible malloc" |
51 |
|
#endif |
52 |
|
|
53 |
/* Exit value when the requested amount of memory is not available. |
#ifndef HAVE_REALLOC |
54 |
The caller may set it to some other value. */ |
"you must run the autoconf test for a GNU libc compatible realloc" |
55 |
int xmalloc_exit_failure = EXIT_FAILURE; |
#endif |
56 |
|
|
57 |
|
/* If non NULL, call this function when memory is exhausted. */ |
58 |
|
void (*xalloc_fail_func) (void) = 0; |
59 |
|
|
60 |
/* Your program must provide these functions in order for |
/* If XALLOC_FAIL_FUNC is NULL, or does return, display this message |
61 |
xmalloc() to work. */ |
before exiting when memory is exhausted. Goes through gettext. */ |
62 |
#if __STDC__ && (HAVE_VPRINTF || HAVE_DOPRNT) |
char const xalloc_msg_memory_exhausted[] = N_("memory exhausted"); |
|
extern void error (int, int, const char *, ...); |
|
|
#else |
|
|
extern void error (); |
|
|
#endif |
|
63 |
|
|
64 |
static void * |
void |
65 |
fixup_null_alloc (n) |
xalloc_die (void) |
|
size_t n; |
|
66 |
{ |
{ |
67 |
void *p; |
if (xalloc_fail_func) |
68 |
|
(*xalloc_fail_func) (); |
69 |
p = 0; |
error (exit_failure, 0, "%s", _(xalloc_msg_memory_exhausted)); |
70 |
if (n == 0) |
/* The `noreturn' cannot be given to error, since it may return if |
71 |
p = malloc ((size_t) 1); |
its first argument is 0. To help compilers understand the |
72 |
if (p == 0) |
xalloc_die does terminate, call exit. */ |
73 |
error (xmalloc_exit_failure, 0, _("Memory exhausted")); |
exit (EXIT_FAILURE); |
|
return p; |
|
74 |
} |
} |
75 |
|
|
76 |
/* Allocate N bytes of memory dynamically, with error checking. */ |
/* Allocate N bytes of memory dynamically, with error checking. */ |
77 |
|
|
78 |
void * |
void * |
79 |
xmalloc (n) |
xmalloc (size_t n) |
|
size_t n; |
|
80 |
{ |
{ |
81 |
void *p; |
void *p; |
82 |
|
|
83 |
p = malloc (n); |
p = malloc (n); |
84 |
if (p == 0) |
if (p == 0) |
85 |
p = fixup_null_alloc (n); |
xalloc_die (); |
86 |
return p; |
return p; |
87 |
} |
} |
88 |
|
|
89 |
/* Allocate memory for N elements of S bytes, with error checking. */ |
/* Change the size of an allocated block of memory P to N bytes, |
90 |
|
with error checking. */ |
91 |
|
|
92 |
void * |
void * |
93 |
xcalloc (n, s) |
xrealloc (void *p, size_t n) |
|
size_t n, s; |
|
94 |
{ |
{ |
95 |
void *p; |
p = realloc (p, n); |
|
#if HAVE_CALLOC |
|
|
p = calloc (n, s); |
|
96 |
if (p == 0) |
if (p == 0) |
97 |
p = fixup_null_alloc (n); |
xalloc_die (); |
|
#else |
|
|
p = xmalloc (n * s); |
|
|
bzero (p, n * s); |
|
|
#endif |
|
98 |
return p; |
return p; |
99 |
} |
} |
100 |
|
|
101 |
/* Change the size of an allocated block of memory P to N bytes, |
/* Allocate memory for N elements of S bytes, with error checking. */ |
|
with error checking. |
|
|
If P is NULL, run xmalloc. */ |
|
102 |
|
|
103 |
void * |
void * |
104 |
xrealloc (p, n) |
xcalloc (size_t n, size_t s) |
|
void *p; |
|
|
size_t n; |
|
105 |
{ |
{ |
106 |
|
void *p; |
107 |
|
|
108 |
|
p = calloc (n, s); |
109 |
if (p == 0) |
if (p == 0) |
110 |
return xmalloc (n); |
xalloc_die (); |
|
p = realloc (p, n); |
|
|
if (p == 0) |
|
|
p = fixup_null_alloc (n); |
|
111 |
return p; |
return p; |
112 |
} |
} |
|
|
|
|
/* Don't free NULL pointers. */ |
|
|
void * |
|
|
xfree (stale) |
|
|
void *stale; |
|
|
{ |
|
|
if (stale) |
|
|
free (stale); |
|
|
return 0; |
|
|
} |
|