From 3a5a5ffdfc215b4ee0bee2383097bd2e1cbebd1b Mon Sep 17 00:00:00 2001
From: Darshit Shah
Date: Tue, 8 Aug 2017 15:56:27 +0200
Subject: [PATCH] Add new module reallocarray
---
MODULES.html.sh | 1 +
doc/glibc-functions/reallocarray.texi | 17 +++++++++++++
lib/reallocarray.c | 37 +++++++++++++++++++++++++++
lib/stdlib.in.h | 14 ++++++++++
m4/reallocarray.m4 | 20 +++++++++++++++
m4/stdlib_h.m4 | 8 +++---
modules/reallocarray | 30 ++++++++++++++++++++++
modules/reallocarray-tests | 10 ++++++++
modules/stdlib | 2 ++
tests/test-reallocarray.c | 48 +++++++++++++++++++++++++++++++++++
10 files changed, 184 insertions(+), 3 deletions(-)
create mode 100644 doc/glibc-functions/reallocarray.texi
create mode 100644 lib/reallocarray.c
create mode 100644 m4/reallocarray.m4
create mode 100644 modules/reallocarray
create mode 100644 modules/reallocarray-tests
create mode 100644 tests/test-reallocarray.c
diff --git a/MODULES.html.sh b/MODULES.html.sh
index a64b9997e..1a258b632 100755
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -1703,6 +1703,7 @@ func_all_modules ()
func_module free
func_module malloc-gnu
func_module realloc-gnu
+ func_module reallocarray
func_module pagealign_alloc
func_end_table
diff --git a/doc/glibc-functions/reallocarray.texi b/doc/glibc-functions/reallocarray.texi
new file mode 100644
index 000000000..ae8da2983
--- /dev/null
+++ b/doc/glibc-functions/reallocarray.texi
@@ -0,0 +1,17 @@
address@hidden reallocarray
address@hidden @code{reallocarray}
address@hidden reallocarray
+
+Gnulib module: reallocarray
+
+Portability problems fixed by Gnulib:
address@hidden
address@hidden
+This function is not available on platforms with glibc < 2.26.
+This function is missing on some platforms:
+AIX 4.3.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw, MSVC 14, BeOS.
address@hidden itemize
+
+Portability problems not fixed by Gnulib:
address@hidden
address@hidden itemize
diff --git a/lib/reallocarray.c b/lib/reallocarray.c
new file mode 100644
index 000000000..dcd5d8df3
--- /dev/null
+++ b/lib/reallocarray.c
@@ -0,0 +1,37 @@
+/* reallocarray() function that is glibc compatible.
+
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* written by Darshit Shah */
+
+#include
+
+#include
+#include
+
+#include "xalloc-oversized.h"
+
+void *
+reallocarray(void *ptr, size_t nmemb, size_t size)
+{
+ if (xalloc_oversized (nmemb, size))
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ /* We rely on using the semantics of the GNU realloc() function here. */
+ return realloc(ptr, nmemb * size);
+}
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index b5cf9d369..6805bfba9 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -765,6 +765,20 @@ _GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - "
"use gnulib module realloc-posix for portability");
#endif
+#if @GNULIB_REALLOCARRAY@
+# if ! @HAVE_REALLOCARRAY@
+_GL_FUNCDECL_SYS (reallocarray, void *,
+ (void *ptr, size_t nmemb, size_t size));
+# endif
+_GL_CXXALIAS_SYS (reallocarray, void *,
+ (void *ptr, size_t nmemb, size_t size));
+_GL_CXXALIASWARN (reallocarray);
+#elif defined GNULIB_POSIXCHECK
+# undef reallocarray
+_GL_WARN_ON_USE (reallocarray, "reallocarray is not portable - "
+ "use gnulib module reallocarray for portability");
+#endif
+
#if @GNULIB_REALPATH@
# if @REPLACE_REALPATH@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/m4/reallocarray.m4 b/m4/reallocarray.m4
new file mode 100644
index 000000000..cdcd2fbf4
--- /dev/null
+++ b/m4/reallocarray.m4
@@ -0,0 +1,20 @@
+# reallocarray.m4 serial 1
+dnl Copyright (C) 2017 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_REALLOCARRAY],
+[
+ dnl Persuade glibc to declare reallocarray().
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_CHECK_FUNCS([reallocarray])
+ if test $ac_cv_func_reallocarray = no; then
+ HAVE_REALLOCARRAY=0
+ fi
+])
+
+# Prerequisites of lib/reallocarray.c.
+AC_DEFUN([gl_PREREQ_REALLOCARRAY], [:])
diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4
index 110fe2d1a..a38dff165 100644
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -21,9 +21,9 @@ AC_DEFUN([gl_STDLIB_H],
#endif
]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt
initstate initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps
- posix_openpt ptsname ptsname_r qsort_r random random_r realpath rpmatch
- secure_getenv setenv setstate setstate_r srandom srandom_r
- strtod strtoll strtoull unlockpt unsetenv])
+ posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray
+ realpath rpmatch secure_getenv setenv setstate setstate_r srandom
+ srandom_r strtod strtoll strtoull unlockpt unsetenv])
])
AC_DEFUN([gl_STDLIB_MODULE_INDICATOR],
@@ -58,6 +58,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
GNULIB_QSORT_R=0; AC_SUBST([GNULIB_QSORT_R])
GNULIB_RANDOM=0; AC_SUBST([GNULIB_RANDOM])
GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R])
+ GNULIB_REALLOCARRAY=0; AC_SUBST([GNULIB_REALLOCARRAY])
GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX])
GNULIB_REALPATH=0; AC_SUBST([GNULIB_REALPATH])
GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH])
@@ -89,6 +90,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
HAVE_RANDOM=1; AC_SUBST([HAVE_RANDOM])
HAVE_RANDOM_H=1; AC_SUBST([HAVE_RANDOM_H])
HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R])
+ HAVE_REALLOCARRAY=1; AC_SUBST([HAVE_REALLOCARRAY])
HAVE_REALPATH=1; AC_SUBST([HAVE_REALPATH])
HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH])
HAVE_SECURE_GETENV=1; AC_SUBST([HAVE_SECURE_GETENV])
diff --git a/modules/reallocarray b/modules/reallocarray
new file mode 100644
index 000000000..1477b2d42
--- /dev/null
+++ b/modules/reallocarray
@@ -0,0 +1,30 @@
+Description:
+reallocarray() function that is glibc compatible.
+
+Files:
+lib/reallocarray.c
+m4/reallocarray.m4
+
+Depends-on:
+xalloc-oversized
+realloc-gnu
+stdlib
+
+configure.ac:
+gl_FUNC_REALLOCARRAY
+if test $HAVE_REALLOCARRAY = 0; then
+ AC_LIBOBJ([reallocarray])
+ gl_PREREQ_REALLOCARRAY
+fi
+gl_MODULE_INDICATOR([reallocarray])
+
+Makefile.am:
+
+Include:
+
+
+License:
+GPLv3+
+
+Maintainer:
+Darshit Shah
diff --git a/modules/reallocarray-tests b/modules/reallocarray-tests
new file mode 100644
index 000000000..4ef4cf679
--- /dev/null
+++ b/modules/reallocarray-tests
@@ -0,0 +1,10 @@
+Files:
+tests/test-reallocarray.c
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-reallocarray
+check_PROGRAMS += test-reallocarray
diff --git a/modules/stdlib b/modules/stdlib
index 27b1caa3b..257b5dbd6 100644
--- a/modules/stdlib
+++ b/modules/stdlib
@@ -53,6 +53,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
-e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \
-e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
-e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \
+ -e 's/@''GNULIB_REALLOCARRAY''@/$(GNULIB_REALLOCARRAY)/g' \
-e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \
-e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \
-e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \
@@ -83,6 +84,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
-e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \
-e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
-e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
+ -e 's|@''HAVE_REALLOCARRAY''@|$(HAVE_REALLOCARRAY)|g' \
-e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \
-e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \
-e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \
diff --git a/tests/test-reallocarray.c b/tests/test-reallocarray.c
new file mode 100644
index 000000000..3a1f4fee9
--- /dev/null
+++ b/tests/test-reallocarray.c
@@ -0,0 +1,48 @@
+/* Test of reallocarray function.
+ Copyright (C) 2010-2017 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+
+/* Return 8.
+ Usual compilers are not able to infer something about the return value. */
+static unsigned int
+eight (void)
+{
+ unsigned int x = rand ();
+ unsigned int y = x * x * x * x;
+ x++; y |= x * x * x * x;
+ x++; y |= x * x * x * x;
+ x++; y |= x * x * x * x;
+ y = y >> 1;
+ return y & -y;
+}
+
+int
+main ()
+{
+ /* Check that reallocarray fails when requested to allocate a block of memory
+ larger than SIZE_MAX bytes.
+ We use eight (), not 8, to avoid a compiler warning from GCC 7. */
+ char *p = reallocarray(NULL, (size_t) -1 / 8 + 1, eight ());
+ if (p != NULL)
+ {
+ free (p);
+ return 1;
+ }
+
+ return 0;
+}
--
2.14.0