diff options
-rw-r--r-- | bin/cp/cp.1 | 11 | ||||
-rw-r--r-- | bin/cp/cp.c | 11 | ||||
-rw-r--r-- | bin/cp/extern.h | 1 | ||||
-rw-r--r-- | bin/cp/utils.c | 22 |
4 files changed, 45 insertions, 0 deletions
diff --git a/bin/cp/cp.1 b/bin/cp/cp.1 index 4fe0123..b12f166 100644 --- a/bin/cp/cp.1 +++ b/bin/cp/cp.1 @@ -225,6 +225,17 @@ 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. +.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 the standard output. .Sh DIAGNOSTICS .Ex -std .Sh COMPATIBILITY diff --git a/bin/cp/cp.c b/bin/cp/cp.c index bcba8d9..9776729 100644 --- a/bin/cp/cp.c +++ b/bin/cp/cp.c @@ -89,6 +89,9 @@ PATH_T to = { to.p_path, emptystring, "" }; int fflag, iflag, nflag, pflag, vflag; static int Rflag, rflag; +int info; +static void siginfo (int notused __unused); + enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE }; static int copy(char *[], enum op, int); @@ -173,6 +176,7 @@ main(int argc, char *argv[]) fts_options &= ~FTS_PHYSICAL; fts_options |= FTS_LOGICAL | FTS_COMFOLLOW; } + (void)signal(SIGINFO, siginfo); /* Save the target base in "to". */ target = argv[--argc]; @@ -501,3 +505,10 @@ mastercmp(const FTSENT * const *a, const FTSENT * const *b) return (1); return (0); } + +static void +siginfo (int notused __unused) +{ + + info = 1; +} diff --git a/bin/cp/extern.h b/bin/cp/extern.h index dfb737d..f06c65e 100644 --- a/bin/cp/extern.h +++ b/bin/cp/extern.h @@ -42,6 +42,7 @@ typedef struct { extern PATH_T to; extern int fflag, iflag, nflag, pflag, vflag; +extern int info; __BEGIN_DECLS int copy_fifo(struct stat *, int); diff --git a/bin/cp/utils.c b/bin/cp/utils.c index 7930195..aa1559e 100644 --- a/bin/cp/utils.c +++ b/bin/cp/utils.c @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #include "extern.h" +#define cp_pct(x,y) (int)(100.0 * (double)(x) / (double)(y)) int copy_file(const FTSENT *entp, int dne) @@ -65,6 +66,7 @@ copy_file(const FTSENT *entp, int dne) int ch, checkch, from_fd, rcount, rval, to_fd; ssize_t wcount; size_t wresid; + size_t wtotal; char *bufp; #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED char *p; @@ -137,9 +139,19 @@ copy_file(const FTSENT *entp, int dne) warn("%s", entp->fts_path); rval = 1; } else { + wtotal = 0; for (bufp = p, wresid = fs->st_size; ; bufp += wcount, wresid -= (size_t)wcount) { wcount = write(to_fd, bufp, wresid); + wtotal += wcount; + if (info) { + info = 0; + (void)fprintf(stderr, + "%s -> %s %3d%%\n", + entp->fts_path, to.p_path, + cp_pct(wtotal, fs->st_size)); + + } if (wcount >= (ssize_t)wresid || wcount <= 0) break; } @@ -156,10 +168,20 @@ copy_file(const 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; + (void)fprintf(stderr, + "%s -> %s %3d%%\n", + entp->fts_path, to.p_path, + cp_pct(wtotal, fs->st_size)); + + } if (wcount >= (ssize_t)wresid || wcount <= 0) break; } |