aboutsummaryrefslogtreecommitdiff
path: root/lib/libarchive/archive_write_open_file.c
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@FreeBSD.org>2006-11-13 00:26:45 +0000
committerTim Kientzle <kientzle@FreeBSD.org>2006-11-13 00:26:45 +0000
commitb2ba9b4e04008ad024e6416132c27cc7b15a8ffb (patch)
treeed97538fdbb50cf64986e9c6b394dcd876243405 /lib/libarchive/archive_write_open_file.c
parentc3b11d8213836d881658470b203b4944c3e17a04 (diff)
downloadsrc-b2ba9b4e04008ad024e6416132c27cc7b15a8ffb.tar.gz
src-b2ba9b4e04008ad024e6416132c27cc7b15a8ffb.zip
Minor cleanup of the standard read/write I/O modules:
* Use public API, don't access struct archive directly. (People should be able to copy these into their applications as a template for custom I/O callbacks.) * Set "skip" only for regular files. ("skip" allows the low-level library to catch attempts to add an archive to itself or extract over itself.) * Simplify the write_open functions by just calling stat() at the beginning. Somehow, these functions had acquired some complex logic that tried to avoid the stat() call but never succeeded. MFC after: 10 days
Notes
Notes: svn path=/head/; revision=164233
Diffstat (limited to 'lib/libarchive/archive_write_open_file.c')
-rw-r--r--lib/libarchive/archive_write_open_file.c65
1 files changed, 26 insertions, 39 deletions
diff --git a/lib/libarchive/archive_write_open_file.c b/lib/libarchive/archive_write_open_file.c
index 8cf59953ccd0..a464a0130355 100644
--- a/lib/libarchive/archive_write_open_file.c
+++ b/lib/libarchive/archive_write_open_file.c
@@ -88,53 +88,42 @@ file_open(struct archive *a, void *client_data)
{
int flags;
struct write_file_data *mine;
- struct stat st, *pst;
+ struct stat st;
- pst = NULL;
mine = (struct write_file_data *)client_data;
flags = O_WRONLY | O_CREAT | O_TRUNC;
+ /*
+ * Open the file.
+ */
if (mine->filename[0] != '\0') {
mine->fd = open(mine->filename, flags, 0666);
-
- /*
- * If client hasn't explicitly set the last block
- * handling, then set it here: If the output is a
- * block or character device, pad the last block,
- * otherwise leave it unpadded.
- */
- if (mine->fd >= 0 && a->bytes_in_last_block < 0) {
- if (fstat(mine->fd, &st) == 0) {
- pst = &st;
- if (S_ISCHR(st.st_mode) ||
- S_ISBLK(st.st_mode) ||
- S_ISFIFO(st.st_mode))
- /* Pad last block. */
- archive_write_set_bytes_in_last_block(a, 0);
- else
- /* Don't pad last block. */
- archive_write_set_bytes_in_last_block(a, 1);
- }
+ if (mine->fd < 0) {
+ archive_set_error(a, errno, "Failed to open '%s'",
+ mine->filename);
+ return (ARCHIVE_FATAL);
}
} else {
+ /*
+ * NULL filename is stdout.
+ */
mine->fd = 1;
- if (a->bytes_in_last_block < 0) /* Still default? */
- /* Last block will be fully padded. */
+ /* By default, pad archive when writing to stdout. */
+ if (archive_write_get_bytes_in_last_block(a) < 0)
archive_write_set_bytes_in_last_block(a, 0);
}
- if (mine->fd < 0) {
- archive_set_error(a, errno, "Failed to open '%s'",
- mine->filename);
- return (ARCHIVE_FATAL);
- }
-
- if (pst == NULL && fstat(mine->fd, &st) == 0)
- pst = &st;
- if (pst == NULL) {
- archive_set_error(a, errno, "Couldn't stat '%s'",
- mine->filename);
- return (ARCHIVE_FATAL);
+ /*
+ * Set up default last block handling.
+ */
+ if (archive_write_get_bytes_in_last_block(a) < 0) {
+ if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
+ S_ISFIFO(st.st_mode))
+ /* Pad last block when writing to device or FIFO. */
+ archive_write_set_bytes_in_last_block(a, 0);
+ else
+ /* Don't pad last block otherwise. */
+ archive_write_set_bytes_in_last_block(a, 1);
}
/*
@@ -142,10 +131,8 @@ file_open(struct archive *a, void *client_data)
* itself. If it's a device file, it's okay to add the device
* entry to the output archive.
*/
- if (S_ISREG(pst->st_mode)) {
- a->skip_file_dev = pst->st_dev;
- a->skip_file_ino = pst->st_ino;
- }
+ if (S_ISREG(st.st_mode))
+ archive_write_set_skip_file(a, st.st_dev, st.st_ino);
return (ARCHIVE_OK);
}