On 11/01/2012 08:16:39 PM, Rob Landley wrote:
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...

TT.destname isn't getting initialized. Last commit that worked (before the dirtree changes) was 528, so comparing with that. What was I thinking?

  http://landley.net/hg/toybox/file/538/toys/cp.c

First line of cp_main() used to be TT.destname = toys.optargs[--toys.optc]; and the reason I removed that was:

A) I was thinking about someday adding NOFORK capability (the ability for toysh or similar to just call cp_main() as a function, probably through some variant of toy_exec(), and clean up after it in the same process context without fork/exec overhead). This meant the ability to free the argument memory, so permuting the arguments so it lost track of one and potentially leaked memory would be a downside. But that's bogus because toys.argc still has them all.

B) Adding the ability to tell the optstring to parse non-option arguments into the global block, so the <2 fixed arguments would wing up in TT without needing to do it by hand. (The idea was getting it to automatically do the type conversions.) I poked at this a bit, but couldn't work out a good way to express it that actually reduced complexity.

So, putting that back in...

Next up, TT.destisnew was only ever set, not read, so I yanked that case, tested for the other one, and unified the else cases to avoid the goto that was combining the two error_exit() cases.

That gets us to the TODO, which is about this problem:

readlink -f ./nonexistent : prints absolute path of where it _would_ go.
  realpath("./nonexistent", NULL): returns NULL

This is actually why toybox's readlink defaults to "n" for now, I need to make this case work.

However, what I'm trying to do here is duplicate detection, as mentioned in the previous reply...

Rob

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