Blame gnulib/lib/safe-alloc.c

Packit Service a2ae7a
/* safe-alloc.c: safer memory allocation
Packit Service a2ae7a
Packit Service a2ae7a
   Copyright (C) 2009-2019 Free Software Foundation, Inc.
Packit Service a2ae7a
Packit Service a2ae7a
   This program is free software: you can redistribute it and/or modify it
Packit Service a2ae7a
   under the terms of the GNU Lesser General Public License as published by the
Packit Service a2ae7a
   Free Software Foundation; either version 2.1 of the License, or any
Packit Service a2ae7a
   later version.
Packit Service a2ae7a
Packit Service a2ae7a
   This program is distributed in the hope that it will be useful,
Packit Service a2ae7a
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a2ae7a
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service a2ae7a
   GNU Lesser General Public License for more details.
Packit Service a2ae7a
Packit Service a2ae7a
   You should have received a copy of the GNU Lesser General Public License
Packit Service a2ae7a
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit Service a2ae7a
Packit Service a2ae7a
/* Written by Daniel Berrange <berrange@redhat.com>, 2008 */
Packit Service a2ae7a
Packit Service a2ae7a
#include <config.h>
Packit Service a2ae7a
Packit Service a2ae7a
/* Specification.  */
Packit Service a2ae7a
#include "safe-alloc.h"
Packit Service a2ae7a
Packit Service a2ae7a
#include "xalloc-oversized.h"
Packit Service a2ae7a
Packit Service a2ae7a
#include <stdlib.h>
Packit Service a2ae7a
#include <stddef.h>
Packit Service a2ae7a
#include <errno.h>
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
/**
Packit Service a2ae7a
 * safe_alloc_alloc_n:
Packit Service a2ae7a
 * @ptrptr: pointer to pointer for address of allocated memory
Packit Service a2ae7a
 * @size: number of bytes to allocate
Packit Service a2ae7a
 * @count: number of elements to allocate
Packit Service a2ae7a
 *
Packit Service a2ae7a
 * Allocate an array of memory 'count' elements long,
Packit Service a2ae7a
 * each with 'size' bytes. Return the address of the
Packit Service a2ae7a
 * allocated memory in 'ptrptr'.  The newly allocated
Packit Service a2ae7a
 * memory is filled with zeros.
Packit Service a2ae7a
 *
Packit Service a2ae7a
 * Return -1 on failure to allocate, zero on success
Packit Service a2ae7a
 */
Packit Service a2ae7a
int
Packit Service a2ae7a
safe_alloc_alloc_n (void *ptrptr, size_t size, size_t count, int zeroed)
Packit Service a2ae7a
{
Packit Service a2ae7a
  if (size == 0 || count == 0)
Packit Service a2ae7a
    {
Packit Service a2ae7a
      *(void **) ptrptr = NULL;
Packit Service a2ae7a
      return 0;
Packit Service a2ae7a
    }
Packit Service a2ae7a
Packit Service a2ae7a
  if (xalloc_oversized (count, size))
Packit Service a2ae7a
    {
Packit Service a2ae7a
      errno = ENOMEM;
Packit Service a2ae7a
      return -1;
Packit Service a2ae7a
    }
Packit Service a2ae7a
Packit Service a2ae7a
  if (zeroed)
Packit Service a2ae7a
    *(void **) ptrptr = calloc (count, size);
Packit Service a2ae7a
  else
Packit Service a2ae7a
    *(void **) ptrptr = malloc (count * size);
Packit Service a2ae7a
Packit Service a2ae7a
  if (*(void **) ptrptr == NULL)
Packit Service a2ae7a
    return -1;
Packit Service a2ae7a
  return 0;
Packit Service a2ae7a
}
Packit Service a2ae7a
Packit Service a2ae7a
/**
Packit Service a2ae7a
 * safe_alloc_realloc_n:
Packit Service a2ae7a
 * @ptrptr: pointer to pointer for address of allocated memory
Packit Service a2ae7a
 * @size: number of bytes to allocate
Packit Service a2ae7a
 * @count: number of elements in array
Packit Service a2ae7a
 *
Packit Service a2ae7a
 * Resize the block of memory in 'ptrptr' to be an array of
Packit Service a2ae7a
 * 'count' elements, each 'size' bytes in length. Update 'ptrptr'
Packit Service a2ae7a
 * with the address of the newly allocated memory. On failure,
Packit Service a2ae7a
 * 'ptrptr' is not changed and still points to the original memory
Packit Service a2ae7a
 * block. The newly allocated memory is filled with zeros.
Packit Service a2ae7a
 *
Packit Service a2ae7a
 * Return -1 on failure to allocate, zero on success
Packit Service a2ae7a
 */
Packit Service a2ae7a
int
Packit Service a2ae7a
safe_alloc_realloc_n (void *ptrptr, size_t size, size_t count)
Packit Service a2ae7a
{
Packit Service a2ae7a
  void *tmp;
Packit Service a2ae7a
  if (size == 0 || count == 0)
Packit Service a2ae7a
    {
Packit Service a2ae7a
      free (*(void **) ptrptr);
Packit Service a2ae7a
      *(void **) ptrptr = NULL;
Packit Service a2ae7a
      return 0;
Packit Service a2ae7a
    }
Packit Service a2ae7a
  if (xalloc_oversized (count, size))
Packit Service a2ae7a
    {
Packit Service a2ae7a
      errno = ENOMEM;
Packit Service a2ae7a
      return -1;
Packit Service a2ae7a
    }
Packit Service a2ae7a
  tmp = realloc (*(void **) ptrptr, size * count);
Packit Service a2ae7a
  if (!tmp)
Packit Service a2ae7a
    return -1;
Packit Service a2ae7a
  *(void **) ptrptr = tmp;
Packit Service a2ae7a
  return 0;
Packit Service a2ae7a
}