Blame lib/xmalloc.c

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