[Toybox] [HACK] hackfixing cp for compilation

Rob Landley rob at landley.net
Thu Nov 1 18:16:39 PDT 2012


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


More information about the Toybox mailing list