Merge from coreutils.
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 3 Jul 2006 08:32:46 +0000 (08:32 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 3 Jul 2006 08:32:46 +0000 (08:32 +0000)
46 files changed:
ChangeLog
MODULES.html.sh
lib/.cppi-disable
lib/.cvsignore
lib/ChangeLog
lib/backupfile.c
lib/basename.c
lib/chdir-safer.c
lib/cycle-check.c
lib/cycle-check.h
lib/dirname.c
lib/dirname.h
lib/filemode.c
lib/filemode.h
lib/filenamecat.c
lib/fsusage.c
lib/fsusage.h
lib/fts-cycle.c
lib/getcwd.c
lib/same-inode.h [new file with mode: 0644]
lib/same.c
lib/stat-macros.h
lib/stripslash.c
lib/xstrtod.c
lib/xstrtod.h
lib/xstrtold.c [new file with mode: 0644]
m4/ChangeLog
m4/c-strtod.m4
m4/chdir-safer.m4
m4/dirname.m4
m4/dos.m4
m4/double-slash-root.m4 [new file with mode: 0644]
m4/filemode.m4
m4/ftruncate.m4
m4/getcwd-abort-bug.m4 [new file with mode: 0644]
m4/getcwd-path-max.m4
m4/getcwd.m4
m4/lib-ignore.m4
m4/same.m4
m4/xstrtod.m4
modules/cycle-check
modules/dirname
modules/getcwd
modules/mkdir-p
modules/same
modules/xstrtold [new file with mode: 0644]

index fad326a..de9598e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-07-03  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Merge from coreutils.
+       * MODULES.html.sh: Add xstrtold.
+       * modules/xstrtold: New file.
+       * modules/cycle-check (Files): Add lib/same-inode.h.
+       * modules/dirname (Files): Add m4/double-slash-root.m4.
+       * modules/getcwd (Files): Add m4/getcwd-abort-bug.m4.
+       * modules/mkdir-p (Files): Add lib/same-inode.h.
+       * modules/same (Files): Add lib/same-inode.h.
+
 2006-07-01  Paul Eggert  <eggert@cs.ucla.edu>
 
        * modules/inttypes (Depends-on): No longer depends on stdint.
index dc91ae0..9c820d2 100755 (executable)
@@ -1551,6 +1551,7 @@ func_all_modules ()
   func_module c-strtold
   func_module xstrtod
   func_module xstrtol
+  func_module xstrtold
   func_end_table
 
   element="Date and time <time.h>"
index ce7e664..57a07aa 100644 (file)
@@ -31,6 +31,7 @@ regex_internal.c
 regex_internal.h
 stat-time.h
 stdbool_.h
+stdint_.h
 strcase.h
 strdup.h
 strndup.h
index 5afaa59..f2e6007 100644 (file)
@@ -14,6 +14,7 @@ ref-del.sed
 search.h
 stat.c
 stdbool.h
+stdint.h
 sysexit.h
 t-fpending
 unlocked-io.h
index 46b9c6c..b6861ab 100644 (file)
@@ -1,3 +1,108 @@
+2006-07-03  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Merge from coreutils.
+
+       * .cppi-disable: Add stdint_.h.
+       * .cvsignore: Add stdint.h.
+
+       2006-06-30  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * xstrtod.c (XSTRTOD, DOUBLE): New macros, so that we can support
+       both double and long double versions.
+       (XSTRTOD): Renamed from xstrtod.  Use DOUBLE internally.
+       * xstrtold.c: New file.
+       * xstrtod.h (xstrtold): New decl.
+
+       2006-05-22  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * filemode.c (setst): Remove.
+       (strmode): Rewrite to avoid setst.  This makes the code shorter,
+       (arguably) clearer, and the generated code is a bit smaller on my
+       Debian GNU/Linux stable x86 host.
+
+       2006-04-17  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * filemode.c: Include "filemode.h" first, to test the interface.
+       Assume that filemode.h includes sys/types.h and sys/stat.h.
+       (HAVE_ST_DM_MODE): New macro, moved here from ls.c.
+       (ftypelet): Reorder to put common cases first, for efficiency.
+       Add 'P', 'w'.  Remove 'M', since it's now the caller's responsibility
+       to do 'M'.
+       (strmode): Renamed from mode_string, and now stores 12 bytes instead
+       of 10, for compatibility with FreeBSD.  All callers changed.
+       (filemodestring): Now stores 12 bytes instead of 10, and sets file types
+       that can't be deduced solely from st_mode.  First arg is now a const
+       pointer.
+       * filemode.h (HAVE_DECL_STRMODE): Include <string.h> for strmode.
+       (strmode): Renamed from mode_string.
+       (filemodestring): New decl.
+       * stat-macros.h: Don't undef S_ISDOOR, since it's never buggy.
+       (S_ISDOOR): Don't bother with S_IFDOOR, since that code is never needed.
+       (S_ISPORT, S_ISWHT): New macros, if not already defined.
+
+       2006-04-12  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * fsusage.c: Don't include <inttypes.h> or <stdint.h>, since
+       fsusage.h now does that.  Include fsusage.h first, to test interface.
+       Prefer statvfs if it works, since it's blessed by POSIX.  Attempt
+       at most one method (the old code could have generated decls that
+       didn't conform to C89, not that this was ever exercised).
+       * fsusage.h: Include <inttypes.h> and <stdint.h> if they exist.
+
+       2006-03-19  Jim Meyering  <jim@meyering.net>
+
+       Work even in a chroot where d_ino values for entries in "/"
+       don't match the stat.st_ino values for the same names.
+       * getcwd.c (__getcwd): When no d_ino value matches the target inode
+       number, iterate through all entries again, using lstat instead.
+       Reported by Kenshi Muto in http://bugs.debian.org/355810, and by
+       Zouhir Hafidi in https://bugzilla.redhat.com/bugzilla/190656.
+
+       * getcwd.c (__getcwd): Clarify a comment.
+       Use memcpy in place of a call to strcpy.
+
+       2006-03-12  Jim Meyering  <jim@meyering.net>
+
+       * fts-cycle.c (leave_dir): If cycle-check's saved dev-ino pair matches
+       that of the current directory (which we're about to chdir ".." out of),
+       then save the dev-ino of the parent, instead.
+
+       * same-inode.h (SAME_INODE): New file/macro.
+       * chdir-safer.c (SAME_INODE): Remove definition.
+       Include "same-inode.h", instead.
+       * same.c: Likewise.
+       * cycle-check.h: Include "same-inode.h".
+       (CYCLE_CHECK_REFLECT_CHDIR_UP): Define.
+       * cycle-check.c (SAME_INODE): Remove definition.
+       * root-dev-ino.h: Include "same-inode.h".
+
+       2006-03-11  Eric Blake  <ebb9@byu.net>
+
+       * same.c (same_name): s/base_name/last_component/
+       * backupfile.c (check_extension, numbered_backup): Likewise.
+       * filenamecat.c (file_name_concat): Likewise.
+
+       2006-03-11  Eric Blake  <ebb9@byu.net>,
+                   Paul Eggert  <eggert@cs.ucla.edu>
+
+       * dirname.h (FILE_SYSTEM_PREFIX_LEN): Move here from dos.m4.
+       [FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX]: Don't treat 1: as a
+       drive prefix.
+       (IS_ABSOLUTE_FILE_NAME): Treat all drive letters as absolute on
+       platforms like cygwin with FILE_SYSTEM_DRIVE_PREFIX_IS_ABSOLUTE.
+       (last_component): New method.
+       * dirname.c (dir_len): Determine when drive letters need a
+       subsequent slash.  Preserve // when it is special.
+       (dir_name): Don't append dot when drive letter is absolute.
+       [TEST_DIRNAME]: Move into a full-blown gnulib test.
+       * basename.c (base_name): New semantics - malloc the result.
+       Preserve // when it is special.  Preserve relative files that look
+       like drive letters.
+       (base_len): Preserve // when it is special.
+       (last_component): New method, similar to old base_name semantics.
+       * stripslash.c (strip_trailing_slashes): Use last_component, not
+       base_name.  Strip redundant slashes from ///.
+
 2006-07-02  Paul Eggert  <eggert@cs.ucla.edu>
 
        * stdint_.h (intmax_t, uintmax_t): Prefer long to long long if
index 32ffaea..a990add 100644 (file)
@@ -1,7 +1,8 @@
 /* backupfile.c -- make Emacs style backup file names
 
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 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
@@ -115,7 +116,7 @@ char const *simple_backup_suffix = "~";
 static void
 check_extension (char *file, size_t filelen, char e)
 {
-  char *base = base_name (file);
+  char *base = last_component (file);
   size_t baselen = base_len (base);
   size_t baselen_max = HAVE_LONG_FILE_NAMES ? 255 : NAME_MAX_MINIMUM;
 
@@ -202,7 +203,7 @@ numbered_backup (char **buffer, size_t buffer_size, size_t filelen)
   struct dirent *dp;
   char *buf = *buffer;
   size_t versionlenmax = 1;
-  char *base = base_name (buf);
+  char *base = last_component (buf);
   size_t base_offset = base - buf;
   size_t baselen = base_len (base);
 
index 5cc97cd..8c3dbec 100644 (file)
@@ -1,6 +1,6 @@
 /* basename.c -- return the last element in a file name
 
-   Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005 Free
+   Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 Free
    Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
 #endif
 
 #include "dirname.h"
-#include <string.h>
 
-/* In general, we can't use the builtin `basename' function if available,
-   since it has different meanings in different environments.
-   In some environments the builtin `basename' modifies its argument.
+#include <string.h>
+#include "xalloc.h"
+#include "xstrndup.h"
 
-   Return the address of the last file name component of NAME.  If
-   NAME has no file name components because it is all slashes, return
-   NAME if it is empty, the address of its last slash otherwise.  */
+/* Return the address of the last file name component of NAME.  If
+   NAME has no relative file name components because it is a file
+   system root, return the empty string.  */
 
 char *
-base_name (char const *name)
+last_component (char const *name)
 {
   char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
   char const *p;
+  bool saw_slash = false;
+
+  while (ISSLASH (*base))
+    base++;
 
   for (p = base; *p; p++)
     {
       if (ISSLASH (*p))
+       saw_slash = true;
+      else if (saw_slash)
        {
-         /* Treat multiple adjacent slashes like a single slash.  */
-         do p++;
-         while (ISSLASH (*p));
-
-         /* If the file name ends in slash, use the trailing slash as
-            the basename if no non-slashes have been found.  */
-         if (! *p)
-           {
-             if (ISSLASH (*base))
-               base = p - 1;
-             break;
-           }
-
-         /* *P is a non-slash preceded by a slash.  */
          base = p;
+         saw_slash = false;
        }
     }
 
   return (char *) base;
 }
 
-/* Return the length of of the basename NAME.  Typically NAME is the
-   value returned by base_name.  Act like strlen (NAME), except omit
-   redundant trailing slashes.  */
+
+/* In general, we can't use the builtin `basename' function if available,
+   since it has different meanings in different environments.
+   In some environments the builtin `basename' modifies its argument.
+
+   Return the last file name component of NAME, allocated with
+   xmalloc.  On systems with drive letters, a leading "./"
+   distinguishes relative names that would otherwise look like a drive
+   letter.  Unlike POSIX basename(), NAME cannot be NULL,
+   base_name("") returns "", and the first trailing slash is not
+   stripped.
+
+   If lstat (NAME) would succeed, then { chdir (dir_name (NAME));
+   lstat (base_name (NAME)); } will access the same file.  Likewise,
+   if the sequence { chdir (dir_name (NAME));
+   rename (base_name (NAME), "foo"); } succeeds, you have renamed NAME
+   to "foo" in the same directory NAME was in.  */
+
+char *
+base_name (char const *name)
+{
+  char const *base = last_component (name);
+  size_t length;
+
+  /* If there is no last component, then name is a file system root or the
+     empty string.  */
+  if (! *base)
+    return xstrndup (name, base_len (name));
+
+  /* Collapse a sequence of trailing slashes into one.  */
+  length = base_len (base);
+  if (ISSLASH (base[length]))
+    length++;
+
+  /* On systems with drive letters, `a/b:c' must return `./b:c' rather
+     than `b:c' to avoid confusion with a drive letter.  On systems
+     with pure POSIX semantics, this is not an issue.  */
+  if (FILE_SYSTEM_PREFIX_LEN (base))
+    {
+      char *p = xmalloc (length + 3);
+      p[0] = '.';
+      p[1] = '/';
+      memcpy (p + 2, base, length);
+      p[length + 2] = '\0';
+      return p;
+    }
+
+  /* Finally, copy the basename.  */
+  return xstrndup (base, length);
+}
+
+/* Return the length of the basename NAME.  Typically NAME is the
+   value returned by base_name or last_component.  Act like strlen
+   (NAME), except omit all trailing slashes.  */
 
 size_t
 base_len (char const *name)
 {
   size_t len;
+  size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
 
   for (len = strlen (name);  1 < len && ISSLASH (name[len - 1]);  len--)
     continue;
 
+  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1
+      && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])
+    return 2;
+
+  if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len
+      && len == prefix_len && ISSLASH (name[prefix_len]))
+    return prefix_len + 1;
+
   return len;
 }
