Sync with FreeBSD cp.
authorSimon Schubert <corecode@dragonflybsd.org>
Mon, 28 Feb 2005 23:15:35 +0000 (23:15 +0000)
committerSimon Schubert <corecode@dragonflybsd.org>
Mon, 28 Feb 2005 23:15:35 +0000 (23:15 +0000)
o Bump FreeBSD CVS IDs and manual page date
o Style(9)
o Constify
o Add SIGINFO handler (Author: mdodd, 1.40)
o Don't mmap(2) and munmap(2) zero-length files. (Author: alc, 1.42)
o Note how cp(1) handles directories ending in "/" (Author: trhodes, 1.29.2.1)
o Sync program's usage() with manpage's SYNOPSIS. (Author: ru, 1.45)
o Include <signal.h> instead of depending on namespace pollution in
  <sys/param.h>.  Include <sys/types.h> instead of of <sys/param.h>
  so that further such dependencies don't develop. (Author: bde, 1.47)

Submitted-by: Devon H. O'Dell <dodell@sitetronics.com> and
              Sarunas Vancevicius <svan@redbrick.dcu.ie>
Reviewed-by: joerg
Some-minor-changes: corecode

bin/cp/cp.1
bin/cp/cp.c
bin/cp/extern.h
bin/cp/utils.c

index c4c35f5..4385042 100644 (file)
 .\" SUCH DAMAGE.
 .\"
 .\"    @(#)cp.1        8.3 (Berkeley) 4/18/94
-.\" $FreeBSD: src/bin/cp/cp.1,v 1.16.2.6 2002/08/10 13:20:19 johan Exp $
-.\" $DragonFly: src/bin/cp/cp.1,v 1.3 2005/02/14 02:09:12 cpressey Exp $
+.\" $FreeBSD: src/bin/cp/cp.1,v 1.33 2005/02/25 00:40:46 trhodes Exp $ 
+.\" $DragonFly: src/bin/cp/cp.1,v 1.4 2005/02/28 23:15:35 corecode Exp $
 .\"
-.Dd August 10, 2002
+.Dd February 23, 2005
 .Dt CP 1
 .Os
 .Sh NAME
@@ -98,6 +98,12 @@ If
 designates a directory,
 .Nm
 copies the directory and the entire subtree connected at that point.
+If the
+.Ar source_file
+ends in a
+.Pa / ,
+the contents of the directory are copied rather than the
+directory itself.
 This option also causes symbolic links to be copied, rather than
 indirected through, and for
 .Nm
@@ -228,7 +234,18 @@ options are ignored unless the
 option is specified.
 In addition, these options override each other and the
 command's actions are determined by the last one specified.
-.Sh DIAGNOSTICS
+.Pp
+If
+.Nm
+receives a
+.Dv SIGINFO
+(see the
+.Cm status
+argument for
+.Xr stty 1 )
+signal, the current input and output file and the percentage complete
+will be written to standard error.
+.Sh EXIT STATUS
 .Ex -std
 .Sh COMPATIBILITY
 Historic versions of the
index bae164f..cf05fe2 100644 (file)
@@ -35,8 +35,8 @@
  *
  * @(#) Copyright (c) 1988, 1993, 1994 The Regents of the University of California.  All rights reserved.
  * @(#)cp.c    8.2 (Berkeley) 4/1/94
- * $FreeBSD: src/bin/cp/cp.c,v 1.24.2.7 2002/09/24 12:41:04 mckay Exp $
- * $DragonFly: src/bin/cp/cp.c,v 1.10 2005/02/14 02:09:12 cpressey Exp $
+ * $FreeBSD: src/bin/cp/cp.c,v 1.51 2005/01/10 08:39:21 imp Exp $ $
+ * $DragonFly: src/bin/cp/cp.c,v 1.11 2005/02/28 23:15:35 corecode Exp $
  */
 
 /*
  * in "to") to form the final target path.
  */
 
-#include <sys/param.h>
+#include <sys/types.h>
 #include <sys/stat.h>
 
 #include <err.h>
 #include <errno.h>
 #include <fts.h>
 #include <limits.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -77,11 +78,13 @@ PATH_T to = { to.p_path, to.p_path, "" };
 
 int fflag, iflag, nflag, pflag, vflag;
 static int Rflag, rflag;
+volatile sig_atomic_t info;
 
 enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
 
 static int copy (char **, enum op, int);
 static int mastercmp (const FTSENT **, const FTSENT **);
+static void siginfo (int);
 
 int
 main(int argc, char **argv)
@@ -162,6 +165,7 @@ main(int argc, char **argv)
                fts_options &= ~FTS_PHYSICAL;
                fts_options |= FTS_LOGICAL | FTS_COMFOLLOW;
        }
+       signal(SIGINFO, siginfo);
 
        /* Save the target base in "to". */
        target = argv[--argc];
@@ -486,3 +490,10 @@ mastercmp(const FTSENT **a, const FTSENT **b)
                return (1);
        return (0);
 }
