On Sat, Mar 05, 2016 at 03:03:36AM +0100, Dmitrij D. Czarkoff wrote:
> So the goal of the diff is to replace something like
> 
>   $ for src in ${files}; do [ -r "$src" ] && cp ${src} dst/; done
> 
> with
> 
>   $ yes n | cp -i ${files} dst/
> 
> ?
Or alternatively, to state in the manual that -i will be ignored
if stdin is not a tty, ideally with some rationale on why we deviate
from POSIX there.


> Well, I guess you can save some performance this way, but it is just
> too ugly to make sense.
I'd argue that
>   $ yes n | cp -i ${files} dst/
even if ugly, is more straightforward a solution to arrive at from
the manual alone than
>   $ for src in ${files}; do [ -r "$src" ] && cp ${src} dst/; done
unless one is already familiar with the (undocumented) twist.


> I'd rather add "-n" flag.
I agree that -n would be nice (below a FreeBSD-inspired patch),
but I think -i should be fixed (or the behavior documented) regardless.


----8<-----------------------------------------------------------------

--- bin/cp/cp.1.orig
+++ bin/cp/cp.1
@@ -44,7 +44,7 @@
 .Fl R
 .Op Fl H | Fl L | Fl P
 .Oc
-.Op Fl f | i
+.Op Fl f | i | n
 .Op Fl alNpv
 .Ar source_file target_file
 .Nm cp
@@ -52,7 +52,7 @@
 .Fl R
 .Op Fl H | Fl L | Fl P
 .Oc
-.Op Fl f | i
+.Op Fl f | i | n
 .Op Fl alNpv
 .Ar source_file ... target_directory
 .Sh DESCRIPTION
@@ -82,11 +82,14 @@ Same as
 For each existing destination pathname, attempt to overwrite it.
 If permissions do not allow copy to succeed, remove it and create a new
 file, without prompting for confirmation.
+.br
 (The
-.Fl i
-option is ignored if the
 .Fl f
-option is specified.)
+option overrides any previous
+.Fl i
+or
+.Fl n
+options.)
 .It Fl H
 If the
 .Fl R
@@ -100,6 +103,24 @@ that would overwrite an existing file.
 If the response from the standard input begins with the character
 .Sq Li y ,
 the file copy is attempted.
+.br
+(The
+.Fl i
+option overrides any previous
+.Fl f
+or
+.Fl n
+options.)
+.It Fl n
+Do not overwrite existing files.
+.br
+(The
+.Fl n
+option overrides any previous
+.Fl i
+or
+.Fl f
+options.)
 .It Fl L
 If the
 .Fl R
--- bin/cp/cp.c.orig
+++ bin/cp/cp.c
@@ -87,7 +87,7 @@ static char empty[] = "";
 PATH_T to = { .p_end = to.p_path, .target_end = empty  };
 
 uid_t myuid;
-int Hflag, Lflag, Rflag, Pflag, fflag, iflag, lflag, pflag, rflag, vflag, 
Nflag;
+int Hflag, Lflag, Rflag, Pflag, fflag, iflag, lflag, nflag, pflag, rflag, 
vflag, Nflag;
 mode_t myumask;
 sig_atomic_t pinfo;
 
@@ -114,7 +114,7 @@ main(int argc, char *argv[])
        (void)setlocale(LC_ALL, "");
 
        Hflag = Lflag = Pflag = Rflag = 0;
-       while ((ch = getopt(argc, argv, "HLNPRfailprv")) != -1) 
+       while ((ch = getopt(argc, argv, "HLNPRfailnprv")) != -1)
                switch (ch) {
                case 'H':
                        Hflag = 1;
@@ -142,11 +142,15 @@ main(int argc, char *argv[])
                        break;
                case 'f':
                        fflag = 1;
-                       iflag = 0;
+                       nflag = iflag = 0;
                        break;
                case 'i':
                        iflag = isatty(fileno(stdin));
-                       fflag = 0;
+                       fflag = nflag = 0;
+                       break;
+               case 'n':
+                       nflag = 1;
+                       fflag = iflag = 0;
                        break;
                case 'l':
                        lflag = 1;
--- bin/cp/extern.h.orig
+++ bin/cp/extern.h
@@ -42,7 +42,7 @@ typedef struct {
 
 extern PATH_T to;
 extern uid_t myuid;
-extern int Rflag, rflag, Hflag, Lflag, Pflag, fflag, iflag, lflag, pflag, 
Nflag;
+extern int Rflag, rflag, Hflag, Lflag, Pflag, fflag, iflag, lflag, nflag, 
pflag, Nflag;
 extern mode_t myumask;
 extern sig_atomic_t pinfo;
 
--- bin/cp/utils.c.orig
+++ bin/cp/utils.c
@@ -120,7 +120,10 @@ copy_file(FTSENT *entp, int dne)
                struct stat sb;
                int sval;
 
-               if (iflag) {
+               if (nflag) {
+                       (void)close(from_fd);
+                       return (0);
+               } else if (iflag) {
                        (void)fprintf(stderr, "overwrite %s? ", to.p_path);
                        checkch = ch = getchar();
                        while (ch != '\n' && ch != EOF)
@@ -412,8 +415,8 @@ void
 usage(void)
 {
        (void)fprintf(stderr,
-           "usage: %s [-R [-H | -L | -P]] [-f | -i] [-alNpv] src target\n"
-           "       %s [-R [-H | -L | -P]] [-f | -i] [-alNpv] src1 ... srcN 
directory\n",
+           "usage: %s [-R [-H | -L | -P]] [-f | -i | -n] [-alNpv] src target\n"
+           "       %s [-R [-H | -L | -P]] [-f | -i | -n] [-alNpv] src1 ... 
srcN directory\n",
            getprogname(), getprogname());
        exit(1);
        /* NOTREACHED */

Reply via email to