Blame lib/xmalloc.c

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