index b411230..5c313bc 100644 (file)
@@ -30,6 +30,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include "same-inode.h"
 
 #ifndef O_DIRECTORY
 # define O_DIRECTORY 0
 # define O_NOFOLLOW 0
 #endif
 
-#define SAME_INODE(Stat_buf_1, Stat_buf_2) \
-  ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
-   && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
-
 /* Like chdir, but fail if DIR is a symbolic link to a directory (or
    similar funny business), or if DIR is not readable.  This avoids a
    minor race condition between when a directory is created or statted
index 401dd86..d8a3ca0 100644 (file)
@@ -1,6 +1,6 @@
 /* help detect directory cycles efficiently
 
-   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 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
 
 #include "cycle-check.h"
 
-#define SAME_INODE(Stat_buf_1, Stat_buf_2) \
-  ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
-   && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
-
 #define CC_MAGIC 9827862
 
 /* Return true if I is a power of 2, or is zero.  */
index 0551bf2..b137a60 100644 (file)
@@ -1,6 +1,6 @@
 /* help detect directory cycles efficiently
 
-   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 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
@@ -30,6 +30,7 @@
 # endif
 # include <stdbool.h>
 # include "dev-ino.h"
+# include "same-inode.h"
 
 struct cycle_check_state
 {
@@ -41,4 +42,15 @@ struct cycle_check_state
 void cycle_check_init (struct cycle_check_state *state);
 bool cycle_check (struct cycle_check_state *state, struct stat const *sb);
 
+# define CYCLE_CHECK_REFLECT_CHDIR_UP(State, SB_dir, SB_subdir)        \
+  do                                                           \
+    {                                                          \
+      if (SAME_INODE ((State)->dev_ino, SB_subdir))            \
+       {                                                       \
+         (State)->dev_ino.st_dev = (SB_dir).st_dev;            \
+         (State)->dev_ino.st_ino = (SB_dir).st_ino;            \
+       }                                                       \
+    }                                                          \
+  while (0)
+
 #endif
index e2b9d64..e3c762c 100644 (file)
@@ -1,6 +1,6 @@
 /* dirname.c -- return all but the last element in a file name
 
-   Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005 Free Software
+   Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005, 2006 Free Software
    Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
 #include <string.h>
 #include "xalloc.h"
 
-/* Return the length of `dirname (FILE)', or zero if FILE is
-   in the working directory.  Works properly even if
-   there are trailing slashes (by effectively ignoring them).  */
+/* Return the length of the prefix of FILE that will be used by
+   dir_name.  If FILE is in the working directory, this returns zero
+   even though `dir_name (FILE)' will return ".".  Works properly even
+   if there are trailing slashes (by effectively ignoring them).  */
+
 size_t
 dir_len (char const *file)
 {
   size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file);
   size_t length;
 
+  /* Advance prefix_length beyond important leading slashes.  */
+  prefix_length += (prefix_length != 0
+                   ? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+                      && ISSLASH (file[prefix_length]))
+                   : (ISSLASH (file[0])
+                      ? ((DOUBLE_SLASH_IS_DISTINCT_ROOT
+                          && ISSLASH (file[1]) && ! ISSLASH (file[2])
+                          ? 2 : 1))
+                      : 0));
+
   /* Strip the basename and any redundant slashes before it.  */
-  for (length = base_name (file) - file;  prefix_length < length;  length--)
+  for (length = last_component (file) - file;
+       prefix_length < length; length--)
     if (! ISSLASH (file[length - 1]))
-      return length;
-
-  /* But don't strip the only slash from "/".  */
-  return prefix_length + ISSLASH (file[prefix_length]);
+      break;
+  return length;
 }
 
-/* Return the leading directories part of FILE,
-   allocated with xmalloc.
-   Works properly even if there are trailing slashes
-   (by effectively ignoring them).  */
+
+/* In general, we can't use the builtin `dirname' function if available,
+   since it has different meanings in different environments.
+   In some environments the builtin `dirname' modifies its argument.
+
+   Return the leading directories part of FILE, allocated with xmalloc.
+   Works properly even if there are trailing slashes (by effectively
+   ignoring them).  Unlike POSIX dirname(), FILE cannot be NULL.
+
+   If lstat (FILE) would succeed, then { chdir (dir_name (FILE));
+   lstat (base_name (FILE)); } will access the same file.  Likewise,
+   if the sequence { chdir (dir_name (FILE));
+   rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE
+   to "foo" in the same directory FILE was in.  */
 
 char *
 dir_name (char const *file)
 {
   size_t length = dir_len (file);
-  bool append_dot = (length == FILE_SYSTEM_PREFIX_LEN (file));
+  bool append_dot = (length == 0
+                    || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+                        && length == FILE_SYSTEM_PREFIX_LEN (file)
+                        && file[2] != '\0' && ! ISSLASH (file[2])));
   char *dir = xmalloc (length + append_dot + 1);
   memcpy (dir, file, length);
   if (append_dot)
     dir[length++] = '.';
