summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2020-11-04 02:19:08 +0100
committerBruno Haible <bruno@clisp.org>2020-11-04 02:19:08 +0100
commit419322ec4c4c6ff1df518378d86162b7a53bf2c0 (patch)
tree9de0a3e360ff657b917881291b6ffabad0dd14bf
parent8c989f769f07699d46ba7213ded965afb0e1be35 (diff)
downloadgnulib-419322ec4c4c6ff1df518378d86162b7a53bf2c0.tar.gz
posix_memalign: New module.
* lib/stdlib.in.h (posix_memalign): New declaration. * lib/posix_memalign.c: New file. * m4/posix_memalign.m4: New file. * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether posix_memalign is declared. (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_POSIX_MEMALIGN, HAVE_POSIX_MEMALIGN, REPLACE_POSIX_MEMALIGN. * modules/stdlib (Makefile.am): Substitute GNULIB_POSIX_MEMALIGN, HAVE_POSIX_MEMALIGN, REPLACE_POSIX_MEMALIGN. * modules/posix_memalign: New file. * tests/test-stdlib-c++.cc (posix_memalign): Check signature. * doc/posix-functions/posix_memalign.texi: Mention the new module and the OpenBSD bug.
-rw-r--r--ChangeLog16
-rw-r--r--doc/posix-functions/posix_memalign.texi5
-rw-r--r--lib/posix_memalign.c35
-rw-r--r--lib/stdlib.in.h29
-rw-r--r--m4/posix_memalign.m450
-rw-r--r--m4/stdlib_h.m412
-rw-r--r--modules/posix_memalign28
-rw-r--r--modules/stdlib3
-rw-r--r--tests/test-stdlib-c++.cc5
9 files changed, 178 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index e6089930a0..fd72d3e850 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
2020-11-03 Bruno Haible <bruno@clisp.org>
+ posix_memalign: New module.
+ * lib/stdlib.in.h (posix_memalign): New declaration.
+ * lib/posix_memalign.c: New file.
+ * m4/posix_memalign.m4: New file.
+ * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether posix_memalign is declared.
+ (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_POSIX_MEMALIGN,
+ HAVE_POSIX_MEMALIGN, REPLACE_POSIX_MEMALIGN.
+ * modules/stdlib (Makefile.am): Substitute GNULIB_POSIX_MEMALIGN,
+ HAVE_POSIX_MEMALIGN, REPLACE_POSIX_MEMALIGN.
+ * modules/posix_memalign: New file.
+ * tests/test-stdlib-c++.cc (posix_memalign): Check signature.
+ * doc/posix-functions/posix_memalign.texi: Mention the new module and
+ the OpenBSD bug.
+
+2020-11-03 Bruno Haible <bruno@clisp.org>
+
memalign: Add tests.
* tests/test-memalign.c: New file.
* modules/memalign-tests: New file.
diff --git a/doc/posix-functions/posix_memalign.texi b/doc/posix-functions/posix_memalign.texi
index 084841bd9a..7f58c691fc 100644
--- a/doc/posix-functions/posix_memalign.texi
+++ b/doc/posix-functions/posix_memalign.texi
@@ -4,10 +4,13 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html}
-Gnulib module: ---
+Gnulib module: posix_memalign
Portability problems fixed by Gnulib:
@itemize
+@item
+This function produces misaligned results on some platforms:
+OpenBSD 6.1.
@end itemize
Portability problems not fixed by Gnulib:
diff --git a/lib/posix_memalign.c b/lib/posix_memalign.c
new file mode 100644
index 0000000000..ef8576820b
--- /dev/null
+++ b/lib/posix_memalign.c
@@ -0,0 +1,35 @@
+/* A posix_memalign() function that works around platform bugs.
+ Copyright (C) 2020 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 <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <stdlib.h>
+
+#include <errno.h>
+
+int
+posix_memalign (void **memptr, size_t alignment, size_t size)
+#undef posix_memalign
+{
+ /* Round up SIZE to the next multiple of ALIGNMENT, namely
+ (SIZE + ALIGNMENT - 1) & ~(ALIGNMENT - 1). */
+ size += alignment - 1;
+ if (size >= alignment - 1) /* no overflow? */
+ return posix_memalign (memptr, alignment, size & ~(size_t)(alignment - 1));
+ else
+ return ENOMEM;
+}
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 47a1309e63..58e4bba0a8 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -488,6 +488,35 @@ _GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - "
# define mktemp _mktemp
#endif
+/* Allocate memory with indefinite extent and specified alignment. */
+#if @GNULIB_POSIX_MEMALIGN@
+# if @REPLACE_POSIX_MEMALIGN@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef posix_memalign
+# define posix_memalign rpl_posix_memalign
+# endif
+_GL_FUNCDECL_RPL (posix_memalign, int,
+ (void **memptr, size_t alignment, size_t size)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_memalign, int,
+ (void **memptr, size_t alignment, size_t size));
+# else
+# if @HAVE_POSIX_MEMALIGN@
+_GL_CXXALIAS_SYS (posix_memalign, int,
+ (void **memptr, size_t alignment, size_t size));
+# endif
+# endif
+# if @HAVE_POSIX_MEMALIGN@
+_GL_CXXALIASWARN (posix_memalign);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_memalign
+# if HAVE_RAW_DECL_POSIX_MEMALIGN
+_GL_WARN_ON_USE (posix_memalign, "posix_memalign is not portable - "
+ "use gnulib module posix_memalign for portability");
+# endif
+#endif
+
#if @GNULIB_POSIX_OPENPT@
/* Return an FD open to the master side of a pseudo-terminal. Flags should
include O_RDWR, and may also include O_NOCTTY. */
diff --git a/m4/posix_memalign.m4 b/m4/posix_memalign.m4
new file mode 100644
index 0000000000..67c11b940e
--- /dev/null
+++ b/m4/posix_memalign.m4
@@ -0,0 +1,50 @@
+# posix_memalign.m4 serial 1
+dnl Copyright (C) 2020 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_POSIX_MEMALIGN],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ dnl Persuade glibc <stdlib.h> to declare posix_memalign().
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_CHECK_FUNCS_ONCE([posix_memalign])
+ if test $ac_cv_func_posix_memalign = yes; then
+ dnl On OpenBSD 6.1, posix_memalign (&p, 32, 2406) returns a pointer
+ dnl that is not a multiple of 32.
+ AC_CACHE_CHECK([whether posix_memalign works for large alignments],
+ [gl_cv_func_posix_memalign_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stdlib.h>
+ ]],
+ [[void *p;
+ if (posix_memalign (&p, 32, 2406) == 0)
+ if (((unsigned long)p % 32) != 0)
+ return 1;
+ return 0;
+ ]])
+ ],
+ [gl_cv_func_posix_memalign_works=yes],
+ [gl_cv_func_posix_memalign_works=no],
+ [case "$host_os" in
+ # Guess no on OpenBSD.
+ openbsd*) gl_cv_func_posix_memalign_works="guessing no" ;;
+ # If we don't know, obey --enable-cross-guesses.
+ *) gl_cv_func_posix_memalign_works="$gl_cross_guess_normal" ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_posix_memalign_works" in
+ *yes) ;;
+ *) REPLACE_POSIX_MEMALIGN=1 ;;
+ esac
+ else
+ dnl The system does not have posix_memalign.
+ HAVE_POSIX_MEMALIGN=0
+ fi
+])
diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4
index 743066a633..d9b13b6d1f 100644
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 49
+# stdlib_h.m4 serial 50
dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -24,9 +24,10 @@ AC_DEFUN([gl_STDLIB_H],
#endif
]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt
initstate initstate_r mbtowc mkdtemp mkostemp mkostemps mkstemp mkstemps
- posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray
- realpath rpmatch secure_getenv setenv setstate setstate_r srandom
- srandom_r strtod strtold strtoll strtoull unlockpt unsetenv])
+ posix_memalign posix_openpt ptsname ptsname_r qsort_r
+ random random_r reallocarray realpath rpmatch secure_getenv setenv
+ setstate setstate_r srandom srandom_r
+ strtod strtold strtoll strtoull unlockpt unsetenv])
AC_REQUIRE([AC_C_RESTRICT])
])
@@ -56,6 +57,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
GNULIB_MKOSTEMPS=0; AC_SUBST([GNULIB_MKOSTEMPS])
GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP])
GNULIB_MKSTEMPS=0; AC_SUBST([GNULIB_MKSTEMPS])
+ GNULIB_POSIX_MEMALIGN=0;AC_SUBST([GNULIB_POSIX_MEMALIGN])
GNULIB_POSIX_OPENPT=0; AC_SUBST([GNULIB_POSIX_OPENPT])
GNULIB_PTSNAME=0; AC_SUBST([GNULIB_PTSNAME])
GNULIB_PTSNAME_R=0; AC_SUBST([GNULIB_PTSNAME_R])
@@ -92,6 +94,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
HAVE_MKOSTEMPS=1; AC_SUBST([HAVE_MKOSTEMPS])
HAVE_MKSTEMP=1; AC_SUBST([HAVE_MKSTEMP])
HAVE_MKSTEMPS=1; AC_SUBST([HAVE_MKSTEMPS])
+ HAVE_POSIX_MEMALIGN=1; AC_SUBST([HAVE_POSIX_MEMALIGN])
HAVE_POSIX_OPENPT=1; AC_SUBST([HAVE_POSIX_OPENPT])
HAVE_PTSNAME=1; AC_SUBST([HAVE_PTSNAME])
HAVE_PTSNAME_R=1; AC_SUBST([HAVE_PTSNAME_R])
@@ -121,6 +124,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
REPLACE_MALLOC=0; AC_SUBST([REPLACE_MALLOC])
REPLACE_MBTOWC=0; AC_SUBST([REPLACE_MBTOWC])
REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP])
+ REPLACE_POSIX_MEMALIGN=0; AC_SUBST([REPLACE_POSIX_MEMALIGN])
REPLACE_PTSNAME=0; AC_SUBST([REPLACE_PTSNAME])
REPLACE_PTSNAME_R=0; AC_SUBST([REPLACE_PTSNAME_R])
REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV])
diff --git a/modules/posix_memalign b/modules/posix_memalign
new file mode 100644
index 0000000000..86e8a52787
--- /dev/null
+++ b/modules/posix_memalign
@@ -0,0 +1,28 @@
+Description:
+Allocate memory with indefinite extent and specified alignment.
+
+Files:
+lib/posix_memalign.c
+m4/posix_memalign.m4
+
+Depends-on:
+extensions
+stdlib
+
+configure.ac:
+gl_FUNC_POSIX_MEMALIGN
+if test $REPLACE_POSIX_MEMALIGN = 1; then
+ AC_LIBOBJ([posix_memalign])
+fi
+gl_STDLIB_MODULE_INDICATOR([posix_memalign])
+
+Makefile.am:
+
+Include:
+<stdlib.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
diff --git a/modules/stdlib b/modules/stdlib
index ea838c9170..df533a96e2 100644
--- a/modules/stdlib
+++ b/modules/stdlib
@@ -45,6 +45,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
-e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \
-e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \
-e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \
+ -e 's/@''GNULIB_POSIX_MEMALIGN''@/$(GNULIB_POSIX_MEMALIGN)/g' \
-e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \
-e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \
-e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \
@@ -81,6 +82,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
-e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \
-e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \
-e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \
+ -e 's|@''HAVE_POSIX_MEMALIGN''@|$(HAVE_POSIX_MEMALIGN)|g' \
-e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \
-e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
-e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \
@@ -109,6 +111,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
-e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
-e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \
-e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+ -e 's|@''REPLACE_POSIX_MEMALIGN''@|$(REPLACE_POSIX_MEMALIGN)|g' \
-e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \
-e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \
-e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
diff --git a/tests/test-stdlib-c++.cc b/tests/test-stdlib-c++.cc
index 405c8144d5..25b1c3d444 100644
--- a/tests/test-stdlib-c++.cc
+++ b/tests/test-stdlib-c++.cc
@@ -85,6 +85,11 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::mkstemp, int, (char *));
SIGNATURE_CHECK (GNULIB_NAMESPACE::mkstemps, int, (char *, int));
#endif
+#if GNULIB_TEST_POSIX_MEMALIGN && HAVE_POSIX_MEMALIGN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_memalign, int,
+ (void **, size_t, size_t));
+#endif
+
#if GNULIB_TEST_POSIX_OPENPT
SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_openpt, int, (int));
#endif