+
+static void
+siginfo(int notused __unused)
+{
+
+       info = 1;
+}
index 1639030..e261e22 100644 (file)
  * SUCH DAMAGE.
  *
  *     @(#)extern.h    8.2 (Berkeley) 4/1/94
- * $FreeBSD: src/bin/cp/extern.h,v 1.9.2.3 2002/08/10 13:20:19 johan Exp $
- * $DragonFly: src/bin/cp/extern.h,v 1.4 2004/08/25 01:23:15 dillon Exp $
+ * $FreeBSD: src/bin/cp/extern.h,v 1.19 2004/04/06 20:06:44 markm $
+ * $DragonFly: src/bin/cp/extern.h,v 1.5 2005/02/28 23:15:35 corecode Exp $
  */
 
 typedef struct {
-       char *p_end;                    /* pointer to NULL at end of path */
-       char *target_end;               /* pointer to end of target base */
-       char p_path[PATH_MAX];          /* pointer to the start of a path */
+       char    *p_end;                 /* pointer to NULL at end of path */
+       char    *target_end;            /* pointer to end of target base */
+       char    p_path[PATH_MAX];       /* pointer to the start of a path */
 } PATH_T;
 
 extern PATH_T to;
 extern int fflag, iflag, nflag, pflag, vflag;
+extern volatile sig_atomic_t info;
 
 __BEGIN_DECLS
-int    copy_fifo (struct stat *, int);
-int    copy_file (FTSENT *, int);
-int    copy_link (FTSENT *, int);
-int    copy_special (struct stat *, int);
-int    setfile (struct stat *, int);
-void   usage (void);
+int    copy_fifo(struct stat *, int);
+int    copy_file(const FTSENT *, int);
+int    copy_link(const FTSENT *, int);
+int    copy_special(struct stat *, int);
+int    setfile(struct stat *, int);
+void   usage(void);
 __END_DECLS
index e545e80..1dc863f 100644 (file)
@@ -31,8 +31,8 @@
  * SUCH DAMAGE.
  *
  * @(#)utils.c 8.3 (Berkeley) 4/1/94
- * $FreeBSD: src/bin/cp/utils.c,v 1.27.2.6 2002/08/10 13:20:19 johan Exp $
- * $DragonFly: src/bin/cp/utils.c,v 1.7 2004/10/22 22:34:10 dillon Exp $
+ * $FreeBSD: src/bin/cp/utils.c,v 1.45 2005/02/09 17:37:37 ru Exp $
+ * $DragonFly: src/bin/cp/utils.c,v 1.8 2005/02/28 23:15:35 corecode Exp $
  */
 
 #include <sys/param.h>
 #include <unistd.h>
 
 #include "extern.h"
+#define        cp_pct(x,y)     (int)(100.0 * (double)(x) / (double)(y))
 
 #define YESNO "(y/n [n]) "
 
 int
-copy_file(FTSENT *entp, int dne)
+copy_file(const FTSENT *entp, int dne)
 {
        static char buf[MAXBSIZE];
        struct stat *fs;
-       int ch, checkch, from_fd, rcount, rval, to_fd, wcount, wresid;
+       int ch, checkch, from_fd, rcount, rval, to_fd, wcount, wresid, wtotal;
        char *bufp;
 #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
        char *p;
@@ -86,6 +87,7 @@ copy_file(FTSENT *entp, int dne)
                if (nflag) {
                        if (vflag)
                                printf("%s not overwritten\n", to.p_path);
+                       close(from_fd);
                        return (0);
                } else if (iflag) {
                        fprintf(stderr, "overwrite %s? %s", 
@@ -127,15 +129,25 @@ copy_file(FTSENT *entp, int dne)
         * wins some CPU back.
         */
 #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
-       if (S_ISREG(fs->st_mode) && fs->st_size <= 8 * 1048576) {
+       if (S_ISREG(fs->st_mode) && fs->st_size > 0 &&
+           fs->st_size <= 8 * 1048576) {
                if ((p = mmap(NULL, (size_t)fs->st_size, PROT_READ,
                    MAP_SHARED, from_fd, (off_t)0)) == MAP_FAILED) {
                        warn("%s", entp->fts_path);
                        rval = 1;
                } else {
+                       wtotal = 0;
                        for (bufp = p, wresid = fs->st_size; ;
                            bufp += wcount, wresid -= wcount) {
                                wcount = write(to_fd, bufp, wresid);
+                               wtotal += wcount;
+                               if (info) {
+                                       info = 0;
+                                       fprintf(stderr,
+                                           "%s -> %s %3d%%\n",
+                                           entp->fts_path, to.p_path,
+                                           cp_pct(wtotal, fs->st_size));
+                               }
                                if (wcount >= wresid || wcount <= 0)
                                        break;
                        }
@@ -152,10 +164,19 @@ copy_file(FTSENT *entp, int dne)
        } else
 #endif
        {
+               wtotal = 0;
                while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
                        for (bufp = buf, wresid = rcount; ;
                            bufp += wcount, wresid -= wcount) {
                                wcount = write(to_fd, bufp, wresid);
+                               wtotal += wcount;
+                               if (info) {
+                                       info = 0;
+                                       fprintf(stderr,
+                                           "%s -> %s %3d%%\n",
+                                           entp->fts_path, to.p_path,
+                                           cp_pct(wtotal, fs->st_size));
+                               }
                                if (wcount >= wresid || wcount <= 0)
                                        break;
                        }
@@ -189,7 +210,7 @@ copy_file(FTSENT *entp, int dne)
 }
 
 int
-copy_link(FTSENT *p, int exists)
+copy_link(const FTSENT *p, int exists)
 {
        int len;
        char linkname[PATH_MAX];
@@ -305,9 +326,9 @@ setfile(struct stat *fs, int fd)
 void
 usage(void)
 {
-
        fprintf(stderr, "%s\n%s\n",
-"usage: cp [-R [-H | -L | -P]] [-f | -i | -n] [-pv] src target",
-"       cp [-R [-H | -L | -P]] [-f | -i | -n] [-pv] src1 ... srcN directory");
+"usage: cp [-R [-H | -L | -P]] [-f | -i | -n] [-pv] source_file target_file",
+"       cp [-R [-H | -L | -P]] [-f | -i | -n] [-pv] source_file ... "
+"target_directory");
        exit(EX_USAGE);
 }