bug-gnulib
[Top][All Lists]
Advanced

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

Re: xreadlink


From: Bruno Haible
Subject: Re: xreadlink
Date: Thu, 1 Mar 2007 01:42:30 +0100
User-agent: KMail/1.5.4

Jim Meyering wrote:
> I like (a), but would prefer a different name, e.g.,
>   xreadlink_with_hint
>   xreadlink_with_size
>   xreadlink_size_hint
>   xreadlink_length_hint
> because the hint needn't come from stat/st_size,
> 
> or even just
>   xreadlink_hint
> or, shortest of all ("2", for two parameters),
>   xreadlink2
> 
> So far, I prefer xreadlink2.

OK. In private mail you said that 'xreadlink_with_size' was also acceptable
to you. I applied the following patch.

NOTE for gnulib users:
  - The module 'xreadlink' is renamed to 'xreadlink-with-size'.
  - The function xreadlink() is renamed to xreadlink_with_size().
  - Find attached also a coreutils patch.


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

        * MODULES.html.sh (File system functions): Add xreadlink-with-size.

        * modules/xreadlink: New file, from GNU gettext with modifications.
        * lib/xreadlink.c: New file, from GNU gettext.
        * lib/xreadlink.h: Add comments.
        (xreadlink): New declaration.

        * modules/xreadlink-with-size: Renamed from modules/xreadlink.
        (Files): Remove m4/xreadlink.m4. Replace lib/xreadlink.c with
        lib/xreadlink-with-size.c.
        (configure.ac): Remove gl_XREADLINK invocation.
        (Makefile.am): Augment lib_SOURCES.
        * m4/xreadlink.m4: Remove file.
        * lib/xreadlink-with-size.c: Renamed from lib/xreadlink.c.
        (xreadlink_with_size): Renamed from xreadink.
        * lib/xreadlink.h (xreadlink_with_size): Renamed from xreadink.
        * modules/canonicalize (Depends-on): Replace xreadlink with
        xreadlink-with-size.
        * lib/canonicalize.c (canonicalize_filename_mode): Update.

--- gnulib-cvs/modules/xreadlink        2006-10-13 14:40:23.000000000 +0200
+++ gnulib-work/modules/xreadlink-with-size     2007-03-01 00:51:33.000000000 
+0100
@@ -3,8 +3,7 @@
 
 Files:
 lib/xreadlink.h
-lib/xreadlink.c
-m4/xreadlink.m4
+lib/xreadlink-with-size.c
 
 Depends-on:
 xalloc
@@ -12,9 +11,9 @@
 ssize_t
 
 configure.ac:
-gl_XREADLINK
 
 Makefile.am:
+lib_SOURCES += xreadlink-with-size.c
 
 Include:
 "xreadlink.h"
--- lib/xreadlink.h     14 May 2005 06:03:58 -0000      1.5
+++ lib/xreadlink.h     1 Mar 2007 00:07:34 -0000       1.7
@@ -1,6 +1,6 @@
-/* readlink wrapper to return the link name in malloc'd storage
+/* Reading symbolic links without size limitation.
 
-   Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2003, 2004, 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
@@ -20,4 +20,15 @@
 /* Written by Jim Meyering <address@hidden>  */
 
 #include <stddef.h>
-char *xreadlink (char const *, size_t);
+
+/* Call readlink to get the symbolic link value of FILENAME.
+   Return a pointer to that NUL-terminated string in malloc'd storage.
+   If readlink fails, return NULL and set errno.  */
+extern char *xreadlink (char const *filename);
+
+/* Call readlink to get the symbolic link value of FILENAME.
+   SIZE_HINT is a hint as to how long the link is expected to be;
+   typically it is taken from st_size.  It need not be correct.
+   Return a pointer to that NUL-terminated string in malloc'd storage.
+   If readlink fails, return NULL and set errno.  */
+extern char *xreadlink_with_size (char const *filename, size_t size_hint);
--- gnulib-cvs/lib/xreadlink.c  2007-01-13 02:30:16.000000000 +0100
+++ gnulib-work/lib/xreadlink-with-size.c       2007-03-01 00:54:33.000000000 
+0100
@@ -1,6 +1,6 @@
 /* xreadlink.c -- readlink wrapper to return the link name in malloc'd storage
 
-   Copyright (C) 2001, 2003, 2004, 2005, 2006 Free Software
+   Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007 Free Software
    Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
@@ -58,7 +58,7 @@
    give a diagnostic and exit.  */
 
 char *
