Merging upstream version 0.3.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
0e913c7a20
commit
5b23556820
11 changed files with 455 additions and 814 deletions
445
main.cc
445
main.cc
|
@ -25,20 +25,17 @@
|
|||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
#include <csignal>
|
||||
#include <cstdarg>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -49,7 +46,6 @@
|
|||
#endif
|
||||
|
||||
#include "arg_parser.h"
|
||||
#include "main.h"
|
||||
#include "plzip.h"
|
||||
|
||||
#ifndef LLONG_MAX
|
||||
|
@ -72,6 +68,12 @@ const char * const Program_name = "Plzip";
|
|||
const char * const program_name = "plzip";
|
||||
const char * const program_year = "2010";
|
||||
|
||||
#ifdef O_BINARY
|
||||
const int o_binary = O_BINARY;
|
||||
#else
|
||||
const int o_binary = 0;
|
||||
#endif
|
||||
|
||||
struct { const char * from; const char * to; } const known_extensions[] = {
|
||||
{ ".lz", "" },
|
||||
{ ".tlz", ".tar" },
|
||||
|
@ -88,6 +90,8 @@ enum Mode { m_compress = 0, m_decompress, m_test };
|
|||
std::string output_filename;
|
||||
int outhandle = -1;
|
||||
bool delete_output_on_interrupt = false;
|
||||
pthread_t main_thread;
|
||||
pid_t main_thread_pid;
|
||||
|
||||
class Pretty_print
|
||||
{
|
||||
|
@ -132,6 +136,7 @@ void show_help() throw()
|
|||
std::printf( " -h, --help display this help and exit\n" );
|
||||
std::printf( " -V, --version output version information and exit\n" );
|
||||
// std::printf( " -b, --member-size=<n> set member size limit in bytes\n" );
|
||||
std::printf( " -B, --data-size=<n> set input data block size in bytes\n" );
|
||||
std::printf( " -c, --stdout send output to standard output\n" );
|
||||
std::printf( " -d, --decompress decompress\n" );
|
||||
std::printf( " -f, --force overwrite existing output files\n" );
|
||||
|
@ -267,7 +272,7 @@ int open_instream( const std::string & name, struct stat * in_statsp,
|
|||
}
|
||||
else
|
||||
{
|
||||
inhandle = open( name.c_str(), O_RDONLY );
|
||||
inhandle = open( name.c_str(), O_RDONLY | o_binary );
|
||||
if( inhandle < 0 )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
|
@ -324,9 +329,11 @@ void set_d_outname( const std::string & name, const int i ) throw()
|
|||
bool open_outstream( const bool force ) throw()
|
||||
{
|
||||
if( force )
|
||||
outhandle = open( output_filename.c_str(), O_CREAT | O_TRUNC | O_WRONLY,
|
||||
outhandle = open( output_filename.c_str(),
|
||||
O_CREAT | O_TRUNC | O_WRONLY | o_binary,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
|
||||
else outhandle = open( output_filename.c_str(), O_CREAT | O_EXCL | O_WRONLY,
|
||||
else outhandle = open( output_filename.c_str(),
|
||||
O_CREAT | O_EXCL | O_WRONLY | o_binary,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
|
||||
if( outhandle < 0 )
|
||||
{
|
||||
|
@ -412,14 +419,13 @@ int do_decompress( LZ_Decoder * const decoder, const int inhandle,
|
|||
const int in_buffer_size = 65536, out_buffer_size = 8 * in_buffer_size;
|
||||
uint8_t in_buffer[in_buffer_size], out_buffer[out_buffer_size];
|
||||
|
||||
if( verbosity >= 1 ) pp();
|
||||
while( true )
|
||||
{
|
||||
int in_size = std::min( LZ_decompress_write_size( decoder ), in_buffer_size );
|
||||
if( in_size > 0 )
|
||||
{
|
||||
const int max_in_size = in_size;
|
||||
in_size = readblock( inhandle, (char *)in_buffer, max_in_size );
|
||||
in_size = readblock( inhandle, in_buffer, max_in_size );
|
||||
if( in_size != max_in_size && errno )
|
||||
{ pp(); show_error( "read error", errno ); return 1; }
|
||||
if( in_size == 0 ) LZ_decompress_finish( decoder );
|
||||
|
@ -458,7 +464,7 @@ int do_decompress( LZ_Decoder * const decoder, const int inhandle,
|
|||
}
|
||||
else if( out_size > 0 && outhandle >= 0 )
|
||||
{
|
||||
const int wr = writeblock( outhandle, (char *)out_buffer, out_size );
|
||||
const int wr = writeblock( outhandle, out_buffer, out_size );
|
||||
if( wr != out_size )
|
||||
{ pp(); show_error( "write error", errno ); return 1; }
|
||||
}
|
||||
|
@ -490,9 +496,12 @@ int decompress( const int inhandle, const Pretty_print & pp,
|
|||
}
|
||||
|
||||
|
||||
extern "C" void signal_handler( int ) throw()
|
||||
extern "C" void signal_handler( int sig ) throw()
|
||||
{
|
||||
show_error( "Control-C or similar caught, quitting." );
|
||||
if( !pthread_equal( pthread_self(), main_thread ) )
|
||||
kill( main_thread_pid, sig );
|
||||
if( sig != SIGUSR1 )
|
||||
show_error( "Control-C or similar caught, quitting." );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
|
||||
|
@ -502,6 +511,7 @@ void set_signals() throw()
|
|||
signal( SIGHUP, signal_handler );
|
||||
signal( SIGINT, signal_handler );
|
||||
signal( SIGTERM, signal_handler );
|
||||
signal( SIGUSR1, signal_handler );
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
@ -551,372 +561,16 @@ void internal_error( const char * msg )
|
|||
}
|
||||
|
||||
|
||||
/* Private stuff needed by fatal(). */
|
||||
static pthread_t main_thread;
|
||||
|
||||
static pid_t pid;
|
||||
|
||||
|
||||
/* Public utility variables and functions. */
|
||||
|
||||
/*
|
||||
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()
|
||||
{
|
||||
if( pthread_equal(pthread_self(), main_thread) )
|
||||
cleanup_and_fail( 1 );
|
||||
else
|
||||
{
|
||||
if( 0 == kill(pid, SIGUSR1) )
|
||||
pthread_exit(0);
|
||||
}
|
||||
_exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fail(const char *fmt, int err, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
/* Locking stderr should also protect strerror(). */
|
||||
flockfile(stderr);
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
|
||||
va_start(args, err);
|
||||
(void)vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
(void)fprintf(stderr, ": %s\n", strerror(err));
|
||||
funlockfile(stderr);
|
||||
/* Stream stderr is never fully buffered originally. */
|
||||
fatal();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xinit(Cond *cond)
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
int ret = pthread_mutexattr_init(&attr);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_mutexattr_init()", ret);
|
||||
}
|
||||
|
||||
ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_mutexattr_settype()", ret);
|
||||
}
|
||||
|
||||
ret = pthread_mutex_init(&cond->lock, &attr);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_mutex_init()", ret);
|
||||
}
|
||||
|
||||
ret = pthread_mutexattr_destroy(&attr);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_mutexattr_destroy()", ret);
|
||||
}
|
||||
|
||||
ret = pthread_cond_init(&cond->cond, 0);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_cond_init()", ret);
|
||||
}
|
||||
|
||||
cond->ccount = 0;
|
||||
cond->wcount = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xdestroy(Cond *cond)
|
||||
{
|
||||
int ret = pthread_cond_destroy(&cond->cond);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_cond_destroy()", ret);
|
||||
}
|
||||
|
||||
ret = pthread_mutex_destroy(&cond->lock);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_mutex_destroy()", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xlock(Cond *cond)
|
||||
{
|
||||
int ret = pthread_mutex_lock(&cond->lock);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_mutex_lock()", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xlock_pred(Cond *cond)
|
||||
{
|
||||
xlock(cond);
|
||||
++cond->ccount;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xunlock(Cond *cond)
|
||||
{
|
||||
int ret = pthread_mutex_unlock(&cond->lock);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_mutex_unlock()", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xwait(Cond *cond)
|
||||
{
|
||||
++cond->wcount;
|
||||
int ret = pthread_cond_wait(&cond->cond, &cond->lock);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_cond_wait()", ret);
|
||||
}
|
||||
++cond->ccount;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xsignal(Cond *cond)
|
||||
{
|
||||
int ret = pthread_cond_signal(&cond->cond);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_cond_signal()", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xbroadcast(Cond *cond)
|
||||
{
|
||||
int ret = pthread_cond_broadcast(&cond->cond);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_cond_broadcast()", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xcreate(pthread_t *thread, void *(*routine)(void *), void *arg)
|
||||
{
|
||||
int ret = pthread_create(thread, 0, routine, arg);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_create()", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xjoin(pthread_t thread)
|
||||
{
|
||||
int ret = pthread_join(thread, 0);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_join()", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xraise(int sig)
|
||||
{
|
||||
if( -1 == kill(pid, sig) ) {
|
||||
fail("kill()", errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Private stuff part 2. */
|
||||
|
||||
|
||||
static void
|
||||
xsigemptyset(sigset_t *set)
|
||||
{
|
||||
if( -1 == sigemptyset(set) ) {
|
||||
fail("sigemptyset()", errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xsigaddset(sigset_t *set, int signo)
|
||||
{
|
||||
if( -1 == sigaddset(set, signo) ) {
|
||||
fail("sigaddset()", errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xsigmask(int how, const sigset_t *set, sigset_t *oset)
|
||||
{
|
||||
int ret = pthread_sigmask(how, set, oset);
|
||||
if( ret != 0 ) {
|
||||
fail("pthread_sigmask()", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xsigaction(int sig, void (*handler)(int))
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_handler = handler;
|
||||
xsigemptyset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
|
||||
if( -1 == sigaction(sig, &act, 0) ) {
|
||||
fail("sigaction()", errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum Caught_sig { CS_INT = 1, CS_TERM, CS_USR1, CS_USR2 };
|
||||
|
||||
static volatile sig_atomic_t caught_sig;
|
||||
|
||||
|
||||
extern "C" void sighandler( int sig )
|
||||
{
|
||||
/* sig_atomic_t is nowhere required to be able to hold signal values. */
|
||||
switch( sig )
|
||||
{
|
||||
case SIGINT : caught_sig = CS_INT; break;
|
||||
case SIGTERM: caught_sig = CS_TERM; break;
|
||||
case SIGUSR1: caught_sig = CS_USR1; break;
|
||||
case SIGUSR2: caught_sig = CS_USR2; break;
|
||||
default: internal_error( "caught signal not in set" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void compress( const lzma_options & encoder_options, const int num_workers,
|
||||
int debug_level, int num_slots, int infd, int outfd,
|
||||
const Pretty_print & pp, const sigset_t *unblocked )
|
||||
{
|
||||
/*
|
||||
We could wait for signals with either sigwait() or sigsuspend(). SUSv2
|
||||
states about sigwait() that its effect on signal actions is unspecified.
|
||||
SUSv3 still claims the same.
|
||||
|
||||
The SUSv2 description of sigsuspend() talks about both the thread and the
|
||||
whole process being suspended until a signal arrives, although thread
|
||||
suspension seems much more likely from the wording. They note that they
|
||||
filed a clarification request for this. SUSv3 cleans this up and chooses
|
||||
thread suspension which was more logical anyway.
|
||||
|
||||
I favor sigsuspend() because I need to re-raise SIGTERM and SIGINT, and
|
||||
unspecified action behavior with sigwait() seems messy.
|
||||
|
||||
13-OCT-2009 lacos
|
||||
*/
|
||||
|
||||
if( verbosity >= 1 ) pp();
|
||||
|
||||
Muxer_arg muxer_arg;
|
||||
muxer_arg.dictionary_size = encoder_options.dictionary_size;
|
||||
muxer_arg.match_len_limit = encoder_options.match_len_limit;
|
||||
muxer_arg.num_workers = num_workers;
|
||||
muxer_arg.num_slots = num_slots;
|
||||
muxer_arg.debug_level = debug_level;
|
||||
muxer_arg.infd = infd;
|
||||
muxer_arg.outfd = outfd;
|
||||
|
||||
pthread_t muxer_thread;
|
||||
xcreate(&muxer_thread, muxer, &muxer_arg);
|
||||
|
||||
/* Unblock signals, wait for them, then block them again. */
|
||||
{
|
||||
int ret = sigsuspend(unblocked);
|
||||
assert(-1 == ret && EINTR == errno);
|
||||
}
|
||||
|
||||
switch( caught_sig ) {
|
||||
case CS_INT:
|
||||
case CS_TERM: // FIXME remove output file
|
||||
{
|
||||
int sig;
|
||||
sigset_t mask;
|
||||
|
||||
sig = (CS_INT == caught_sig) ? SIGINT : SIGTERM;
|
||||
/*
|
||||
We might have inherited a SIG_IGN from the parent, but that would
|
||||
make no sense here. 24-OCT-2009 lacos
|
||||
*/
|
||||
xsigaction(sig, SIG_DFL);
|
||||
xraise(sig);
|
||||
|
||||
xsigemptyset(&mask);
|
||||
xsigaddset(&mask, sig);
|
||||
xsigmask(SIG_UNBLOCK, &mask, 0);
|
||||
}
|
||||
/*
|
||||
We shouldn't reach this point, but if we do for some reason, fall
|
||||
through.
|
||||
*/
|
||||
|
||||
case CS_USR1:
|
||||
/* Error from a non-main thread via fatal(). */
|
||||
fatal();
|
||||
|
||||
case CS_USR2:
|
||||
/* Muxer thread joined other sub-threads and finished successfully. */
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
xjoin(muxer_thread);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sigs_mod(int block_n_catch, sigset_t *oset)
|
||||
{
|
||||
void (*handler)(int);
|
||||
|
||||
if( block_n_catch ) {
|
||||
sigset_t mask;
|
||||
|
||||
xsigemptyset(&mask);
|
||||
xsigaddset(&mask, SIGINT);
|
||||
xsigaddset(&mask, SIGTERM);
|
||||
xsigaddset(&mask, SIGUSR1);
|
||||
xsigaddset(&mask, SIGUSR2);
|
||||
xsigmask(SIG_BLOCK, &mask, oset);
|
||||
|
||||
handler = sighandler;
|
||||
}
|
||||
else {
|
||||
handler = SIG_DFL;
|
||||
}
|
||||
|
||||
xsigaction(SIGINT, handler);
|
||||
xsigaction(SIGTERM, handler);
|
||||
xsigaction(SIGUSR1, handler);
|
||||
xsigaction(SIGUSR2, handler);
|
||||
|
||||
if( !block_n_catch ) {
|
||||
xsigmask(SIG_SETMASK, oset, 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() { signal_handler( SIGUSR1 ); }
|
||||
|
||||
|
||||
// Returns the number of bytes really read.
|
||||
// If (returned value < size) and (errno == 0), means EOF was reached.
|
||||
//
|
||||
int readblock( const int fd, char * buf, const int size ) throw()
|
||||
int readblock( const int fd, uint8_t * buf, const int size ) throw()
|
||||
{
|
||||
int rest = size;
|
||||
errno = 0;
|
||||
|
@ -935,7 +589,7 @@ int readblock( const int fd, char * buf, const int size ) throw()
|
|||
// Returns the number of bytes really written.
|
||||
// If (returned value < size), it is always an error.
|
||||
//
|
||||
int writeblock( const int fd, const char * buf, const int size ) throw()
|
||||
int writeblock( const int fd, const uint8_t * buf, const int size ) throw()
|
||||
{
|
||||
int rest = size;
|
||||
errno = 0;
|
||||
|
@ -966,6 +620,7 @@ int main( const int argc, const char * argv[] )
|
|||
{ 1 << 24, 163 }, // -8
|
||||
{ 1 << 25, 273 } }; // -9
|
||||
lzma_options encoder_options = option_mapping[5]; // default = "-6"
|
||||
int data_size = 0;
|
||||
int debug_level = 0;
|
||||
int inhandle = -1;
|
||||
int num_workers = 0; // Start this many worker threads
|
||||
|
@ -977,22 +632,18 @@ int main( const int argc, const char * argv[] )
|
|||
std::string default_output_filename;
|
||||
std::vector< std::string > filenames;
|
||||
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" );
|
||||
|
||||
main_thread = pthread_self();
|
||||
pid = getpid();
|
||||
|
||||
xsigaction(SIGPIPE, SIG_IGN);
|
||||
xsigaction(SIGXFSZ, SIG_IGN);
|
||||
|
||||
const int slots_per_worker = 2;
|
||||
long max_workers = sysconf( _SC_THREAD_THREADS_MAX );
|
||||
if( max_workers < 1 || max_workers > INT_MAX / slots_per_worker )
|
||||
max_workers = INT_MAX / slots_per_worker;
|
||||
if( max_workers > INT_MAX / (int)sizeof( pthread_t ) )
|
||||
max_workers = INT_MAX / sizeof( pthread_t );
|
||||
if( max_workers > INT_MAX / (int)sizeof (pthread_t) )
|
||||
max_workers = INT_MAX / sizeof (pthread_t);
|
||||
|
||||
const Arg_parser::Option options[] =
|
||||
{
|
||||
|
@ -1006,6 +657,7 @@ int main( const int argc, const char * argv[] )
|
|||
{ '8', 0, Arg_parser::no },
|
||||
{ '9', "best", Arg_parser::no },
|
||||
{ 'b', "member-size", Arg_parser::yes },
|
||||
{ 'B', "data-size", Arg_parser::yes },
|
||||
{ 'c', "stdout", Arg_parser::no },
|
||||
{ 'd', "decompress", Arg_parser::no },
|
||||
{ 'D', "debug", Arg_parser::yes },
|
||||
|
@ -1040,6 +692,8 @@ int main( const int argc, const char * argv[] )
|
|||
case '7': case '8': case '9':
|
||||
encoder_options = option_mapping[code-'1']; break;
|
||||
case 'b': break;
|
||||
case 'B': data_size = getnum( arg, 0, 100000,
|
||||
2 * LZ_max_dictionary_size() ); break;
|
||||
case 'c': to_stdout = true; break;
|
||||
case 'd': program_mode = m_decompress; break;
|
||||
case 'D': debug_level = getnum( arg, 0, 0, 3 );
|
||||
|
@ -1048,8 +702,8 @@ int main( const int argc, const char * argv[] )
|
|||
case 'h': show_help(); return 0;
|
||||
case 'k': keep_input_files = true; break;
|
||||
case 'm': encoder_options.match_len_limit =
|
||||
getnum( arg, 0, LZ_min_match_len_limit(),
|
||||
LZ_max_match_len_limit() ); break;
|
||||
getnum( arg, 0, LZ_min_match_len_limit(),
|
||||
LZ_max_match_len_limit() ); break;
|
||||
case 'o': default_output_filename = arg; break;
|
||||
case 'n': num_workers = getnum( arg, 0, 1, max_workers ); break;
|
||||
case 'q': verbosity = -1; break;
|
||||
|
@ -1063,13 +717,16 @@ int main( const int argc, const char * argv[] )
|
|||
}
|
||||
}
|
||||
|
||||
if( data_size <= 0 )
|
||||
data_size = 2 * std::max( 65536, encoder_options.dictionary_size );
|
||||
|
||||
if( num_workers <= 0 )
|
||||
{
|
||||
long num_online = sysconf( _SC_NPROCESSORS_ONLN );
|
||||
if( num_online <= 0 ) num_online = 2;
|
||||
if( num_online <= 0 ) num_online = 1;
|
||||
num_workers = std::min( num_online, max_workers );
|
||||
}
|
||||
const int num_slots = num_workers * slots_per_worker;
|
||||
const int num_slots = std::max( 1, ( num_workers * slots_per_worker ) - 1 );
|
||||
|
||||
bool filenames_given = false;
|
||||
for( ; argind < parser.arguments(); ++argind )
|
||||
|
@ -1079,7 +736,9 @@ int main( const int argc, const char * argv[] )
|
|||
}
|
||||
|
||||
if( filenames.empty() ) filenames.push_back("-");
|
||||
if( filenames_given && program_mode != m_compress ) set_signals();
|
||||
if( !to_stdout && program_mode != m_test &&
|
||||
( filenames_given || default_output_filename.size() ) )
|
||||
set_signals();
|
||||
|
||||
Pretty_print pp( filenames );
|
||||
if( program_mode == m_test )
|
||||
|
@ -1144,14 +803,12 @@ int main( const int argc, const char * argv[] )
|
|||
delete_output_on_interrupt = true;
|
||||
const struct stat * const in_statsp = input_filename.size() ? &in_stats : 0;
|
||||
pp.set_name( input_filename );
|
||||
if( verbosity >= 1 ) pp();
|
||||
int tmp = 0;
|
||||
if( program_mode == m_compress )
|
||||
{
|
||||
sigset_t unblocked;
|
||||
sigs_mod(1, &unblocked);
|
||||
compress( encoder_options, num_workers, debug_level, num_slots, inhandle, outhandle, pp, &unblocked );
|
||||
sigs_mod(0, &unblocked);
|
||||
}
|
||||
tmp = compress( data_size, encoder_options.dictionary_size,
|
||||
encoder_options.match_len_limit, num_workers,
|
||||
num_slots, inhandle, outhandle, debug_level );
|
||||
else
|
||||
tmp = decompress( inhandle, pp, program_mode == m_test );
|
||||
if( tmp > retval ) retval = tmp;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue