[Top][All Lists]
[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' \