On 10/28/2012 10:42:32 PM, Roy Tam wrote:
It is broken for months, so I hackfixed it.

Sigh. Good point.

I was fixing cp properly before work and email and life went nuts.

Let's see...

diff -U8 toys/posix/cp.c toys/posix/cp.c_hf
--- toys/posix/cp.c     2012-10-27 10:15:31.000000000 +0800
+++ toys/posix/cp.c_hf  2012-10-29 11:41:01.000000000 +0800
@@ -171,37 +171,37 @@

        // Loop through sources

        for (i=0; i<toys.optc; i++) {
                char *dst, *src = toys.optargs[i];

// Skip src==dest (TODO check inodes to catch "cp blah ./blah").

-               if (!strncmp(src, TT.destname)) continue;
+               if (!strcmp(src, TT.destname)) continue;

Sigh. Looks like I checked in half-finished work at some point. (Possibly when I categorized commands into subdirectories.)

What I was going for here is trying to catch destinations that are _under_ source, ala:

  cp -r dir dir/sub

If I'm using cannonicalized absolute paths (with all the symlinks resolved), then a matching prefix tells me I've got an endless loop coming up. But I also need to catch:

  cp * .

Last I poked at this, I'm was trying to work out what all the cases were and a graceful way to catch them without a forest of special cases...

                // Skip nonexistent sources.

                TT.keep_symlinks = toys.optflags & (FLAG_d|FLAG_a);
if (TT.keep_symlinks ? lstat(src, &st) : stat(src, &st) - || (st.st_dev = dst.st_dev && st.st_ino == dst.dst_ino))
+                       /*|| (st.st_dev = dst.st_dev && st.st_ino ==
dst.dst_ino)*/)

Another variant of the same thing. I was stepping back and trying to collate it all into one test.

Unfortunately, "endless recursion with -r" and "copy over itself" seem like the need to be two separate tests.

                {
 objection:
                        perror_msg("bad '%s'", src);
                        toys.exitval = 1;
                        continue;
                }

                // Copy directory or file.

                if (TT.destisdir) {
                        char *s;

                        // Catch "cp -R .. ." and friends that would
go on forever
-                       if (dpath && (s = realpath(src, NULL)) {
+                       if (dpath && (s = realpath(src, NULL))) {

Ok, that's just embarassing. But it also means "I never actually tested this code, and it needs a largeish test suite entry because it's a pile of corner cases with a bunch of command line options".

I'm poking at it.

Thanks,

Rob
_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to