From 44c81eeffe9c8820b1009a7a5c728782aa5ebf40 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Tue, 3 Mar 2020 19:43:54 +0100 Subject: Add a generic copying mechanism to sqfs_object_t This patch adds a deep-copy callback to sqfs_object_t and removes the copying mechanism from sqfs_compressor_t. This is also interesting for other types. Signed-off-by: David Oberhollenzer --- lib/sqfs/unix/io_file.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'lib/sqfs/unix') diff --git a/lib/sqfs/unix/io_file.c b/lib/sqfs/unix/io_file.c index 1c181ab..52fc94b 100644 --- a/lib/sqfs/unix/io_file.c +++ b/lib/sqfs/unix/io_file.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,7 @@ typedef struct { sqfs_file_t base; + bool readonly; sqfs_u64 size; int fd; } sqfs_file_stdio_t; @@ -33,6 +35,34 @@ static void stdio_destroy(sqfs_object_t *base) free(file); } +static sqfs_object_t *stdio_copy(const sqfs_object_t *base) +{ + const sqfs_file_stdio_t *file = (const sqfs_file_stdio_t *)base; + sqfs_file_stdio_t *copy; + int err; + + if (!file->readonly) { + errno = ENOTSUP; + return NULL; + } + + copy = calloc(1, sizeof(*copy)); + if (copy == NULL) + return NULL; + + memcpy(copy, file, sizeof(*file)); + + copy->fd = dup(file->fd); + if (copy->fd < 0) { + err = errno; + free(copy); + copy = NULL; + errno = err; + } + + return (sqfs_object_t *)copy; +} + static int stdio_read_at(sqfs_file_t *base, sqfs_u64 offset, void *buffer, size_t size) { @@ -125,8 +155,10 @@ sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags) return NULL; if (flags & SQFS_FILE_OPEN_READ_ONLY) { + file->readonly = true; open_mode = O_RDONLY; } else { + file->readonly = false; open_mode = O_CREAT | O_RDWR; if (flags & SQFS_FILE_OPEN_OVERWRITE) { @@ -158,6 +190,7 @@ sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags) base->write_at = stdio_write_at; base->get_size = stdio_get_size; base->truncate = stdio_truncate; + ((sqfs_object_t *)base)->copy = stdio_copy; ((sqfs_object_t *)base)->destroy = stdio_destroy; return base; } -- cgit v1.2.3