]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Overhaul the SIGINFO/SIGUSR1 reporting. This is a little
authorTim Kientzle <kientzle@gmail.com>
Fri, 17 Jul 2009 01:21:18 +0000 (21:21 -0400)
committerTim Kientzle <kientzle@gmail.com>
Fri, 17 Jul 2009 01:21:18 +0000 (21:21 -0400)
simpler and gives a lot more information.  In particular,
it reports total bytes in/out, total files and compression
ratio, in addition to reporting the current file being processed.

SVN-Revision: 1223

Makefile.am
tar/CMakeLists.txt
tar/Makefile
tar/bsdtar.c
tar/bsdtar.h
tar/config_freebsd.h
tar/read.c
tar/siginfo.c [deleted file]
tar/write.c

index 34dc9cc537723955e91926b473db28f9708af80b..5426dc9d321303ab164525e46277a112225b48a8 100644 (file)
@@ -370,7 +370,6 @@ bsdtar_SOURCES=                             \
                tar/cmdline.c           \
                tar/getdate.c           \
                tar/read.c              \
-               tar/siginfo.c           \
                tar/subst.c             \
                tar/tree.c              \
                tar/tree.h              \
index 0eb6037e418733084dbfa6e1d823ca212b0ed8fc..1d9896f93bcb334a4b0070681235a42b42055853 100644 (file)
@@ -11,7 +11,6 @@ IF (ENABLE_TAR)
     cmdline.c
     getdate.c
     read.c
-    siginfo.c
     subst.c
     tree.c
     tree.h
index 298a2fb46b4599069e8814c10f87215b0f054fec..cd1005426c303b9540750fff49be51be1d53230d 100644 (file)
@@ -4,7 +4,7 @@
 
 PROG=  bsdtar
 BSDTAR_VERSION_STRING=2.7.900a
-SRCS=  bsdtar.c cmdline.c getdate.c read.c siginfo.c subst.c tree.c util.c write.c
+SRCS=  bsdtar.c cmdline.c getdate.c read.c subst.c tree.c util.c write.c
 SRCS+=  err.c line_reader.c matching.c pathmatch.c
 WARNS?=        5
 DPADD= ${LIBARCHIVE} ${LIBBZ2} ${LIBZ}
index 8606608c22ebda3dcb37aedbd964e7d0dc0d8b11..3cf150c1328df229b9634898a7fc9544f05aa515 100644 (file)
@@ -47,6 +47,9 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.93 2008/11/08 04:43:24 kientzle
 #ifdef HAVE_PATHS_H
 #include <paths.h>
 #endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
 #include <stdio.h>
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
@@ -82,7 +85,34 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.93 2008/11/08 04:43:24 kientzle
 #define        _PATH_DEFTAPE "/dev/tape"
 #endif
 
-/* External function to parse a date/time string (from getdate.y) */
+static struct bsdtar *_bsdtar;
+
+#if defined(SIGINFO) || defined(SIGUSR1)
+static volatile int siginfo_occurred;
+
+static void
+siginfo_handler(int sig)
+{
+       (void)sig; /* UNUSED */
+       siginfo_occurred = 1;
+}
+
+int
+need_report(void)
+{
+       int r = siginfo_occurred;
+       siginfo_occurred = 0;
+       return (r);
+}
+#else
+int
+need_report(void)
+{
+       return (0);
+}
+#endif
+
+/* External function to parse a date/time string */
 time_t get_date(time_t, const char *);
 
 static void             long_help(void);
@@ -110,11 +140,30 @@ main(int argc, char **argv)
         * Use a pointer for consistency, but stack-allocated storage
         * for ease of cleanup.
         */
-       bsdtar = &bsdtar_storage;
+       _bsdtar = bsdtar = &bsdtar_storage;
        memset(bsdtar, 0, sizeof(*bsdtar));
        bsdtar->fd = -1; /* Mark as "unused" */
        option_o = 0;
 
+#if defined(SIGINFO) || defined(SIGUSR1)
+       { /* Catch SIGINFO and SIGUSR1, if they exist. */
+               struct sigaction sa;
+               sa.sa_handler = siginfo_handler;
+               sigemptyset(&sa.sa_mask);
+               sa.sa_flags = 0;
+#ifdef SIGINFO
+               if (sigaction(SIGINFO, &sa, NULL))
+                       lafe_errc(1, errno, "sigaction(SIGINFO) failed");
+#endif
+#ifdef SIGUSR1
+               /* ... and treat SIGUSR1 the same way as SIGINFO. */
+               if (sigaction(SIGUSR1, &sa, NULL))
+                       lafe_errc(1, errno, "sigaction(SIGUSR1) failed");
+#endif
+       }
+#endif
+
+
        /* Need lafe_progname before calling lafe_warnc. */
        if (*argv == NULL)
                lafe_progname = "bsdtar";
