@@ -17,6 +17,8 @@ static unsigned long offset;
1717
1818static int tar_umask = 002 ;
1919
20+ static gzFile gzip ;
21+
2022static int write_tar_filter_archive (const struct archiver * ar ,
2123 struct archiver_args * args );
2224
@@ -38,11 +40,21 @@ static int write_tar_filter_archive(const struct archiver *ar,
3840#define USTAR_MAX_MTIME 077777777777ULL
3941#endif
4042
43+ /* writes out the whole block, or dies if fails */
44+ static void write_block_or_die (const char * block ) {
45+ if (gzip ) {
46+ if (gzwrite (gzip , block , (unsigned ) BLOCKSIZE ) != BLOCKSIZE )
47+ die (_ ("gzwrite failed" ));
48+ } else {
49+ write_or_die (1 , block , BLOCKSIZE );
50+ }
51+ }
52+
4153/* writes out the whole block, but only if it is full */
4254static void write_if_needed (void )
4355{
4456 if (offset == BLOCKSIZE ) {
45- write_or_die ( 1 , block , BLOCKSIZE );
57+ write_block_or_die ( block );
4658 offset = 0 ;
4759 }
4860}
@@ -66,7 +78,7 @@ static void do_write_blocked(const void *data, unsigned long size)
6678 write_if_needed ();
6779 }
6880 while (size >= BLOCKSIZE ) {
69- write_or_die ( 1 , buf , BLOCKSIZE );
81+ write_block_or_die ( buf );
7082 size -= BLOCKSIZE ;
7183 buf += BLOCKSIZE ;
7284 }
@@ -101,10 +113,10 @@ static void write_trailer(void)
101113{
102114 int tail = BLOCKSIZE - offset ;
103115 memset (block + offset , 0 , tail );
104- write_or_die ( 1 , block , BLOCKSIZE );
116+ write_block_or_die ( block );
105117 if (tail < 2 * RECORDSIZE ) {
106118 memset (block , 0 , offset );
107- write_or_die ( 1 , block , BLOCKSIZE );
119+ write_block_or_die ( block );
108120 }
109121}
110122
@@ -454,18 +466,34 @@ static int write_tar_filter_archive(const struct archiver *ar,
454466 filter .use_shell = 1 ;
455467 filter .in = -1 ;
456468
457- if (start_command (& filter ) < 0 )
458- die_errno (_ ("unable to start '%s' filter" ), argv [0 ]);
459- close (1 );
460- if (dup2 (filter .in , 1 ) < 0 )
461- die_errno (_ ("unable to redirect descriptor" ));
462- close (filter .in );
469+ if (!strcmp ("gzip -cn" , ar -> data )) {
470+ char outmode [4 ] = "wb\0" ;
471+
472+ if (args -> compression_level >= 0 && args -> compression_level <= 9 )
473+ outmode [2 ] = '0' + args -> compression_level ;
474+
475+ gzip = gzdopen (fileno (stdout ), outmode );
476+ if (!gzip )
477+ die (_ ("Could not gzdopen stdout" ));
478+ } else {
479+ if (start_command (& filter ) < 0 )
480+ die_errno (_ ("unable to start '%s' filter" ), argv [0 ]);
481+ close (1 );
482+ if (dup2 (filter .in , 1 ) < 0 )
483+ die_errno (_ ("unable to redirect descriptor" ));
484+ close (filter .in );
485+ }
463486
464487 r = write_tar_archive (ar , args );
465488
466- close (1 );
467- if (finish_command (& filter ) != 0 )
468- die (_ ("'%s' filter reported error" ), argv [0 ]);
489+ if (gzip ) {
490+ if (gzclose (gzip ) != Z_OK )
491+ die (_ ("gzclose failed" ));
492+ } else {
493+ close (1 );
494+ if (finish_command (& filter ) != 0 )
495+ die (_ ("'%s' filter reported error" ), argv [0 ]);
496+ }
469497
470498 strbuf_release (& cmd );
471499 return r ;
0 commit comments