bug-gnulib
[Top][All Lists]
Advanced

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

new module 'calloc-posix' (was: Re: getline() behaviour change)


From: Bruno Haible
Subject: new module 'calloc-posix' (was: Re: getline() behaviour change)
Date: Mon, 3 Sep 2007 01:22:53 +0200
User-agent: KMail/1.5.4

Eric Blake wrote:
> > I would somewhat like this idea - it is much nicer assuming that malloc
> > reliably sets errno to ENOMEM on failure than having to patch all callers
> > of malloc to do the same.

Jim Meyering confirmed:
> Yes.  This is a fundamental goal of gnulib:
> If there is some portability problem, don't penalize *all* software and
> all systems.  Instead, keep the client software clean, and penalize
> only the systems that have the problem.  The losing system (mingw,
> in this case) can endure a little overhead in malloc/realloc wrappers.

Hmm, I was hesitating, because adding runtime overhead to _all_ malloc/realloc
calls for the (rare) case of failure seems like overkill. But now I stumble
on the need to set errno = ENOMEM even in totally unsuspected modules like
'xreadlink', so I come to agree that handling this in all callers is
practically infeasible.

So I propose to add three modules 'malloc-posix', 'realloc-posix',
'calloc-posix' (using the '-posix' suffix that we already know from
'fnmatch-posix'/'fnmatch-gnu' and 'printf-posix').

Since 'calloc' is a little simpler to handle than 'malloc' and 'realloc',
here is first a proposal for 'calloc'.

Also, I would propose to rename the modules 'malloc' -> 'malloc-gnu',
'realloc' -> 'realloc-gnu', 'calloc' -> 'calloc-gnu', similar to the naming
of the fnmatch-* modules. (Only the modules. The file names and autoconf
macro names can be left untouched.) Objections?

2007-09-02  Bruno Haible  <address@hidden>

        * modules/calloc-posix: New file.
        * lib/calloc.c: Include errno.h.
        (rpl_calloc): Merge the requirements of a glibc-compatible calloc
        and a POSIX-compatible calloc into a single function. Set ENOMEM
        when returning NULL.
        * m4/calloc.m4 (gl_FUNC_CALLOC_POSIX): New macro.
        * doc/functions/calloc.texi: Mention the calloc-posix module.
        * lib/stdlib_.h (calloc): New declaration.
        * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Initialize
        GNULIB_CALLOC_POSIX and HAVE_CALLOC_POSIX.
        * modules/stdlib (stdlib.h): Substitute also GNULIB_CALLOC_POSIX
        and HAVE_CALLOC_POSIX.

======================= modules/calloc-posix =============================
Description:
calloc() function: allocate memory with indefinite extent.

Files:
lib/calloc.c
m4/calloc.m4

Depends-on:
stdlib

configure.ac:
gl_FUNC_CALLOC_POSIX
gl_STDLIB_MODULE_INDICATOR([calloc-posix])

Makefile.am:

Include:
<stdlib.h>

License:
LGPL

Maintainer:
Bruno Haible

==========================================================================
*** lib/calloc.c        13 Sep 2006 22:38:14 -0000      1.6
--- lib/calloc.c        2 Sep 2007 23:16:14 -0000
***************
*** 1,6 ****
  /* calloc() function that is glibc compatible.
!    This wrapper function is required at least on Tru64 UNIX 5.1.
!    Copyright (C) 2004, 2005, 2006 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
--- 1,6 ----
  /* calloc() function that is glibc compatible.
!    This wrapper function is required at least on Tru64 UNIX 5.1 and mingw.
!    Copyright (C) 2004, 2005, 2006, 2007 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
***************
*** 16,44 ****
     along with this program; if not, write to the Free Software Foundation,
     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  
! /* written by Jim Meyering */
  
  #include <config.h>
