summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PORTING21
-rw-r--r--project/headers.mk1
-rw-r--r--src/internal/tpax_getdents_impl.h64
3 files changed, 86 insertions, 0 deletions
diff --git a/PORTING b/PORTING
new file mode 100644
index 0000000..90dccc1
--- /dev/null
+++ b/PORTING
@@ -0,0 +1,21 @@
+PORTING
+=======
+
+* tpax relies on a modern getdents interface. This interface is invoked
+ via a static inlined wrapper named tpax_getdents(), which is provided
+ by the tpax_getdents_impl.h internal header.
+
+ If your system is not currently covered, you can still easily build
+ and use tpax by (1) providing your own version of tpax_getdents() in
+ a linker archive of any name; and (2) adding -DTPAX_GETDENTS_PORTED
+ to CFLAGS, and the full path to the above archive to LDFLAGS_LAST.
+
+ The wrapper's signature shall then be:
+
+ long tpax_getdents(int, struct dirent *, size_t);
+
+ And your ./configure invocation would then look like:
+
+ CFLAGS=-DTPAX_GETDENTS_PORTED \\
+ LDFLAGS_LAST=/path/to/tpax_getdents_impl.a \\
+ ./configure
diff --git a/project/headers.mk b/project/headers.mk
index 2d49c17..b33a797 100644
--- a/project/headers.mk
+++ b/project/headers.mk
@@ -8,6 +8,7 @@ INTERNAL_HEADERS = \
$(SOURCE_DIR)/src/internal/tpax_dprintf_impl.h \
$(SOURCE_DIR)/src/internal/tpax_driver_impl.h \
$(SOURCE_DIR)/src/internal/tpax_errinfo_impl.h \
+ $(SOURCE_DIR)/src/internal/tpax_getdents_impl.h \
$(SOURCE_DIR)/src/internal/tpax_readlink_impl.h \
$(SOURCE_DIR)/src/internal/tpax_tmpfile_impl.h \
diff --git a/src/internal/tpax_getdents_impl.h b/src/internal/tpax_getdents_impl.h
new file mode 100644
index 0000000..e4d0e2f
--- /dev/null
+++ b/src/internal/tpax_getdents_impl.h
@@ -0,0 +1,64 @@
+/******************************************************/
+/* tpax: a topological pax implementation */
+/* Copyright (C) 2020--2021 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */
+/******************************************************/
+
+#ifndef TPAX_GETDENTS_IMPL_H
+#define TPAX_GETDENTS_IMPL_H
+
+#include <sys/types.h>
+#include <dirent.h>
+
+/**************************************************************************/
+/* */
+/* provide a (static inlined) wrapper around a modern getdents interface. */
+/* */
+/* see also the PORTING document in the top-level source directory. */
+/* */
+/**************************************************************************/
+
+
+
+/* first priority given to a user-provided emulation */
+#if defined (TPAX_GETDENTS_PORTED)
+
+extern long tpax_getdents(int, struct dirent *, size_t);
+
+
+
+/* linux & midipix fallback: use the getdents64() system call. */
+#elif defined (__linux__) || defined (__midipix__)
+
+#include <sys/syscall.h>
+
+extern long syscall(long, ...);
+
+static long tpax_getdents(int fd, struct dirent * dirents, size_t count)
+{
+ return syscall(SYS_getdents64,fd,dirents,count);
+}
+
+
+
+/* freebsd fallback: use the __sys_getdirentries() system call. */
+#elif defined (__FreeBSD__)
+
+extern ssize_t __sys_getdirentries(int, struct dirent *, size_t, off_t *);
+
+static long tpax_getdents(int fd, struct dirent * dirents, size_t count)
+{
+ return __sys_getdirentries(fd,dirents,count,0);
+}
+
+
+
+/* not covered and no user-provided emulation */
+#else
+
+#error tpax: your target requires the emulation of a modern getdents interface.
+#error tpax: see the top-level PORTING document for additional information.
+
+#endif
+
+#endif