-  dir[length] = 0;
+  dir[length] = '\0';
   return dir;
 }
-
-#ifdef TEST_DIRNAME
-/*
-
-Run the test like this (expect no output):
-  gcc -DHAVE_CONFIG_H -DTEST_DIRNAME -I.. -O -Wall \
-     basename.c dirname.c xmalloc.c error.c
-  sed -n '/^BEGIN-DATA$/,/^END-DATA$/p' dirname.c|grep -v DATA|./a.out
-
-If it's been built on a DOS or Windows platforms, run another test like
-this (again, expect no output):
-  sed -n '/^BEGIN-DOS-DATA$/,/^END-DOS-DATA$/p' dirname.c|grep -v DATA|./a.out
-
-BEGIN-DATA
-foo//// .
-bar/foo//// bar
-foo/ .
-/ /
-. .
-a .
-END-DATA
-
-BEGIN-DOS-DATA
-c:///// c:/
-c:/ c:/
-c:/. c:/
-c:foo c:.
-c:foo/bar c:foo
-END-DOS-DATA
-
-*/
-
-# define MAX_BUFF_LEN 1024
-# include <stdio.h>
-
-char *program_name;
-
-int
-main (int argc, char *argv[])
-{
-  char buff[MAX_BUFF_LEN + 1];
-
-  program_name = argv[0];
-
-  buff[MAX_BUFF_LEN] = 0;
-  while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
-    {
-      char file[MAX_BUFF_LEN];
-      char expected_result[MAX_BUFF_LEN];
-      char const *result;
-      sscanf (buff, "%s %s", file, expected_result);
-      result = dir_name (file);
-      if (strcmp (result, expected_result))
-       printf ("%s: got %s, expected %s\n", file, result, expected_result);
-    }
-  return 0;
-}
-#endif
index 1688ae8..f9189c3 100644 (file)
@@ -1,6 +1,6 @@
 /*  Take file names apart into directory and base names.
 
-    Copyright (C) 1998, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+    Copyright (C) 1998, 2001, 2003-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
 # endif
 
 # ifndef FILE_SYSTEM_PREFIX_LEN
-#  define FILE_SYSTEM_PREFIX_LEN(File_name) 0
+#  if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+    /* This internal macro assumes ASCII, but all hosts that support drive
+       letters use ASCII.  */
+#   define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \
+                               <= 'z' - 'a')
+#   define FILE_SYSTEM_PREFIX_LEN(Filename) \
+          (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0)
+#  else
+#   define FILE_SYSTEM_PREFIX_LEN(Filename) 0
+#  endif
 # endif
 
-# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
+# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+#  define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
+# endif
+
+# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
+#  define DOUBLE_SLASH_IS_DISTINCT_ROOT 1
+# endif
+
+# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+#  define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
+# else
+#  define IS_ABSOLUTE_FILE_NAME(F) \
+         (ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F))
+# endif
 # define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
 
 char *base_name (char const *file);
 char *dir_name (char const *file);
 size_t base_len (char const *file);
 size_t dir_len (char const *file);
+char *last_component (char const *file);
 
 bool strip_trailing_slashes (char *file);
 
index 08b9b13..5636c9e 100644 (file)
@@ -1,5 +1,7 @@
 /* filemode.c -- make a string describing file modes
-   Copyright (C) 1985, 1990, 1993, 1998-2000, 2004 Free Software Foundation, Inc.
+
+   Copyright (C) 1985, 1990, 1993, 1998-2000, 2004, 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
 # include <config.h>
 #endif
 
-#include <sys/types.h>
-#include <sys/stat.h>
-
 #include "filemode.h"
+
 #include "stat-macros.h"
 
+/* The following is for Cray DMF (Data Migration Facility), which is a
+   HSM file system.  A migrated file has a `st_dm_mode' that is
+   different from the normal `st_mode', so any tests for migrated
+   files should use the former.  */
+#if HAVE_ST_DM_MODE
+# define IS_MIGRATED_FILE(statp) \
+    (S_ISOFD (statp->st_dm_mode) || S_ISOFL (statp->st_dm_mode))
+#else
+# define IS_MIGRATED_FILE(statp) 0
+#endif
 
-/* Set the 's' and 't' flags in file attributes string CHARS,
-   according to the file mode BITS.  */
-
-static void
-setst (mode_t bits, char *chars)
-{
-  if (bits & S_ISUID)
-    {
-      if (chars[3] != 'x')
-       /* Set-uid, but not executable by owner.  */
-       chars[3] = 'S';
-      else
-       chars[3] = 's';
-    }
-  if (bits & S_ISGID)
-    {
-      if (chars[6] != 'x')
-       /* Set-gid, but not executable by group.  */
-       chars[6] = 'S';
-      else
-       chars[6] = 's';
-    }
-  if (bits & S_ISVTX)
-    {
-      if (chars[9] != 'x')
-       /* Sticky, but not executable by others.  */
-       chars[9] = 'T';
-      else
-       chars[9] = 't';
-    }
-}
+#if ! HAVE_DECL_STRMODE
 
 /* Return a character indicating the type of file described by
    file mode BITS:
-   'd' for directories
-   'D' for doors
-   'b' for block special files
-   'c' for character special files
-   'n' for network special files
-   'm' for multiplexor files
-   'M' for an off-line (regular) file
-   'l' for symbolic links
-   's' for sockets
-   'p' for fifos
-   'C' for contigous data files
-   '-' for regular files
-   '?' for any other file type.  */
+   '-' regular file
+   'b' block special file
+   'c' character special file
+   'C' high performance ("contiguous data") file
+   'd' directory
+   'D' door
+   'l' symbolic link
+   'm' multiplexed file (7th edition Unix; obsolete)
+   'n' network special file (HP-UX)
+   'p' fifo (named pipe)
+   'P' port
+   's' socket
+   'w' whiteout (4.4BSD)
+   '?' some other file type  */
 
 static char
 ftypelet (mode_t bits)
 {
+  /* These are the most common, so test for them first.  */
+  if (S_ISREG (bits))
+    return '-';
+  if (S_ISDIR (bits))
+    return 'd';
+
+  /* Other letters standardized by POSIX 1003.1-2004.  */
   if (S_ISBLK (bits))
     return 'b';
   if (S_ISCHR (bits))
     return 'c';
-  if (S_ISDIR (bits))
-    return 'd';
-  if (S_ISREG (bits))
-    return '-';
-  if (S_ISFIFO (bits))
-    return 'p';
   if (S_ISLNK (bits))
     return 'l';
+  if (S_ISFIFO (bits))
+    return 'p';
+
+  /* Other file types (though not letters) standardized by POSIX.  */
   if (S_ISSOCK (bits))
     return 's';
-  if (S_ISMPC (bits))
+
+  /* Nonstandard file types.  */
+  if (S_ISCTG (bits))
+    return 'C';
+  if (S_ISDOOR (bits))
+    return 'D';
+  if (S_ISMPB (bits) || S_ISMPC (bits))
     return 'm';
   if (S_ISNWK (bits))
     return 'n';
-  if (S_ISDOOR (bits))
-    return 'D';
-  if (S_ISCTG (bits))
-    return 'C';
+  if (S_ISPORT (bits))
+    return 'P';
+  if (S_ISWHT (bits))
+    return 'w';
 
-  /* The following two tests are for Cray DMF (Data Migration
-     Facility), which is a HSM file system.  A migrated file has a
-     `st_dm_mode' that is different from the normal `st_mode', so any
-     tests for migrated files should use the former.  */
-
-  if (S_ISOFD (bits))
-    /* off line, with data  */
-    return 'M';
-  /* off line, with no data  */
-  if (S_ISOFL (bits))
-    return 'M';
   return '?';
 }
 
-/* Like filemodestring, but only the relevant part of the `struct stat'
-   is given as an argument.  */
+/* Like filemodestring, but rely only on MODE.  */
 
 void
-mode_string (mode_t mode, char *str)
+strmode (mode_t mode, char *str)
 {
   str[0] = ftypelet (mode);
   str[1] = mode & S_IRUSR ? 'r' : '-';
   str[2] = mode & S_IWUSR ? 'w' : '-';
-  str[3] = mode & S_IXUSR ? 'x' : '-';
+  str[3] = (mode & S_ISUID
+           ? (mode & S_IXUSR ? 's' : 'S')
+           : (mode & S_IXUSR ? 'x' : '-'));
   str[4] = mode & S_IRGRP ? 'r' : '-';
   str[5] = mode & S_IWGRP ? 'w' : '-';
-  str[6] = mode & S_IXGRP ? 'x' : '-';
+  str[6] = (mode & S_ISGID
+           ? (mode & S_IXGRP ? 's' : 'S')
+           : (mode & S_IXGRP ? 'x' : '-'));
   str[7] = mode & S_IROTH ? 'r' : '-';
   str[8] = mode & S_IWOTH ? 'w' : '-';
-  str[9] = mode & S_IXOTH ? 'x' : '-';
-  setst (mode, str);
+  str[9] = (mode & S_ISVTX
+           ? (mode & S_IXOTH ? 't' : 'T')
+           : (mode & S_IXOTH ? 'x' : '-'));
+  str[10] = ' ';
+  str[11] = '\0';
 }
 
