diff options
author | Eric Blake <eblake@redhat.com> | 2012-03-14 13:42:59 -0600 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2012-03-15 13:28:19 -0600 |
commit | be17e3b98a178ea6e2c973bf49282f11f7060353 (patch) | |
tree | fc13d79392e4c5e416a9838b33c6f8f5e14f2d1a /src | |
parent | 9f5aa4850133976eee22dcc0b506d7b632cd674c (diff) | |
download | coreutils-be17e3b98a178ea6e2c973bf49282f11f7060353.tar.xz |
realpath: optimize --relative-base usage
There is no need to recompute for every path being visited whether
the base is a prefix of the relative location.
* src/realpath.c (relpath): Hoist base check...
(main): ...here.
Based on a suggestion by Pádraig Brady.
Diffstat (limited to 'src')
-rw-r--r-- | src/realpath.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/src/realpath.c b/src/realpath.c index f95535b12..206f8006d 100644 --- a/src/realpath.c +++ b/src/realpath.c @@ -179,12 +179,8 @@ relpath (const char *can_fname) if (can_relative_to) { /* Enforce --relative-base. */ - if (can_relative_base) - { - if (!path_prefix (can_relative_base, can_fname) - || !path_prefix (can_relative_base, can_relative_to)) - return false; - } + if (can_relative_base && !path_prefix (can_relative_base, can_fname)) + return false; /* Skip the prefix common to --relative-to and path. */ int common_index = path_common_prefix (can_relative_to, can_fname); @@ -341,13 +337,25 @@ main (int argc, char **argv) if (need_dir && !isdir (can_relative_to)) error (EXIT_FAILURE, ENOTDIR, "%s", quote (relative_to)); } - if (relative_base) + if (relative_base == relative_to) + can_relative_base = can_relative_to; + else if (relative_base) { - can_relative_base = realpath_canon (relative_base, can_mode); - if (!can_relative_base) + char *base = realpath_canon (relative_base, can_mode); + if (!base) error (EXIT_FAILURE, errno, "%s", quote (relative_base)); - if (need_dir && !isdir (can_relative_base)) + if (need_dir && !isdir (base)) error (EXIT_FAILURE, ENOTDIR, "%s", quote (relative_base)); + /* --relative-to is a no-op if it does not have --relative-base + as a prefix */ + if (path_prefix (base, can_relative_to)) + can_relative_base = base; + else + { + free (base); + can_relative_base = can_relative_to; + can_relative_to = NULL; + } } for (; optind < argc; ++optind) |