summaryrefslogtreecommitdiffstats
path: root/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'main.cc')
-rw-r--r--main.cc106
1 files changed, 66 insertions, 40 deletions
diff --git a/main.cc b/main.cc
index 4ec73df..3fdf9da 100644
--- a/main.cc
+++ b/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 );