! #undef calloc
  
  #include <stdlib.h>
  
  /* Allocate and zero-fill an NxS-byte block of memory from the heap.
     If N or S is zero, allocate and zero-fill a 1-byte block.  */
  
  void *
  rpl_calloc (size_t n, size_t s)
  {
!   size_t bytes;
  
    if (n == 0 || s == 0)
!     return calloc (1, 1);
! 
!   /* Defend against buggy calloc implementations that mishandle
!      size_t overflow.  */
!   bytes = n * s;
!   if (bytes / s != n)
!     return NULL;
  
!   return calloc (n, s);
  }
--- 16,68 ----
     along with this program; if not, write to the Free Software Foundation,
     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  
! /* written by Jim Meyering and Bruno Haible*/
  
  #include <config.h>
! /* Only the AC_FUNC_CALLOC macro defines 'calloc' already in config.h.  */
! #ifdef calloc
! # define NEED_CALLOC_GNU
! # undef calloc
! #endif
  
+ /* Specification.  */
  #include <stdlib.h>
  
+ #include <errno.h>
+ 
  /* Allocate and zero-fill an NxS-byte block of memory from the heap.
     If N or S is zero, allocate and zero-fill a 1-byte block.  */
  
  void *
  rpl_calloc (size_t n, size_t s)
  {
!   void *result;
  
+ #ifdef NEED_CALLOC_GNU
    if (n == 0 || s == 0)
!     {
!       n = 1;
!       s = 1;
!     }
!   else
!     {
!       /* Defend against buggy calloc implementations that mishandle
!        size_t overflow.  */
!       size_t bytes = n * s;
!       if (bytes / s != n)
!       {
!         errno = ENOMEM;
!         return NULL;
!       }
!     }
! #endif
! 
!   result = calloc (n, s);
! 
! #if !HAVE_CALLOC_POSIX
!   if (result == NULL)
!     errno = ENOMEM;
! #endif
  
!   return result;
  }
*** m4/calloc.m4        5 Jul 2006 23:35:19 -0000       1.6
--- m4/calloc.m4        2 Sep 2007 23:16:14 -0000
***************
*** 1,6 ****
! # calloc.m4 serial 6
  
! # Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
  # This file is free software; the Free Software Foundation
  # gives unlimited permission to copy and/or distribute it,
  # with or without modifications, as long as this notice is preserved.
--- 1,6 ----
! # calloc.m4 serial 7
  
! # Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  # This file is free software; the Free Software Foundation
  # gives unlimited permission to copy and/or distribute it,
  # with or without modifications, as long as this notice is preserved.
***************
*** 41,43 ****
--- 41,73 ----
     AC_DEFINE([calloc], [rpl_calloc],
        [Define to rpl_calloc if the replacement function should be used.])])
  ])# AC_FUNC_CALLOC
