]> Savannah Git Hosting - gnulib.git/commitdiff
free: preserve errno
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 14 Dec 2020 19:38:18 +0000 (11:38 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 17 Dec 2020 09:39:45 +0000 (01:39 -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
lib/free.c
m4/free.m4
modules/free

index 445e2c0744d3e22504e3591d7805d85bb79202e3..e97d82aa6aa3274cf3f2e6da2bfee903f8338c65 100644 (file)
--- 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.
index 50a300ffa6c2db60ee0b1be244d2adb029d0e610..843ce4816b4148243a79cbb92face90e0e7c98c8 100644 (file)
 
 #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;
 }
index a62214cd127022b829fd680e3de336fc07055156..62daa8ecc3a3e583715d077dddb8389f4997e78e 100644 (file)
@@ -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.
index ec91f8889df3a92e2db639fc8e8c7c78ea74873c..ea2509821ff14fcbeb89bd8ee1a712342bdac04c 100644 (file)
@@ -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: