summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/common/data_reader_dump.c57
-rw-r--r--lib/tar/padd_file.c4
-rw-r--r--lib/tar/write_header.c30
-rw-r--r--lib/tar/write_retry.c15
4 files changed, 52 insertions, 54 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;
}
diff --git a/lib/tar/padd_file.c b/lib/tar/padd_file.c
index f58cfbf..dd945a3 100644
--- a/lib/tar/padd_file.c
+++ b/lib/tar/padd_file.c
@@ -10,7 +10,7 @@
#include <stdlib.h>
#include <stdio.h>
-int padd_file(int outfd, sqfs_u64 size)
+int padd_file(FILE *fp, sqfs_u64 size)
{
size_t padd_sz = size % TAR_RECORD_SIZE;
int status = -1;
@@ -26,7 +26,7 @@ int padd_file(int outfd, sqfs_u64 size)
goto fail_errno;
if (write_retry("padding output file to block size",
- outfd, buffer, padd_sz)) {
+ fp, buffer, padd_sz)) {
goto out;
}
diff --git a/lib/tar/write_header.c b/lib/tar/write_header.c
index 84aa2d3..6626d00 100644
--- a/lib/tar/write_header.c
+++ b/lib/tar/write_header.c
@@ -53,7 +53,7 @@ static void write_number_signed(char *dst, sqfs_s64 value, int digits)
}
}
-static int write_header(int fd, const struct stat *sb, const char *name,
+static int write_header(FILE *fp, const struct stat *sb, const char *name,
const char *slink_target, int type)
{
int maj = 0, min = 0;
@@ -88,10 +88,10 @@ static int write_header(int fd, const struct stat *sb, const char *name,
update_checksum(&hdr);
- return write_retry("writing tar header record", fd, &hdr, sizeof(hdr));
+ return write_retry("writing tar header record", fp, &hdr, sizeof(hdr));
}
-static int write_gnu_header(int fd, const struct stat *orig,
+static int write_gnu_header(FILE *fp, const struct stat *orig,
const char *payload, size_t payload_len,
int type, const char *name)
{
@@ -101,15 +101,15 @@ static int write_gnu_header(int fd, const struct stat *orig,
sb.st_mode = S_IFREG | 0644;
sb.st_size = payload_len;
- if (write_header(fd, &sb, name, NULL, type))
+ if (write_header(fp, &sb, name, NULL, type))
return -1;
if (write_retry("writing GNU extension header",
- fd, payload, payload_len)) {
+ fp, payload, payload_len)) {
return -1;
}
- return padd_file(fd, payload_len);
+ return padd_file(fp, payload_len);
}
static size_t num_digits(size_t num)
@@ -124,7 +124,7 @@ static size_t num_digits(size_t num)
return i;
}
-static int write_schily_xattr(int fd, const struct stat *orig,
+static int write_schily_xattr(FILE *fp, const struct stat *orig,
const char *name, const tar_xattr_t *xattr)
{
static const char *prefix = "SCHILY.xattr.";
@@ -142,20 +142,20 @@ static int write_schily_xattr(int fd, const struct stat *orig,
sb.st_mode = S_IFREG | 0644;
sb.st_size = total_size;
- if (write_header(fd, &sb, name, NULL, TAR_TYPE_PAX))
+ if (write_header(fp, &sb, name, NULL, TAR_TYPE_PAX))
return -1;
for (it = xattr; it != NULL; it = it->next) {
len = strlen(prefix) + strlen(it->key) + strlen(it->value) + 2;
len += num_digits(len) + 1;
- dprintf(fd, "%zu %s%s=%s\n", len, prefix, it->key, it->value);
+ fprintf(fp, "%zu %s%s=%s\n", len, prefix, it->key, it->value);
}
- return padd_file(fd, total_size);
+ return padd_file(fp, total_size);
}
-int write_tar_header(int fd, const struct stat *sb, const char *name,
+int write_tar_header(FILE *fp, const struct stat *sb, const char *name,
const char *slink_target, const tar_xattr_t *xattr,
unsigned int counter)
{
@@ -166,7 +166,7 @@ int write_tar_header(int fd, const struct stat *sb, const char *name,
if (xattr != NULL) {
sprintf(buffer, "pax/xattr%u", counter);
- if (write_schily_xattr(fd, sb, buffer, xattr))
+ if (write_schily_xattr(fp, sb, buffer, xattr))
return -1;
}
@@ -175,7 +175,7 @@ int write_tar_header(int fd, const struct stat *sb, const char *name,
if (S_ISLNK(sb->st_mode) && sb->st_size >= 100) {
sprintf(buffer, "gnu/target%u", counter);
- if (write_gnu_header(fd, sb, slink_target, sb->st_size,
+ if (write_gnu_header(fp, sb, slink_target, sb->st_size,
TAR_TYPE_GNU_SLINK, buffer))
return -1;
slink_target = NULL;
@@ -184,7 +184,7 @@ int write_tar_header(int fd, const struct stat *sb, const char *name,
if (strlen(name) >= 100) {
sprintf(buffer, "gnu/name%u", counter);
- if (write_gnu_header(fd, sb, name, strlen(name),
+ if (write_gnu_header(fp, sb, name, strlen(name),
TAR_TYPE_GNU_PATH, buffer)) {
return -1;
}
@@ -208,7 +208,7 @@ int write_tar_header(int fd, const struct stat *sb, const char *name,
goto out_skip;
}
- return write_header(fd, sb, name, slink_target, type);
+ return write_header(fp, sb, name, slink_target, type);
out_skip:
fprintf(stderr, "WARNING: %s: %s\n", name, reason);
return 1;
diff --git a/lib/tar/write_retry.c b/lib/tar/write_retry.c
index 1ff1a7e..3977db1 100644
--- a/lib/tar/write_retry.c
+++ b/lib/tar/write_retry.c
@@ -12,23 +12,22 @@
#include "tar.h"
-int write_retry(const char *errstr, int fd, const void *data, size_t size)
+int write_retry(const char *errstr, FILE *fp, const void *data, size_t size)
{
- ssize_t ret;
+ size_t ret;
while (size > 0) {
- ret = write(fd, data, size);
- if (ret == 0) {
+ if (feof(fp)) {
fprintf(stderr, "%s: write truncated\n", errstr);
return -1;
}
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- perror(errstr);
+
+ if (ferror(fp)) {
+ fprintf(stderr, "%s: error writing to file\n", errstr);
return -1;
}
+ ret = fwrite(data, 1, size, fp);
data = (const char *)data + ret;
size -= ret;
}