Home | History | Annotate | Download | only in libiberty
      1 /* memory allocation routines with error checking.
      2    Copyright 1989, 1990, 1991, 1992, 1993, 1994, 2015
      3    Free Software Foundation, Inc.
      4 
      5 This file is part of the libiberty library.
      6 Libiberty is free software; you can redistribute it and/or
      7 modify it under the terms of the GNU Library General Public
      8 License as published by the Free Software Foundation; either
      9 version 2 of the License, or (at your option) any later version.
     10 
     11 Libiberty is distributed in the hope that it will be useful,
     12 but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 Library General Public License for more details.
     15 
     16 You should have received a copy of the GNU Library General Public
     17 License along with libiberty; see the file COPYING.LIB.  If
     18 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
     19 Boston, MA 02110-1301, USA.  */
     20 
     21 /*
     22 
     23 @deftypefn Replacement void* xmalloc (size_t)
     24 
     25 Allocate memory without fail.  If @code{malloc} fails, this will print
     26 a message to @code{stderr} (using the name set by
     27 @code{xmalloc_set_program_name},
     28 if any) and then call @code{xexit}.  Note that it is therefore safe for
     29 a 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})
     34 Reallocate memory without fail.  This routine functions like @code{realloc},
     35 but 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 
     41 Allocate memory without fail, and set it to zero.  This routine functions
     42 like @code{calloc}, but will behave the same as @code{xmalloc} if memory
     43 cannot be found.
     44 
     45 @end deftypefn
     46 
     47 @deftypefn Replacement void xmalloc_set_program_name (const char *@var{name})
     48 
     49 You 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 
     56 This function is not meant to be called by client code, and is listed
     57 here for completeness only.  If any of the allocation routines fail, this
     58 function 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
     86 extern "C" {
     87 #    endif /* __cplusplus */
     88 void *malloc (size_t);
     89 void *realloc (void *, size_t);
     90 void *calloc (size_t, size_t);
     91 void *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.  */
     99 static 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.  */
    104 static char *first_break = NULL;
    105 #endif /* HAVE_SBRK */
    106 
    107 void
    108 xmalloc_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 
    118 void
    119 xmalloc_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 
    141 PTR
    142 xmalloc (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 
    155 PTR
    156 xcalloc (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 
    170 PTR
    171 xrealloc (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