Patch for cp(1)
Bruce Evans
bde at zeta.org.au
Wed Mar 30 21:31:00 PST 2005
On Wed, 30 Mar 2005, Tom Rhodes wrote:
> Hi -standards.
>
> What do people think of the following patch to cp.c:
It seems to be wrong. From cp(1):
%%%
COMPATIBILITY
Historic versions of the cp utility had a -r option. This implementation
supports that option, however, its use is strongly discouraged, as it
does not correctly copy special files, symbolic links or fifo's.
%%%
Any change to the semantics of -r would break applications that depend on
its historical behaviour. Any change that doesn't change the man page would
be more broken.
This conforms to at least POSIX.1-200x-draft7:
%%%
10284 OB cp -r [-H | -L | -P][-fip] source_file ... target
10326 * If the -r option was specified, the behavior is implementation-defined.
10430 OB -r Copy file hierarchies. The treatment of special files is implementation-defined.
%%%
The correct fix is to remove the -r option. Unfortunately, POSIX broke
this.
> Index: cp.c
> ===================================================================
> RCS file: /home/ncvs/src/bin/cp/cp.c,v
> retrieving revision 1.51
> diff -u -r1.51 cp.c
> --- cp.c 10 Jan 2005 08:39:21 -0000 1.51
> +++ cp.c 30 Mar 2005 15:42:43 -0000
> @@ -84,7 +84,7 @@
> PATH_T to = { to.p_path, emptystring, "" };
>
> int fflag, iflag, nflag, pflag, vflag;
> -static int Rflag, rflag;
> +static int Rflag;
> volatile sig_atomic_t info;
>
> enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
> @@ -135,7 +135,7 @@
> pflag = 1;
> break;
> case 'r':
> - rflag = 1;
> + Rflag = 1;
> break;
> case 'v':
> vflag = 1;
The patch has lots of tab lossage and collateral indentation lossage...
> @@ -151,16 +151,7 @@
> usage();
>
> fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
> - if (rflag) {
> - if (Rflag)
> - errx(1,
> - "the -R and -r options may not be specified together.");
> - if (Hflag || Lflag || Pflag)
> - errx(1,
> - "the -H, -L, and -P options may not be specified with the -r option.");
> - fts_options &= ~FTS_PHYSICAL;
> - fts_options |= FTS_LOGICAL;
> - }
POSIX.1-200x-draft7 only requires -{HLP} to work with -R. Their behaviour
with -r is not explicitly mentioned. It is strange to show them in
the synopsis with -r when they are errors when actually used with -r.
However, I think they should cause an error when used with -r, since
their use with -r is not supported. -r could be made to work the same
as -R iff it is used together with at least one pf -{HLP}, but that
would be wrong since it would undeprecate -r.
> +
... and wrong whitespace gainage.
> if (Rflag) {
> if (Hflag)
> fts_options |= FTS_COMFOLLOW;
> @@ -224,12 +215,12 @@
> * the initial mkdir().
> */
> if (r == -1) {
> - if (rflag || (Rflag && (Lflag || Hflag)))
> + if ((Rflag && (Lflag || Hflag))
> stat(*argv, &tmp_stat);
> else
> lstat(*argv, &tmp_stat);
This is the main (only?) place where -r gives useful behaviour that is
significantly different from -R. With a bare -r, cp always follows
symlinks, but with a bare -R, cp never follows symlinks. (The behaviour
of cp -r on non-regular files is not useful.)
> ...
> So, why/what am I doing:
>
> My copy of SuSv3 states that -r is about to become obsolete;
My copy of cp.1 says that it became obsolete in BSD before 4.4BSDLite1 :-).
It was obsolete long before that too, since it was obolete in FreeBSD-1.
cp.1 in FreeBSD-1 is dated July 30, 1991. The deprecation apparently
rotted a bit between Net/2 and 4.4BSD -- cp.1 in FreeBSD doesn't mention
-r at all.
> The -r option fails (actually hangs) when trying to copy a fifo
> file within a directory. It does this on both CURRENT,
> STABLE and SunOS 5.9.
This is the documented behaviour.
> The idea was to make -r a synonym for -R, which works in all of
> these cases.
>
> I plan to fix the manual page as -r is not historical, it was
> implemenation dependent. Comments/suggestions? Yes, manual
> page commit would done together of course.
-r is historical. POSIX permits it to be implementation-defined
to prevent breaking it.
Bruce
More information about the freebsd-standards
mailing list