(write_archive_buffer): New function.

(child_open_for_compress, flush_write, flush_read): Use it to write
buffers.
(open_archive): Report error if fstat of archive fails.
Improve efficiency of check for /dev/null.
Also, fix some corner cases with remote archives and /dev/null checking.
(close_archive): Test for input fifo only if not remote.
Truncate output archive only if it's not remote.
This commit is contained in:
Paul Eggert
1999-06-25 23:28:08 +00:00
parent cb562d7194
commit ee734033e8

View File

@@ -319,6 +319,24 @@ is_regular_file (const char *name)
return 0;
}
static ssize_t
write_archive_buffer (void)
{
ssize_t status;
ssize_t written = 0;
while (0 <= (status = rmtwrite (archive, record_start->buffer + written,
record_size - written)))
{
written += status;
if (written == record_size
|| _isrmt (archive) || ! S_ISFIFO (archive_stat.st_mode))
break;
}
return written ? written : status;
}
/*-------------------------------------------------------.
| Set ARCHIVE for writing, then compressing an archive. |
`-------------------------------------------------------*/
@@ -460,7 +478,7 @@ child_open_for_compress (void)
if (length > 0)
{
memset (record_start->buffer + length, 0, record_size - length);
status = rmtwrite (archive, record_start->buffer, record_size);
status = write_archive_buffer ();
if (status != record_size)
write_error (status);
}
@@ -469,7 +487,7 @@ child_open_for_compress (void)
break;
}
status = rmtwrite (archive, record_start->buffer, record_size);
status = write_archive_buffer ();
if (status != record_size)
write_error (status);
}
@@ -784,7 +802,8 @@ open_archive (enum access_mode access)
break;
}
if (archive < 0)
if (archive < 0
|| (! _isrmt (archive) && fstat (archive, &archive_stat) < 0))
{
int saved_errno = errno;
@@ -796,15 +815,17 @@ open_archive (enum access_mode access)
#if !MSDOS
fstat (archive, &archive_stat);
/* Detect if outputting to "/dev/null". */
{
static char const dev_null[] = "/dev/null";
struct stat dev_null_stat;
stat ("/dev/null", &dev_null_stat);
dev_null_output = (S_ISCHR (archive_stat.st_mode)
&& archive_stat.st_rdev == dev_null_stat.st_rdev);
dev_null_output =
(strcmp (archive_name_array[0], dev_null) == 0
|| (! _isrmt (archive)
&& stat (dev_null, &dev_null_stat) == 0
&& S_ISCHR (archive_stat.st_mode)
&& archive_stat.st_rdev == dev_null_stat.st_rdev));
}
if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
@@ -812,6 +833,8 @@ open_archive (enum access_mode access)
ar_dev = archive_stat.st_dev;
ar_ino = archive_stat.st_ino;
}
else
ar_dev = 0;
#endif /* not MSDOS */
@@ -884,7 +907,7 @@ flush_write (void)
else if (dev_null_output)
status = record_size;
else
status = rmtwrite (archive, record_start->buffer, record_size);
status = write_archive_buffer ();
if (status != record_size && !multi_volume_option)
write_error (status);
else if (totals_option)
@@ -984,7 +1007,7 @@ flush_write (void)
record_start--;
}
status = rmtwrite (archive, record_start->buffer, record_size);
status = write_archive_buffer ();
if (status != record_size)
write_error (status);
else if (totals_option)
@@ -1089,7 +1112,7 @@ flush_read (void)
if (write_archive_to_stdout && record_start_block != 0)
{
status = rmtwrite (1, record_start->buffer, record_size);
status = write_archive_buffer ();
if (status != record_size)
write_error (status);
}
@@ -1375,22 +1398,25 @@ close_archive (void)
might become clever enough to just stop working, once there is no more
work to do, we might have to revise this area in such time. */
if (access_mode == ACCESS_READ && S_ISFIFO (archive_stat.st_mode) &&
!ending_file_option)
if (access_mode == ACCESS_READ
&& ! _isrmt (archive)
&& S_ISFIFO (archive_stat.st_mode)
&& ! ending_file_option)
while (rmtread (archive, record_start->buffer, record_size) > 0)
continue;
#endif
if (subcommand_option == DELETE_SUBCOMMAND)
if (! _isrmt (archive) && subcommand_option == DELETE_SUBCOMMAND)
{
off_t pos;
pos = rmtlseek (archive, (off_t) 0, 1);
#if MSDOS
rmtwrite (archive, "", 0);
int status = write (archive, "", 0);
#else
ftruncate (archive, pos);
off_t pos = lseek (archive, (off_t) 0, 1);
int status = pos == -1 ? -1 : ftruncate (archive, pos);
#endif
if (status != 0)
WARN ((0, errno, _("WARNING: Cannot truncate %s"),
*archive_name_cursor));
}
if (verify_option)
verify_volume ();