+#endif /* ! HAVE_DECL_STRMODE */
+
 /* filemodestring - fill in string STR with an ls-style ASCII
    representation of the st_mode field of file stats block STATP.
-   10 characters are stored in STR; no terminating null is added.
+   12 characters are stored in STR.
    The characters stored in STR are:
 
-   0   File type.  'd' for directory, 'c' for character
-       special, 'b' for block special, 'm' for multiplex,
-       'l' for symbolic link, 's' for socket, 'p' for fifo,
-       '-' for regular, '?' for any other file type
+   0   File type, as in ftypelet above, except that other letters are used
+        for files whose type cannot be determined solely from st_mode:
+
+           'F' semaphore
+           'M' migrated file (Cray DMF)
+           'Q' message queue
+           'S' shared memory object
+           'T' typed memory object
 
    1   'r' if the owner may read, '-' otherwise.
 
@@ -167,10 +160,26 @@ mode_string (mode_t mode, char *str)
    9   'x' if any user may execute, 't' if the file is "sticky"
        (will be retained in swap space after execution), '-'
        otherwise.
-       'T' if the file is sticky but not executable.  */
+       'T' if the file is sticky but not executable.
+
+   10   ' ' for compatibility with 4.4BSD strmode,
+       since this interface does not support ACLs.
+
+   11   '\0'.  */
 
 void
-filemodestring (struct stat *statp, char *str)
+filemodestring (struct stat const *statp, char *str)
 {
-  mode_string (statp->st_mode, str);
+  strmode (statp->st_mode, str);
+
+  if (S_TYPEISSEM (statp))
+    str[0] = 'F';
+  else if (IS_MIGRATED_FILE (statp))
+    str[0] = 'M';
+  else if (S_TYPEISMQ (statp))
+    str[0] = 'Q';
+  else if (S_TYPEISSHM (statp))
+    str[0] = 'S';
+  else if (S_TYPEISTMO (statp))
+    str[0] = 'T';
 }
index 5d3da67..4716736 100644 (file)
@@ -1,6 +1,6 @@
 /* Make a string describing file modes.
 
-   Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2003, 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
 #ifndef FILEMODE_H_
 
 # include <sys/types.h>
+# include <sys/stat.h>
 
-void mode_string (mode_t mode, char *str);
+# if HAVE_DECL_STRMODE
+#  include <string.h>
+# else
+void strmode (mode_t mode, char *str);
+# endif
+
+void filemodestring (struct stat const *statp, char *str);
 
 #endif
index f947346..399d7db 100644 (file)
@@ -1,7 +1,7 @@
 /* Concatenate two arbitrary file names.
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
-   Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 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
@@ -64,7 +64,7 @@ longest_relative_suffix (char const *f)
 char *
 file_name_concat (char const *dir, char const *abase, char **base_in_result)
 {
-  char const *dirbase = base_name (dir);
+  char const *dirbase = last_component (dir);
   size_t dirbaselen = base_len (dirbase);
   size_t dirlen = dirbase - dir + dirbaselen;
   size_t needs_separator = (dirbaselen && ! ISSLASH (dirbase[dirbaselen - 1]));
index b137790..0bb6224 100644 (file)
@@ -1,6 +1,6 @@
 /* fsusage.c -- return space usage of mounted file systems
 
-   Copyright (C) 1991, 1992, 1996, 1998, 1999, 2002, 2003, 2004, 2005
+   Copyright (C) 1991, 1992, 1996, 1998, 1999, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
 # include <config.h>
 #endif
 
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#include <unistd.h>
-#ifndef UINTMAX_MAX
-# define UINTMAX_MAX ((uintmax_t) -1)
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
 #include "fsusage.h"
 
 #include <limits.h>
+#include <sys/types.h>
 
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-
-#if HAVE_SYS_MOUNT_H
-# include <sys/mount.h>
-#endif
-
-#if HAVE_SYS_VFS_H
-# include <sys/vfs.h>
-#endif
-
-#if HAVE_SYS_FS_S5PARAM_H      /* Fujitsu UXP/V */
-# include <sys/fs/s5param.h>
-#endif
-
-#if defined HAVE_SYS_FILSYS_H && !defined _CRAY
-# include <sys/filsys.h>       /* SVR2 */
-#endif
-
-#include <fcntl.h>
-
-#if HAVE_SYS_STATFS_H
-# include <sys/statfs.h>
-#endif
-
-#if HAVE_DUSTAT_H              /* AIX PS/2 */
-# include <sys/dustat.h>
-#endif
-
-#if HAVE_SYS_STATVFS_H         /* SVR4 */
+#if STAT_STATVFS               /* POSIX 1003.1-2001 (and later) with XSI */
 # include <sys/statvfs.h>
+#else
+/* Don't include backward-compatibility files unless they're needed.
+   Eventually we'd like to remove all this cruft.  */
+# include <fcntl.h>
+# include <unistd.h>
+# include <sys/stat.h>
+# if HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+# endif
+# if HAVE_SYS_MOUNT_H
+#  include <sys/mount.h>
+# endif
+# if HAVE_SYS_VFS_H
+#  include <sys/vfs.h>
+# endif
+# if HAVE_SYS_FS_S5PARAM_H     /* Fujitsu UXP/V */
+#  include <sys/fs/s5param.h>
+# endif
+# if defined HAVE_SYS_FILSYS_H && !defined _CRAY
+#  include <sys/filsys.h>      /* SVR2 */
+# endif
+# if HAVE_SYS_STATFS_H
+#  include <sys/statfs.h>
+# endif
+# if HAVE_DUSTAT_H             /* AIX PS/2 */
+#  include <sys/dustat.h>
+# endif
+# include "full-read.h"
 #endif
 
-#include "full-read.h"
+#ifndef UINTMAX_MAX
+# define UINTMAX_MAX ((uintmax_t) -1)
+#endif
 
 /* Many space usage primitives use all 1 bits to denote a value that is
    not applicable or unknown.  Propagate this information by returning
 int
 get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
 {
-#ifdef STAT_STATFS3_OSF1
+#if defined STAT_STATVFS               /* POSIX */
 
-  struct statfs fsd;
+  struct statvfs fsd;
 
-  if (statfs (file, &fsd, sizeof (struct statfs)) != 0)
+  if (statvfs (file, &fsd) < 0)
     return -1;
 
-  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);
-
-#endif /* STAT_STATFS3_OSF1 */
+  /* f_frsize isn't guaranteed to be supported.  */
+  fsp->fsu_blocksize = (fsd.f_frsize
+                       ? PROPAGATE_ALL_ONES (fsd.f_frsize)
+                       : PROPAGATE_ALL_ONES (fsd.f_bsize));
 
-#ifdef STAT_STATFS2_FS_DATA    /* Ultrix */
+#elif defined STAT_STATFS2_FS_DATA     /* Ultrix */
 
   struct fs_data fsd;
 
@@ -134,9 +123,7 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
   fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.fd_req.gtot);
   fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.fd_req.gfree);
 
-#endif /* STAT_STATFS2_FS_DATA */
-
-#ifdef STAT_READ_FILSYS                /* SVR2 */
+#elif defined STAT_READ_FILSYS         /* SVR2 */
 # ifndef SUPERBOFF
 #  define SUPERBOFF (SUPERB * 512)
 # endif
@@ -171,9 +158,16 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
                    : (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1));
   fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.s_tinode);
 
-#endif /* STAT_READ_FILSYS */
+#elif defined STAT_STATFS3_OSF1
+
+  struct statfs fsd;
+
+  if (statfs (file, &fsd, sizeof (struct statfs)) != 0)
+    return -1;
+
+  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);
 
-#ifdef STAT_STATFS2_BSIZE      /* 4.3BSD, SunOS 4, HP-UX, AIX */
+#elif defined STAT_STATFS2_BSIZE       /* 4.3BSD, SunOS 4, HP-UX, AIX */
 
   struct statfs fsd;
 
@@ -197,9 +191,7 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
     }
 # endif /* STATFS_TRUNCATES_BLOCK_COUNTS */
 
-#endif /* STAT_STATFS2_BSIZE */
-
-#ifdef STAT_STATFS2_FSIZE      /* 4.4BSD */
+#elif defined STAT_STATFS2_FSIZE       /* 4.4BSD */
 
   struct statfs fsd;
 
@@ -208,9 +200,7 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
 
   fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);
 
-#endif /* STAT_STATFS2_FSIZE */
-
-#ifdef STAT_STATFS4            /* SVR3, Dynix, Irix, AIX */
+#elif defined STAT_STATFS4             /* SVR3, Dynix, Irix, AIX */
 
 # if !_AIX && !defined _SEQUENT_ && !defined DOLPHIN
 #  define f_bavail f_bfree
@@ -230,24 +220,10 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
    fsp->fsu_blocksize = 512;
 # endif
 