index 0c8dc69ca7560eb794ac39fc3201224dfa533c6d..ff1aff5661004d3f9d83289fa394b230754b8cee 100644 (file)
@@ -79,7 +79,6 @@ struct bsdtar {
        int               fd;
 
        /* Miscellaneous state information */
-       struct archive   *archive;
        int               argc;
        char            **argv;
        const char       *optarg;
@@ -139,14 +138,10 @@ enum {
 int    bsdtar_getopt(struct bsdtar *);
 void   do_chdir(struct bsdtar *);
 int    edit_pathname(struct bsdtar *, struct archive_entry *);
+int    need_report(void);
 int    pathcmp(const char *a, const char *b);
 void   safe_fprintf(FILE *, const char *fmt, ...);
 void   set_chdir(struct bsdtar *, const char *newdir);
-void   siginfo_init(struct bsdtar *);
-void   siginfo_setinfo(struct bsdtar *, const char * oper,
-           const char * path, int64_t size);
-void   siginfo_printinfo(struct bsdtar *, off_t progress);
-void   siginfo_done(struct bsdtar *);
 void   tar_mode_c(struct bsdtar *bsdtar);
 void   tar_mode_r(struct bsdtar *bsdtar);
 void   tar_mode_t(struct bsdtar *bsdtar);
index 568f61a18900f20a6ae568441a2712403c46dcce..81313c3111aef8f3a9b04e5d38f45991ca8b5809 100644 (file)
@@ -55,6 +55,7 @@
 #define        HAVE_PWD_H 1
 #define        HAVE_REGEX_H 1
 #define        HAVE_SETLOCALE 1
+#define        HAVE_SIGNAL_H 1
 #define        HAVE_STDARG_H 1
 #define        HAVE_STDLIB_H 1
 #define        HAVE_STRING_H 1
index 234bcb76f07b232d848e30597edfacf8dd6c429a..3d26a3a5eecdf5d768dec3baedcd1e36b03e8cf4 100644 (file)
@@ -70,6 +70,12 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/read.c,v 1.40 2008/08/21 06:41:14 kientzle E
 #include "bsdtar.h"
 #include "err.h"
 
+struct progress_data {
+       struct bsdtar *bsdtar;
+       struct archive *archive;
+       struct archive_entry *entry;
+};
+
 static void    list_item_verbose(struct bsdtar *, FILE *,
                    struct archive_entry *);
 static void    read_archive(struct bsdtar *bsdtar, char mode);
@@ -85,23 +91,41 @@ tar_mode_t(struct bsdtar *bsdtar)
 void
 tar_mode_x(struct bsdtar *bsdtar)
 {
-       /* We want to catch SIGINFO and SIGUSR1. */
-       siginfo_init(bsdtar);
-
        read_archive(bsdtar, 'x');
 
        if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0)
                bsdtar->return_value = 1;
-       /* Restore old SIGINFO + SIGUSR1 handlers. */
-       siginfo_done(bsdtar);
 }
 
 static void
-progress_func(void * cookie)
+progress_func(void *cookie)
 {
-       struct bsdtar * bsdtar = cookie;
-
-       siginfo_printinfo(bsdtar, 0);
+       struct progress_data *progress_data = cookie;
+       struct bsdtar *bsdtar = progress_data->bsdtar;
+       struct archive *a = progress_data->archive;
+       struct archive_entry *entry = progress_data->entry;
+       uintmax_t comp, uncomp;
+
+       if (!need_report())
+               return;
+
+       if (bsdtar->verbose)
+               fprintf(stderr, "\n");
+       if (a != NULL) {
+               comp = archive_position_compressed(a);
+               uncomp = archive_position_uncompressed(a);
+               fprintf(stderr,
+                   "In: %ju bytes, compression %d%%;",
+                   comp, (int)((uncomp - comp) * 100 / uncomp));
+               fprintf(stderr, "  Out: %d files, %ju bytes\n",
+                   archive_file_count(a), uncomp);
+       }
+       if (entry != NULL) {
+               safe_fprintf(stderr, "Current: %s (%ju bytes)",
+                   archive_entry_pathname(entry),
+                   (uintmax_t)archive_entry_size(entry));
+               fprintf(stderr, "\n");
+       }
 }
 
 /*
@@ -110,6 +134,7 @@ progress_func(void * cookie)
 static void
 read_archive(struct bsdtar *bsdtar, char mode)
 {
+       struct progress_data    progress_data;
        FILE                     *out;
        struct archive           *a;
        struct archive_entry     *entry;
@@ -142,8 +167,10 @@ read_archive(struct bsdtar *bsdtar, char mode)
 
        if (mode == 'x') {
                /* Set an extract callback so that we can handle SIGINFO. */
+               progress_data.bsdtar = bsdtar;
+               progress_data.archive = a;
                archive_read_extract_set_progress_callback(a, progress_func,
-                   bsdtar);
+                   &progress_data);
        }
 
        if (mode == 'x' && bsdtar->option_chroot) {
@@ -163,6 +190,7 @@ read_archive(struct bsdtar *bsdtar, char mode)
                        break;
 
                r = archive_read_next_header(a, &entry);
+               progress_data.entry = entry;
                if (r == ARCHIVE_EOF)
                        break;
                if (r < ARCHIVE_OK)
@@ -270,10 +298,7 @@ read_archive(struct bsdtar *bsdtar, char mode)
                                fflush(stderr);
                        }
 
