Hi Bruno,

Thanks for your help.
I've made the changes you mentioned and attached a new version of the patch. Do let me know if something is missing. I am not sure of how the documentation should be written. Specifically, which platforms this module is targeting.

* Bruno Haible <br...@clisp.org> [170808 14:42]:
Hi Darshit,

Thanks for the guidelines. I've written a very rudimentary version of
the module. This is a barely working version

The implementation (.c file) looks good. However, it could be formatted
in GNU style (like the rest of gnulib, with very few exceptions, e.g. fts.c).

The module name should IMO be 'reallocarray'. We use the suffix '-gnu' only
when there is ambiguity between POSIX and GNU behaviour (e.g. for getopt).

I know that this is missing:

1. An autoconf check
2. A way for reallocarray() to be defined within <stdlib.h>
3. Unit tests

And 4. A documentation file doc/glibc-functions/reallocarray.texi.

for the other two, I don't know how to write them

1. Look at m4/strsep.m4.
2. grep for strsep and STRSEP in lib/string.in.h, m4/string_h.m4, 
modules/string.
  We use the same idioms everywhere.

The glibc version is implemented behind the feature macro, _GNU_SOURCE.
I am not sure how that should be implemented into the module in gnulib.

The gnulib modules make their symbols visible unconditionally. That is, a
user that includes the gnulib module 'reallocarray' should be able to use
reallocarray() without defining _GNU_SOURCE by themselves. This is done through
an invocation of AC_USE_SYSTEM_EXTENSIONS from within m4/reallocarray.m4.

Bruno



--
Thanking You,
Darshit Shah
PGP Fingerprint: 7845 120B 07CB D8D6 ECE5 FF2B 2A17 43ED A91A 35B6
From 85b855a446cf0f634627f03b3bb10694ac419c74 Mon Sep 17 00:00:00 2001
From: Darshit Shah <dar...@gmail.com>
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/stdlib                        |  2 ++
 tests/test-reallocarray.c             | 57 +++++++++++++++++++++++++++++++++++
 9 files changed, 183 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 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 @@
+@node reallocarray
+@subsection @code{reallocarray}
+@findex reallocarray
+
+Gnulib module: reallocarray
+
+Portability problems fixed by Gnulib:
+@itemize
+@item
+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.
+@end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
+@end 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 <http://www.gnu.org/licenses/>.  */
+
+/* written by Darshit Shah */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <errno.h>
+
+#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 <stdlib.h> 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:
+<stdlib.h>
+
+License:
+GPLv3+
+
+Maintainer:
+Darshit Shah
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..d1f332203
--- /dev/null
+++ b/tests/test-reallocarray.c
@@ -0,0 +1,57 @@
+/* Test of calloc 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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+/* 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 calloc (0, 0) is not a NULL pointer.  */
+  void *p = calloc (0, 0);
+  if (p == NULL)
+    return 1;
+  free (p);
+
+
+  /* Check that calloc 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.  */
+  p = NULL;
+  p = reallocarray(p, (size_t) -1 / 8 + 1, eight ());
+  if (p != NULL)
+    {
+      free (p);
+      return 1;
+    }
+
+  return 0;
+}
-- 
2.14.0

Attachment: signature.asc
Description: PGP signature

Reply via email to