diff options
author | Jim Meyering <meyering@redhat.com> | 2012-09-04 11:36:38 +0200 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2012-09-04 13:08:16 +0200 |
commit | 3a9002d3cc63da7110f133b1040d2d2b0aad8305 (patch) | |
tree | 58a7aa665a1be2c5d8d39ec1662fbbfac6aeb9d6 | |
parent | acb0726a65e9a6c954adcd50b50d4d02c016de26 (diff) | |
download | gnulib-3a9002d3cc63da7110f133b1040d2d2b0aad8305.tar.gz |
fts: reduce two or more trailing slashes to just one, usually
* lib/fts.c (fts_open): Upon initialization, if a name ends in two
or more slashes, trim all but the final one. But if a name consists
solely of two slashes, don't modify it. If it consists solely of
three or more slashes, strip all but one.
This is part of the solution to a minor problem with rm:
it would print a bogus ELOOP diagnostic when failing to remove
the slash-decorated name of a symlink-to-directory:
$ mkdir d && ln -s d s && env rm -r s/
rm: cannot remove 's': Too many levels of symbolic links
With the change below and a trivial don't-trim-trailing-slashes
adjustment to remove.c, it does this:
$ env rm -r s/
rm: cannot remove 's/': Not a directory
Improved by: Eric Blake
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | lib/fts.c | 8 |
2 files changed, 29 insertions, 0 deletions
@@ -1,5 +1,26 @@ 2012-09-04 Jim Meyering <meyering@redhat.com> + fts: reduce two or more trailing spaces to just one, usually + * lib/fts.c (fts_open): Upon initialization, if a name ends in two + or more slashes, trim all but the final one. But if a name consists + solely of two slashes, don't modify it. If it consists solely of + three or more slashes, strip all but one. + + This is part of the solution to a minor problem with rm: + it would print a bogus ELOOP diagnostic when failing to remove + the slash-decorated name of a symlink-to-directory: + + $ mkdir d && ln -s d s && env rm -r s/ + rm: cannot remove 's': Too many levels of symbolic links + + With the change below and a trivial don't-trim-trailing-slashes + adjustment to remove.c, it does this: + + $ env rm -r s/ + rm: cannot remove 's/': Not a directory + + Improved by: Eric Blake + fts: when there is no risk of overlap, use memcpy, not memmove * lib/fts.c (fts_alloc): Fix unjustified memcopy: s/memmove/memcpy/ @@ -487,6 +487,14 @@ fts_open (char * const *argv, for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) { /* *Do* allow zero-length file names. */ size_t len = strlen(*argv); + + /* If there are two or more trailing slashes, trim all but one, + but don't change "//" to "/", and do map "///" to "/". */ + char const *v = *argv; + if (2 < len && v[len - 1] == '/') + while (1 < len && v[len - 2] == '/') + --len; + if ((p = fts_alloc(sp, *argv, len)) == NULL) goto mem3; p->fts_level = FTS_ROOTLEVEL; |