summaryrefslogtreecommitdiffstats
path: root/main.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--main.cc45
1 files changed, 30 insertions, 15 deletions
diff --git a/main.cc b/main.cc
index 25ff394..976bbd0 100644
--- a/main.cc
+++ b/main.cc
@@ -67,15 +67,15 @@ enum Mode { m_none, m_append, m_concatenate, m_create, m_extract, m_list };
void show_help( const long num_online )
{
- std::printf( "Tarlz is a combined implementation of the tar archiver and the lzip\n"
- "compressor. By default tarlz creates, lists and extracts archives in a\n"
- "simplified posix pax format compressed with lzip on a per file basis. Each\n"
- "tar member is compressed in its own lzip member, as well as the end-of-file\n"
- "blocks. This method adds an indexed lzip layer on top of the tar archive,\n"
- "making it possible to decode the archive safely in parallel. The resulting\n"
- "multimember tar.lz archive is fully backward compatible with standard tar\n"
- "tools like GNU tar, which treat it like any other tar.lz archive. Tarlz can\n"
- "append files to the end of such compressed archives.\n"
+ std::printf( "Tarlz is a massively parallel (multi-threaded) combined implementation of\n"
+ "the tar archiver and the lzip compressor. Tarlz creates, lists and extracts\n"
+ "archives in a simplified posix pax format compressed with lzip, keeping the\n"
+ "alignment between tar members and lzip members. This method adds an indexed\n"
+ "lzip layer on top of the tar archive, making it possible to decode the\n"
+ "archive safely in parallel. The resulting multimember tar.lz archive is\n"
+ "fully backward compatible with standard tar tools like GNU tar, which treat\n"
+ "it like any other tar.lz archive. Tarlz can append files to the end of such\n"
+ "compressed archives.\n"
"\nThe tarlz file format is a safe posix-style backup format. In case of\n"
"corruption, tarlz can extract all the undamaged members from the tar.lz\n"
"archive, skipping over the damaged members, just like the standard\n"
@@ -91,7 +91,7 @@ void show_help( const long num_online )
" -c, --create create a new archive\n"
" -C, --directory=<dir> change to directory <dir>\n"
" -f, --file=<archive> use archive file <archive>\n"
- " -n, --threads=<n> set number of decompression threads [%ld]\n"
+ " -n, --threads=<n> set number of (de)compression threads [%ld]\n"
" -q, --quiet suppress all messages\n"
" -r, --append append files to the end of an archive\n"
" -t, --list list the contents of an archive\n"
@@ -99,9 +99,9 @@ void show_help( const long num_online )
" -x, --extract extract files from an archive\n"
" -0 .. -9 set compression level [default 6]\n"
" --asolid create solidly compressed appendable archive\n"
- " --bsolid create per-data-block compressed archive\n"
- " --dsolid create per-directory compressed archive\n"
- " --no-solid create per-file compressed archive (default)\n"
+ " --bsolid create per block compressed archive (default)\n"
+ " --dsolid create per directory compressed archive\n"
+ " --no-solid create per file compressed archive\n"
" --solid create solidly compressed archive\n"
" --anonymous equivalent to '--owner=root --group=root'\n"
" --owner=<owner> use <owner> name/ID for files added\n"
@@ -239,6 +239,20 @@ int open_outstream( const std::string & name, const bool create )
}
+// 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
+ std::exit( retval );
+ }
+
+
void show_error( const char * const msg, const int errcode, const bool help )
{
if( verbosity < 0 ) return;
@@ -342,7 +356,8 @@ int main( const int argc, const char * const argv[] )
for( int argind = 0; argind < parser.arguments(); ++argind )
{
const int code = parser.code( argind );
- if( !code ) { ++filenames; continue; } // skip non-options
+ if( !code ) // skip non-options
+ { if( parser.argument( argind ).size() ) ++filenames; continue; }
const std::string & sarg = parser.argument( argind );
const char * const arg = sarg.c_str();
switch( code )
@@ -394,7 +409,7 @@ int main( const int argc, const char * const argv[] )
case m_none: show_error( "Missing operation.", 0, true ); return 2;
case m_append:
case m_create: return encode( archive_name, parser, filenames, level,
- program_mode == m_append );
+ num_workers, debug_level, program_mode == m_append );
case m_concatenate: return concatenate( archive_name, parser, filenames );
case m_extract:
case m_list: return decode( archive_name, parser, filenames, num_workers,