On 2025-12-04 07:17, Reuben Thomas wrote:
Is it possible that the documentation is incomplete, i.e. that Solaris 11.3
*can* return EAGAIN in this situation, but can also simply succeed?

Yes, that must be it. I went to the trouble of improving the commentary and its test program and then discovered that I can't login to cfarm211.cfarm.net (Solaris 11.3) even though I can login to nearby hosts. Oh well. I installed the attached Gnulib patch anyway.
From 05cf7c4a591b9f97a161cd51cac1fdf6c70e02cb Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Thu, 4 Dec 2025 09:38:39 -0800
Subject: [PATCH] malloc-posix: improve commentary

* m4/malloc.m4: Improve commentary in response to:
https://lists.gnu.org/r/bug-gnulib/2025-12/msg00038.html
---
 m4/malloc.m4 | 52 ++++++++++++++++++++++++++++------------------------
 1 file changed, 28 insertions(+), 24 deletions(-)

diff --git a/m4/malloc.m4 b/m4/malloc.m4
index e4bf33a789..c49c91e040 100644
--- a/m4/malloc.m4
+++ b/m4/malloc.m4
@@ -1,5 +1,5 @@
 # malloc.m4
-# serial 45
+# serial 46
 dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -188,37 +188,41 @@ AC_DEFUN([gl_CHECK_MALLOC_POSIX],
             [gl_cv_func_malloc_posix="guessing no"])
           ;;
         solaris*)
-          dnl On Solaris 11.3, the three functions return NULL with errno set
+          dnl On Solaris 11.3, the three functions might fail with errno set
           dnl to EAGAIN, not ENOMEM, when the argument is larger than
-          dnl PTRDIFF_MAX.
+          dnl PTRDIFF_MAX.  See:
+          dnl https://lists.gnu.org/r/bug-gnulib/2021-05/msg00052.html
           dnl Here is a test program:
+
 m4_divert_push([KILL])
 #include <errno.h>
+#include <stddef.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
-#define ptrdiff_t long
-#ifndef PTRDIFF_MAX
-# define PTRDIFF_MAX ((ptrdiff_t) ((1UL << (8 * sizeof (ptrdiff_t) - 1)) - 1))
-#endif
 
-int main ()
+#define TEST_CALL(call) \
+  do { \
+    void *p = call; \
+    if (p) \
+      fprintf (stderr, "returned %p (incorrect success)\n", p); \
+    else if (errno == ENOMEM) \
+      perror ("correct failure"); \
+    else \
+      perror ("incorrect failure (wrong errno)"); \
+    free (p); \
+  } while (0)
+
+int
+main ()
 {
-  void *p;
-
-  fprintf (stderr, "PTRDIFF_MAX = %lu\n", (unsigned long) PTRDIFF_MAX);
-
-  errno = 0;
-  p = malloc ((unsigned long) PTRDIFF_MAX + 1);
-  fprintf (stderr, "p=%p errno=%d\n", p, errno);
-
-  errno = 0;
-  p = calloc (PTRDIFF_MAX / 2 + 1, 2);
-  fprintf (stderr, "p=%p errno=%d\n", p, errno);
-
-  errno = 0;
-  p = realloc (NULL, (unsigned long) PTRDIFF_MAX + 1);
-  fprintf (stderr, "p=%p errno=%d\n", p, errno);
-
+  size_t big = PTRDIFF_MAX;
+  TEST_CALL (malloc (big + 1));
+  TEST_CALL (calloc (big / 2 + 1, 2));
+  TEST_CALL (realloc (NULL, big + 1));
+  void *small = malloc (1);
+  TEST_CALL (realloc (small, big + 1));
+  free (small);
   return 0;
 }
 m4_divert_pop([KILL])
-- 
2.51.0

Reply via email to