@@ -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
@@ -455,18 +467,34 @@ static int write_tar_filter_archive(const struct archiver *ar,
455
467
filter .use_shell = 1 ;
456
468
filter .in = -1 ;
457
469
458
- if (start_command (& filter ) < 0 )
459
- die_errno (_ ("unable to start '%s' filter" ), argv [0 ]);
460
- close (1 );
461
- if (dup2 (filter .in , 1 ) < 0 )
462
- die_errno (_ ("unable to redirect descriptor" ));
463
- close (filter .in );
470
+ if (!strcmp ("gzip -cn" , ar -> data )) {
471
+ char outmode [4 ] = "wb\0" ;
472
+
473
+ if (args -> compression_level >= 0 && args -> compression_level <= 9 )
474
+ outmode [2 ] = '0' + args -> compression_level ;
475
+
476
+ gzip = gzdopen (fileno (stdout ), outmode );
477
+ if (!gzip )
478
+ die (_ ("Could not gzdopen stdout" ));
479
+ } else {
480
+ if (start_command (& filter ) < 0 )
481
+ die_errno (_ ("unable to start '%s' filter" ), argv [0 ]);
482
+ close (1 );
483
+ if (dup2 (filter .in , 1 ) < 0 )
484
+ die_errno (_ ("unable to redirect descriptor" ));
485
+ close (filter .in );
486
+ }
464
487
465
488
r = write_tar_archive (ar , args );
466
489
467
- close (1 );
468
- if (finish_command (& filter ) != 0 )
469
- die (_ ("'%s' filter reported error" ), argv [0 ]);
490
+ if (gzip ) {
491
+ if (gzclose (gzip ) != Z_OK )
492
+ die (_ ("gzclose failed" ));
493
+ } else {
494
+ close (1 );
495
+ if (finish_command (& filter ) != 0 )
496
+ die (_ ("'%s' filter reported error" ), argv [0 ]);
497
+ }
470
498
471
499
strbuf_release (& cmd );
472
500
return r ;
0 commit comments