Blame lib/xmalloc.c

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