-                       /* Tell the SIGINFO-handler code what we're doing. */
-                       siginfo_setinfo(bsdtar, "extracting",
-                           archive_entry_pathname(entry), 0);
-                       siginfo_printinfo(bsdtar, 0);
+                       // TODO siginfo_printinfo(bsdtar, 0);
 
                        if (bsdtar->option_stdout)
                                r = archive_read_data_into_fd(a, 1);
diff --git a/tar/siginfo.c b/tar/siginfo.c
deleted file mode 100644 (file)
index e7e41b3..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*-
- * Copyright 2008 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/siginfo.c,v 1.2 2008/05/22 21:08:36 cperciva Exp $");
-
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "bsdtar.h"
-#include "err.h"
-
-/* Is there a pending SIGINFO or SIGUSR1? */
-static volatile sig_atomic_t siginfo_received = 0;
-
-struct siginfo_data {
-       /* What sort of operation are we doing? */
-       char * oper;
-
-       /* What path are we handling? */
-       char * path;
-
-       /* How large is the archive entry? */
-       int64_t size;
-
-       /* Old signal handlers. */
-#ifdef SIGINFO
-       struct sigaction siginfo_old;
-#endif
-#ifdef SIGUSR1
-       struct sigaction sigusr1_old;
-#endif
-};
-
-#if defined(SIGINFO) || defined(SIGUSR1)
-static void             siginfo_handler(int sig);
-
-/* Handler for SIGINFO / SIGUSR1. */
-static void
-siginfo_handler(int sig)
-{
-
-       (void)sig; /* UNUSED */
-
-       /* Record that SIGINFO or SIGUSR1 has been received. */
-       siginfo_received = 1;
-}
-
-void
-siginfo_init(struct bsdtar *bsdtar)
-{
-       struct sigaction sa;
-
-       /* Allocate space for internal structure. */
-       if ((bsdtar->siginfo = malloc(sizeof(struct siginfo_data))) == NULL)
-               lafe_errc(1, errno, "malloc failed");
-
-       /* Set the strings to NULL so that free() is safe. */
-       bsdtar->siginfo->path = bsdtar->siginfo->oper = NULL;
-
-       /* We want to catch SIGINFO, if it exists. */
-       sa.sa_handler = siginfo_handler;
-       sigemptyset(&sa.sa_mask);
-       sa.sa_flags = 0;
-#ifdef SIGINFO
-       if (sigaction(SIGINFO, &sa, &bsdtar->siginfo->siginfo_old))
-               lafe_errc(1, errno, "sigaction(SIGINFO) failed");
-#endif
-#ifdef SIGUSR1
-       /* ... and treat SIGUSR1 the same way as SIGINFO. */
-       if (sigaction(SIGUSR1, &sa, &bsdtar->siginfo->sigusr1_old))
-               lafe_errc(1, errno, "sigaction(SIGUSR1) failed");
-#endif
-}
-#else
-void
-siginfo_init(struct bsdtar *bsdtar)
-{
-       /* Set the strings to NULL so that free() is safe. */
-       bsdtar->siginfo = NULL;
-}
-#endif
-
-void
-siginfo_setinfo(struct bsdtar *bsdtar, const char * oper, const char * path,
-    int64_t size)
-{
-
-       /* Free old operation and path strings. */
-       if (bsdtar->siginfo == NULL)
-               return;
-       free(bsdtar->siginfo->oper);
-       free(bsdtar->siginfo->path);
-
-       /* Duplicate strings and store entry size. */
-       if ((bsdtar->siginfo->oper = strdup(oper)) == NULL)
-               lafe_errc(1, errno, "Cannot strdup");
-       if ((bsdtar->siginfo->path = strdup(path)) == NULL)
-               lafe_errc(1, errno, "Cannot strdup");
-       bsdtar->siginfo->size = size;
-}
-
-void
-siginfo_printinfo(struct bsdtar *bsdtar, off_t progress)
-{
-
-       /* If there's a signal to handle and we know what we're doing... */
-       if ((siginfo_received == 1) &&
-           (bsdtar->siginfo->path != NULL) &&
-           (bsdtar->siginfo->oper != NULL)) {
-               if (bsdtar->verbose)
-                       fprintf(stderr, "\n");
-               if (bsdtar->siginfo->size > 0) {
-                       safe_fprintf(stderr, "%s %s (%ju / %" PRId64 ")",
-                           bsdtar->siginfo->oper, bsdtar->siginfo->path,
-                           (uintmax_t)progress, bsdtar->siginfo->size);
-               } else {
-                       safe_fprintf(stderr, "%s %s",
-                           bsdtar->siginfo->oper, bsdtar->siginfo->path);
-               }
-               if (!bsdtar->verbose)
-                       fprintf(stderr, "\n");
-               siginfo_received = 0;
-       }
-}
-
-void
-siginfo_done(struct bsdtar *bsdtar)
-{
-
-#ifdef SIGINFO
-       /* Restore old SIGINFO handler. */
-       sigaction(SIGINFO, &bsdtar->siginfo->siginfo_old, NULL);
-#endif
-#ifdef SIGUSR1
-       /* And the old SIGUSR1 handler, too. */
-       sigaction(SIGUSR1, &bsdtar->siginfo->sigusr1_old, NULL);
-#endif
-
-       if (bsdtar->siginfo) {
-               /* Free strings. */
-               free(bsdtar->siginfo->path);
-               free(bsdtar->siginfo->oper);
-
-               /* Free internal data structure. */
-               free(bsdtar->siginfo);
-       }
-}
index 0301af747b39abe079c95df5182bc5ceee93d2da..591a3da26875b84161ed40b6c89f24daea4699ff 100644 (file)
@@ -123,10 +123,12 @@ static int                 append_archive_filename(struct bsdtar *,
                             struct archive *, const char *fname);
 static void             archive_names_from_file(struct bsdtar *bsdtar,
                             struct archive *a);
