summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/cp/cp.111
-rw-r--r--bin/cp/cp.c11
-rw-r--r--bin/cp/extern.h1
-rw-r--r--bin/cp/utils.c22
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;
}
OpenPOWER on IntegriCloud