1
0
Fork 0

Merging upstream version 1.3~pre1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-24 04:08:02 +01:00
parent f04d94e9dd
commit e4e17ab53e
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
17 changed files with 387 additions and 259 deletions

106
main.cc
View file

@ -130,8 +130,7 @@ void show_help( const long num_online )
"The bidimensional parameter space of LZMA can't be mapped to a linear\n"
"scale optimal for all files. If your files are large, very repetitive,\n"
"etc, you may need to use the --match-length and --dictionary-size\n"
"options directly to achieve optimal performance. For example, -9m64\n"
"usually compresses executables more (and faster) than -9.\n"
"options directly to achieve optimal performance.\n"
"\nExit status: 0 for a normal exit, 1 for environmental problems (file\n"
"not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or\n"
"invalid input file, 3 for an internal consistency error (eg, bug) which\n"
@ -152,6 +151,28 @@ void show_version()
"There is NO WARRANTY, to the extent permitted by law.\n" );
}
} // end namespace
void show_header( const unsigned dictionary_size )
{
if( verbosity >= 3 )
{
const char * const prefix[8] =
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
enum { factor = 1024 };
const char * p = "";
const char * np = " ";
unsigned num = dictionary_size;
bool exact = ( num % factor == 0 );
for( int i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i )
{ num /= factor; if( num % factor != 0 ) exact = false;
p = prefix[i]; np = ""; }
std::fprintf( stderr, "dictionary size %s%4u %sB. ", np, num, p );
}
}
namespace {
unsigned long long getnum( const char * const ptr,
const unsigned long long llimit,
@ -323,7 +344,7 @@ bool open_outstream( const bool force )
bool check_tty( const int infd, const Mode program_mode )
{
if( program_mode == m_compress && outfd >= 0 && isatty( outfd ) )
if( program_mode == m_compress && isatty( outfd ) )
{
show_error( "I won't write compressed data to a terminal.", 0, true );
return false;
@ -337,6 +358,32 @@ bool check_tty( const int infd, const Mode program_mode )
return true;
}
} // end namespace
// 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 );
}
namespace {
// Set permissions, owner and times.
void close_and_set_permissions( const struct stat * const in_statsp )
@ -431,30 +478,6 @@ 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 unsigned long long cfile_size )
@ -464,17 +487,20 @@ void show_progress( const int packet_size,
static const Pretty_print * pp = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
if( p ) // initialize static vars
{ csize = cfile_size; pos = 0; pp = p; }
if( pp )
if( verbosity >= 2 )
{
xlock( &mutex );
pos += packet_size;
if( csize > 0 )
std::fprintf( stderr, "%4llu%%", pos / csize );
std::fprintf( stderr, " %.1f MB\r", pos / 1000000.0 );
pp->reset(); (*pp)(); // restore cursor position
xunlock( &mutex );
if( p ) // initialize static vars
{ csize = cfile_size; pos = 0; pp = p; }
if( pp )
{
xlock( &mutex );
pos += packet_size;
if( csize > 0 )
std::fprintf( stderr, "%4llu%%", pos / csize );
std::fprintf( stderr, " %.1f MB\r", pos / 1000000.0 );
pp->reset(); (*pp)(); // restore cursor position
xunlock( &mutex );
}
}
}
@ -688,15 +714,13 @@ int main( const int argc, const char * const argv[] )
int tmp;
if( program_mode == m_compress )
{
if( verbosity >= 2 ) // init
show_progress( 0, &pp, infd_isreg ? in_statsp->st_size / 100 : 0 );
show_progress( 0, &pp, infd_isreg ? in_statsp->st_size / 100 : 0 ); // init
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 );
tmp = decompress( num_workers, infd, outfd, pp, debug_level, infd_isreg );
if( tmp > retval ) retval = tmp;
if( tmp && program_mode != m_test ) cleanup_and_fail( retval );