@@ -17,6 +17,8 @@ static unsigned long offset;
17
17
18
18
static int tar_umask = 002 ;
19
19
20
+ static gzFile gzip ;
21
+
20
22
static int write_tar_filter_archive (const struct archiver * ar ,
21
23
struct archiver_args * args );
22
24
@@ -38,11 +40,21 @@ static int write_tar_filter_archive(const struct archiver *ar,
38
40
#define USTAR_MAX_MTIME 077777777777ULL
39
41
#endif
40
42
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
+
41
53
/* writes out the whole block, but only if it is full */
42
54
static void write_if_needed (void )
43
55
{
44
56
if (offset == BLOCKSIZE ) {
45
- write_or_die ( 1 , block , BLOCKSIZE );
57
+ write_block_or_die ( block );
46
58
offset = 0 ;
47
59
}
48
60
}
@@ -66,7 +78,7 @@ static void do_write_blocked(const void *data, unsigned long size)
66
78
write_if_needed ();
67
79
}
68
80
while (size >= BLOCKSIZE ) {
69
- write_or_die ( 1 , buf , BLOCKSIZE );
81
+ write_block_or_die ( buf );
70
82
size -= BLOCKSIZE ;
71
83
buf += BLOCKSIZE ;
72
84
}
@@ -101,10 +113,10 @@ static void write_trailer(void)
101
113
{
102
114
int tail = BLOCKSIZE - offset ;
103
115
memset (block + offset , 0 , tail );
104
- write_or_die ( 1 , block , BLOCKSIZE );
116
+ write_block_or_die ( block );
105
117
if (tail < 2 * RECORDSIZE ) {
106
118
memset (block , 0 , offset );
107
- write_or_die ( 1 , block , BLOCKSIZE );
119
+ write_block_or_die ( block );
108
120
}
109
121
}
110
122
@@ -454,18 +466,34 @@ static int write_tar_filter_archive(const struct archiver *ar,
454
466
filter .use_shell = 1 ;
455
467
filter .in = -1 ;
456
468
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
+ }
463
486
464
487
r = write_tar_archive (ar , args );
465
488
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
+ }
469
497
470
498
strbuf_release (& cmd );
471
499
return r ;
0 commit comments