On Wed, Jun 15, 2011 at 06:11:37PM +0200, Jan Stary wrote:

> On Jun 15 17:41:08, Otto Moerbeek wrote:
> > On Wed, Jun 15, 2011 at 05:25:17PM +0200, Boudewijn Dijkstra wrote:
> > 
> > > Op Wed, 15 Jun 2011 16:52:12 +0200 schreef Jan Stary <[email protected]>:
> > > >The manpage of cp says
> > > >
> > > >     -f       For each existing destination pathname, remove it and
> > > >create a
> > > >      new file, without prompting for confirmation, regardless of its
> > > >      permissions.  This option overrides any use of -i.
> > > >
> > > >     -i       Write a prompt to the standard error output before
> > > >copying a file
> > > >      that would overwrite an existing file.  If the response from the
> > > >      standard input begins with the character `y', the file copy is
> > > >      attempted.
> > > >
> > > >but that isnot what cp actually does:
> > > >
> > > >$ rm -f echo bar
> > > >$ echo new > foo
> > > >$ echo old > bar
> > > >$ cp -fi foo bar
> > > >overwrite bar? n
> > > >$ cat bar
> > > >old
> > > >
> > > >Accoording to the manpage, the '-f' should have overrided the '-i'.
> > > >Instead, it asked for confirmation, which said 'n', and cp(1) did
> > > >not copy foo over bar, as it still has the old content.
> > > 
> > > Manpage has been like this forever.  Looks like the behaviour has
> > > been bugged since 1999:
> > 
> > Comments below.
> > 
> > > 
> > > --- src/bin/cp/cp.c       1998/07/03 17:43:56     1.12
> > > +++ src/bin/cp/cp.c       1999/05/06 18:19:45     1.13
> > > @@ -91,7 +91,7 @@ static char rcsid[] = "$OpenBSD: cp.c,v 1.12 1998/07/0
> > >  PATH_T to = { to.p_path, "" };
> > > 
> > >  uid_t myuid;
> > > -int Rflag, iflag, pflag, rflag;
> > > +int Rflag, fflag, iflag, pflag, rflag;
> > >  int myumask;
> > > 
> > >  enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
> > > @@ -129,10 +129,12 @@ main(argc, argv)
> > >                   Rflag = 1;
> > >                   break;
> > >           case 'f':
> > > +                 fflag = 1;
> > >                   iflag = 0;
> > >                   break;
> > >           case 'i':
> > >                   iflag = isatty(fileno(stdin));
> > > +                 fflag = 0;
> > >                   break;
> > >           case 'p':
> > >                   pflag = 1;
> > > 
> > > So the behaviour depends on the order of the arguments.  E.g. when doing:
> > >   $ cp -if foo bar
> > > no confirmation is asked, and:
> > >   $ cat bar
> > >   new
> > > .
> > > 
> > > Here's a fix (tested):
> > > 
> > > --- src/bin/cp/cp.c.orig        Sun Nov  4 03:01:57 2007
> > > +++ src/bin/cp/cp.c     Wed Jun 15 17:20:25 2011
> > > @@ -113,8 +113,10 @@
> > >                         iflag = 0;
> > >                         break;
> > >                 case 'i':
> > > -                       iflag = isatty(STDIN_FILENO);
> > > -                       fflag = 0;
> > > +                       if (!fflag) {
> > > +                               iflag = isatty(STDIN_FILENO);
> > > +                               fflag = 0;
> > 
> > Redundant assignment
> > 
> > Posix does not say anything about the interaction of -i and -f. I
> > hesitate to change the behaviour. Maybe we should check against other
> > BSD's first.
> > 
> 
> Or maybe just
> 
> --- cp.1.orig Wed Jun 15 18:09:22 2011
> +++ cp.1      Wed Jun 15 18:09:53 2011
> @@ -78,7 +78,7 @@
>  For each existing destination pathname, remove it and
>  create a new file, without prompting for confirmation,
>  regardless of its permissions.
> -This option overrides any use of
> +This option overrides any previous use of
>  .Fl i .
>  .It Fl H
>  If the

Yes, that's the wording used for rm(1). And -i should have a similar line.

I checked net and free, they implement -i and -f as we do.

        -Otto

Reply via email to