bug-gnulib
[Top][All Lists]
Advanced

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

[bug-gnulib] Re: stat and lstat should define their replacements


From: Bruno Haible
Subject: [bug-gnulib] Re: stat and lstat should define their replacements
Date: Fri, 27 May 2005 21:48:13 +0200
User-agent: KMail/1.5

Jim Meyering wrote:
> We should try hard not to let the bugs of a few broken systems
> push us into polluting our interfaces with the work-arounds. ...
> ...
> BTW, I suspect that testing for the HAVE_LSTAT_EMPTY_STRING_BUG
> code isn't useful anymore.  It works around bugs in SunOS4.1.4
> and vintage Hurd (1998 or 1999, presuming it was fixed back then).
> IMHO, SunOS4.1.4 stopped being a reasonable portability target a
> couple of years ago.

You are right. And indeed by dropping the HAVE_LSTAT_EMPTY_STRING_BUG
handling, we don't need to wrap the stat() function any more, and thanks
to the facts that
  - lstat can be #defined since it is not a type/struct name,
  - lstat.c doesn't #include "sys_stat.h",
[huh! what a luck!]
=> we can actually wrap lstat() under this name.

So I'm now proposing to
  1) drop the 'stat' module,
  2) change the 'lstat' module as follows.

The crucial trick here is the ability to compile lstat.c so that it uses
the original lstat function (be it #defined to lstat64 or not).

Bruno


diff -c -3 -r1.20 lstat.m4
*** m4/lstat.m4 2 May 2005 07:00:50 -0000       1.20
--- m4/lstat.m4 27 May 2005 19:45:49 -0000
***************
*** 18,24 ****
  
  AC_DEFUN([gl_FUNC_LSTAT],
  [
!   AC_REQUIRE([AC_FUNC_LSTAT])
!   dnl Note: AC_FUNC_LSTAT does AC_LIBOBJ(lstat).
    :
  ])
--- 18,24 ----
  
  AC_DEFUN([gl_FUNC_LSTAT],
  [
!   AC_REQUIRE([AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK])
!   dnl Note: AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK does AC_LIBOBJ(lstat).
    :
  ])
*** /dev/null   1970-01-01 01:00:00.000000000 +0100
--- lib/lstat.h 2005-05-27 21:41:31.000000000 +0200
***************
*** 0 ****
--- 1,24 ----
+ /* Retrieving information about files.
+    Copyright (C) 2005 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; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+ 
+ #include <sys/stat.h>
+ 
+ #if !LSTAT_FOLLOWS_SLASHED_SYMLINK
+ extern int rpl_lstat (const char *name, struct stat *buf);
+ # undef lstat
+ # define lstat rpl_lstat
+ #endif
diff -c -3 -r1.7 lstat.c
*** lib/lstat.c 14 May 2005 06:03:58 -0000      1.7
--- lib/lstat.c 27 May 2005 19:46:08 -0000
***************
*** 1,8 ****
! /* Work around the bug in some systems whereby lstat succeeds when
!    given the zero-length file name argument.  The lstat from SunOS 4.1.4
!    has this bug.
  
!    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free
     Software Foundation, Inc.
  
     This program is free software; you can redistribute it and/or modify
--- 1,6 ----
! /* Work around a bug of lstat on some systems
  
!    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
     Software Foundation, Inc.
  
     This program is free software; you can redistribute it and/or modify
***************
*** 19,23 ****
     along with this program; if not, write to the Free Software Foundation,
     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  
! #define LSTAT
! #include "stat.c"
--- 17,76 ----
     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>
! 
! /* The specification of these functions is in sys_stat.h.  But we cannot
!    include this include file here, because on some systems, a
!    "#define lstat lstat64" is being used, and sys_stat.h deletes this
!    definition.  */
! 
! #include <sys/types.h>
! #include <sys/stat.h>
! #include <errno.h>
! #include <stdlib.h>
! #include <string.h>
! 
! #include "stat-macros.h"
! #include "xalloc.h"
! 
! /* lstat works differently on Linux and Solaris systems.  POSIX (see
!    `pathname resolution' in the glossary) requires that programs like `ls'
!    take into consideration the fact that FILE has a trailing slash when
!    FILE is a symbolic link.  On Linux systems, the lstat function already
!    has the desired semantics (in treating `lstat("symlink/",sbuf)' just like
!    `lstat("symlink/.",sbuf)', but on Solaris it does not.
! 
!    If FILE has a trailing slash and specifies a symbolic link,
!    then append a `.' to FILE and call lstat a second time.  */
! 
! static int
! rpl_lstat (const char *file, struct stat *sbuf)
! {
!   size_t len;
!   char *new_file;
! 
!   int lstat_result = lstat (file, sbuf);
! 
!   if (lstat_result != 0 || !S_ISLNK (sbuf->st_mode))
!     return lstat_result;
! 
!   len = strlen (file);
!   if (len == 0 || file[len - 1] != '/')
!     return lstat_result;
! 
!   /* FILE refers to a symbolic link and the name ends with a slash.
!      Append a `.' to FILE and repeat the lstat call.  */
! 
!   /* Add one for the `.' we'll append, and one more for the trailing NUL.  */
!   new_file = xmalloc (len + 1 + 1);
!   memcpy (new_file, file, len);
!   new_file[len] = '.';
!   new_file[len + 1] = 0;
! 
!   lstat_result = lstat (new_file, sbuf);
!   free (new_file);
! 
!   return lstat_result;
! }





reply via email to

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