summaryrefslogtreecommitdiffstats
path: root/create.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2019-02-24 20:21:12 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2019-02-24 20:21:12 +0000
commit1d0f658132f3be0c133ecd8bec347ad426244f40 (patch)
tree565d4821fbbc10694ad552fdb77e270d8eeb2a1e /create.cc
parentReleasing debian version 0.11-1. (diff)
downloadtarlz-1d0f658132f3be0c133ecd8bec347ad426244f40.tar.xz
tarlz-1d0f658132f3be0c133ecd8bec347ad426244f40.zip
Merging upstream version 0.12.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'create.cc')
-rw-r--r--create.cc75
1 files changed, 32 insertions, 43 deletions
diff --git a/create.cc b/create.cc
index 1cc7cb3..0eaa183 100644
--- a/create.cc
+++ b/create.cc
@@ -25,6 +25,7 @@
#include <cstring>
#include <string>
#include <vector>
+#include <pthread.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/stat.h>
@@ -91,14 +92,15 @@ bool option_C_after_relative_filename( const Arg_parser & parser )
}
-int seek_read( const int fd, uint8_t * const buf, const int size,
- const long long pos )
+bool writeblock_wrapper( const int outfd, const uint8_t * const buffer,
+ const int size )
{
- if( lseek( fd, pos, SEEK_SET ) == pos )
- return readblock( fd, buf, size );
- return 0;
+ if( writeblock( outfd, buffer, size ) != size )
+ { show_file_error( archive_namep, "Write error", errno ); return false; }
+ return true;
}
+
// infd and outfd can refer to the same file if copying to a lower file
// position or if source and destination blocks don't overlap.
// max_size < 0 means no size limit.
@@ -120,10 +122,7 @@ bool copy_file( const int infd, const int outfd, const long long max_size = -1 )
{ show_error( "Error reading input file", errno ); error = true; break; }
if( rd > 0 )
{
- const int wr = writeblock( outfd, buffer, rd );
- if( wr != rd )
- { show_error( "Error writing output file", errno );
- error = true; break; }
+ if( !writeblock_wrapper( outfd, buffer, rd ) ) { error = true; break; }
copied_size += rd;
}
if( rd < size ) break; // EOF
@@ -193,7 +192,7 @@ bool archive_write( const uint8_t * const buf, const int size )
if( size <= 0 && flushed ) return true;
flushed = ( size <= 0 );
if( !encoder ) // uncompressed
- return ( writeblock( goutfd, buf, size ) == size );
+ return writeblock_wrapper( goutfd, buf, size );
enum { obuf_size = 65536 };
uint8_t obuf[obuf_size];
int sz = 0;
@@ -207,7 +206,7 @@ bool archive_write( const uint8_t * const buf, const int size )
const int rd = LZ_compress_read( encoder, obuf, obuf_size );
if( rd < 0 ) internal_error( "library error (LZ_compress_read)." );
if( rd == 0 && sz >= size ) break;
- if( writeblock( goutfd, obuf, rd ) != rd ) return false;
+ if( !writeblock_wrapper( goutfd, obuf, rd ) ) return false;
}
if( LZ_compress_finished( encoder ) == 1 &&
LZ_compress_restart_member( encoder, LLONG_MAX ) < 0 )
@@ -270,13 +269,10 @@ int add_member( const char * const filename, const struct stat *,
if( encoder && solidity == bsolid &&
block_is_full( extended, file_size, partial_data_size ) &&
- !archive_write( 0, 0 ) )
- { show_error( "Error flushing encoder", errno ); return 1; }
+ !archive_write( 0, 0 ) ) return 1;
- if( !write_extended( extended ) )
- { show_error( "Error writing extended header", errno ); return 1; }
- if( !archive_write( header, header_size ) )
- { show_error( "Error writing ustar header", errno ); return 1; }
+ if( !write_extended( extended ) || !archive_write( header, header_size ) )
+ return 1;
if( file_size )
{
enum { bufsize = 32 * header_size };
@@ -301,15 +297,12 @@ int add_member( const char * const filename, const struct stat *,
{ const int padding = header_size - rem;
std::memset( buf + size, 0, padding ); size += padding; }
}
- if( !archive_write( buf, size ) )
- { show_error( "Error writing archive", errno ); close( infd );
- return 1; }
+ if( !archive_write( buf, size ) ) { close( infd ); return 1; }
}
if( close( infd ) != 0 )
{ show_file_error( filename, "Error closing file", errno ); return 1; }
}
- if( encoder && solidity == no_solid && !archive_write( 0, 0 ) )
- { show_error( "Error flushing encoder", errno ); return 1; }
+ if( encoder && solidity == no_solid && !archive_write( 0, 0 ) ) return 1;
if( verbosity >= 1 ) std::fprintf( stderr, "%s\n", filename );
return 0;
}
@@ -378,7 +371,7 @@ bool fill_headers( const char * const filename, Extended & extended,
set_error_status( 1 ); return false; }
print_octal( header + uid_o, uid_l - 1, uid );
print_octal( header + gid_o, gid_l - 1, gid );
- const long long mtime = st.st_mtime; // shut up gcc
+ const long long mtime = st.st_mtime; // shut up gcc about time_t
if( mtime < 0 || mtime >= 1LL << 33 )
{ show_file_error( filename, "mtime is out of ustar range [0, 8_589_934_591]." );
set_error_status( 1 ); return false; }
@@ -413,28 +406,28 @@ bool fill_headers( const char * const filename, Extended & extended,
else if( S_ISCHR( mode ) || S_ISBLK( mode ) )
{
typeflag = S_ISCHR( mode ) ? tf_chardev : tf_blockdev;
- if( major( st.st_dev ) >= 2 << 20 || minor( st.st_dev ) >= 2 << 20 )
+ if( major( st.st_rdev ) >= 2 << 20 || minor( st.st_rdev ) >= 2 << 20 )
{ show_file_error( filename, "devmajor or devminor is larger than 2_097_151." );
set_error_status( 1 ); return false; }
- print_octal( header + devmajor_o, devmajor_l - 1, major( st.st_dev ) );
- print_octal( header + devminor_o, devminor_l - 1, minor( st.st_dev ) );
+ print_octal( header + devmajor_o, devmajor_l - 1, major( st.st_rdev ) );
+ print_octal( header + devminor_o, devminor_l - 1, minor( st.st_rdev ) );
}
else if( S_ISFIFO( mode ) ) typeflag = tf_fifo;
else { show_file_error( filename, "Unknown file type." );
set_error_status( 2 ); return false; }
header[typeflag_o] = typeflag;
- errno = 0;
+// errno = 0;
const struct passwd * const pw = getpwuid( uid );
if( pw && pw->pw_name )
std::strncpy( (char *)header + uname_o, pw->pw_name, uname_l - 1 );
- else { show_file_error( filename, "Can't read user name from database", errno );
- set_error_status( 1 ); }
- errno = 0;
+/* else { show_file_error( filename, "Can't read user name from database", errno );
+ set_error_status( 1 ); } */ // numerical only
+// errno = 0;
const struct group * const gr = getgrgid( gid );
if( gr && gr->gr_name )
std::strncpy( (char *)header + gname_o, gr->gr_name, gname_l - 1 );
- else { show_file_error( filename, "Can't read group name from database", errno );
- set_error_status( 1 ); }
+/* else { show_file_error( filename, "Can't read group name from database", errno );
+ set_error_status( 1 ); } */ // numerical only
if( file_size >= 1ULL << 33 )
{ extended.file_size( file_size ); force_extended_name = true; }
else print_octal( header + size_o, size_l - 1, file_size );
@@ -469,10 +462,11 @@ void set_error_status( const int retval )
xunlock( &mutex );
}
-int final_exit_status( int retval )
+int final_exit_status( int retval, const bool show_msg )
{
if( !retval && error_status )
- { show_error( "Exiting with failure status due to previous errors." );
+ { if( show_msg )
+ show_error( "Exiting with failure status due to previous errors." );
retval = error_status; }
return retval;
}
@@ -511,9 +505,7 @@ int concatenate( const std::string & archive_name, const Arg_parser & parser,
if( parser.argument( i ).empty() ) continue; // skip empty names
const char * const filename = parser.argument( i ).c_str();
const int infd = open_instream( filename );
- if( infd < 0 )
- { show_file_error( filename, "Can't open input file", errno );
- retval = 1; break; }
+ if( infd < 0 ) { retval = 1; break; }
if( !check_appendable( infd, false ) )
{ show_file_error( filename, "Not an appendable tar.lz archive." );
close( infd ); retval = 2; break; }
@@ -640,7 +632,7 @@ int encode( const std::string & archive_name, const Arg_parser & parser,
else if( ( retval = nftw( filename, add_member, 16, FTW_PHYS ) ) != 0 )
break; // write error
else if( encoder && solidity == dsolid && !archive_write( 0, 0 ) )
- { show_error( "Error flushing encoder", errno ); retval = 1; }
+ retval = 1;
}
if( !retval ) // write End-Of-Archive records
@@ -650,12 +642,9 @@ int encode( const std::string & archive_name, const Arg_parser & parser,
std::memset( buf, 0, bufsize );
if( encoder &&
( solidity == asolid || ( solidity == bsolid && partial_data_size ) ) &&
- !archive_write( 0, 0 ) )
- { show_error( "Error flushing encoder", errno ); retval = 1; }
+ !archive_write( 0, 0 ) ) retval = 1; // flush encoder
else if( !archive_write( buf, bufsize ) ||
- ( encoder && !archive_write( 0, 0 ) ) ) // flush encoder
- { show_error( "Error writing end-of-archive blocks", errno );
- retval = 1; }
+ ( encoder && !archive_write( 0, 0 ) ) ) retval = 1;
}
if( encoder && LZ_compress_close( encoder ) < 0 )
{ show_error( "LZ_compress_close failed." ); retval = 1; }