bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] free: preserve errno


From: Paul Eggert
Subject: [PATCH] free: preserve errno
Date: Thu, 17 Dec 2020 01:54:06 -0800

* lib/free.c (rpl_free): Preserve errno.  Check for null only if
CANNOT_FREE_NULL is defined, as an optimization for POSIX 2008
platforms that do not preserve errno.
* m4/free.m4 (gl_FUNC_FREE): Check whether free preserves errno.
Also, define CANNOT_FREE_NULL if free cannot free NULL.
* modules/free (configure.ac): Also replace 'free' if
it does not preserve errno.
---
 ChangeLog    |  9 +++++++++
 lib/free.c   | 12 ++++++++++--
 m4/free.m4   | 35 ++++++++++++++++++++++++++++++++++-
 modules/free | 12 ++++++------
 4 files changed, 59 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 445e2c074..e97d82aa6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2020-12-17  Paul Eggert  <eggert@cs.ucla.edu>
 
+       free: preserve errno
+       * lib/free.c (rpl_free): Preserve errno.  Check for null only if
+       CANNOT_FREE_NULL is defined, as an optimization for POSIX 2008
+       platforms that do not preserve errno.
+       * m4/free.m4 (gl_FUNC_FREE): Check whether free preserves errno.
+       Also, define CANNOT_FREE_NULL if free cannot free NULL.
+       * modules/free (configure.ac): Also replace 'free' if
+       it does not preserve errno.
+
        idx: simplify IDX_MAX, remove IDX_WIDTH
        * lib/idx.h (IDX_MAX): Simplify by removing obsolete reference
        to UNSIGNED_IDX_T.
diff --git a/lib/free.c b/lib/free.c
index 50a300ffa..843ce4816 100644
--- a/lib/free.c
+++ b/lib/free.c
@@ -22,9 +22,17 @@
 
 #include <stdlib.h>
 
+#include <errno.h>
+
 void
 rpl_free (void *p)
 {
-  if (p)
-    free (p);
+#ifdef CANNOT_FREE_NULL
+  if (!p)
+    return;
+#endif
+
+  int err = errno;
+  free (p);
+  errno = err;
 }
diff --git a/m4/free.m4 b/m4/free.m4
index a62214cd1..62daa8ecc 100644
--- a/m4/free.m4
+++ b/m4/free.m4
@@ -35,10 +35,43 @@ AC_DEFUN([gl_FUNC_FREE],
      esac
     ])
 
+  dnl In the next release of POSIX, free must preserve errno.
+  dnl https://www.austingroupbugs.net/view.php?id=385
+  dnl https://sourceware.org/bugzilla/show_bug.cgi?id=17924
+  dnl For now, assume implementations other than glibc do not preserve errno
+  dnl unless they set _POSIX_VERSION to the next release number,
+  dnl whatever that happens to be.
+  AC_CACHE_CHECK([whether free is known to preserve errno],
+    [gl_cv_func_free_preserves_errno],
+    [case $host_os in
+       *-gnu* | gnu*)
+         gl_cv_func_free_preserves_errno=yes;;
+       *)
+         AC_COMPILE_IFELSE(
+           [AC_LANG_PROGRAM(
+              [[#include <unistd.h>
+              ]],
+              [[#if _POSIX_VERSION <= 200809
+                  #error "'free' is not known to preserve errno"
+                #endif
+              ]])],
+           [gl_cv_func_free_preserves_errno=yes],
+           [gl_cv_func_free_preserves_errno=no]);;
+     esac
+    ])
+
   if test $gl_cv_func_free = no; then
+    AC_DEFINE([CANNOT_FREE_NULL], [1],
+      [Define to 1 if free (NULL) does not work.])
+  fi
+
+  case $gl_cv_func_free,$gl_cv_func_free_preserves_errno in
+   *yes,*yes) ;;
+   *)
     AC_DEFINE([free], [rpl_free],
       [Define to rpl_free if the replacement function should be used.])
-  fi
+    ;;
+  esac
 ])
 
 # Prerequisites of lib/free.c.
diff --git a/modules/free b/modules/free
index ec91f8889..ea2509821 100644
--- a/modules/free
+++ b/modules/free
@@ -1,8 +1,5 @@
 Description:
-Work around incompatibility on older systems where free (NULL) fails.
-
-Notice:
-This module is obsolete.
+Work around systems where free sets errno or free (NULL) fails.
 
 Files:
 lib/free.c
@@ -12,10 +9,13 @@ Depends-on:
 
 configure.ac:
 gl_FUNC_FREE
-if test $gl_cv_func_free = no; then
+case $gl_cv_func_free,$gl_cv_func_free_errno in
+ *yes,*yes) ;;
+ *)
   AC_LIBOBJ([free])
   gl_PREREQ_FREE
-fi
+  ;;
+esac
 
 Makefile.am:
 
-- 
2.27.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]