Merging upstream version 1.1~pre1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
19bde4a70f
commit
8871145941
17 changed files with 356 additions and 277 deletions
106
main.cc
106
main.cc
|
@ -1,4 +1,4 @@
|
|||
/* Plzip - A parallel compressor compatible with lzip
|
||||
/* Plzip - Parallel compressor compatible with lzip
|
||||
Copyright (C) 2009 Laszlo Ersek.
|
||||
Copyright (C) 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
|
||||
|
@ -96,13 +96,11 @@ const mode_t usr_rw = S_IRUSR | S_IWUSR;
|
|||
const mode_t all_rw = usr_rw | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
mode_t outfd_mode = usr_rw;
|
||||
bool delete_output_on_interrupt = false;
|
||||
pthread_t main_thread;
|
||||
pid_t main_thread_pid;
|
||||
|
||||
|
||||
void show_help( const long num_online )
|
||||
{
|
||||
std::printf( "%s - A parallel compressor compatible with lzip.\n", Program_name );
|
||||
std::printf( "%s - Parallel compressor compatible with lzip.\n", Program_name );
|
||||
std::printf( "\nUsage: %s [options] [files]\n", invocation_name );
|
||||
std::printf( "\nOptions:\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
|
@ -262,12 +260,13 @@ int open_instream( const char * const name, struct stat * const in_statsp,
|
|||
const bool can_read = ( i == 0 &&
|
||||
( S_ISBLK( mode ) || S_ISCHR( mode ) ||
|
||||
S_ISFIFO( mode ) || S_ISSOCK( mode ) ) );
|
||||
if( i != 0 || ( !S_ISREG( mode ) && ( !to_stdout || !can_read ) ) )
|
||||
const bool no_ofile = to_stdout || ( program_mode == m_test );
|
||||
if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || !no_ofile ) ) )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n",
|
||||
program_name, name,
|
||||
( can_read && !to_stdout ) ?
|
||||
( can_read && !no_ofile ) ?
|
||||
" and '--stdout' was not specified" : "" );
|
||||
close( infd );
|
||||
infd = -1;
|
||||
|
@ -340,22 +339,6 @@ bool check_tty( const int infd, const Mode program_mode )
|
|||
}
|
||||
|
||||
|
||||
void cleanup_and_fail( const int retval )
|
||||
{
|
||||
if( delete_output_on_interrupt )
|
||||
{
|
||||
delete_output_on_interrupt = false;
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Deleting output file '%s', if it exists.\n",
|
||||
program_name, output_filename.c_str() );
|
||||
if( outfd >= 0 ) { close( outfd ); outfd = -1; }
|
||||
if( std::remove( output_filename.c_str() ) != 0 && errno != ENOENT )
|
||||
show_error( "WARNING: deletion of output file (apparently) failed." );
|
||||
}
|
||||
std::exit( retval );
|
||||
}
|
||||
|
||||
|
||||
// Set permissions, owner and times.
|
||||
void close_and_set_permissions( const struct stat * const in_statsp )
|
||||
{
|
||||
|
@ -382,13 +365,10 @@ void close_and_set_permissions( const struct stat * const in_statsp )
|
|||
}
|
||||
|
||||
|
||||
extern "C" void signal_handler( int sig )
|
||||
extern "C" void signal_handler( int )
|
||||
{
|
||||
if( !pthread_equal( pthread_self(), main_thread ) )
|
||||
kill( main_thread_pid, sig );
|
||||
if( sig != SIGUSR1 && sig != SIGUSR2 )
|
||||
show_error( "Control-C or similar caught, quitting." );
|
||||
cleanup_and_fail( ( sig != SIGUSR2 ) ? 1 : 2 );
|
||||
show_error( "Control-C or similar caught, quitting." );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -405,14 +385,6 @@ void set_signals()
|
|||
int verbosity = 0;
|
||||
|
||||
|
||||
// This can be called from any thread, main thread or sub-threads alike,
|
||||
// since they all call common helper functions that call fatal() in case
|
||||
// of an error.
|
||||
//
|
||||
void fatal( const int retval )
|
||||
{ signal_handler( ( retval != 2 ) ? SIGUSR1 : SIGUSR2 ); }
|
||||
|
||||
|
||||
void Pretty_print::operator()( const char * const msg ) const
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
|
@ -456,6 +428,60 @@ void internal_error( const char * const msg )
|
|||
}
|
||||
|
||||
|
||||
// This can be called from any thread, main thread or sub-threads alike,
|
||||
// since they all call common helper functions that call cleanup_and_fail()
|
||||
// in case of an error.
|
||||
//
|
||||
void cleanup_and_fail( const int retval )
|
||||
{
|
||||
// only one thread can delete and exit
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
pthread_mutex_lock( &mutex ); // ignore errors to avoid loop
|
||||
if( delete_output_on_interrupt )
|
||||
{
|
||||
delete_output_on_interrupt = false;
|
||||
if( verbosity >= 0 )
|
||||
std::fprintf( stderr, "%s: Deleting output file '%s', if it exists.\n",
|
||||
program_name, output_filename.c_str() );
|
||||
if( outfd >= 0 ) { close( outfd ); outfd = -1; }
|
||||
if( std::remove( output_filename.c_str() ) != 0 && errno != ENOENT )
|
||||
show_error( "WARNING: deletion of output file (apparently) failed." );
|
||||
}
|
||||
std::exit( retval );
|
||||
}
|
||||
|
||||
|
||||
void show_progress( const int packet_size,
|
||||
const Pretty_print * const p,
|
||||
const struct stat * const in_statsp )
|
||||
{
|
||||
static unsigned long long cfile_size = 0; // file_size / 100
|
||||
static unsigned long long pos = 0;
|
||||
static const Pretty_print * pp = 0;
|
||||
static pthread_mutex_t mutex;
|
||||
|
||||
if( p ) // initialize static vars
|
||||
{
|
||||
if( !pp ) xinit( &mutex ); // init mutex only once
|
||||
pos = 0; pp = p;
|
||||
cfile_size = ( in_statsp && S_ISREG( in_statsp->st_mode ) ) ?
|
||||
in_statsp->st_size / 100 : 0;
|
||||
return;
|
||||
}
|
||||
if( pp )
|
||||
{
|
||||
xlock( &mutex );
|
||||
pos += packet_size;
|
||||
if( cfile_size > 0 )
|
||||
std::fprintf( stderr, "%4llu%%", pos / cfile_size );
|
||||
std::fprintf( stderr, " %.1f MB\r", pos / 1000000.0 );
|
||||
pp->reset(); (*pp)(); // restore cursor position
|
||||
xunlock( &mutex );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main( const int argc, const char * const argv[] )
|
||||
{
|
||||
// Mapping from gzip/bzip2 style 1..9 compression modes
|
||||
|
@ -486,8 +512,6 @@ int main( const int argc, const char * const argv[] )
|
|||
bool recompress = false;
|
||||
bool to_stdout = false;
|
||||
invocation_name = argv[0];
|
||||
main_thread = pthread_self();
|
||||
main_thread_pid = getpid();
|
||||
|
||||
if( LZ_version()[0] != LZ_version_string[0] )
|
||||
internal_error( "bad library version" );
|
||||
|
@ -598,8 +622,6 @@ int main( const int argc, const char * const argv[] )
|
|||
if( !to_stdout && program_mode != m_test &&
|
||||
( filenames_given || default_output_filename.size() ) )
|
||||
set_signals();
|
||||
std::signal( SIGUSR1, signal_handler );
|
||||
std::signal( SIGUSR2, signal_handler );
|
||||
|
||||
Pretty_print pp( filenames );
|
||||
|
||||
|
@ -668,9 +690,13 @@ int main( const int argc, const char * const argv[] )
|
|||
if( verbosity >= 1 ) pp();
|
||||
int tmp;
|
||||
if( program_mode == m_compress )
|
||||
{
|
||||
show_progress( 0, &pp, in_statsp ); // initialize static vars
|
||||
if( verbosity >= 2 ) show_progress( 0 ); // show initial zero size
|
||||
tmp = compress( data_size, encoder_options.dictionary_size,
|
||||
encoder_options.match_len_limit,
|
||||
num_workers, infd, outfd, pp, debug_level );
|
||||
}
|
||||
else
|
||||
tmp = decompress( num_workers, infd, outfd, pp, debug_level,
|
||||
program_mode == m_test, infd_isreg );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue