Merging upstream version 0.21.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
337c761a4d
commit
0703aa798f
27 changed files with 961 additions and 324 deletions
61
create_lz.cc
61
create_lz.cc
|
@ -19,22 +19,19 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdint.h> // for lzlib.h
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ftw.h>
|
||||
#include <lzlib.h>
|
||||
|
||||
#include "arg_parser.h"
|
||||
#include "tarlz.h"
|
||||
#include "arg_parser.h"
|
||||
#include "create.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
@ -272,7 +269,8 @@ int add_member_lz( const char * const filename, const struct stat *,
|
|||
{ delete[] header; delete extended; return 0; }
|
||||
|
||||
if( gcl_opts->solidity == bsolid &&
|
||||
block_is_full( *extended, file_size, partial_data_size ) )
|
||||
block_is_full( extended->full_size(), file_size, gcl_opts->data_size,
|
||||
partial_data_size ) )
|
||||
courierp->receive_packet( new Ipacket ); // end of group
|
||||
|
||||
courierp->receive_packet( new Ipacket( filename, file_size, extended, header ) );
|
||||
|
@ -307,7 +305,7 @@ extern "C" void * grouper( void * arg )
|
|||
const char * filename = arg.c_str();
|
||||
if( code == 'C' && chdir( filename ) != 0 )
|
||||
{ show_file_error( filename, "Error changing working directory", errno );
|
||||
cleanup_and_fail(); }
|
||||
exit_fail_mt(); }
|
||||
if( code ) continue; // skip options
|
||||
if( cl_opts.parser.argument( i ).empty() ) continue; // skip empty names
|
||||
std::string deslashed; // arg without trailing slashes
|
||||
|
@ -322,7 +320,7 @@ extern "C" void * grouper( void * arg )
|
|||
set_error_status( 1 ); }
|
||||
else if( nftw( filename, add_member_lz, 16,
|
||||
cl_opts.dereference ? 0 : FTW_PHYS ) != 0 )
|
||||
cleanup_and_fail(); // write error or OOM
|
||||
exit_fail_mt(); // write error or OOM
|
||||
else if( cl_opts.solidity == dsolid ) // end of group
|
||||
courier.receive_packet( new Ipacket );
|
||||
}
|
||||
|
@ -363,7 +361,7 @@ void loop_encode( const uint8_t * const ibuf, const int isize,
|
|||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "LZ_compress_read error: %s\n",
|
||||
LZ_strerror( LZ_compress_errno( encoder ) ) );
|
||||
cleanup_and_fail();
|
||||
exit_fail_mt();
|
||||
}
|
||||
opos += rd;
|
||||
// obuf is full or last opacket in lzip member
|
||||
|
@ -373,11 +371,11 @@ void loop_encode( const uint8_t * const ibuf, const int isize,
|
|||
internal_error( "opacket size exceeded in worker." );
|
||||
courier.collect_packet( new Opacket( obuf, opos ), worker_id );
|
||||
opos = 0; obuf = new( std::nothrow ) uint8_t[max_packet_size];
|
||||
if( !obuf ) { show_error( mem_msg2 ); cleanup_and_fail(); }
|
||||
if( !obuf ) { show_error( mem_msg2 ); exit_fail_mt(); }
|
||||
if( LZ_compress_finished( encoder ) == 1 )
|
||||
{
|
||||
if( LZ_compress_restart_member( encoder, LLONG_MAX ) >= 0 ) break;
|
||||
show_error( "LZ_compress_restart_member failed." ); cleanup_and_fail();
|
||||
show_error( "LZ_compress_restart_member failed." ); exit_fail_mt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -409,7 +407,7 @@ extern "C" void * cworker( void * arg )
|
|||
LZ_Encoder * encoder = 0;
|
||||
uint8_t * data = 0;
|
||||
Resizable_buffer rbuf; // extended header + data
|
||||
if( !rbuf.size() ) { show_error( mem_msg2 ); cleanup_and_fail(); }
|
||||
if( !rbuf.size() ) { show_error( mem_msg2 ); exit_fail_mt(); }
|
||||
|
||||
int opos = 0;
|
||||
bool flushed = true; // avoid producing empty lzip members
|
||||
|
@ -425,8 +423,9 @@ extern "C" void * cworker( void * arg )
|
|||
flushed = true; delete ipacket; continue;
|
||||
}
|
||||
|
||||
const char * const filename = ipacket->filename.c_str();
|
||||
const int infd =
|
||||
ipacket->file_size ? open_instream( ipacket->filename.c_str() ) : -1;
|
||||
ipacket->file_size ? open_instream( filename ) : -1;
|
||||
if( ipacket->file_size && infd < 0 ) // can't read file data
|
||||
{ delete[] ipacket->header; delete ipacket->extended; delete ipacket;
|
||||
set_error_status( 1 ); continue; } // skip file
|
||||
|
@ -442,7 +441,7 @@ extern "C" void * cworker( void * arg )
|
|||
show_error( mem_msg2 );
|
||||
else
|
||||
internal_error( "invalid argument to encoder." );
|
||||
cleanup_and_fail();
|
||||
exit_fail_mt();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,13 +449,12 @@ extern "C" void * cworker( void * arg )
|
|||
{
|
||||
const long long ebsize = ipacket->extended->format_block( rbuf );
|
||||
if( ebsize < 0 )
|
||||
{ show_error( "Error formatting extended records." ); cleanup_and_fail(); }
|
||||
{ show_error( "Error formatting extended records." ); exit_fail_mt(); }
|
||||
/* Limit the size of the extended block to INT_MAX - 1 so that it can
|
||||
be fed to lzlib as one buffer. */
|
||||
if( ebsize >= INT_MAX )
|
||||
{ show_error( "Extended records size >= INT_MAX." ); cleanup_and_fail(); }
|
||||
loop_encode( (const uint8_t *)rbuf(), ebsize, data, opos, courier,
|
||||
encoder, worker_id );
|
||||
{ show_error( "Extended records size >= INT_MAX." ); exit_fail_mt(); }
|
||||
loop_encode( rbuf.u8(), ebsize, data, opos, courier, encoder, worker_id );
|
||||
}
|
||||
// compress ustar header
|
||||
loop_encode( ipacket->header, header_size, data, opos, courier,
|
||||
|
@ -477,8 +475,8 @@ extern "C" void * cworker( void * arg )
|
|||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "File '%s' ends unexpectedly at pos %llu\n",
|
||||
ipacket->filename.c_str(), ipacket->file_size - rest );
|
||||
close( infd ); cleanup_and_fail();
|
||||
filename, ipacket->file_size - rest );
|
||||
close( infd ); exit_fail_mt();
|
||||
}
|
||||
if( rest == 0 ) // last read
|
||||
{
|
||||
|
@ -491,14 +489,17 @@ extern "C" void * cworker( void * arg )
|
|||
loop_encode( buf, size, data, opos, courier, encoder, worker_id );
|
||||
}
|
||||
if( close( infd ) != 0 )
|
||||
{ show_file_error( ipacket->filename.c_str(), "Error closing file", errno );
|
||||
cleanup_and_fail(); }
|
||||
{ show_file_error( filename, "Error closing file", errno );
|
||||
exit_fail_mt(); }
|
||||
}
|
||||
if( gcl_opts->warn_newer && archive_attrs.is_newer( filename ) )
|
||||
{ show_file_error( filename, "File is newer than the archive." );
|
||||
set_error_status( 1 ); }
|
||||
delete ipacket;
|
||||
}
|
||||
if( data ) delete[] data;
|
||||
if( encoder && LZ_compress_close( encoder ) < 0 )
|
||||
{ show_error( "LZ_compress_close failed." ); cleanup_and_fail(); }
|
||||
{ show_error( "LZ_compress_close failed." ); exit_fail_mt(); }
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -514,7 +515,7 @@ void muxer( Packet_courier & courier, const int outfd )
|
|||
if( !opacket ) break; // queue is empty. all workers exited
|
||||
|
||||
if( !writeblock_wrapper( outfd, opacket->data, opacket->size ) )
|
||||
cleanup_and_fail();
|
||||
exit_fail_mt();
|
||||
delete[] opacket->data;
|
||||
delete opacket;
|
||||
}
|
||||
|
@ -546,12 +547,12 @@ int encode_lz( const Cl_options & cl_opts, const char * const archive_namep,
|
|||
pthread_t grouper_thread;
|
||||
int errcode = pthread_create( &grouper_thread, 0, grouper, &grouper_arg );
|
||||
if( errcode )
|
||||
{ show_error( "Can't create grouper thread", errcode ); cleanup_and_fail(); }
|
||||
{ show_error( "Can't create grouper thread", errcode ); exit_fail_mt(); }
|
||||
|
||||
Worker_arg * worker_args = new( std::nothrow ) Worker_arg[num_workers];
|
||||
pthread_t * worker_threads = new( std::nothrow ) pthread_t[num_workers];
|
||||
if( !worker_args || !worker_threads )
|
||||
{ show_error( mem_msg ); cleanup_and_fail(); }
|
||||
{ show_error( mem_msg ); exit_fail_mt(); }
|
||||
for( int i = 0; i < num_workers; ++i )
|
||||
{
|
||||
worker_args[i].courier = &courier;
|
||||
|
@ -560,7 +561,7 @@ int encode_lz( const Cl_options & cl_opts, const char * const archive_namep,
|
|||
worker_args[i].worker_id = i;
|
||||
errcode = pthread_create( &worker_threads[i], 0, cworker, &worker_args[i] );
|
||||
if( errcode )
|
||||
{ show_error( "Can't create worker threads", errcode ); cleanup_and_fail(); }
|
||||
{ show_error( "Can't create worker threads", errcode ); exit_fail_mt(); }
|
||||
}
|
||||
|
||||
muxer( courier, outfd );
|
||||
|
@ -569,14 +570,14 @@ int encode_lz( const Cl_options & cl_opts, const char * const archive_namep,
|
|||
{
|
||||
errcode = pthread_join( worker_threads[i], 0 );
|
||||
if( errcode )
|
||||
{ show_error( "Can't join worker threads", errcode ); cleanup_and_fail(); }
|
||||
{ show_error( "Can't join worker threads", errcode ); exit_fail_mt(); }
|
||||
}
|
||||
delete[] worker_threads;
|
||||
delete[] worker_args;
|
||||
|
||||
errcode = pthread_join( grouper_thread, 0 );
|
||||
if( errcode )
|
||||
{ show_error( "Can't join grouper thread", errcode ); cleanup_and_fail(); }
|
||||
{ show_error( "Can't join grouper thread", errcode ); exit_fail_mt(); }
|
||||
|
||||
// write End-Of-Archive records
|
||||
int retval = !write_eof_records( outfd, true );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue