reallocarr.c revision 1.1
11.1Sjoerg/* $NetBSD: reallocarr.c,v 1.1 2015/02/17 20:29:21 joerg 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.1Sjoerg#include <sys/cdefs.h>
331.1Sjoerg__RCSID("$NetBSD: reallocarr.c,v 1.1 2015/02/17 20:29:21 joerg Exp $");
341.1Sjoerg
351.1Sjoerg#include "namespace.h"
361.1Sjoerg#include <errno.h>
371.1Sjoerg/* Old POSIX has SIZE_MAX in limits.h */
381.1Sjoerg#include <limits.h>
391.1Sjoerg#include <stdint.h>
401.1Sjoerg#include <stdlib.h>
411.1Sjoerg#include <string.h>
421.1Sjoerg
431.1Sjoerg__CTASSERT(65535 < SIZE_MAX / 65535);
441.1Sjoerg
451.1Sjoerg#ifdef _LIBC
461.1Sjoerg#ifdef __weak_alias
471.1Sjoerg__weak_alias(reallocarr, _reallocarr)
481.1Sjoerg#endif
491.1Sjoerg#endif
501.1Sjoerg
511.1Sjoergint
521.1Sjoergreallocarr(void *ptr, size_t num, size_t size)
531.1Sjoerg{
541.1Sjoerg	int saved_errno, result;
551.1Sjoerg	void *optr;
561.1Sjoerg	void *nptr;
571.1Sjoerg
581.1Sjoerg	memcpy(&optr, ptr, sizeof(ptr));
591.1Sjoerg	saved_errno = errno;
601.1Sjoerg	if (num == 0 || size == 0) {
611.1Sjoerg		free(optr);
621.1Sjoerg		nptr = NULL;
631.1Sjoerg		memcpy(ptr, &nptr, sizeof(ptr));
641.1Sjoerg		errno = saved_errno;
651.1Sjoerg		return 0;
661.1Sjoerg	}
671.1Sjoerg	if ((num >= 65535 || size >= 65535) && num > SIZE_MAX / size)
681.1Sjoerg		return EOVERFLOW;
691.1Sjoerg	nptr = realloc(optr, num * size);
701.1Sjoerg	if (nptr == NULL) {
711.1Sjoerg		result = errno;
721.1Sjoerg	} else {
731.1Sjoerg		result = 0;
741.1Sjoerg		memcpy(ptr, &nptr, sizeof(ptr));
751.1Sjoerg	}
761.1Sjoerg	errno = saved_errno;
771.1Sjoerg	return result;
781.1Sjoerg}
79