summaryrefslogtreecommitdiff
path: root/lib/common/data_reader_dump.c
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-11-06 10:44:26 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-11-06 11:10:58 +0100
commit3afffc2a59cfc3888a84b2b2305b5312393ff4e8 (patch)
tree029ac4c5f55e9e7149cd40d0f57c52efcd41608f /lib/common/data_reader_dump.c
parent9f1f3f959d3411c200afb5a1df4fffa9d87df616 (diff)
Remove raw file descriptors from unpack write paths
Instead, use stdio FILE pointers. On POSIX systems, use fileno to get the file descriptor and hopefully create sparase files. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/common/data_reader_dump.c')
-rw-r--r--lib/common/data_reader_dump.c57
1 files changed, 28 insertions, 29 deletions
diff --git a/lib/common/data_reader_dump.c b/lib/common/data_reader_dump.c
index 4053f73..4065677 100644
--- a/lib/common/data_reader_dump.c
+++ b/lib/common/data_reader_dump.c
@@ -12,26 +12,23 @@
#include <stdio.h>
#include <errno.h>
-static int append_block(int fd, const sqfs_block_t *blk)
+static int append_block(FILE *fp, const sqfs_block_t *blk)
{
const unsigned char *ptr = blk->data;
- size_t size = blk->size;
- ssize_t ret;
+ size_t ret, size = blk->size;
while (size > 0) {
- ret = write(fd, ptr, size);
-
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- perror("writing data block");
+ if (ferror(fp)) {
+ fputs("writing data block: error writing to file\n",
+ stderr);
}
- if (ret == 0) {
+ if (feof(fp)) {
fputs("writing data block: unexpected end of file\n",
stderr);
}
+ ret = fwrite(ptr, 1, size, fp);
ptr += ret;
size -= ret;
}
@@ -41,7 +38,7 @@ static int append_block(int fd, const sqfs_block_t *blk)
int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,
const sqfs_inode_generic_t *inode,
- int outfd, size_t block_size, bool allow_sparse)
+ FILE *fp, size_t block_size, bool allow_sparse)
{
sqfs_block_t *blk;
sqfs_u64 filesz;
@@ -50,21 +47,23 @@ int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,
sqfs_inode_get_file_size(inode, &filesz);
- if (allow_sparse && ftruncate(outfd, filesz))
- goto fail_sparse;
+#if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200112L)
+ if (allow_sparse) {
+ int fd = fileno(fp);
+
+ if (ftruncate(fd, filesz))
+ goto fail_sparse;
+ }
+#else
+ allow_sparse = false;
+#endif
for (i = 0; i < inode->num_file_blocks; ++i) {
+ diff = (filesz < block_size) ? filesz : block_size;
+
if (SQFS_IS_SPARSE_BLOCK(inode->block_sizes[i]) &&
allow_sparse) {
- if (filesz < block_size) {
- diff = filesz;
- filesz = 0;
- } else {
- diff = block_size;
- filesz -= block_size;
- }
-
- if (lseek(outfd, diff, SEEK_CUR) == (off_t)-1)
+ if (fseek(fp, diff, SEEK_CUR) < 0)
goto fail_sparse;
} else {
err = sqfs_data_reader_get_block(data, inode, i, &blk);
@@ -73,14 +72,14 @@ int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,
return -1;
}
- if (append_block(outfd, blk)) {
- free(blk);
- return -1;
- }
-
- filesz -= blk->size;
+ err = append_block(fp, blk);
free(blk);
+
+ if (err)
+ return -1;
}
+
+ filesz -= diff;
}
if (filesz > 0) {
@@ -90,7 +89,7 @@ int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,
return -1;
}
- if (append_block(outfd, blk)) {
+ if (append_block(fp, blk)) {
free(blk);
return -1;
}