reallocarr.c revision 1.3
11.3Skamil/* $NetBSD: reallocarr.c,v 1.3 2015/07/28 17:13:34 kamil Exp $ */ 21.1Sjoerg 31.1Sjoerg/*- 41.1Sjoerg * Copyright (c) 2015 Joerg Sonnenberger <joerg@NetBSD.org>. 51.1Sjoerg * All rights reserved. 61.1Sjoerg * 71.1Sjoerg * Redistribution and use in source and binary forms, with or without 81.1Sjoerg * modification, are permitted provided that the following conditions 91.1Sjoerg * are met: 101.1Sjoerg * 111.1Sjoerg * 1. Redistributions of source code must retain the above copyright 121.1Sjoerg * notice, this list of conditions and the following disclaimer. 131.1Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 141.1Sjoerg * notice, this list of conditions and the following disclaimer in 151.1Sjoerg * the documentation and/or other materials provided with the 161.1Sjoerg * distribution. 171.1Sjoerg * 181.1Sjoerg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 191.1Sjoerg * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 201.1Sjoerg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 211.1Sjoerg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 221.1Sjoerg * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 231.1Sjoerg * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 241.1Sjoerg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 251.1Sjoerg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 261.1Sjoerg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 271.1Sjoerg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 281.1Sjoerg * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 291.1Sjoerg * SUCH DAMAGE. 301.1Sjoerg */ 311.1Sjoerg 321.3Skamil#if HAVE_NBTOOL_CONFIG_H 331.3Skamil#include "nbtool_config.h" 341.3Skamil#endif 351.3Skamil 361.1Sjoerg#include <sys/cdefs.h> 371.3Skamil__RCSID("$NetBSD: reallocarr.c,v 1.3 2015/07/28 17:13:34 kamil Exp $"); 381.1Sjoerg 391.1Sjoerg#include "namespace.h" 401.1Sjoerg#include <errno.h> 411.1Sjoerg/* Old POSIX has SIZE_MAX in limits.h */ 421.1Sjoerg#include <limits.h> 431.1Sjoerg#include <stdint.h> 441.1Sjoerg#include <stdlib.h> 451.1Sjoerg#include <string.h> 461.1Sjoerg 471.1Sjoerg#ifdef _LIBC 481.1Sjoerg#ifdef __weak_alias 491.1Sjoerg__weak_alias(reallocarr, _reallocarr) 501.1Sjoerg#endif 511.1Sjoerg#endif 521.1Sjoerg 531.3Skamil#define SQRT_SIZE_MAX (1UL << (sizeof(size_t) << 2)) 541.3Skamil 551.3Skamil#if !HAVE_REALLOCARR 561.1Sjoergint 571.3Skamilreallocarr(void *ptr, size_t number, size_t size) 581.1Sjoerg{ 591.1Sjoerg int saved_errno, result; 601.1Sjoerg void *optr; 611.1Sjoerg void *nptr; 621.1Sjoerg 631.2Skamil saved_errno = errno; 641.1Sjoerg memcpy(&optr, ptr, sizeof(ptr)); 651.3Skamil if (number == 0 || size == 0) { 661.1Sjoerg free(optr); 671.1Sjoerg nptr = NULL; 681.1Sjoerg memcpy(ptr, &nptr, sizeof(ptr)); 691.1Sjoerg errno = saved_errno; 701.1Sjoerg return 0; 711.1Sjoerg } 721.3Skamil 731.3Skamil if ((number >= SQRT_SIZE_MAX || size >= SQRT_SIZE_MAX) && 741.3Skamil number > SIZE_MAX / size) { 751.3Skamil errno = saved_errno; 761.1Sjoerg return EOVERFLOW; 771.3Skamil } 781.3Skamil 791.3Skamil nptr = realloc(optr, number * size); 801.1Sjoerg if (nptr == NULL) { 811.1Sjoerg result = errno; 821.1Sjoerg } else { 831.1Sjoerg result = 0; 841.1Sjoerg memcpy(ptr, &nptr, sizeof(ptr)); 851.1Sjoerg } 861.1Sjoerg errno = saved_errno; 871.1Sjoerg return result; 881.1Sjoerg} 891.3Skamil#endif 90