-static int              copy_file_data(struct bsdtar *bsdtar,
-                            struct archive *a, struct archive *ina);
+static int              copy_file_data(struct bsdtar *, struct archive *a,
+                            struct archive *ina, struct archive_entry *);
 static int              new_enough(struct bsdtar *, const char *path,
                             const struct stat *);
+static void             report_write(struct bsdtar *, struct archive *,
+                            struct archive_entry *, int64_t progress);
 static void             test_for_append(struct bsdtar *);
 static void             write_archive(struct archive *, struct bsdtar *);
 static void             write_entry_backend(struct bsdtar *, struct archive *,
@@ -475,9 +477,6 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
        const char *arg;
        struct archive_entry *entry, *sparse_entry;
 
-       /* We want to catch SIGINFO and SIGUSR1. */
-       siginfo_init(bsdtar);
-
        /* Allocate a buffer for file data. */
        if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL)
                lafe_errc(1, 0, "cannot allocate memory");
@@ -554,9 +553,6 @@ cleanup:
        }
 
        archive_write_finish(a);
-
-       /* Restore old SIGINFO + SIGUSR1 handlers. */
-       siginfo_done(bsdtar);
 }
 
 /*
@@ -572,8 +568,6 @@ archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
        struct lafe_line_reader *lr;
        const char *line;
 
-       bsdtar->archive = a;
-
        bsdtar->next_line_is_dir = 0;
 
        lr = lafe_line_reader(bsdtar->names_from_file, '\n');
@@ -586,7 +580,7 @@ archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
                else {
                        if (*line != '/')
                                do_chdir(bsdtar); /* Handle a deferred -C */