-#endif /* STAT_STATFS4 */
-
-#ifdef STAT_STATVFS            /* SVR4 */
-
-  struct statvfs fsd;
-
-  if (statvfs (file, &fsd) < 0)
-    return -1;
-
-  /* f_frsize isn't guaranteed to be supported.  */
-  fsp->fsu_blocksize = (fsd.f_frsize
-                       ? PROPAGATE_ALL_ONES (fsd.f_frsize)
-                       : PROPAGATE_ALL_ONES (fsd.f_bsize));
-
-#endif /* STAT_STATVFS */
+#endif
 
-#if !defined STAT_STATFS2_FS_DATA && !defined STAT_READ_FILSYS
-                               /* !Ultrix && !SVR2 */
+#if (defined STAT_STATVFS \
+     || (!defined STAT_STATFS2_FS_DATA && !defined STAT_READ_FILSYS))
 
   fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks);
   fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.f_bfree);
@@ -256,7 +232,7 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
   fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.f_files);
   fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.f_ffree);
 
-#endif /* not STAT_STATFS2_FS_DATA && not STAT_READ_FILSYS */
+#endif
 
   return 0;
 }
index f3eda2d..645d107 100644 (file)
@@ -1,6 +1,6 @@
 /* fsusage.h -- declarations for file system space usage info
 
-   Copyright (C) 1991, 1992, 1997, 2003, 2004, 2005 Free Software
+   Copyright (C) 1991, 1992, 1997, 2003, 2004, 2005, 2006 Free Software
    Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
 #if !defined FSUSAGE_H_
 # define FSUSAGE_H_
 
+# if HAVE_INTTYPES_H
+#  include <inttypes.h>
+# endif
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
 # include <stdbool.h>
 
 struct fs_usage
index 13b43db..19c5ded 100644 (file)
@@ -1,6 +1,6 @@
 /* Detect cycles in file tree walks.
 
-   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    Written by Jim Meyering.
 
@@ -129,9 +129,9 @@ enter_dir (FTS *fts, FTSENT *ent)
 static void
 leave_dir (FTS *fts, FTSENT *ent)
 {
+  struct stat const *st = ent->fts_statp;
   if (fts->fts_options & (FTS_TIGHT_CYCLE_CHECK | FTS_LOGICAL))
     {
-      struct stat const *st = ent->fts_statp;
       struct Active_dir obj;
       void *found;
       obj.dev = st->st_dev;
@@ -141,6 +141,13 @@ leave_dir (FTS *fts, FTSENT *ent)
        abort ();
       free (found);
     }
+  else
+    {
+      FTSENT *parent = ent->fts_parent;
+      if (parent != NULL)
+       CYCLE_CHECK_REFLECT_CHDIR_UP (fts->fts_cycle.state,
+                                     *(parent->fts_statp), *st);
+    }
 }
 
 /* Free any memory used for cycle detection.  */
index 5bb9e4b..ba22679 100644 (file)
@@ -211,6 +211,7 @@ __getcwd (char *buf, size_t size)
       int parent_status;
       size_t dirroom;
       size_t namlen;
+      bool use_d_ino = true;
 
       /* Look at the parent directory.  */
 #ifdef AT_FDCWD
@@ -257,11 +258,26 @@ __getcwd (char *buf, size_t size)
             NULL.  */
          __set_errno (0);
          d = __readdir (dirstream);
+
+         /* When we've iterated through all directory entries without finding
+            one with a matching d_ino, rewind the stream and consider each
+            name again, but this time, using lstat.  This is necessary in a
+            chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where
+            .., ../.., ../../.., etc. all had the same device number, yet the
+            d_ino values for entries in / did not match those obtained
+            via lstat.  */
+         if (d == NULL && errno == 0 && use_d_ino)
+           {
+             use_d_ino = false;
+             rewinddir (dirstream);
+             d = __readdir (dirstream);
+           }
+
          if (d == NULL)
            {
              if (errno == 0)
-               /* EOF on dirstream, which means that the current directory
-                  has been removed.  */
+               /* EOF on dirstream, which can mean e.g., that the current
+                  directory has been removed.  */
                __set_errno (ENOENT);
              goto lose;
            }
@@ -269,58 +285,65 @@ __getcwd (char *buf, size_t size)
              (d->d_name[1] == '\0' ||
               (d->d_name[1] == '.' && d->d_name[2] == '\0')))
            continue;
-         if (MATCHING_INO (d, thisino) || mount_point)
+
+         if (use_d_ino)
            {
-             int entry_status;
+             bool match = (MATCHING_INO (d, thisino) || mount_point);
+             if (! match)
+               continue;
+           }
+
+         {
+           int entry_status;
 #ifdef AT_FDCWD
-             entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
+           entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
 #else
-             /* Compute size needed for this file name, or for the file
-                name ".." in the same directory, whichever is larger.
-                Room for ".." might be needed the next time through
-                the outer loop.  */
-             size_t name_alloc = _D_ALLOC_NAMLEN (d);
-             size_t filesize = dotlen + MAX (sizeof "..", name_alloc);
-
-             if (filesize < dotlen)
-               goto memory_exhausted;
-
-             if (dotsize < filesize)
-               {
-                 /* My, what a deep directory tree you have, Grandma.  */
-                 size_t newsize = MAX (filesize, dotsize * 2);
-                 size_t i;
-                 if (newsize < dotsize)
-                   goto memory_exhausted;
-                 if (dotlist != dots)
-                   free (dotlist);
-                 dotlist = malloc (newsize);
-                 if (dotlist == NULL)
-                   goto lose;
-                 dotsize = newsize;
-
-                 i = 0;
-                 do
-                   {
-                     dotlist[i++] = '.';
-                     dotlist[i++] = '.';
-                     dotlist[i++] = '/';
-                   }
-                 while (i < dotlen);
-               }
-
-             strcpy (dotlist + dotlen, d->d_name);
-             entry_status = __lstat (dotlist, &st);
+           /* Compute size needed for this file name, or for the file
+              name ".." in the same directory, whichever is larger.
+              Room for ".." might be needed the next time through
+              the outer loop.  */
+           size_t name_alloc = _D_ALLOC_NAMLEN (d);
+           size_t filesize = dotlen + MAX (sizeof "..", name_alloc);
+
+           if (filesize < dotlen)
+             goto memory_exhausted;
+
+           if (dotsize < filesize)
+             {
+               /* My, what a deep directory tree you have, Grandma.  */
+               size_t newsize = MAX (filesize, dotsize * 2);
+               size_t i;
+               if (newsize < dotsize)
+                 goto memory_exhausted;
+               if (dotlist != dots)
+                 free (dotlist);
+               dotlist = malloc (newsize);
+               if (dotlist == NULL)
+                 goto lose;
+               dotsize = newsize;
+
+               i = 0;
+               do
+                 {
+                   dotlist[i++] = '.';
+                   dotlist[i++] = '.';
+                   dotlist[i++] = '/';
+                 }
+               while (i < dotlen);
+             }
+
+           memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d));
+           entry_status = __lstat (dotlist, &st);
 #endif
-             /* We don't fail here if we cannot stat() a directory entry.
-                This can happen when (network) file systems fail.  If this
-                entry is in fact the one we are looking for we will find
-                out soon as we reach the end of the directory without
-                having found anything.  */
-             if (entry_status == 0 && S_ISDIR (st.st_mode)
-                 && st.st_dev == thisdev && st.st_ino == thisino)
-               break;
-           }
+           /* We don't fail here if we cannot stat() a directory entry.
+              This can happen when (network) file systems fail.  If this
+              entry is in fact the one we are looking for we will find
+              out soon as we reach the end of the directory without
+              having found anything.  */
+           if (entry_status == 0 && S_ISDIR (st.st_mode)
+               && st.st_dev == thisdev && st.st_ino == thisino)
+             break;
+         }
        }
 
       dirroom = dirp - dir;
diff --git a/lib/same-inode.h b/lib/same-inode.h
new file mode 100644 (file)
index 0000000..deca87b
--- /dev/null
@@ -0,0 +1,26 @@
+/* Determine whether two stat buffers refer to the same file.
+
+   Copyright (C) 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
+   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.  */
+
+#ifndef SAME_INODE_H
+# define SAME_INODE_H 1
+
+# define SAME_INODE(Stat_buf_1, Stat_buf_2) \
+   ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
+    && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
+
+#endif
index 4854b3a..e267ba4 100644 (file)
@@ -1,6 +1,6 @@
 /* Determine whether two file names refer to the same file.
 
-   Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005 Free
+   Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free
    Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
 #include "same.h"
 #include "dirname.h"
 #include "error.h"
+#include "same-inode.h"
 #include "xalloc.h"
 
 #ifndef MIN
 # define MIN(a, b) ((a) < (b) ? (a) : (b))
 #endif
 
-#define SAME_INODE(Stat_buf_1, Stat_buf_2) \
-  ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
-   && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
-
 /* Return nonzero if SOURCE and DEST point to the same name in the same
    directory.  */
 
