Patch from Laurence Anderson <L.D.Anderson@warwick.ac.uk> for
authorEric Andersen <andersen@codepoet.org>
Sat, 13 Apr 2002 08:43:01 +0000 (08:43 -0000)
committerEric Andersen <andersen@codepoet.org>
Sat, 13 Apr 2002 08:43:01 +0000 (08:43 -0000)
better tape drive support in tar/cpio by using an intervening
pipe...

archival/config.in
archival/libunarchive/unarchive.c

index 7b5644f0125ed373260f0c44745a81959f85ebfe..5a064dc89d147a354e6fcb0b318b44b0170bd6c9 100644 (file)
@@ -20,5 +20,8 @@ if [ "$CONFIG_TAR" = "y" ] ; then
     bool '  Enable -X and --exclude options (exclude files)'   CONFIG_FEATURE_TAR_EXCLUDE
     bool '  Enable -z option (currently only for extracting)'  CONFIG_FEATURE_TAR_GZIP
 fi
+if [ "$CONFIG_CPIO" = "y" -o "$CONFIG_TAR" = "y" ] ; then
+    bool '  Enable tape drive support' CONFIG_FEATURE_UNARCHIVE_TAPE
+fi
 bool 'unzip'       CONFIG_UNZIP
 endmenu
index 41be963efa294d9fabb620a4a44c1fbd4139fcbd..49908affb7e8c9854ce7d340c0a51f0ed6a5540c 100644 (file)
 #include <string.h>
 #include <unistd.h>
 #include <utime.h>
+#include <sys/wait.h>
+#include <signal.h>
 #include "unarchive.h"
-#include "libbb.h"
+#include "busybox.h"
 
 /* Extract the data postioned at src_stream to either filesystem, stdout or 
  * buffer depending on the value of 'function' which is defined in libbb.h 
@@ -202,7 +204,22 @@ char *unarchive(FILE *src_stream, FILE *out_stream, file_header_t *(*get_headers
        int extract_flag = TRUE;
        int i;
        char *buffer = NULL;
+#ifdef CONFIG_FEATURE_UNARCHIVE_TAPE
+       int pid, tape_pipe[2];
 
+       if (pipe(tape_pipe) != 0) error_msg_and_die("Can't create pipe\n");
+       if ((pid = fork()) == -1) error_msg_and_die("Fork failed\n");
+       if (pid==0) { /* child process */
+           close(tape_pipe[0]); /* We don't wan't to read from the pipe */
+           copyfd(fileno(src_stream), tape_pipe[1]);
+           close(tape_pipe[1]); /* Send EOF */
+           exit(0);
+           /* notreached */
+       }
+       close(tape_pipe[1]); /* Don't want to write down the pipe */
+       fclose(src_stream);
+       src_stream = fdopen(tape_pipe[0], "r");
+#endif
        archive_offset = 0;
        while ((file_entry = get_headers(src_stream)) != NULL) {
 
@@ -238,5 +255,9 @@ char *unarchive(FILE *src_stream, FILE *out_stream, file_header_t *(*get_headers
                free(file_entry->link_name);
                free(file_entry);
        }
+#ifdef CONFIG_FEATURE_UNARCHIVE_TAPE
+       kill(pid, SIGTERM);
+       waitpid(pid, NULL, 0);
+#endif
        return(buffer);
 }