+ 
+ 
+ # gl_FUNC_CALLOC_POSIX
+ # --------------------
+ # Test whether 'calloc' is POSIX compliant (sets errno to ENOMEM when it
+ # fails), and replace calloc if it is not.
+ AC_DEFUN([gl_FUNC_CALLOC_POSIX],
+ [
+   AC_CACHE_CHECK([whether calloc is POSIX compliant],
+     [gl_cv_func_calloc_posix],
+     [
+       dnl It is too dangerous to try to allocate a large amount of memory:
+       dnl some systems go to their knees when you do that. So assume that
+       dnl all Unix implementations of the function are POSIX compliant.
+       AC_TRY_COMPILE([],
+         [#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+          choke me
+          #endif
+         ], [gl_cv_func_calloc_posix=yes], [gl_cv_func_calloc_posix=no])
+     ])
+   if test $gl_cv_func_calloc_posix = yes; then
+     HAVE_CALLOC_POSIX=1
+     AC_DEFINE([HAVE_CALLOC_POSIX], 1,
+       [Define if the 'calloc' function is POSIX compliant.])
+   else
+     AC_LIBOBJ([calloc])
+     HAVE_CALLOC_POSIX=0
+   fi
+   AC_SUBST([HAVE_CALLOC_POSIX])
+ ])
*** doc/functions/calloc.texi   1 May 2007 15:11:37 -0000       1.1
--- doc/functions/calloc.texi   2 Sep 2007 23:16:14 -0000
***************
*** 4,13 ****
  
  POSIX specification: @url{http://www.opengroup.org/susv3xsh/calloc.html}
  
! Gnulib module: ---
  
  Portability problems fixed by Gnulib:
  @itemize
  @end itemize
  
  Portability problems not fixed by Gnulib:
--- 4,17 ----
  
  POSIX specification: @url{http://www.opengroup.org/susv3xsh/calloc.html}
  
! Gnulib module: calloc-posix
  
  Portability problems fixed by Gnulib:
  @itemize
+ @item
+ Upon failure, the function does not set @code{errno} to @code{ENOMEM} on
+ some platforms:
+ mingw.
  @end itemize
  
  Portability problems not fixed by Gnulib:
*** lib/stdlib_.h       21 Jun 2007 04:39:10 -0000      1.13
--- lib/stdlib_.h       2 Sep 2007 23:16:14 -0000
***************
*** 55,60 ****
--- 55,75 ----
  #endif
  
  
+ #if @GNULIB_CALLOC_POSIX@
+ # if address@hidden@
+ #  undef calloc
+ #  define calloc rpl_calloc
+ extern void * calloc (size_t nmemb, size_t size);
+ # endif
+ #elif defined GNULIB_POSIXCHECK
+ # undef calloc
+ # define calloc(n,s) \
+     (GL_LINK_WARNING ("calloc is not POSIX compliant everywhere - " \
+                       "use gnulib module calloc-posix for portability"), \
+      calloc (n, s))
+ #endif
+ 
+ 
  #if @GNULIB_GETSUBOPT@
  /* Assuming *OPTIONP is a comma separated list of elements of the form
     "token" or "token=value", getsubopt parses the first of these elements.
*** m4/stdlib_h.m4      21 Jun 2007 04:39:10 -0000      1.3
--- m4/stdlib_h.m4      2 Sep 2007 23:16:14 -0000
***************
*** 1,4 ****
! # stdlib_h.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # stdlib_h.m4 serial 3
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 19,29 ****
  
  AC_DEFUN([gl_STDLIB_H_DEFAULTS],
  [
!   GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT])
!   GNULIB_MKDTEMP=0;   AC_SUBST([GNULIB_MKDTEMP])
!   GNULIB_MKSTEMP=0;   AC_SUBST([GNULIB_MKSTEMP])
    dnl Assume proper GNU behavior unless another module says otherwise.
!   HAVE_GETSUBOPT=1;   AC_SUBST([HAVE_GETSUBOPT])
!   HAVE_MKDTEMP=1;     AC_SUBST([HAVE_MKDTEMP])
!   REPLACE_MKSTEMP=0;  AC_SUBST([REPLACE_MKSTEMP])
  ])
--- 19,31 ----
  
  AC_DEFUN([gl_STDLIB_H_DEFAULTS],
  [
!   GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX])
!   GNULIB_GETSUBOPT=0;    AC_SUBST([GNULIB_GETSUBOPT])
!   GNULIB_MKDTEMP=0;      AC_SUBST([GNULIB_MKDTEMP])
!   GNULIB_MKSTEMP=0;      AC_SUBST([GNULIB_MKSTEMP])
    dnl Assume proper GNU behavior unless another module says otherwise.
!   HAVE_CALLOC_POSIX=1;   AC_SUBST([HAVE_CALLOC_POSIX])
!   HAVE_GETSUBOPT=1;      AC_SUBST([HAVE_GETSUBOPT])
!   HAVE_MKDTEMP=1;        AC_SUBST([HAVE_MKDTEMP])
!   REPLACE_MKSTEMP=0;     AC_SUBST([REPLACE_MKSTEMP])
  ])
*** modules/stdlib      21 Jun 2007 04:39:11 -0000      1.5
--- modules/stdlib      2 Sep 2007 23:16:14 -0000
***************
*** 23,31 ****
--- 23,33 ----
        { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
          sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \
              -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \
+             -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \
              -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \
              -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \
              -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \
+             -e 's|@''HAVE_CALLOC_POSIX''@|$(HAVE_CALLOC_POSIX)|g' \
              -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \
              -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \
              -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \





reply via email to

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