diff options
Diffstat (limited to 'create.cc')
-rw-r--r-- | create.cc | 75 |
1 files changed, 32 insertions, 43 deletions
@@ -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; } |