xref: /dflybsd-src/contrib/grep/lib/xmalloc.c (revision 91b9ed38d3db6a8a8ac5b66da1d43e6e331e259a)
195b7b453SJohn Marino /* xmalloc.c -- malloc with out of memory checking
295b7b453SJohn Marino 
3*09d4459fSDaniel Fojt    Copyright (C) 1990-2000, 2002-2006, 2008-2020 Free Software Foundation, Inc.
495b7b453SJohn Marino 
595b7b453SJohn Marino    This program is free software: you can redistribute it and/or modify
695b7b453SJohn Marino    it under the terms of the GNU General Public License as published by
795b7b453SJohn Marino    the Free Software Foundation; either version 3 of the License, or
895b7b453SJohn Marino    (at your option) any later version.
995b7b453SJohn Marino 
1095b7b453SJohn Marino    This program is distributed in the hope that it will be useful,
1195b7b453SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
1295b7b453SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1395b7b453SJohn Marino    GNU General Public License for more details.
1495b7b453SJohn Marino 
1595b7b453SJohn Marino    You should have received a copy of the GNU General Public License
16*09d4459fSDaniel Fojt    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
1795b7b453SJohn Marino 
1895b7b453SJohn Marino #include <config.h>
1995b7b453SJohn Marino 
20680a9cb8SJohn Marino #define XALLOC_INLINE _GL_EXTERN_INLINE
21680a9cb8SJohn Marino 
2295b7b453SJohn Marino #include "xalloc.h"
2395b7b453SJohn Marino 
2495b7b453SJohn Marino #include <stdlib.h>
2595b7b453SJohn Marino #include <string.h>
2695b7b453SJohn Marino 
2795b7b453SJohn Marino /* 1 if calloc is known to be compatible with GNU calloc.  This
2895b7b453SJohn Marino    matters if we are not also using the calloc module, which defines
2995b7b453SJohn Marino    HAVE_CALLOC_GNU and supports the GNU API even on non-GNU platforms.  */
30200fbe8dSJohn Marino #if defined HAVE_CALLOC_GNU || (defined __GLIBC__ && !defined __UCLIBC__)
3195b7b453SJohn Marino enum { HAVE_GNU_CALLOC = 1 };
3295b7b453SJohn Marino #else
3395b7b453SJohn Marino enum { HAVE_GNU_CALLOC = 0 };
3495b7b453SJohn Marino #endif
3595b7b453SJohn Marino 
3695b7b453SJohn Marino /* Allocate N bytes of memory dynamically, with error checking.  */
3795b7b453SJohn Marino 
3895b7b453SJohn Marino void *
xmalloc(size_t n)3995b7b453SJohn Marino xmalloc (size_t n)
4095b7b453SJohn Marino {
4195b7b453SJohn Marino   void *p = malloc (n);
4295b7b453SJohn Marino   if (!p && n != 0)
4395b7b453SJohn Marino     xalloc_die ();
4495b7b453SJohn Marino   return p;
4595b7b453SJohn Marino }
4695b7b453SJohn Marino 
4795b7b453SJohn Marino /* Change the size of an allocated block of memory P to N bytes,
4895b7b453SJohn Marino    with error checking.  */
4995b7b453SJohn Marino 
5095b7b453SJohn Marino void *
xrealloc(void * p,size_t n)5195b7b453SJohn Marino xrealloc (void *p, size_t n)
5295b7b453SJohn Marino {
53200fbe8dSJohn Marino   if (!n && p)
54200fbe8dSJohn Marino     {
55200fbe8dSJohn Marino       /* The GNU and C99 realloc behaviors disagree here.  Act like
56200fbe8dSJohn Marino          GNU, even if the underlying realloc is C99.  */
57200fbe8dSJohn Marino       free (p);
58200fbe8dSJohn Marino       return NULL;
59200fbe8dSJohn Marino     }
60200fbe8dSJohn Marino 
6195b7b453SJohn Marino   p = realloc (p, n);
62200fbe8dSJohn Marino   if (!p && n)
6395b7b453SJohn Marino     xalloc_die ();
6495b7b453SJohn Marino   return p;
6595b7b453SJohn Marino }
6695b7b453SJohn Marino 
6795b7b453SJohn Marino /* If P is null, allocate a block of at least *PN bytes; otherwise,
6895b7b453SJohn Marino    reallocate P so that it contains more than *PN bytes.  *PN must be
6995b7b453SJohn Marino    nonzero unless P is null.  Set *PN to the new block's size, and
7095b7b453SJohn Marino    return the pointer to the new block.  *PN is never set to zero, and
7195b7b453SJohn Marino    the returned pointer is never null.  */
7295b7b453SJohn Marino 
7395b7b453SJohn Marino void *
x2realloc(void * p,size_t * pn)7495b7b453SJohn Marino x2realloc (void *p, size_t *pn)
7595b7b453SJohn Marino {
7695b7b453SJohn Marino   return x2nrealloc (p, pn, 1);
7795b7b453SJohn Marino }
7895b7b453SJohn Marino 
79*09d4459fSDaniel Fojt /* Allocate N bytes of zeroed memory dynamically, with error checking.
8095b7b453SJohn Marino    There's no need for xnzalloc (N, S), since it would be equivalent
8195b7b453SJohn Marino    to xcalloc (N, S).  */
8295b7b453SJohn Marino 
8395b7b453SJohn Marino void *
xzalloc(size_t n)84*09d4459fSDaniel Fojt xzalloc (size_t n)
8595b7b453SJohn Marino {
86*09d4459fSDaniel Fojt   return xcalloc (n, 1);
8795b7b453SJohn Marino }
8895b7b453SJohn Marino 
8995b7b453SJohn Marino /* Allocate zeroed memory for N elements of S bytes, with error
9095b7b453SJohn Marino    checking.  S must be nonzero.  */
9195b7b453SJohn Marino 
9295b7b453SJohn Marino void *
xcalloc(size_t n,size_t s)9395b7b453SJohn Marino xcalloc (size_t n, size_t s)
9495b7b453SJohn Marino {
9595b7b453SJohn Marino   void *p;
96*09d4459fSDaniel Fojt   /* Test for overflow, since objects with size greater than
97*09d4459fSDaniel Fojt      PTRDIFF_MAX cause pointer subtraction to go awry.  Omit size-zero
98*09d4459fSDaniel Fojt      tests if HAVE_GNU_CALLOC, since GNU calloc never returns NULL if
99*09d4459fSDaniel Fojt      successful.  */
100*09d4459fSDaniel Fojt   if (xalloc_oversized (n, s)
10195b7b453SJohn Marino       || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0)))
10295b7b453SJohn Marino     xalloc_die ();
10395b7b453SJohn Marino   return p;
10495b7b453SJohn Marino }
10595b7b453SJohn Marino 
10695b7b453SJohn Marino /* Clone an object P of size S, with error checking.  There's no need
10795b7b453SJohn Marino    for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
10895b7b453SJohn Marino    need for an arithmetic overflow check.  */
10995b7b453SJohn Marino 
11095b7b453SJohn Marino void *
xmemdup(void const * p,size_t s)11195b7b453SJohn Marino xmemdup (void const *p, size_t s)
11295b7b453SJohn Marino {
11395b7b453SJohn Marino   return memcpy (xmalloc (s), p, s);
11495b7b453SJohn Marino }
11595b7b453SJohn Marino 
11695b7b453SJohn Marino /* Clone STRING.  */
11795b7b453SJohn Marino 
11895b7b453SJohn Marino char *
xstrdup(char const * string)11995b7b453SJohn Marino xstrdup (char const *string)
12095b7b453SJohn Marino {
12195b7b453SJohn Marino   return xmemdup (string, strlen (string) + 1);
12295b7b453SJohn Marino }
123