diff options
Diffstat (limited to '')
-rw-r--r-- | main.c | 53 |
1 files changed, 31 insertions, 22 deletions
@@ -1,4 +1,4 @@ -/* Xlunzip - Test tool for the lunzip linux module +/* Xlunzip - Test tool for the lzip_decompress linux module Copyright (C) 2016-2018 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify @@ -79,8 +79,10 @@ const struct { const char * from; const char * to; } known_extensions[] = { { ".tlz", ".tar" }, { 0, 0 } }; -char * output_filename = 0; int infd = -1; /* needed by the fill function */ +/* Variables used in signal handler context. + They are not declared volatile because the handler never returns. */ +char * output_filename = 0; int outfd = -1; bool delete_output_on_interrupt = false; @@ -283,7 +285,7 @@ static int open_instream( const char * const name, struct stat * const in_statsp fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n", program_name, name, ( can_read && !no_ofile ) ? - ",\n and '--stdout' was not specified" : "" ); + ",\n and '--stdout' was not specified" : "" ); close( infd ); infd = -1; } @@ -315,8 +317,17 @@ static bool open_outstream( const bool force, const bool from_stdin ) } +static void set_signals( void (*action)(int) ) + { + signal( SIGHUP, action ); + signal( SIGINT, action ); + signal( SIGTERM, action ); + } + + void cleanup_and_fail( const int retval ) { + set_signals( SIG_IGN ); /* ignore signals */ if( delete_output_on_interrupt ) { delete_output_on_interrupt = false; @@ -331,6 +342,14 @@ void cleanup_and_fail( const int retval ) } +void signal_handler( int sig ) + { + if( sig ) {} /* keep compiler happy */ + show_error( "Control-C or similar caught, quitting.", 0, false ); + cleanup_and_fail( 1 ); + } + + /* Set permissions, owner and times. */ static void close_and_set_permissions( const struct stat * const in_statsp ) { @@ -416,7 +435,7 @@ long flush( void * buf, unsigned long size ) return sz; } -const char * global_name; +const char * global_name; /* copy of filename for 'error' */ static void error(char *x) { show_file_error( global_name, x, 0 ); } @@ -471,22 +490,6 @@ static int decompress( struct Pretty_print * const pp, const long cl_insize, } -void signal_handler( int sig ) - { - if( sig ) {} /* keep compiler happy */ - show_error( "Control-C or similar caught, quitting.", 0, false ); - cleanup_and_fail( 1 ); - } - - -static void set_signals( void ) - { - signal( SIGHUP, signal_handler ); - signal( SIGINT, signal_handler ); - signal( SIGTERM, signal_handler ); - } - - void show_error( const char * const msg, const int errcode, const bool help ) { if( verbosity < 0 ) return; @@ -619,7 +622,7 @@ int main( const int argc, const char * const argv[] ) if( !to_stdout && !testing && ( filenames_given || default_output_filename[0] ) ) - set_signals(); + set_signals( signal_handler ); Pp_init( &pp, filenames, num_filenames ); @@ -690,6 +693,13 @@ int main( const int argc, const char * const argv[] ) tmp = decompress_in_place( infd, &pp, testing ); else tmp = decompress( &pp, cl_insize, cl_outsize, nofill, noflush, testing ); + if( close( infd ) != 0 ) + { + show_error( input_filename[0] ? "Error closing input file" : + "Error closing stdin", errno, false ); + if( tmp < 1 ) tmp = 1; + } + infd = -1; if( tmp > retval ) retval = tmp; if( tmp ) { if( !testing ) cleanup_and_fail( retval ); @@ -699,7 +709,6 @@ int main( const int argc, const char * const argv[] ) close_and_set_permissions( in_statsp ); if( input_filename[0] ) { - close( infd ); infd = -1; if( !keep_input_files && !to_stdout && !testing ) remove( input_filename ); } |