From 79c0a43808d9ca85acd04600149fc1a9b75bd1b9 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 3 Jul 2006 08:32:46 +0000 Subject: [PATCH] Merge from coreutils. --- ChangeLog | 11 +++ MODULES.html.sh | 1 + lib/.cppi-disable | 1 + lib/.cvsignore | 1 + lib/ChangeLog | 105 ++++++++++++++++++++++++++++ lib/backupfile.c | 7 +- lib/basename.c | 104 +++++++++++++++++++++------- lib/chdir-safer.c | 5 +- lib/cycle-check.c | 6 +- lib/cycle-check.h | 14 +++- lib/dirname.c | 112 +++++++++++------------------- lib/dirname.h | 29 +++++++- lib/filemode.c | 179 +++++++++++++++++++++++++----------------------- lib/filemode.h | 11 ++- lib/filenamecat.c | 6 +- lib/fsusage.c | 140 ++++++++++++++++--------------------- lib/fsusage.h | 8 ++- lib/fts-cycle.c | 11 ++- lib/getcwd.c | 123 +++++++++++++++++++-------------- lib/same-inode.h | 26 +++++++ lib/same.c | 11 ++- lib/stat-macros.h | 21 +++--- lib/stripslash.c | 27 +++++--- lib/xstrtod.c | 27 +++++--- lib/xstrtod.h | 4 +- lib/xstrtold.c | 2 + m4/ChangeLog | 58 ++++++++++++++++ m4/c-strtod.m4 | 6 +- m4/chdir-safer.m4 | 6 +- m4/dirname.m4 | 5 +- m4/dos.m4 | 41 +++++++---- m4/double-slash-root.m4 | 43 ++++++++++++ m4/filemode.m4 | 5 +- m4/ftruncate.m4 | 16 ++++- m4/getcwd-abort-bug.m4 | 106 ++++++++++++++++++++++++++++ m4/getcwd-path-max.m4 | 6 +- m4/getcwd.m4 | 11 +-- m4/lib-ignore.m4 | 19 ++++- m4/same.m4 | 6 +- m4/xstrtod.m4 | 11 ++- modules/cycle-check | 1 + modules/dirname | 1 + modules/getcwd | 1 + modules/mkdir-p | 1 + modules/same | 3 +- modules/xstrtold | 25 +++++++ 46 files changed, 947 insertions(+), 416 deletions(-) create mode 100644 lib/same-inode.h create mode 100644 lib/xstrtold.c create mode 100644 m4/double-slash-root.m4 create mode 100644 m4/getcwd-abort-bug.m4 create mode 100644 modules/xstrtold diff --git a/ChangeLog b/ChangeLog index fad326aa9..de9598e1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-07-03 Paul Eggert + + 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 * modules/inttypes (Depends-on): No longer depends on stdint. diff --git a/MODULES.html.sh b/MODULES.html.sh index dc91ae013..9c820d2b3 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -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 " diff --git a/lib/.cppi-disable b/lib/.cppi-disable index ce7e66446..57a07aa85 100644 --- a/lib/.cppi-disable +++ b/lib/.cppi-disable @@ -31,6 +31,7 @@ regex_internal.c regex_internal.h stat-time.h stdbool_.h +stdint_.h strcase.h strdup.h strndup.h diff --git a/lib/.cvsignore b/lib/.cvsignore index 5afaa5942..f2e600792 100644 --- a/lib/.cvsignore +++ b/lib/.cvsignore @@ -14,6 +14,7 @@ ref-del.sed search.h stat.c stdbool.h +stdint.h sysexit.h t-fpending unlocked-io.h diff --git a/lib/ChangeLog b/lib/ChangeLog index 46b9c6c21..b6861ab05 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,108 @@ +2006-07-03 Paul Eggert + + Merge from coreutils. + + * .cppi-disable: Add stdint_.h. + * .cvsignore: Add stdint.h. + + 2006-06-30 Paul Eggert + + * 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 + + * 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 + + * 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 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 + + * fsusage.c: Don't include or , 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 and if they exist. + + 2006-03-19 Jim Meyering + + 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 + + * 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 + + * 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 , + Paul Eggert + + * 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 * stdint_.h (intmax_t, uintmax_t): Prefer long to long long if diff --git a/lib/backupfile.c b/lib/backupfile.c index 32ffaeaa7..a990addec 100644 --- a/lib/backupfile.c +++ b/lib/backupfile.c @@ -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); diff --git a/lib/basename.c b/lib/basename.c index 5cc97cd4a..8c3dbece7 100644 --- a/lib/basename.c +++ b/lib/basename.c @@ -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 @@ -22,58 +22,110 @@ #endif #include "dirname.h" -#include -/* 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 +#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; } diff --git a/lib/chdir-safer.c b/lib/chdir-safer.c index b41123014..5c313bcab 100644 --- a/lib/chdir-safer.c +++ b/lib/chdir-safer.c @@ -30,6 +30,7 @@ #include #include #include +#include "same-inode.h" #ifndef O_DIRECTORY # define O_DIRECTORY 0 @@ -39,10 +40,6 @@ # 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 diff --git a/lib/cycle-check.c b/lib/cycle-check.c index 401dd862f..d8a3ca01d 100644 --- a/lib/cycle-check.c +++ b/lib/cycle-check.c @@ -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 @@ -33,10 +33,6 @@ #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. */ diff --git a/lib/cycle-check.h b/lib/cycle-check.h index 0551bf265..b137a60a8 100644 --- a/lib/cycle-check.h +++ b/lib/cycle-check.h @@ -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 # 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 diff --git a/lib/dirname.c b/lib/dirname.c index e2b9d648c..e3c762c7d 100644 --- a/lib/dirname.c +++ b/lib/dirname.c @@ -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 @@ -26,96 +26,62 @@ #include #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 - -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 diff --git a/lib/dirname.h b/lib/dirname.h index 1688ae810..f9189c356 100644 --- a/lib/dirname.h +++ b/lib/dirname.h @@ -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 @@ -31,16 +31,39 @@ # 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); diff --git a/lib/filemode.c b/lib/filemode.c index 08b9b13bb..5636c9e7c 100644 --- a/lib/filemode.c +++ b/lib/filemode.c @@ -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 @@ -19,129 +21,120 @@ # include #endif -#include -#include - #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'; } diff --git a/lib/filemode.h b/lib/filemode.h index 5d3da6703..47167367b 100644 --- a/lib/filemode.h +++ b/lib/filemode.h @@ -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 @@ -19,7 +19,14 @@ #ifndef FILEMODE_H_ # include +# include -void mode_string (mode_t mode, char *str); +# if HAVE_DECL_STRMODE +# include +# else +void strmode (mode_t mode, char *str); +# endif + +void filemodestring (struct stat const *statp, char *str); #endif diff --git a/lib/filenamecat.c b/lib/filenamecat.c index f94734630..399d7db31 100644 --- a/lib/filenamecat.c +++ b/lib/filenamecat.c @@ -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])); diff --git a/lib/fsusage.c b/lib/fsusage.c index b13779073..0bb622447 100644 --- a/lib/fsusage.c +++ b/lib/fsusage.c @@ -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 @@ -21,58 +21,46 @@ # include #endif -#if HAVE_INTTYPES_H -# include -#endif -#if HAVE_STDINT_H -# include -#endif -#include -#ifndef UINTMAX_MAX -# define UINTMAX_MAX ((uintmax_t) -1) -#endif - -#include -#include #include "fsusage.h" #include +#include -#if HAVE_SYS_PARAM_H -# include -#endif - -#if HAVE_SYS_MOUNT_H -# include -#endif - -#if HAVE_SYS_VFS_H -# include -#endif - -#if HAVE_SYS_FS_S5PARAM_H /* Fujitsu UXP/V */ -# include -#endif - -#if defined HAVE_SYS_FILSYS_H && !defined _CRAY -# include /* SVR2 */ -#endif - -#include - -#if HAVE_SYS_STATFS_H -# include -#endif - -#if HAVE_DUSTAT_H /* AIX PS/2 */ -# include -#endif - -#if HAVE_SYS_STATVFS_H /* SVR4 */ +#if STAT_STATVFS /* POSIX 1003.1-2001 (and later) with XSI */ # include +#else +/* Don't include backward-compatibility files unless they're needed. + Eventually we'd like to remove all this cruft. */ +# include +# include +# include +# if HAVE_SYS_PARAM_H +# include +# endif +# if HAVE_SYS_MOUNT_H +# include +# endif +# if HAVE_SYS_VFS_H +# include +# endif +# if HAVE_SYS_FS_S5PARAM_H /* Fujitsu UXP/V */ +# include +# endif +# if defined HAVE_SYS_FILSYS_H && !defined _CRAY +# include /* SVR2 */ +# endif +# if HAVE_SYS_STATFS_H +# include +# endif +# if HAVE_DUSTAT_H /* AIX PS/2 */ +# include +# 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 @@ -108,18 +96,19 @@ 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; } diff --git a/lib/fsusage.h b/lib/fsusage.h index f3eda2d09..645d107ea 100644 --- a/lib/fsusage.h +++ b/lib/fsusage.h @@ -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 @@ -22,6 +22,12 @@ #if !defined FSUSAGE_H_ # define FSUSAGE_H_ +# if HAVE_INTTYPES_H +# include +# endif +# if HAVE_STDINT_H +# include +# endif # include struct fs_usage diff --git a/lib/fts-cycle.c b/lib/fts-cycle.c index 13b43dbdd..19c5ded4c 100644 --- a/lib/fts-cycle.c +++ b/lib/fts-cycle.c @@ -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. */ diff --git a/lib/getcwd.c b/lib/getcwd.c index 5bb9e4be1..ba226799d 100644 --- a/lib/getcwd.c +++ b/lib/getcwd.c @@ -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 index 000000000..deca87b03 --- /dev/null +++ b/lib/same-inode.h @@ -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 diff --git a/lib/same.c b/lib/same.c index 4854b3a97..e267ba444 100644 --- a/lib/same.c +++ b/lib/same.c @@ -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 @@ -42,16 +42,13 @@ #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 = diff --git a/lib/stat-macros.h b/lib/stat-macros.h index 0957a22e6..829ddd35d 100644 --- a/lib/stat-macros.h +++ b/lib/stat-macros.h @@ -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 @@ -70,11 +70,7 @@ # 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 @@ -119,6 +115,10 @@ # 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) @@ -161,7 +161,7 @@ # endif # endif -/* contiguous */ +/* high performance ("contiguous data") */ # ifndef S_ISCTG # define S_ISCTG(p) 0 # endif @@ -176,6 +176,11 @@ # 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 diff --git a/lib/stripslash.c b/lib/stripslash.c index 9b55da48e..4ba5dadbe 100644 --- a/lib/stripslash.c +++ b/lib/stripslash.c @@ -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 @@ -22,19 +22,26 @@ #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; } diff --git a/lib/xstrtod.c b/lib/xstrtod.c index 8639869f9..e711ec860 100644 --- a/lib/xstrtod.c +++ b/lib/xstrtod.c @@ -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 @@ -29,17 +29,26 @@ #include #include -/* 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; } diff --git a/lib/xstrtod.h b/lib/xstrtod.h index 3addb8c5f..1e5ad94f5 100644 --- a/lib/xstrtod.h +++ b/lib/xstrtod.h @@ -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 index 000000000..50dc6a400 --- /dev/null +++ b/lib/xstrtold.c @@ -0,0 +1,2 @@ +#define LONG 1 +#include "xstrtod.c" diff --git a/m4/ChangeLog b/m4/ChangeLog index 2a9931b00..c9f5287ea 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,61 @@ +2006-07-03 Paul Eggert + + Merge from coreutils. + + 2006-06-30 Paul Eggert + + * 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 + + * lib-ignore.m4 (gl_IGNORE_UNUSED_LIBRARIES): Prefer binutils's + --as-needed option if available. Problem reported by Albert Chin in + . + 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 + + 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 + + * filemode.m4 (gl_FILEMODE): Check for strmode declaration. + + 2006-03-12 Jim Meyering + + * 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 + + * 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 * wcwidth.m4 (gl_FUNC_WCWIDTH): Simplify by using AC_CHECK_DECLS. diff --git a/m4/c-strtod.m4 b/m4/c-strtod.m4 index dca1cbc70..729f1aac7 100644 --- a/m4/c-strtod.m4 +++ b/m4/c-strtod.m4 @@ -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]) : ]) diff --git a/m4/chdir-safer.m4 b/m4/chdir-safer.m4 index f3d7351b5..b3c351c78 100644 --- a/m4/chdir-safer.m4 +++ b/m4/chdir-safer.m4 @@ -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]) ]) diff --git a/m4/dirname.m4 b/m4/dirname.m4 index e36937d8f..f3412ad08 100644 --- a/m4/dirname.m4 +++ b/m4/dirname.m4 @@ -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. ]) diff --git a/m4/dos.m4 b/m4/dos.m4 index 0713cf14e..dd59571c0 100644 --- 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 index 000000000..f8cbd54f3 --- /dev/null +++ b/m4/double-slash-root.m4 @@ -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 + # . + 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 /.]) +]) diff --git a/m4/filemode.m4 b/m4/filemode.m4 index 3b6ccb924..2b9334f85 100644 --- a/m4/filemode.m4 +++ b/m4/filemode.m4 @@ -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]) ]) diff --git a/m4/ftruncate.m4 b/m4/ftruncate.m4 index c225e48a3..b82705cca 100644 --- a/m4/ftruncate.m4 +++ b/m4/ftruncate.m4 @@ -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 index 000000000..a431a7ccc --- /dev/null +++ b/m4/getcwd-abort-bug.m4 @@ -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 +#include +#include +#include +#include + +/* 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]) +]) diff --git a/m4/getcwd-path-max.m4 b/m4/getcwd-path-max.m4 index 4bc8ab70f..3d0af8751 100644 --- a/m4/getcwd-path-max.m4 +++ b/m4/getcwd-path-max.m4 @@ -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) diff --git a/m4/getcwd.m4 b/m4/getcwd.m4 index 35d0b53bd..8f17432b5 100644 --- a/m4/getcwd.m4 +++ b/m4/getcwd.m4 @@ -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_]], diff --git a/m4/lib-ignore.m4 b/m4/lib-ignore.m4 index 348f6f44a..e518f8113 100644 --- a/m4/lib-ignore.m4 +++ b/m4/lib-ignore.m4 @@ -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 + # . + 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" diff --git a/m4/same.m4 b/m4/same.m4 index cd7c16174..0eacf4f1b 100644 --- a/m4/same.m4 +++ b/m4/same.m4 @@ -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. diff --git a/m4/xstrtod.m4 b/m4/xstrtod.m4 index 9307bd391..e9c94ca68 100644 --- a/m4/xstrtod.m4 +++ b/m4/xstrtod.m4 @@ -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]) +]) diff --git a/modules/cycle-check b/modules/cycle-check index 8eca3e1e5..89e087e71 100644 --- a/modules/cycle-check +++ b/modules/cycle-check @@ -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: diff --git a/modules/dirname b/modules/dirname index c0ba7d7e1..46b1639d8 100644 --- a/modules/dirname +++ b/modules/dirname @@ -8,6 +8,7 @@ lib/basename.c lib/stripslash.c m4/dos.m4 m4/dirname.m4 +m4/double-slash-root.m4 Depends-on: xalloc diff --git a/modules/getcwd b/modules/getcwd index b80d7eb00..0f3871201 100644 --- a/modules/getcwd +++ b/modules/getcwd @@ -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 diff --git a/modules/mkdir-p b/modules/mkdir-p index 582a81a98..0ef6f6044 100644 --- a/modules/mkdir-p +++ b/modules/mkdir-p @@ -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 diff --git a/modules/same b/modules/same index 5587ba244..70b1e146e 100644 --- a/modules/same +++ b/modules/same @@ -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 index 000000000..a29769c8f --- /dev/null +++ b/modules/xstrtold @@ -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 -- 2.11.0