Blame lib/xmalloc.c

Packit 8f70b4
/* xmalloc.c -- malloc with out of memory checking
Packit 8f70b4
Packit 8f70b4
   Copyright (C) 1990-2000, 2002-2006, 2008-2018 Free Software Foundation, Inc.
Packit 8f70b4
Packit 8f70b4
   This program is free software: you can redistribute it and/or modify
Packit 8f70b4
   it under the terms of the GNU General Public License as published by
Packit 8f70b4
   the Free Software Foundation; either version 3 of the License, or
Packit 8f70b4
   (at your option) any later version.
Packit 8f70b4
Packit 8f70b4
   This program is distributed in the hope that it will be useful,
Packit 8f70b4
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8f70b4
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8f70b4
   GNU General Public License for more details.
Packit 8f70b4
Packit 8f70b4
   You should have received a copy of the GNU General Public License
Packit 8f70b4
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit 8f70b4
Packit 8f70b4
#include <config.h>
Packit 8f70b4
Packit 8f70b4
#define XALLOC_INLINE _GL_EXTERN_INLINE
Packit 8f70b4
Packit 8f70b4
#include "xalloc.h"
Packit 8f70b4
Packit 8f70b4
#include <stdlib.h>
Packit 8f70b4
#include <string.h>
Packit 8f70b4
Packit 8f70b4
/* 1 if calloc is known to be compatible with GNU calloc.  This
Packit 8f70b4
   matters if we are not also using the calloc module, which defines
Packit 8f70b4
   HAVE_CALLOC_GNU and supports the GNU API even on non-GNU platforms.  */
Packit 8f70b4
#if defined HAVE_CALLOC_GNU || (defined __GLIBC__ && !defined __UCLIBC__)
Packit 8f70b4
enum { HAVE_GNU_CALLOC = 1 };
Packit 8f70b4
#else
Packit 8f70b4
enum { HAVE_GNU_CALLOC = 0 };
Packit 8f70b4
#endif
Packit 8f70b4
Packit 8f70b4
/* Allocate N bytes of memory dynamically, with error checking.  */
Packit 8f70b4
Packit 8f70b4
void *
Packit 8f70b4
xmalloc (size_t n)
Packit 8f70b4
{
Packit 8f70b4
  void *p = malloc (n);
Packit 8f70b4
  if (!p && n != 0)
Packit 8f70b4
    xalloc_die ();
Packit 8f70b4
  return p;
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
/* Change the size of an allocated block of memory P to N bytes,
Packit 8f70b4
   with error checking.  */
Packit 8f70b4
Packit 8f70b4
void *
Packit 8f70b4
xrealloc (void *p, size_t n)
Packit 8f70b4
{
Packit 8f70b4
  if (!n && p)
Packit 8f70b4
    {
Packit 8f70b4
      /* The GNU and C99 realloc behaviors disagree here.  Act like
Packit 8f70b4
         GNU, even if the underlying realloc is C99.  */
Packit 8f70b4
      free (p);
Packit 8f70b4
      return NULL;
Packit 8f70b4
    }
Packit 8f70b4
Packit 8f70b4
  p = realloc (p, n);
Packit 8f70b4
  if (!p && n)
Packit 8f70b4
    xalloc_die ();
Packit 8f70b4
  return p;
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
/* If P is null, allocate a block of at least *PN bytes; otherwise,
Packit 8f70b4
   reallocate P so that it contains more than *PN bytes.  *PN must be
Packit 8f70b4
   nonzero unless P is null.  Set *PN to the new block's size, and
Packit 8f70b4
   return the pointer to the new block.  *PN is never set to zero, and
Packit 8f70b4
   the returned pointer is never null.  */
Packit 8f70b4
Packit 8f70b4
void *
Packit 8f70b4
x2realloc (void *p, size_t *pn)
Packit 8f70b4
{
Packit 8f70b4
  return x2nrealloc (p, pn, 1);
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
/* Allocate S bytes of zeroed memory dynamically, with error checking.
Packit 8f70b4
   There's no need for xnzalloc (N, S), since it would be equivalent
Packit 8f70b4
   to xcalloc (N, S).  */
Packit 8f70b4
Packit 8f70b4
void *
Packit 8f70b4
xzalloc (size_t s)
Packit 8f70b4
{
Packit 8f70b4
  return memset (xmalloc (s), 0, s);
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
/* Allocate zeroed memory for N elements of S bytes, with error
Packit 8f70b4
   checking.  S must be nonzero.  */
Packit 8f70b4
Packit 8f70b4
void *
Packit 8f70b4
xcalloc (size_t n, size_t s)
Packit 8f70b4
{
Packit 8f70b4
  void *p;
Packit 8f70b4
  /* Test for overflow, since objects with size greater than
Packit 8f70b4
     PTRDIFF_MAX cause pointer subtraction to go awry.  Omit size-zero
Packit 8f70b4
     tests if HAVE_GNU_CALLOC, since GNU calloc never returns NULL if
Packit 8f70b4
     successful.  */
Packit 8f70b4
  if (xalloc_oversized (n, s)
Packit 8f70b4
      || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0)))
Packit 8f70b4
    xalloc_die ();
Packit 8f70b4
  return p;
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
/* Clone an object P of size S, with error checking.  There's no need
Packit 8f70b4
   for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
Packit 8f70b4
   need for an arithmetic overflow check.  */
Packit 8f70b4
Packit 8f70b4
void *
Packit 8f70b4
xmemdup (void const *p, size_t s)
Packit 8f70b4
{
Packit 8f70b4
  return memcpy (xmalloc (s), p, s);
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
/* Clone STRING.  */
Packit 8f70b4
Packit 8f70b4
char *
Packit 8f70b4
xstrdup (char const *string)
Packit 8f70b4
{
Packit 8f70b4
  return xmemdup (string, strlen (string) + 1);
Packit 8f70b4
}