@@ -59,8 +56,8 @@ bool
 same_name (const char *source, const char *dest)
 {
   /* Compare the basenames.  */
-  char const *source_basename = base_name (source);
-  char const *dest_basename = base_name (dest);
+  char const *source_basename = last_component (source);
+  char const *dest_basename = last_component (dest);
   size_t source_baselen = base_len (source_basename);
   size_t dest_baselen = base_len (dest_basename);
   bool identical_basenames =
index 0957a22..829ddd3 100644 (file)
@@ -1,6 +1,7 @@
 /* stat-related macros
 
-   Copyright (C) 1993, 1994, 2001, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1994, 2001, 2002, 2004, 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
@@ -33,7 +34,6 @@
 #  undef S_ISBLK
 #  undef S_ISCHR
 #  undef S_ISDIR
-#  undef S_ISDOOR
 #  undef S_ISFIFO
 #  undef S_ISLNK
 #  undef S_ISNAM
 # endif
 
 # ifndef S_ISDOOR /* Solaris 2.5 and up */
-#  ifdef S_IFDOOR
-#   define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
-#  else
-#   define S_ISDOOR(m) 0
-#  endif
+#  define S_ISDOOR(m) 0
 # endif
 
 # ifndef S_ISFIFO
 #  endif
 # endif
 
+# ifndef S_ISPORT /* Solaris 10 and up */
+#  define S_ISPORT(m) 0
+# endif
+
 # ifndef S_ISREG
 #  ifdef S_IFREG
 #   define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
 #  endif
 # endif
 
-/* contiguous */
+/* high performance ("contiguous data") */
 # ifndef S_ISCTG
 #  define S_ISCTG(p) 0
 # endif
 #  define S_ISOFL(p) 0
 # endif
 
+/* 4.4BSD whiteout */
+# ifndef S_ISWHT
+#  define S_ISWHT(m) 0
+# endif
+
 /* If any of the following are undefined,
    define them to their de facto standard values.  */
 # if !S_ISUID
index 9b55da4..4ba5dad 100644 (file)
@@ -1,6 +1,6 @@
 /* stripslash.c -- remove redundant trailing slashes from a file name
 
-   Copyright (C) 1990, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1990, 2001, 2003-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
 
 #include "dirname.h"
 
-/* Remove trailing slashes from FILE.
-   Return true if a trailing slash was removed.
-   This is useful when using file name completion from a shell that
-   adds a "/" after directory names (such as tcsh and bash), because
-   the Unix rename and rmdir system calls return an "Invalid argument" error
-   when given a file that ends in "/" (except for the root directory).  */
+/* Remove trailing slashes from FILE.  Return true if a trailing slash
+   was removed.  This is useful when using file name completion from a
+   shell that adds a "/" after directory names (such as tcsh and
+   bash), because on symlinks to directories, several system calls
+   have different semantics according to whether a trailing slash is
+   present.  */
 
 bool
 strip_trailing_slashes (char *file)
 {
-  char *base = base_name (file);
-  char *base_lim = base + base_len (base);
-  bool had_slash = (*base_lim != '\0');
+  char *base = last_component (file);
+  char *base_lim;
+  bool had_slash;
+
+  /* last_component returns "" for file system roots, but we need to turn
+     `///' into `/'.  */
+  if (! *base)
+    base = file;
+  base_lim = base + base_len (base);
+  had_slash = (*base_lim != '\0');
   *base_lim = '\0';
   return had_slash;
 }
index 8639869..e711ec8 100644 (file)
@@ -1,7 +1,7 @@
 /* error-checking interface to strtod-like functions
 
-   Copyright (C) 1996, 1999, 2000, 2003, 2004, 2005 Free Software
-   Foundation, Inc.
+   Copyright (C) 1996, 1999, 2000, 2003, 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
 #include <limits.h>
 #include <stdio.h>
 
-/* An interface to strtod that encapsulates all the error checking
-   one should usually perform.  Like strtod, but upon successful
+#if LONG
+# define XSTRTOD xstrtold
+# define DOUBLE long double
+#else
+# define XSTRTOD xstrtod
+# define DOUBLE double
+#endif
+
+/* An interface to a string-to-floating-point conversion function that
+   encapsulates all the error checking one should usually perform.
+   Like strtod/strtold, but upon successful
    conversion put the result in *RESULT and return true.  Return
    false and don't modify *RESULT upon any failure.  CONVERT
    specifies the conversion function, e.g., strtod itself.  */
 
 bool
-xstrtod (char const *str, char const **ptr, double *result,
-        double (*convert) (char const *, char **))
+XSTRTOD (char const *str, char const **ptr, DOUBLE *result,
+        DOUBLE (*convert) (char const *, char **))
 {
-  double val;
+  DOUBLE val;
   char *terminator;
   bool ok = true;
 
@@ -51,9 +60,9 @@ xstrtod (char const *str, char const **ptr, double *result,
     ok = false;
   else
     {
-      /* Allow underflow (in which case strtod returns zero),
+      /* Allow underflow (in which case CONVERT returns zero),
         but flag overflow as an error. */
-      if (val != 0.0 && errno == ERANGE)
+      if (val != 0 && errno == ERANGE)
        ok = false;
     }
 
index 3addb8c..1e5ad94 100644 (file)
@@ -1,6 +1,6 @@
 /* Error-checking interface to strtod-like functions.
 
-   Copyright (C) 1996, 1998, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1998, 2003, 2004, 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
@@ -25,5 +25,7 @@
 
 bool xstrtod (const char *str, const char **ptr, double *result,
              double (*convert) (char const *, char **));
+bool xstrtold (const char *str, const char **ptr, long double *result,
+              long double (*convert) (char const *, char **));
 
 #endif /* not XSTRTOD_H */
diff --git a/lib/xstrtold.c b/lib/xstrtold.c
new file mode 100644 (file)
index 0000000..50dc6a4
--- /dev/null
@@ -0,0 +1,2 @@
+#define LONG 1
+#include "xstrtod.c"
index 2a9931b..c9f5287 100644 (file)
@@ -1,3 +1,61 @@
+2006-07-03  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Merge from coreutils.
+
+       2006-06-30  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * c-strtod.m4 (gl_C_STRTOLD): Add c-strtod.c to LIBSOURCES.
+       Require gl_USE_SYSTEM_EXTENSIONS, not gl_C_STRTOD, since we don't
+       want to require the building of c-strtod.o.
+       * lib-check.m4 (cu_LIB_CHECK): Remove SEQ_LIBM, since seq no longer
+       needs -lm directly.
+       * xstrtod.m4 (gl_XSTRTOLD): New macro.
+
+       2006-06-19  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * lib-ignore.m4 (gl_IGNORE_UNUSED_LIBRARIES): Prefer binutils's
+       --as-needed option if available.  Problem reported by Albert Chin in
+       <http://lists.gnu.org/archive/html/bug-gnulib/2006-06/msg00114.html>.
+       However, use -Wl,--as-needed, not bare --as-needed, since HP-UX 11.11
+       cc merely issues a bunch of annoying warnings for --as-needed
+       (this problem was reported by Bob Proulx).  Also, try linking with
+       -lm to detect a bug in binutils 2.16 (this problem was reported
+       by Ralf Wildenhues).
+
+       2006-06-18  Jim Meyering  <jim@meyering.net>
+
+       Test for a bug that causes glibc's getcwd to suffer a failed assertion.
+       * getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): New file and macro.
+       * getcwd.m4 (gl_FUNC_GETCWD): If we detect support for getcwd_null,
+       also check for glibc-2.4's abort-inducing bug.
+
+       * getcwd-path-max.m4 (gl_FUNC_GETCWD_PATH_MAX): Fix typo.
+       Low-probability clean-up should be to use rmdir to get rid of
+       the just-created directory, not unlink.
+
+       * ftruncate.m4 (gl_FUNC_FTRUNCATE): If ftruncate is missing, make
+       configure fail, and request a bug report to inform us about it.
+       Add a comment that, barring reports to the contrary, in 2007 we'll
+       assume ftruncate is universally available.
+
+       2006-04-17  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * filemode.m4 (gl_FILEMODE): Check for strmode declaration.
+
+       2006-03-12  Jim Meyering  <jim@meyering.net>
+
+       * chdir-safer.m4 (gl_CHDIR_SAFER): Add same-inode.h to the list.
+       * cycle-check.m4 (gl_CYCLE_CHECK): Likewise.
+       * same.m4 (gl_SAME): Likewise.
+       * root-dev-ino.m4 (gl_ROOT_DEV_INO): Likewise.
+
+       2006-03-11  Eric Blake  <ebb9@byu.net>
+
+       * double-slash-root.m4: New file, provides gl_DOUBLE_SLASH_ROOT.
+       * dirname.m4 (gl_DIRNAME): Use gl_DOUBLE_SLASH_ROOT.
+       * dos.m4 (FILE_SYSTEM_PREFIX_LEN): Move from here to dirname.h.
+       (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE): New define.
+
 2006-07-02  Eric Blake  <ebb9@byu.net>
 
        * wcwidth.m4 (gl_FUNC_WCWIDTH): Simplify by using AC_CHECK_DECLS.
index dca1cbc..729f1aa 100644 (file)
@@ -1,4 +1,4 @@
-# c-strtod.m4 serial 7
+# c-strtod.m4 serial 8
 
 # Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -45,11 +45,11 @@ AC_DEFUN([gl_C_STRTOD],
 
 AC_DEFUN([gl_C_STRTOLD],
 [
-  AC_LIBSOURCES([c-strtold.c, c-strtod.h])
+  AC_LIBSOURCES([c-strtod.c, c-strtold.c, c-strtod.h])
   AC_LIBOBJ([c-strtold])
 
   dnl Prerequisites of lib/c-strtold.c.
-  AC_REQUIRE([gl_C_STRTOD])
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
   AC_REQUIRE([gl_C99_STRTOLD])
   :
 ])
index f3d7351..b3c351c 100644 (file)
@@ -1,11 +1,11 @@
-#serial 1
-dnl Copyright (C) 2005 Free Software Foundation, Inc.
+#serial 2
+dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_CHDIR_SAFER],
 [
-  AC_LIBSOURCES([chdir-safer.c, chdir-safer.h])
+  AC_LIBSOURCES([chdir-safer.c, chdir-safer.h, same-inode.h])
   AC_LIBOBJ([chdir-safer])
 ])