-                       write_hierarchy(bsdtar, bsdtar->archive, line);
+                       write_hierarchy(bsdtar, a, line);
                }
        }
        lafe_line_reader_free(lr);
@@ -652,10 +646,8 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
                if (bsdtar->verbose)
                        safe_fprintf(stderr, "a %s",
                            archive_entry_pathname(in_entry));
-               siginfo_setinfo(bsdtar, "copying",
-                   archive_entry_pathname(in_entry),
-                   archive_entry_size(in_entry));
-               siginfo_printinfo(bsdtar, 0);
+               if (need_report())
+                       report_write(bsdtar, a, in_entry, 0);
 
                e = archive_write_header(a, in_entry);
                if (e != ARCHIVE_OK) {
@@ -672,7 +664,7 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
                if (e >= ARCHIVE_WARN) {
                        if (archive_entry_size(in_entry) == 0)
                                archive_read_data_skip(ina);
-                       else if (copy_file_data(bsdtar, a, ina))
+                       else if (copy_file_data(bsdtar, a, ina, in_entry))
                                exit(1);
                }
 
@@ -686,15 +678,17 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
 
 /* Helper function to copy data between archives. */
 static int
-copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
+copy_file_data(struct bsdtar *bsdtar, struct archive *a,
+    struct archive *ina, struct archive_entry *entry)
 {
        ssize_t bytes_read;
        ssize_t bytes_written;
-       off_t   progress = 0;
+       int64_t progress = 0;
 
        bytes_read = archive_read_data(ina, bsdtar->buff, FILEDATABUFLEN);
        while (bytes_read > 0) {
-               siginfo_printinfo(bsdtar, progress);
+               if (need_report())
+                       report_write(bsdtar, a, entry, progress);
 
                bytes_written = archive_write_data(a, bsdtar->buff,
                    bytes_read);
@@ -921,14 +915,8 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
                if (!S_ISREG(st->st_mode))
                        archive_entry_set_size(entry, 0);
 
-               /* Record what we're doing, for SIGINFO / SIGUSR1. */
-               siginfo_setinfo(bsdtar, "adding",
-                   archive_entry_pathname(entry), archive_entry_size(entry));
                archive_entry_linkify(bsdtar->resolver, &entry, &spare_entry);
 
-               /* Handle SIGINFO / SIGUSR1 request if one was made. */
-               siginfo_printinfo(bsdtar, 0);
-
                while (entry != NULL) {
                        write_entry_backend(bsdtar, a, entry);
                        archive_entry_free(entry);
@@ -998,6 +986,27 @@ write_entry_backend(struct bsdtar *bsdtar, struct archive *a,
                close(fd);
 }
 
+static void
+report_write(struct bsdtar *bsdtar, struct archive *a,
+    struct archive_entry *entry, int64_t progress)
+{
+       uintmax_t comp, uncomp;
+       if (bsdtar->verbose)
+               fprintf(stderr, "\n");
+       comp = archive_position_compressed(a);
+       uncomp = archive_position_uncompressed(a);
+       fprintf(stderr, "In: %d files, %ju bytes;",
+           archive_file_count(a), uncomp);
+       fprintf(stderr,
+           " Out: %ju bytes, compression %d%%\n",
+           comp, (int)((uncomp - comp) * 100 / uncomp));
+       safe_fprintf(stderr, "Current: %s (%ju/%ju bytes)",
+           archive_entry_pathname(entry),
+           (uintmax_t)progress,
+           (uintmax_t)archive_entry_size(entry));
+       fprintf(stderr, "\n");
+}
+
 
 /* Helper function to copy file to archive. */
 static int
@@ -1006,11 +1015,12 @@ write_file_data(struct bsdtar *bsdtar, struct archive *a,
 {
        ssize_t bytes_read;
        ssize_t bytes_written;
-       off_t   progress = 0;
+       int64_t progress = 0;
 
        bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN);
        while (bytes_read > 0) {
-               siginfo_printinfo(bsdtar, progress);
+               if (need_report())
+                       report_write(bsdtar, a, entry, progress);
 
                bytes_written = archive_write_data(a, bsdtar->buff,
                    bytes_read);