SIGINFO handler for CP

Devon H. O'Dell dodell at sitetronics.com
Fri Feb 25 09:19:37 PST 2005


Hey,

This patch incorporates revisions 1.44 - 1.47 (mdodd@; bde@) of
FreeBSD's SIGINFO handler.

I have not tested this patch as I'm on a Linux machine at the moment and
can't hop over to DF.

Hope it's useful,

Devon
diff -ur src/bin/cp.old/cp.1 src/bin/cp/cp.1
--- src/bin/cp.old/cp.1	2005-02-14 03:09:12.000000000 +0100
+++ src/bin/cp/cp.1	2005-02-25 18:01:33.271042322 +0100
@@ -228,6 +228,17 @@
 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 -ur src/bin/cp.old/cp.c src/bin/cp/cp.c
--- src/bin/cp.old/cp.c	2005-02-14 03:09:12.000000000 +0100
+++ src/bin/cp/cp.c	2005-02-25 18:14:50.294710470 +0100
@@ -54,13 +54,14 @@
  * 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 @@
 
 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 notused __unused);
 
 int
 main(int argc, char **argv)
@@ -162,6 +165,7 @@
 		fts_options &= ~FTS_PHYSICAL;
 		fts_options |= FTS_LOGICAL | FTS_COMFOLLOW;
 	}
+	(void)signal(SIGINFO, siginfo);
 
 	/* Save the target base in "to". */
 	target = argv[--argc];
@@ -486,3 +490,10 @@
 		return (1);
 	return (0);
 }
+
+static void
+siginfo(int notused __unused)
+{
+
+	info = 1;
+}
diff -ur src/bin/cp.old/extern.h src/bin/cp/extern.h
--- src/bin/cp.old/extern.h	2004-08-25 03:23:15.000000000 +0200
+++ src/bin/cp/extern.h	2005-02-25 18:12:50.783255844 +0100
@@ -43,6 +43,7 @@
 
 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);
diff -ur src/bin/cp.old/utils.c src/bin/cp/utils.c
--- src/bin/cp.old/utils.c	2004-10-23 00:34:10.000000000 +0200
+++ src/bin/cp/utils.c	2005-02-25 18:10:01.094228337 +0100
@@ -53,6 +53,7 @@
 #include <unistd.h>
 
 #include "extern.h"
+#define	cp_pct(x,y)	(int)(100.0 * (double)(x) / (double)(y))
 
 #define YESNO "(y/n [n]) "
 
@@ -61,7 +62,7 @@
 {
 	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;
@@ -133,9 +134,18 @@
 			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;
 			}
@@ -156,6 +166,15 @@
 			for (bufp = buf, wresid = rcount; ;
 			    bufp += wcount, wresid -= wcount) {
 				wcount = write(to_fd, bufp, wresid);
+				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;
 			}




More information about the Submit mailing list