summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--project/common.mk1
-rw-r--r--src/driver/tpax_driver_ctx.c3
-rw-r--r--src/internal/tpax_driver_impl.h3
-rw-r--r--src/logic/tpax_queue_vector.c60
4 files changed, 67 insertions, 0 deletions
diff --git a/project/common.mk b/project/common.mk
index 378de0c..8bc157e 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -8,6 +8,7 @@ API_SRCS = \
src/logic/tpax_init_ustar_header.c \
src/logic/tpax_file_create_memory_snapshot.c \
src/logic/tpax_file_create_tmpfs_snapshot.c \
+ src/logic/tpax_queue_vector.c \
src/output/tpax_output_error.c \
src/skin/tpax_skin_default.c \
diff --git a/src/driver/tpax_driver_ctx.c b/src/driver/tpax_driver_ctx.c
index 3eca506..77eedd1 100644
--- a/src/driver/tpax_driver_ctx.c
+++ b/src/driver/tpax_driver_ctx.c
@@ -589,6 +589,9 @@ static void tpax_free_driver_ctx_impl(struct tpax_driver_ctx_alloc * ictx)
if (ictx->ctx.prefixv != ictx->ctx.prefptr)
free(ictx->ctx.prefixv);
+ if (ictx->ctx.direntv)
+ free(ictx->ctx.direntv);
+
argv_free(ictx->meta);
free(ictx);
}
diff --git a/src/internal/tpax_driver_impl.h b/src/internal/tpax_driver_impl.h
index f5fb9c8..1779043 100644
--- a/src/internal/tpax_driver_impl.h
+++ b/src/internal/tpax_driver_impl.h
@@ -78,6 +78,7 @@ struct tpax_driver_ctx_impl {
char ** prefixp;
char ** prefcap;
char * prefptr[64];
+ struct tpax_dirent ** direntv;
struct tpax_dirent_buffer * dirents;
struct tpax_dirent * dirmark;
void * dirbuff;
@@ -275,4 +276,6 @@ static inline ssize_t tpax_get_archive_block_size(const struct tpax_driver_ctx *
return 0;
}
+int tpax_update_queue_vector(const struct tpax_driver_ctx * dctx);
+
#endif
diff --git a/src/logic/tpax_queue_vector.c b/src/logic/tpax_queue_vector.c
new file mode 100644
index 0000000..092f39f
--- /dev/null
+++ b/src/logic/tpax_queue_vector.c
@@ -0,0 +1,60 @@
+/**************************************************************/
+/* tpax: a topological pax implementation */
+/* Copyright (C) 2020--2024 SysDeer Technologies, LLC */
+/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */
+/**************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <tpax/tpax.h>
+#include "tpax_driver_impl.h"
+#include "tpax_errinfo_impl.h"
+#include "tpax_visibility_impl.h"
+
+tpax_hidden int tpax_update_queue_vector(const struct tpax_driver_ctx * dctx)
+{
+ uintptr_t addr;
+ struct tpax_driver_ctx_impl * ictx;
+ struct tpax_dirent_buffer * dentbuf;
+ struct tpax_dirent ** direntv;
+ struct tpax_dirent * cdent;
+ struct tpax_dirent * cnext;
+ size_t arrsize;
+
+ /* driver */
+ ictx = tpax_get_driver_ictx(dctx);
+
+ /* vector alloc */
+ if (ictx->direntv)
+ free(ictx->direntv);
+
+ arrsize = ictx->nqueued + 1;
+
+ if (!(ictx->direntv = calloc(arrsize,sizeof(struct tpax_dirent *))))
+ return TPAX_SYSTEM_ERROR(dctx);
+
+ if (ictx->nqueued == 0)
+ return 0;
+
+ /* queue vector */
+ dentbuf = tpax_get_driver_dirents(dctx);
+ cdent = dentbuf->dbuf;
+
+ for (direntv=ictx->direntv; cdent; direntv++) {
+ *direntv = cdent;
+
+ addr = (uintptr_t)cdent;
+ addr += cdent->nsize;
+ cnext = (struct tpax_dirent *)addr;
+
+ if (cnext == dentbuf->cdent) {
+ dentbuf = dentbuf->next;
+ cnext = dentbuf ? dentbuf->dbuf : 0;
+ }
+
+ cdent = cnext;
+ }
+
+ return 0;
+}