-xreadlink (char const *file, size_t size)
+xreadlink_with_size (char const *file, size_t size)
 {
   /* Some buggy file systems report garbage in st_size.  Defend
      against them by ignoring outlandish st_size values in the initial
--- gnulib-cvs/modules/canonicalize     2007-01-08 22:31:56.000000000 +0100
+++ gnulib-work/modules/canonicalize    2007-03-01 01:35:33.000000000 +0100
@@ -13,7 +13,7 @@
 sys_stat
 xalloc
 xgetcwd
-xreadlink
+xreadlink-with-size
 
 configure.ac:
 AC_FUNC_CANONICALIZE_FILE_NAME
--- gnulib-cvs/lib/canonicalize.c       2006-10-27 22:46:43.000000000 +0200
+++ gnulib-work/lib/canonicalize.c      2007-03-01 01:34:28.000000000 +0100
@@ -1,5 +1,5 @@
 /* Return the canonical absolute name of a given file.
-   Copyright (C) 1996-2006 Free Software Foundation, Inc.
+   Copyright (C) 1996-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
@@ -246,7 +246,7 @@
                    goto error;
                }
 
-             buf = xreadlink (rname, st.st_size);
+             buf = xreadlink_with_size (rname, st.st_size);
              if (!buf)
                {
                  if (can_mode == CAN_MISSING)
--- MODULES.html.sh     25 Feb 2007 15:31:15 -0000      1.200
+++ MODULES.html.sh     1 Mar 2007 00:07:34 -0000       1.201
@@ -2074,6 +2074,7 @@
   func_module utimens
   func_module xgetcwd
   func_module xreadlink
+  func_module xreadlink-with-size
   func_end_table
 
   element="File descriptor based Input/Output"
======================== modules/xreadlink ==================================
Description:
Reading symbolic links without size limitation.

Files:
lib/xreadlink.h
lib/xreadlink.c

Depends-on:
readlink
ssize_t
xalloc

configure.ac:

Makefile.am:
lib_SOURCES += xreadlink.c

Include:
"xreadlink.h"

License:
GPL

Maintainer:
Bruno Haible

======================== lib/xreadlink.c ====================================
/* xreadlink.c -- readlink wrapper to return the link name in malloc'd storage

   Copyright (C) 2001, 2003-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
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.
   If not, write to the Free Software Foundation,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Jim Meyering <address@hidden>
   and Bruno Haible <address@hidden>.  */

#include <config.h>

/* Specification.  */
#include "xreadlink.h"

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <stdlib.h>
#if HAVE_UNISTD_H
# include <unistd.h>
#endif

#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
#ifndef SSIZE_MAX
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
#endif

#ifdef NO_XMALLOC
# define xmalloc malloc
#else
# include "xalloc.h"
#endif

/* Call readlink to get the symbolic link value of FILENAME.
   Return a pointer to that NUL-terminated string in malloc'd storage.
   If readlink fails, return NULL (caller may use errno to diagnose).
   If realloc fails, or if the link value is longer than SIZE_MAX :-),
   give a diagnostic and exit.  */

char *
xreadlink (char const *filename)
{
  /* The initial buffer size for the link value.  A power of 2
     detects arithmetic overflow earlier, but is not required.  */
#define INITIAL_BUF_SIZE 1024

  /* Allocate the initial buffer on the stack.  This way, in the common
     case of a symlink of small size, we get away with a single small malloc()
     instead of a big malloc() followed by a shrinking realloc().  */
  char initial_buf[INITIAL_BUF_SIZE];

  char *buffer = initial_buf;
  size_t buf_size = sizeof (initial_buf);

  while (1)
    {
      /* Attempt to read the link into the current buffer.  */
      ssize_t link_length = readlink (filename, buffer, buf_size);

      /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1
         with errno == ERANGE if the buffer is too small.  */
      if (link_length < 0 && errno != ERANGE)
        {
          if (buffer != initial_buf)
            {
              int saved_errno = errno;
              free (buffer);
              errno = saved_errno;
            }
          return NULL;
        }

      if ((size_t) link_length < buf_size)
        {
          buffer[link_length++] = '\0';

          /* Return it in a chunk of memory as small as possible.  */
          if (buffer == initial_buf)
            {
              buffer = (char *) xmalloc (link_length);
#ifdef NO_XMALLOC
              if (buffer == NULL)
                return NULL;
#endif
              memcpy (buffer, initial_buf, link_length);
            }
          else
            {
              /* Shrink buffer before returning it.  */
              if ((size_t) link_length < buf_size)
                {
                  char *smaller_buffer = (char *) realloc (buffer, link_length);

                  if (smaller_buffer != NULL)
                    buffer = smaller_buffer;
                }
            }
          return buffer;
        }

      if (buffer != initial_buf)
        free (buffer);
      buf_size *= 2;
      if (SSIZE_MAX < buf_size || (SIZE_MAX / 2 < SSIZE_MAX && buf_size == 0))
#ifdef NO_XMALLOC
        return NULL;
#else
        xalloc_die ();
#endif
      buffer = (char *) xmalloc (buf_size);
#ifdef NO_XMALLOC
      if (buffer == NULL)
        return NULL;
#endif
    }
}





reply via email to

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