blob: 2344d2d54ec62edfe13b4549aa09d48cc8bfb748 [file] [log] [blame]
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001/* xmalloc.c -- safe versions of malloc and realloc */
2
Jari Aalto31859422009-01-12 13:36:28 +00003/* Copyright (C) 1991-2009 Free Software Foundation, Inc.
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004
Jari Aalto31859422009-01-12 13:36:28 +00005 This file is part of GNU Bash, the GNU Bourne Again SHell.
Jari Aaltoccc6cda1996-12-23 17:02:34 +00006
Jari Aalto31859422009-01-12 13:36:28 +00007 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
Jari Aaltoccc6cda1996-12-23 17:02:34 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
Jari Aaltoccc6cda1996-12-23 17:02:34 +000016
17 You should have received a copy of the GNU General Public License
Jari Aalto31859422009-01-12 13:36:28 +000018 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
Jari Aaltoccc6cda1996-12-23 17:02:34 +000020
21#if defined (HAVE_CONFIG_H)
22#include <config.h>
23#endif
24
Jari Aaltod166f041997-06-05 14:59:13 +000025#include "bashtypes.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000026#include <stdio.h>
27
28#if defined (HAVE_UNISTD_H)
29# include <unistd.h>
30#endif
31
32#if defined (HAVE_STDLIB_H)
33# include <stdlib.h>
34#else
35# include "ansi_stdlib.h"
36#endif /* HAVE_STDLIB_H */
37
38#include "error.h"
39
Jari Aaltob80f6442004-07-27 13:29:18 +000040#include "bashintl.h"
41
Jari Aaltoccc6cda1996-12-23 17:02:34 +000042#if !defined (PTR_T)
43# if defined (__STDC__)
44# define PTR_T void *
45# else
46# define PTR_T char *
47# endif /* !__STDC__ */
48#endif /* !PTR_T */
49
Jari Aaltof73dda02001-11-13 17:56:06 +000050#if defined (HAVE_SBRK) && !HAVE_DECL_SBRK
Jari Aaltoccc6cda1996-12-23 17:02:34 +000051extern char *sbrk();
52#endif
53
54static PTR_T lbreak;
55static int brkfound;
56static size_t allocated;
57
58/* **************************************************************** */
59/* */
60/* Memory Allocation and Deallocation. */
61/* */
62/* **************************************************************** */
63
Jari Aaltob72432f1999-02-19 17:11:39 +000064#if defined (HAVE_SBRK)
Chet Ramey00018032011-11-21 20:51:19 -050065#define FINDBRK() \
66do { \
67 if (brkfound == 0) \
68 { \
69 lbreak = (PTR_T)sbrk (0); \
70 brkfound++; \
71 } \
72} while (0)
73
Jari Aaltob72432f1999-02-19 17:11:39 +000074static size_t
75findbrk ()
76{
Chet Ramey00018032011-11-21 20:51:19 -050077 FINDBRK();
Jari Aaltob72432f1999-02-19 17:11:39 +000078 return (char *)sbrk (0) - (char *)lbreak;
79}
Chet Ramey00018032011-11-21 20:51:19 -050080#else
81#define FINDBRK()
Jari Aaltob72432f1999-02-19 17:11:39 +000082#endif
83
Chet Ramey00018032011-11-21 20:51:19 -050084static void
85allocerr (func, bytes)
86 const char *func;
87 size_t bytes;
88{
89#if defined (HAVE_SBRK)
90 allocated = findbrk ();
91 fatal_error (_("%s: cannot allocate %lu bytes (%lu bytes allocated)"), func, (unsigned long)bytes, (unsigned long)allocated);
92#else
93 fatal_error (_("%s: cannot allocate %lu bytes"), func, (unsigned long)bytes);
94#endif /* !HAVE_SBRK */
95}
96
Jari Aaltoccc6cda1996-12-23 17:02:34 +000097/* Return a pointer to free()able block of memory large enough
98 to hold BYTES number of bytes. If the memory cannot be allocated,
99 print an error message and abort. */
Jari Aaltof73dda02001-11-13 17:56:06 +0000100PTR_T
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000101xmalloc (bytes)
102 size_t bytes;
103{
Jari Aaltof73dda02001-11-13 17:56:06 +0000104 PTR_T temp;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000105
Chet Ramey00018032011-11-21 20:51:19 -0500106#if defined (DEBUG)
107 if (bytes == 0)
108 internal_warning("xmalloc: size argument is 0");
109#endif
110
111 FINDBRK();
Jari Aaltof73dda02001-11-13 17:56:06 +0000112 temp = malloc (bytes);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000113
114 if (temp == 0)
Chet Ramey00018032011-11-21 20:51:19 -0500115 allocerr ("xmalloc", bytes);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000116
117 return (temp);
118}
119
Jari Aaltof73dda02001-11-13 17:56:06 +0000120PTR_T
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000121xrealloc (pointer, bytes)
122 PTR_T pointer;
123 size_t bytes;
124{
Jari Aaltof73dda02001-11-13 17:56:06 +0000125 PTR_T temp;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000126
Chet Ramey00018032011-11-21 20:51:19 -0500127#if defined (DEBUG)
128 if (bytes == 0)
129 internal_warning("xrealloc: size argument is 0");
130#endif
131
132 FINDBRK();
Jari Aaltof73dda02001-11-13 17:56:06 +0000133 temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000134
135 if (temp == 0)
Chet Ramey00018032011-11-21 20:51:19 -0500136 allocerr ("xrealloc", bytes);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000137
138 return (temp);
139}
140
141/* Use this as the function to call when adding unwind protects so we
142 don't need to know what free() returns. */
143void
144xfree (string)
Jari Aaltobb706242000-03-17 21:46:59 +0000145 PTR_T string;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000146{
147 if (string)
148 free (string);
149}
Jari Aaltof73dda02001-11-13 17:56:06 +0000150
151#ifdef USING_BASH_MALLOC
152#include <malloc/shmalloc.h>
153
Chet Ramey00018032011-11-21 20:51:19 -0500154static void
155sh_allocerr (func, bytes, file, line)
156 const char *func;
157 size_t bytes;
158 char *file;
159 int line;
160{
161#if defined (HAVE_SBRK)
162 allocated = findbrk ();
163 fatal_error (_("%s: %s:%d: cannot allocate %lu bytes (%lu bytes allocated)"), func, file, line, (unsigned long)bytes, (unsigned long)allocated);
164#else
165 fatal_error (_("%s: %s:%d: cannot allocate %lu bytes"), func, file, line, (unsigned long)bytes);
166#endif /* !HAVE_SBRK */
167}
168
Jari Aaltof73dda02001-11-13 17:56:06 +0000169PTR_T
170sh_xmalloc (bytes, file, line)
171 size_t bytes;
172 char *file;
173 int line;
174{
175 PTR_T temp;
176
Chet Ramey00018032011-11-21 20:51:19 -0500177#if defined (DEBUG)
178 if (bytes == 0)
179 internal_warning("xmalloc: %s:%d: size argument is 0", file, line);
180#endif
181
182 FINDBRK();
Jari Aaltof73dda02001-11-13 17:56:06 +0000183 temp = sh_malloc (bytes, file, line);
184
185 if (temp == 0)
Chet Ramey00018032011-11-21 20:51:19 -0500186 sh_allocerr ("xmalloc", bytes, file, line);
Jari Aaltof73dda02001-11-13 17:56:06 +0000187
188 return (temp);
189}
190
191PTR_T
192sh_xrealloc (pointer, bytes, file, line)
193 PTR_T pointer;
194 size_t bytes;
195 char *file;
196 int line;
197{
198 PTR_T temp;
199
Chet Ramey00018032011-11-21 20:51:19 -0500200#if defined (DEBUG)
201 if (bytes == 0)
202 internal_warning("xrealloc: %s:%d: size argument is 0", file, line);
203#endif
204
205 FINDBRK();
Jari Aaltof73dda02001-11-13 17:56:06 +0000206 temp = pointer ? sh_realloc (pointer, bytes, file, line) : sh_malloc (bytes, file, line);
207
208 if (temp == 0)
Chet Ramey00018032011-11-21 20:51:19 -0500209 sh_allocerr ("xrealloc", bytes, file, line);
Jari Aaltof73dda02001-11-13 17:56:06 +0000210
211 return (temp);
212}
213
214void
215sh_xfree (string, file, line)
216 PTR_T string;
217 char *file;
218 int line;
219{
220 if (string)
221 sh_free (string, file, line);
222}
223#endif