index e36937d..f3412ad 100644 (file)
@@ -1,5 +1,5 @@
-# dirname.m4 serial 5
-dnl Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+#serial 6   -*- autoconf -*-
+dnl Copyright (C) 2002-2006 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -11,6 +11,7 @@ AC_DEFUN([gl_DIRNAME],
 
   dnl Prerequisites of lib/dirname.h.
   AC_REQUIRE([gl_AC_DOS])
+  AC_REQUIRE([gl_DOUBLE_SLASH_ROOT])
 
   dnl No prerequisites of lib/basename.c, lib/dirname.c, lib/stripslash.c.
 ])
index 0713cf1..dd59571 100644 (file)
--- a/m4/dos.m4
+++ b/m4/dos.m4
@@ -1,9 +1,9 @@
-#serial 9
+#serial 10   -*- autoconf -*-
 
 # Define some macros required for proper operation of code in lib/*.c
 # on MSDOS/Windows systems.
 
-# Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 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.
@@ -14,30 +14,38 @@ AC_DEFUN([gl_AC_DOS],
   [
     AC_CACHE_CHECK([whether system is Windows or MSDOS], [ac_cv_win_or_dos],
       [
-        AC_TRY_COMPILE([],
-        [#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ && !defined __CYGWIN__
+       AC_TRY_COMPILE([],
+       [#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ && !defined __CYGWIN__
 neither MSDOS nor Windows
 #endif],
-        [ac_cv_win_or_dos=yes],
-        [ac_cv_win_or_dos=no])
+       [ac_cv_win_or_dos=yes],
+       [ac_cv_win_or_dos=no])
       ])
 
     if test x"$ac_cv_win_or_dos" = xyes; then
       ac_fs_accepts_drive_letter_prefix=1
       ac_fs_backslash_is_file_name_separator=1
+      AC_CACHE_CHECK([whether drive letter can start relative path],
+                    [ac_cv_drive_letter_can_be_relative],
+       [
+         AC_TRY_COMPILE([],
+         [#if defined __CYGWIN__
+drive letters are always absolute
+#endif],
+         [ac_cv_drive_letter_can_be_relative=yes],
+         [ac_cv_drive_letter_can_be_relative=no])
+       ])
+      if test x"$ac_cv_drive_letter_can_be_relative" = xyes; then
+       ac_fs_drive_letter_can_be_relative=1
+      else
+       ac_fs_drive_letter_can_be_relative=0
+      fi
     else
       ac_fs_accepts_drive_letter_prefix=0
       ac_fs_backslash_is_file_name_separator=0
+      ac_fs_drive_letter_can_be_relative=0
     fi
 
-    AH_VERBATIM(FILE_SYSTEM_PREFIX_LEN,
-    [#if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
-# define FILE_SYSTEM_PREFIX_LEN(Filename) \
-  ((Filename)[0] && (Filename)[1] == ':' ? 2 : 0)
-#else
-# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
-#endif])
-
     AC_DEFINE_UNQUOTED([FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX],
       $ac_fs_accepts_drive_letter_prefix,
       [Define on systems for which file names may have a so-called
@@ -55,4 +63,9 @@ neither MSDOS nor Windows
       $ac_fs_backslash_is_file_name_separator,
       [Define if the backslash character may also serve as a file name
        component separator.])
+
+    AC_DEFINE_UNQUOTED([FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE],
+      $ac_fs_drive_letter_can_be_relative,
+      [Define if a drive letter prefix denotes a relative path if it is
+       not followed by a file name component separator.])
   ])
diff --git a/m4/double-slash-root.m4 b/m4/double-slash-root.m4
new file mode 100644 (file)
index 0000000..f8cbd54
--- /dev/null
@@ -0,0 +1,43 @@
+#serial 1   -*- autoconf -*-
+dnl Copyright (C) 2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_DOUBLE_SLASH_ROOT],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_CACHE_CHECK([whether // is distinct from /], [ac_cv_double_slash_root],
+    [ if test x"$cross_compiling" = xyes ; then
+       # When cross-compiling, there is no way to tell whether // is special
+       # short of a list of hosts.  However, the only known hosts to date
+       # that have a distinct // are Apollo DomainOS (too old to port to)
+       # and Cygwin.  If anyone knows of another system for which // has
+       # special semantics and is distinct from /, please report it to
+       # <bug-coreutils@gnu.org>.
+       case $host in
+         *-cygwin)
+           ac_cv_double_slash_root=yes ;;
+         *)
+           # Be optimistic and assume that / and // are the same when we
+           # don't know.
+           ac_cv_double_slash_root='unknown, assuming no' ;;
+       esac
+      else
+       set x `ls -di / //`
+       if test $[2] = $[4]; then
+         ac_cv_double_slash_root=no
+       else
+         ac_cv_double_slash_root=yes
+       fi
+      fi])
+  if test x"$ac_cv_double_slash_root" = xyes; then
+    ac_double_slash_root=1
+  else
+    ac_double_slash_root=0
+  fi
+
+  AC_DEFINE_UNQUOTED([DOUBLE_SLASH_IS_DISTINCT_ROOT],
+   $ac_double_slash_root,
+   [Define to 1 if // is a file system root distinct from /.])
+])
index 3b6ccb9..2b9334f 100644 (file)
@@ -1,5 +1,5 @@
-# filemode.m4 serial 5
-dnl Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+# filemode.m4 serial 6
+dnl Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -8,4 +8,5 @@ AC_DEFUN([gl_FILEMODE],
 [
   AC_LIBSOURCES([filemode.c, filemode.h])
   AC_LIBOBJ([filemode])
+  AC_CHECK_DECLS_ONCE([strmode])
 ])
index c225e48..b82705c 100644 (file)
@@ -1,17 +1,29 @@
-#serial 8
+#serial 9
 
 # See if we need to emulate a missing ftruncate function using fcntl or chsize.
 
-# Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2003-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.
 
+# FIXME: remove this macro, along with all uses of HAVE_FTRUNCATE in 2007,
+# if the check below provokes no reports.
+
 AC_DEFUN([gl_FUNC_FTRUNCATE],
 [
   AC_REPLACE_FUNCS(ftruncate)
   if test $ac_cv_func_ftruncate = no; then
     gl_PREREQ_FTRUNCATE
+    # If someone lacks ftruncate, make configure fail, and request
+    # a bug report to inform us about it.
+    if test x"$SKIP_FTRUNCATE_CHECK" != xyes; then
+      AC_MSG_FAILURE([Your system lacks the ftruncate function.
+         Please report this, along with the output of "uname -a", to the
+         bug-coreutils@gnu.org mailing list.  To continue past this point,
+         rerun configure with SKIP_FTRUNCATE_CHECK=yes set in the environment.
+         E.g., env SKIP_FTRUNCATE_CHECK=yes ./configure])
+    fi
   fi
 ])
 
diff --git a/m4/getcwd-abort-bug.m4 b/m4/getcwd-abort-bug.m4
new file mode 100644 (file)
index 0000000..a431a7c
--- /dev/null
@@ -0,0 +1,106 @@
+#serial 1
+# Determine whether getcwd aborts when the length of the working directory
+# name is unusually large.  Any length between 4k and 16k trigger the bug
+# when using glibc-2.4.90-9 or older.
+
+# Copyright (C) 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.
+
+# From Jim Meyering
+
+# gl_FUNC_GETCWD_ABORT_BUG([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG],
+[
+  AC_CHECK_DECLS_ONCE(getcwd)
+  AC_CHECK_FUNCS(getpagesize)
+  AC_CACHE_CHECK([whether getcwd aborts when 4k < cwd_length < 16k],
+    gl_cv_func_getcwd_abort_bug,
+    [# Remove any remnants of a previous test.
+     rm -rf confdir-14B---
+     # Arrange for deletion of the temporary directory this test creates.
+     ac_clean_files="$ac_clean_files confdir-14B---"
+     AC_RUN_IFELSE(
+       [AC_LANG_SOURCE(
+         [[
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/stat.h>
+
+/* Don't get link errors because mkdir is redefined to rpl_mkdir.  */
+#undef mkdir
+
+#ifndef S_IRWXU
+# define S_IRWXU 0700
+#endif
+
+/* FIXME: skip the run-test altogether on systems without getpagesize.  */
+#if ! HAVE_GETPAGESIZE
+# define getpagesize() 0
+#endif
+
+/* This size is chosen to be larger than PATH_MAX (4k), yet smaller than
+   the 16kB pagesize on ia64 linux.  Those conditions make the code below
+   trigger a bug in glibc's getcwd implementation before 2.4.90-10.  */
+#define TARGET_LEN (5 * 1024)
+
+int
+main ()
+{
+  char const *dir_name = "confdir-14B---";
+  char *cwd;
+  size_t initial_cwd_len;
+  int fail = 0;
+  size_t desired_depth;
+  size_t d;
+
+  /* The bug is triggered when PATH_MAX < getpagesize (), so skip
+     this relative expensive and invasive test if that's not true.  */
+  if (getpagesize () <= PATH_MAX)
+    return 0;
+
+  cwd = getcwd (NULL, 0);
+  if (cwd == NULL)
+    return 0;
+
+  initial_cwd_len = strlen (cwd);
+  free (cwd);
+  desired_depth = ((TARGET_LEN - 1 - initial_cwd_len)
+                  / (1 + strlen (dir_name)));
+  for (d = 0; d < desired_depth; d++)
+    {
+      if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
+       {
+         fail = 3; /* Unable to construct deep hierarchy.  */
+         break;
+       }
+    }
+
+  /* If libc has the bug in question, this invocation of getcwd
+     results in a failed assertion.  */
+  cwd = getcwd (NULL, 0);
+  if (cwd == NULL)
+    fail = 4; /* getcwd failed.  This is ok, and expected.  */
+  free (cwd);
+
+  /* Call rmdir first, in case the above chdir failed.  */
+  rmdir (dir_name);
+  while (0 < d--)
+    {
+      if (chdir ("..") < 0)
+       break;
+      rmdir (dir_name);
+    }
+
+  return 0;
+}
+          ]])],
+    [gl_cv_func_getcwd_abort_bug=no],
+    [gl_cv_func_getcwd_abort_bug=yes],
+    [gl_cv_func_getcwd_abort_bug=yes])
+  ])
+  AS_IF([test $gl_cv_func_getcwd_abort_bug = yes], [$1], [$2])
+])
index 4bc8ab7..3d0af87 100644 (file)
@@ -1,4 +1,4 @@
-#serial 11
+#serial 12
 # Check for several getcwd bugs with long file names.
 # If so, arrange to compile the wrapper function.
 
@@ -157,8 +157,8 @@ main ()
   {
     size_t i;
 
-    /* Unlink first, in case the chdir failed.  */
-    unlink (DIR_NAME);
+    /* Try rmdir first, in case the chdir failed.  */
+    rmdir (DIR_NAME);
     for (i = 0; i <= n_chdirs; i++)
       {
        if (chdir ("..") < 0)
index 35d0b53..8f17432 100644 (file)
@@ -1,6 +1,6 @@
 # getcwd.m4 - check for working getcwd that is compatible with glibc
 
-# Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 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.
@@ -40,12 +40,15 @@ AC_DEFUN([gl_FUNC_GETCWD],
 [
   AC_REQUIRE([gl_FUNC_GETCWD_NULL])
 
+  gl_abort_bug=no
   case $gl_cv_func_getcwd_null in
-  yes) gl_FUNC_GETCWD_PATH_MAX;;
+  yes)
+    gl_FUNC_GETCWD_PATH_MAX
+    gl_FUNC_GETCWD_ABORT_BUG([gl_abort_bug=yes]);;
   esac
 
-  case $gl_cv_func_getcwd_null,$gl_cv_func_getcwd_path_max in
-  yes,yes) ;;
+  case $gl_cv_func_getcwd_null,$gl_cv_func_getcwd_path_max,$gl_abort_bug in
+  yes,yes,no) ;;
   *)
     AC_LIBOBJ([getcwd])
     AC_DEFINE([__GETCWD_PREFIX], [[rpl_]],
index 348f6f4..e518f81 100644 (file)
@@ -13,15 +13,30 @@ AC_DEFUN([gl_IGNORE_UNUSED_LIBRARIES],
     [gl_cv_ignore_unused_libraries],
     [gl_cv_ignore_unused_libraries=none
      gl_saved_ldflags=$LDFLAGS
+     gl_saved_libs=$LIBS
+     # Link with -lm to detect binutils 2.16 bug with --as-needed; see
+     # <http://lists.gnu.org/archive/html/bug-gnulib/2006-06/msg00131.html>.
+     LIBS="$LIBS -lm"
      # Use long option sequences like '-z ignore' to test for the feature,
      # to forestall problems with linkers that have -z, -i, -g, -n, etc. flags.
-     for gl_flags in '-Wl,-z,ignore' '-z ignore'; do
+     # GCC + binutils likes '-Wl,--as-needed'.
+     # GCC + Solaris ld likes '-Wl,-z,ignore'.
+     # Sun C likes '-z ignore'.
+     # Don't try bare '--as-needed'; nothing likes it and the HP-UX 11.11
+     # native cc issues annoying warnings and then ignores it,
+     # which would cause us to incorrectly conclude that it worked.
+     for gl_flags in \
+       '-Wl,--as-needed' \
+       '-Wl,-z,ignore' \
+       '-z ignore'
+     do
        LDFLAGS="$gl_flags $LDFLAGS"
        AC_LINK_IFELSE([AC_LANG_PROGRAM()],
         [gl_cv_ignore_unused_libraries=$gl_flags])
        LDFLAGS=$gl_saved_ldflags
        test "$gl_cv_ignore_unused_libraries" != none && break
-     done])
+     done
+     LIBS=$gl_saved_libs])
 
   test "$gl_cv_ignore_unused_libraries" != none &&
     LDFLAGS="$LDFLAGS $gl_cv_ignore_unused_libraries"
index cd7c161..0eacf4f 100644 (file)
@@ -1,12 +1,12 @@
-# same.m4 serial 6
-dnl Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+#serial 7
+dnl Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_SAME],
 [
-  AC_LIBSOURCES([same.c, same.h])
+  AC_LIBSOURCES([same.c, same.h, same-inode.h])
   AC_LIBOBJ([same])
 
   dnl Prerequisites of lib/same.c.
index 9307bd3..e9c94ca 100644 (file)
@@ -1,5 +1,5 @@
-#serial 4
-dnl Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+#serial 5
+dnl Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -10,3 +10,10 @@ AC_DEFUN([gl_XSTRTOD],
   AC_LIBSOURCES([xstrtod.c, xstrtod.h])
   AC_LIBOBJ([xstrtod])
 ])
