1/* memory allocation routines with error checking.
2   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 2015
3   Free Software Foundation, Inc.
4
5This file is part of the libiberty library.
6Libiberty is free software; you can redistribute it and/or
7modify it under the terms of the GNU Library General Public
8License as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later version.
10
11Libiberty is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14Library General Public License for more details.
15
16You should have received a copy of the GNU Library General Public
17License along with libiberty; see the file COPYING.LIB.  If
18not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19Boston, MA 02110-1301, USA.  */
20
21/*
22
23@deftypefn Replacement void* xmalloc (size_t)
24
25Allocate memory without fail.  If @code{malloc} fails, this will print
26a message to @code{stderr} (using the name set by
27@code{xmalloc_set_program_name},
28if any) and then call @code{xexit}.  Note that it is therefore safe for
29a program to contain @code{#define malloc xmalloc} in its source.
30
31@end deftypefn
32
33@deftypefn Replacement void* xrealloc (void *@var{ptr}, size_t @var{size})
34Reallocate memory without fail.  This routine functions like @code{realloc},
35but will behave the same as @code{xmalloc} if memory cannot be found.
36
37@end deftypefn
38
39@deftypefn Replacement void* xcalloc (size_t @var{nelem}, size_t @var{elsize})
40
41Allocate memory without fail, and set it to zero.  This routine functions
42like @code{calloc}, but will behave the same as @code{xmalloc} if memory
43cannot be found.
44
45@end deftypefn
46
47@deftypefn Replacement void xmalloc_set_program_name (const char *@var{name})
48
49You can use this to set the name of the program used by
50@code{xmalloc_failed} when printing a failure message.
51
52@end deftypefn
53
54@deftypefn Replacement void xmalloc_failed (size_t)
55
56This function is not meant to be called by client code, and is listed
57here for completeness only.  If any of the allocation routines fail, this
58function will be called to print an error message and terminate execution.
59
60@end deftypefn
61
62*/
63
64#ifdef HAVE_CONFIG_H
65#include "config.h"
66#endif
67#include "ansidecl.h"
68#include "libiberty.h"
69#include "environ.h"
70
71#include <stdio.h>
72
73#include <stddef.h>
74
75#if VMS
76#include <stdlib.h>
77#include <unixlib.h>
78#else
79/* For systems with larger pointers than ints, these must be declared.  */
80#  if HAVE_STDLIB_H && HAVE_UNISTD_H && HAVE_DECL_MALLOC \
81      && HAVE_DECL_REALLOC && HAVE_DECL_CALLOC && HAVE_DECL_SBRK
82#    include <stdlib.h>
83#    include <unistd.h>
84#  else
85#    ifdef __cplusplus
86extern "C" {
87#    endif /* __cplusplus */
88void *malloc (size_t);
89void *realloc (void *, size_t);
90void *calloc (size_t, size_t);
91void *sbrk (ptrdiff_t);
92#    ifdef __cplusplus
93}
94#    endif /* __cplusplus */
95#  endif /* HAVE_STDLIB_H ...  */
96#endif /* VMS */
97
98/* The program name if set.  */
99static const char *name = "";
100
101#ifdef HAVE_SBRK
102/* The initial sbrk, set when the program name is set. Not used for win32
103   ports other than cygwin32.  */
104static char *first_break = NULL;
105#endif /* HAVE_SBRK */
106
107void
108xmalloc_set_program_name (const char *s)
109{
110  name = s;
111#ifdef HAVE_SBRK
112  /* Win32 ports other than cygwin32 don't have brk() */
113  if (first_break == NULL)
114    first_break = (char *) sbrk (0);
115#endif /* HAVE_SBRK */
116}
117
118void
119xmalloc_failed (size_t size)
120{
121#ifdef HAVE_SBRK
122  size_t allocated;
123
124  if (first_break != NULL)
125    allocated = (char *) sbrk (0) - first_break;
126  else
127    allocated = (char *) sbrk (0) - (char *) &environ;
128  fprintf (stderr,
129	   "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
130	   name, *name ? ": " : "",
131	   (unsigned long) size, (unsigned long) allocated);
132#else /* HAVE_SBRK */
133  fprintf (stderr,
134	   "\n%s%sout of memory allocating %lu bytes\n",
135	   name, *name ? ": " : "",
136	   (unsigned long) size);
137#endif /* HAVE_SBRK */
138  xexit (1);
139}
140
141PTR
142xmalloc (size_t size)
143{
144  PTR newmem;
145
146  if (size == 0)
147    size = 1;
148  newmem = malloc (size);
149  if (!newmem)
150    xmalloc_failed (size);
151
152  return (newmem);
153}
154
155PTR
156xcalloc (size_t nelem, size_t elsize)
157{
158  PTR newmem;
159
160  if (nelem == 0 || elsize == 0)
161    nelem = elsize = 1;
162
163  newmem = calloc (nelem, elsize);
164  if (!newmem)
165    xmalloc_failed (nelem * elsize);
166
167  return (newmem);
168}
169
170PTR
171xrealloc (PTR oldmem, size_t size)
172{
173  PTR newmem;
174
175  if (size == 0)
176    size = 1;
177  if (!oldmem)
178    newmem = malloc (size);
179  else
180    newmem = realloc (oldmem, size);
181  if (!newmem)
182    xmalloc_failed (size);
183
184  return (newmem);
185}
186