+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.
func_module c-strtold
func_module xstrtod
func_module xstrtol
+ func_module xstrtold
func_end_table
element="Date and time <time.h>"
regex_internal.h
stat-time.h
stdbool_.h
+stdint_.h
strcase.h
strdup.h
strndup.h
search.h
stat.c
stdbool.h
+stdint.h
sysexit.h
t-fpending
unlocked-io.h
+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
/* 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
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;
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);
/* 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;
}
#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
/* 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. */
/* 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
# endif
# include <stdbool.h>
# include "dev-ino.h"
+# include "same-inode.h"
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
/* 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
/* 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);
/* 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.
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';
}
/* 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
/* 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
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]));
/* 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;
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
: (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;
}
# 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;
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
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);
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;
}
/* 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
/* 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.
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;
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. */
int parent_status;
size_t dirroom;
size_t namlen;
+ bool use_d_ino = true;
/* Look at the parent directory. */
#ifdef AT_FDCWD
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;
}
(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;
--- /dev/null
+/* 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
/* 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. */
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 =
/* 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
# 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
/* 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;
}
/* 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;
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;
}
/* 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
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 */
--- /dev/null
+#define LONG 1
+#include "xstrtod.c"
+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.
-# 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
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])
:
])
-#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])
])
-# 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.
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.
])
-#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.
[
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
$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.])
])
--- /dev/null
+#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 /.])
+])
-# 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.
[
AC_LIBSOURCES([filemode.c, filemode.h])
AC_LIBOBJ([filemode])
+ AC_CHECK_DECLS_ONCE([strmode])
])
-#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
])
--- /dev/null
+#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])
+])
-#serial 11
+#serial 12
# Check for several getcwd bugs with long file names.
# If so, arrange to compile the wrapper function.
{
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)
# 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.
[
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_]],
[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"
-# 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.
-#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.
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])
+])
Files:
lib/cycle-check.c
lib/cycle-check.h
+lib/same-inode.h
lib/dev-ino.h
Depends-on:
lib/stripslash.c
m4/dos.m4
m4/dirname.m4
+m4/double-slash-root.m4
Depends-on:
xalloc
lib/getcwd.h
lib/getcwd.c
m4/d-ino.m4
+m4/getcwd-abort-bug.m4
m4/getcwd-path-max.m4
m4/getcwd.m4
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
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:
--- /dev/null
+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