summaryrefslogtreecommitdiff
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
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>
-rw-r--r--difftool/extract.c13
-rw-r--r--include/common.h2
-rw-r--r--include/tar.h7
-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
-rw-r--r--tar/sqfs2tar.c8
-rw-r--r--unpack/fill_files.c13
-rw-r--r--unpack/rdsquashfs.c3
10 files changed, 76 insertions, 76 deletions
diff --git a/difftool/extract.c b/difftool/extract.c
index df00977..979572a 100644
--- a/difftool/extract.c
+++ b/difftool/extract.c
@@ -10,7 +10,7 @@ static int extract(sqfs_data_reader_t *data, const sqfs_inode_generic_t *inode,
const char *prefix, const char *path, size_t block_size)
{
char *ptr, *temp;
- int fd;
+ FILE *fp;
temp = alloca(strlen(prefix) + strlen(path) + 2);
sprintf(temp, "%s/%s", prefix, path);
@@ -21,18 +21,19 @@ static int extract(sqfs_data_reader_t *data, const sqfs_inode_generic_t *inode,
return -1;
*ptr = '/';
- fd = open(temp, O_CREAT | O_EXCL | O_WRONLY, 0600);
- if (fd < 0) {
+ fp = fopen(temp, "wb");
+ if (fp == NULL) {
perror(temp);
return -1;
}
- if (sqfs_data_reader_dump(path, data, inode, fd, block_size, true)) {
- close(fd);
+ if (sqfs_data_reader_dump(path, data, inode, fp, block_size, true)) {
+ fclose(fp);
return -1;
}
- close(fd);
+ fflush(fp);
+ fclose(fp);
return 0;
}
diff --git a/include/common.h b/include/common.h
index ba42054..da9093f 100644
--- a/include/common.h
+++ b/include/common.h
@@ -118,7 +118,7 @@ char *sqfs_tree_node_get_path(const sqfs_tree_node_t *node);
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_file_t *sqfs_get_stdin_file(const sparse_map_t *map, sqfs_u64 size);
diff --git a/include/tar.h b/include/tar.h
index c5d48ef..8f9f55c 100644
--- a/include/tar.h
+++ b/include/tar.h
@@ -12,6 +12,7 @@
#include <stdbool.h>
#include <stdint.h>
+#include <stdio.h>
typedef struct sparse_map_t {
struct sparse_map_t *next;
@@ -118,7 +119,7 @@ typedef struct {
The counter is an incremental record counter used if additional
headers need to be generated.
*/
-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);
@@ -136,7 +137,7 @@ void clear_header(tar_header_decoded_t *hdr);
Write zero bytes to an output file to padd it to the tar record size.
Returns 0 on success. On failure, prints error message to stderr.
*/
-int padd_file(int outfd, sqfs_u64 size);
+int padd_file(FILE *fp, sqfs_u64 size);
/*
@@ -153,6 +154,6 @@ int read_retry(const char *errstr, int fd, void *buffer, size_t size);
on success. Writes to stderr on failure using 'errstr' as a perror style
error prefix.
*/
-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);
#endif /* TAR_H */
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;
}
diff --git a/tar/sqfs2tar.c b/tar/sqfs2tar.c
index 1e05cd4..af116b8 100644
--- a/tar/sqfs2tar.c
+++ b/tar/sqfs2tar.c
@@ -174,7 +174,7 @@ static int terminate_archive(void)
memset(buffer, '\0', sizeof(buffer));
- return write_retry("adding archive terminator", STDOUT_FILENO,
+ return write_retry("adding archive terminator", stdout,
buffer, sizeof(buffer));
}
@@ -295,7 +295,7 @@ static int write_tree_dfs(const sqfs_tree_node_t *n)
}
target = S_ISLNK(sb.st_mode) ? n->inode->slink_target : NULL;
- ret = write_tar_header(STDOUT_FILENO, &sb, name, target, xattr,
+ ret = write_tar_header(stdout, &sb, name, target, xattr,
record_counter++);
while (xattr != NULL) {
@@ -313,13 +313,13 @@ static int write_tree_dfs(const sqfs_tree_node_t *n)
}
if (S_ISREG(sb.st_mode)) {
- if (sqfs_data_reader_dump(name, data, n->inode, STDOUT_FILENO,
+ if (sqfs_data_reader_dump(name, data, n->inode, stdout,
super.block_size, false)) {
free(name);
return -1;
}
- if (padd_file(STDOUT_FILENO, sb.st_size)) {
+ if (padd_file(stdout, sb.st_size)) {
free(name);
return -1;
}
diff --git a/unpack/fill_files.c b/unpack/fill_files.c
index e6444b2..d22e9d1 100644
--- a/unpack/fill_files.c
+++ b/unpack/fill_files.c
@@ -136,11 +136,11 @@ static int gen_file_list_dfs(const sqfs_tree_node_t *n)
static int fill_files(sqfs_data_reader_t *data, int flags)
{
size_t i;
- int fd;
+ FILE *fp;
for (i = 0; i < num_files; ++i) {
- fd = open(files[i].path, O_WRONLY);
- if (fd < 0) {
+ fp = fopen(files[i].path, "wb");
+ if (fp == NULL) {
fprintf(stderr, "unpacking %s: %s\n",
files[i].path, strerror(errno));
return -1;
@@ -150,13 +150,14 @@ static int fill_files(sqfs_data_reader_t *data, int flags)
printf("unpacking %s\n", files[i].path);
if (sqfs_data_reader_dump(files[i].path, data, files[i].inode,
- fd, block_size,
+ fp, block_size,
(flags & UNPACK_NO_SPARSE) == 0)) {
- close(fd);
+ fclose(fp);
return -1;
}
- close(fd);
+ fflush(fp);
+ fclose(fp);
}
return 0;
diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c
index 5ef367b..2f84264 100644
--- a/unpack/rdsquashfs.c
+++ b/unpack/rdsquashfs.c
@@ -128,8 +128,7 @@ int main(int argc, char **argv)
}
if (sqfs_data_reader_dump(opt.cmdpath, data, n->inode,
- STDOUT_FILENO,
- super.block_size, false)) {
+ stdout, super.block_size, false)) {
goto out;
}
break;