+
+# Prerequisites of lib/xstrtold.c.
+AC_DEFUN([gl_XSTRTOLD],
+[
+  AC_LIBSOURCES([xstrtold.c, xstrtod.c, xstrtod.h])
+  AC_LIBOBJ([xstrtold])
+])
index 8eca3e1..89e087e 100644 (file)
@@ -4,6 +4,7 @@ help detect directory cycles efficiently
 Files:
 lib/cycle-check.c
 lib/cycle-check.h
+lib/same-inode.h
 lib/dev-ino.h
 
 Depends-on:
index c0ba7d7..46b1639 100644 (file)
@@ -8,6 +8,7 @@ lib/basename.c
 lib/stripslash.c
 m4/dos.m4
 m4/dirname.m4
+m4/double-slash-root.m4
 
 Depends-on:
 xalloc
index b80d7eb..0f38712 100644 (file)
@@ -5,6 +5,7 @@ Files:
 lib/getcwd.h
 lib/getcwd.c
 m4/d-ino.m4
+m4/getcwd-abort-bug.m4
 m4/getcwd-path-max.m4
 m4/getcwd.m4
 
index 582a81a..0ef6f60 100644 (file)
@@ -7,6 +7,7 @@ lib/chdir-safer.h
 lib/lchmod.h
 lib/mkdir-p.c
 lib/mkdir-p.h
+lib/same-inode.h
 m4/afs.m4
 m4/chdir-safer.m4
 m4/lchmod.m4
index 5587ba2..70b1e14 100644 (file)
@@ -1,10 +1,11 @@
 Description:
-Determine whether two pathnames refer to the same directory entry of the same
+Determine whether two file names refer to the same directory entry of the same
 directory.
 
 Files:
 lib/same.h
 lib/same.c
+lib/same-inode.h
 m4/same.m4
 
 Depends-on:
diff --git a/modules/xstrtold b/modules/xstrtold
new file mode 100644 (file)
index 0000000..a29769c
--- /dev/null
@@ -0,0 +1,25 @@
+Description:
+Convert string to 'long double', with error checking.
+
+Files:
+lib/xstrtod.h
+lib/xstrtod.c
+lib/xstrtold.c
+m4/xstrtod.m4
+
+Depends-on:
+stdbool
+
+configure.ac:
+gl_XSTRTOLD
+
+Makefile.am:
+
+Include:
+"xstrtod.h"
+
+License:
+GPL
+
+Maintainer:
+Jim Meyering