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