From d7d5dfbcf513f94115990102c56eccf177417889 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 8 Nov 2015 05:26:56 +0100 Subject: Merging upstream version 1.1~rc2. Signed-off-by: Daniel Baumann --- zcmp.cc | 60 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 27 deletions(-) (limited to 'zcmp.cc') diff --git a/zcmp.cc b/zcmp.cc index 0e5b781..48731a3 100644 --- a/zcmp.cc +++ b/zcmp.cc @@ -37,6 +37,7 @@ #include "arg_parser.h" #include "zutils.h" +#include "rc.h" #if CHAR_BIT != 8 #error "Environments where CHAR_BIT != 8 are not supported." @@ -57,19 +58,19 @@ void show_help() std::printf( "Zcmp compares two files (\"-\" means standard input), and if they\n" "differ, tells the first byte and line number where they differ. Bytes\n" "and lines are numbered starting with 1. If any given file is compressed,\n" - "its uncompressed content is used. Compressed files are uncompressed on\n" + "its decompressed content is used. Compressed files are decompressed on\n" "the fly; no temporary files are created.\n" "\nThe supported formats are bzip2, gzip, lzip and xz.\n" "\nUsage: zcmp [options] file1 [file2]\n" "\nCompares to . If is omitted zcmp tries the\n" "following:\n" - "If is compressed, compares to the file with the\n" - "corresponding decompressed file name (removes the extension from\n" - ").\n" - "If is not compressed, compares to the uncompressed\n" - "contents of .[lz|bz2|gz|xz] (the first one that is found).\n" - "If no suitable file is found, compares to data read from\n" - "standard input.\n" + "\n 1. If is compressed, compares its decompressed contents with\n" + " the corresponding uncompressed file (the name of with the\n" + " extension removed).\n" + "\n 2. If is uncompressed, compares it with the decompressed\n" + " contents of .[lz|bz2|gz|xz] (the first one that is found).\n" + "\n 3. If no suitable file is found, compares with data read from\n" + " standard input.\n" "\nExit status is 0 if inputs are identical, 1 if different, 2 if trouble.\n" "\nOptions:\n" " -h, --help display this help and exit\n" @@ -79,9 +80,14 @@ void show_help() " -i, --ignore-initial=[,] ignore differences in the first bytes\n" " -l, --list list position, value of all differing bytes\n" " -n, --bytes= compare at most bytes\n" + " -N, --no-rcfile don't read runtime configuration file\n" " -q, --quiet suppress all messages\n" " -s, --silent (same as --quiet)\n" " -v, --verbose verbose mode (same as --list)\n" + " --bz2= set compressor and options for bzip2 format\n" + " --gz= set compressor and options for gzip format\n" + " --lz= set compressor and options for lzip format\n" + " --xz= set compressor and options for xz format\n" "Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n" "Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n" ); show_help_addr(); @@ -310,7 +316,7 @@ int cmp( const long long max_size, const int infd[2], int main( const int argc, const char * const argv[] ) { - enum { format_opt = 256 }; + enum { format_opt = 256, bz2_opt, gz_opt, lz_opt, xz_opt }; // number of initial bytes ignored for each file long long ignore_initial[2] = { 0, 0 }; long long max_size = -1; // < 0 means unlimited size @@ -326,17 +332,24 @@ int main( const int argc, const char * const argv[] ) { 'i', "ignore-initial", Arg_parser::yes }, { 'l', "list", Arg_parser::no }, { 'n', "bytes", Arg_parser::yes }, + { 'N', "no-rcfile", Arg_parser::no }, { 'q', "quiet", Arg_parser::no }, { 's', "silent", Arg_parser::no }, { 'v', "verbose", Arg_parser::no }, { 'V', "version", Arg_parser::no }, { format_opt, "format", Arg_parser::yes }, + { bz2_opt, "bz2", Arg_parser::yes }, + { gz_opt, "gz", Arg_parser::yes }, + { lz_opt, "lz", Arg_parser::yes }, + { xz_opt, "xz", Arg_parser::yes }, { 0 , 0, Arg_parser::no } }; const Arg_parser parser( argc, argv, options ); if( parser.error().size() ) // bad option { show_error( parser.error().c_str(), 0, true ); return 2; } + maybe_process_config_file( parser ); + int argind = 0; for( ; argind < parser.arguments(); ++argind ) { @@ -350,11 +363,16 @@ int main( const int argc, const char * const argv[] ) case 'i': parse_ignore_initial( arg, ignore_initial ); break; case 'l': verbosity = 1; break; case 'n': max_size = getnum( arg ); break; + case 'N': break; case 'q': case 's': verbosity = -1; break; case 'v': verbosity = 1; break; case 'V': show_version( "Zcmp" ); return 0; - case format_opt: get_format_types( arg, format_types ); break; + case format_opt: parse_format_types( arg, format_types ); break; + case bz2_opt: parse_compressor( arg, fmt_bz2 ); break; + case gz_opt: parse_compressor( arg, fmt_gz ); break; + case lz_opt: parse_compressor( arg, fmt_lz ); break; + case xz_opt: parse_compressor( arg, fmt_xz ); break; default : internal_error( "uncaught option" ); } } // end process options @@ -405,9 +423,9 @@ int main( const int argc, const char * const argv[] ) int old_infd[2]; // copy of file descriptors of the two files old_infd[0] = infd[0]; old_infd[1] = infd[1]; - pid_t pid[2]; - if( !set_data_feeder( &infd[0], &pid[0], format_types[0] ) || - !set_data_feeder( &infd[1], &pid[1], format_types[1] ) ) + Children children[2]; + if( !set_data_feeder( &infd[0], children[0], format_types[0] ) || + !set_data_feeder( &infd[1], children[1], format_types[1] ) ) return 2; for( int i = 0; i < 2; ++i ) @@ -419,20 +437,8 @@ int main( const int argc, const char * const argv[] ) int retval = cmp( max_size, infd, filenames, print_bytes ); - if( retval != 0 || max_size >= 0 ) - { - for( int i = 0; i < 2; ++i ) - if( pid[i] ) - { - const int tmp = child_status( pid[i], "data feeder" ); - if( tmp < 0 ) kill( pid[i], SIGTERM ); // child not terminated - else if( tmp != 0 ) retval = 2; // child status != 0 - } - } - else - if( ( pid[0] && wait_for_child( pid[0], "data feeder" ) != 0 ) || - ( pid[1] && wait_for_child( pid[1], "data feeder" ) != 0 ) ) - retval = 2; + for( int i = 0; i < 2; ++i ) + if( !good_status( children[i], retval == 0 && max_size < 0 ) ) retval = 2; for( int i = 0; i < 2; ++i ) { -- cgit v1.2.3