summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/common.h2
-rw-r--r--lib/common/io_stdin.c105
2 files changed, 94 insertions, 13 deletions
diff --git a/include/common.h b/include/common.h
index d4e11c4..19c95a3 100644
--- a/include/common.h
+++ b/include/common.h
@@ -120,6 +120,8 @@ int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,
sqfs_file_t *sqfs_get_stdin_file(const sparse_map_t *map, sqfs_u64 size);
+sqfs_file_t *sqfs_get_stdout_file(void);
+
void register_stat_hooks(sqfs_data_writer_t *data, data_writer_stats_t *stats);
int write_data_from_file(const char *filename, sqfs_data_writer_t *data,
diff --git a/lib/common/io_stdin.c b/lib/common/io_stdin.c
index 0e9fb17..9e96e45 100644
--- a/lib/common/io_stdin.c
+++ b/lib/common/io_stdin.c
@@ -18,18 +18,31 @@ typedef struct {
const sparse_map_t *map;
sqfs_u64 offset;
sqfs_u64 size;
-} sqfs_file_stdin_t;
+} sqfs_file_stdinout_t;
-static void stdin_destroy(sqfs_file_t *base)
+static void stdinout_destroy(sqfs_file_t *base)
{
free(base);
}
+static sqfs_u64 stdinout_get_size(const sqfs_file_t *base)
+{
+ return ((const sqfs_file_stdinout_t *)base)->size;
+}
+
+static int stdinout_truncate(sqfs_file_t *base, sqfs_u64 size)
+{
+ (void)base; (void)size;
+ return SQFS_ERROR_IO;
+}
+
+/*****************************************************************************/
+
static int stdin_read_at(sqfs_file_t *base, sqfs_u64 offset,
void *buffer, size_t size)
{
- sqfs_file_stdin_t *file = (sqfs_file_stdin_t *)base;
+ sqfs_file_stdinout_t *file = (sqfs_file_stdinout_t *)base;
size_t temp_size = 0;
sqfs_u8 *temp = NULL;
sqfs_u64 diff;
@@ -80,7 +93,7 @@ static int stdin_read_at(sqfs_file_t *base, sqfs_u64 offset,
static int stdin_read_condensed(sqfs_file_t *base, sqfs_u64 offset,
void *buffer, size_t size)
{
- sqfs_file_stdin_t *file = (sqfs_file_stdin_t *)base;
+ sqfs_file_stdinout_t *file = (sqfs_file_stdinout_t *)base;
sqfs_u64 poffset = 0, src_start;
size_t dst_start, diff, count;
const sparse_map_t *it;
@@ -138,20 +151,69 @@ static int stdin_write_at(sqfs_file_t *base, sqfs_u64 offset,
return SQFS_ERROR_IO;
}
-static sqfs_u64 stdin_get_size(const sqfs_file_t *base)
+/*****************************************************************************/
+
+static int stdout_read_at(sqfs_file_t *base, sqfs_u64 offset,
+ void *buffer, size_t size)
{
- return ((const sqfs_file_stdin_t *)base)->size;
+ (void)base; (void)offset; (void)buffer; (void)size;
+ return SQFS_ERROR_IO;
}
-static int stdin_truncate(sqfs_file_t *base, sqfs_u64 size)
+static int stdout_write_at(sqfs_file_t *base, sqfs_u64 offset,
+ const void *buffer, size_t size)
{
- (void)base; (void)size;
- return SQFS_ERROR_IO;
+ sqfs_file_stdinout_t *file = (sqfs_file_stdinout_t *)base;
+ size_t temp_size = 0;
+ sqfs_u8 *temp = NULL;
+ sqfs_u64 diff;
+ ssize_t ret;
+
+ if (offset < file->size)
+ return SQFS_ERROR_IO;
+
+ if (offset > file->size) {
+ temp_size = 1024;
+ temp = alloca(temp_size);
+ memset(temp, 0, temp_size);
+ }
+
+ while (size > 0) {
+ if (offset > file->size) {
+ diff = offset - file->size;
+ diff = diff > (sqfs_u64)temp_size ? temp_size : diff;
+
+ ret = write(STDOUT_FILENO, temp, diff);
+ } else {
+ ret = write(STDOUT_FILENO, buffer, size);
+ }
+
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ return SQFS_ERROR_IO;
+ }
+
+ if (ret == 0)
+ return SQFS_ERROR_OUT_OF_BOUNDS;
+
+ if (offset <= file->size) {
+ buffer = (char *)buffer + ret;
+ size -= ret;
+ offset += ret;
+ }
+
+ file->size += ret;
+ }
+
+ return 0;
}
+/*****************************************************************************/
+
sqfs_file_t *sqfs_get_stdin_file(const sparse_map_t *map, sqfs_u64 size)
{
- sqfs_file_stdin_t *file = calloc(1, sizeof(*file));
+ sqfs_file_stdinout_t *file = calloc(1, sizeof(*file));
sqfs_file_t *base = (sqfs_file_t *)file;
if (file == NULL)
@@ -160,10 +222,10 @@ sqfs_file_t *sqfs_get_stdin_file(const sparse_map_t *map, sqfs_u64 size)
file->size = size;
file->map = map;
- base->destroy = stdin_destroy;
+ base->destroy = stdinout_destroy;
base->write_at = stdin_write_at;
- base->get_size = stdin_get_size;
- base->truncate = stdin_truncate;
+ base->get_size = stdinout_get_size;
+ base->truncate = stdinout_truncate;
if (map == NULL) {
base->read_at = stdin_read_at;
@@ -172,3 +234,20 @@ sqfs_file_t *sqfs_get_stdin_file(const sparse_map_t *map, sqfs_u64 size)
}
return base;
}
+
+sqfs_file_t *sqfs_get_stdout_file(void)
+{
+ sqfs_file_stdinout_t *file = calloc(1, sizeof(*file));
+ sqfs_file_t *base = (sqfs_file_t *)file;
+
+ if (file == NULL)
+ return NULL;
+
+ base->destroy = stdinout_destroy;
+ base->write_at = stdout_write_at;
+ base->get_size = stdinout_get_size;
+ base->truncate = stdinout_truncate;
+ base->read_at = stdout_read_at;
+
+ return base;
+}