summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Mazieres <dm@uun.org>2015-08-16 16:22:52 -0700
committerDavid Mazieres <dm@uun.org>2015-08-16 16:22:52 -0700
commit43ed0e7649ae46e43e47b3a1140d4b683df05eb9 (patch)
treeab4dbc105bbe0578d0395aeef3a99bcbcf9b1126
parentd3c76c74fb604c234149610f2e63ccf7c8fb0393 (diff)
also work around missing fstatat and fdopendirmuchsync-2
-rw-r--r--configure.ac1
-rw-r--r--xapian_sync.cc35
2 files changed, 28 insertions, 8 deletions
diff --git a/configure.ac b/configure.ac
index e9de6c2..9aedcba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,6 +19,7 @@ AC_LANG(C++)
AX_APPEND_COMPILE_FLAGS([-pthread])
AC_CHECK_FUNCS(openat)
+AC_CHECK_FUNCS(fdopendir)
PKG_CHECK_MODULES([sqlite3], [sqlite3])
PKG_CHECK_MODULES([libcrypto], [libcrypto])
diff --git a/xapian_sync.cc b/xapian_sync.cc
index 3f7706b..5ab8422 100644
--- a/xapian_sync.cc
+++ b/xapian_sync.cc
@@ -63,22 +63,41 @@ CREATE TEMP TRIGGER link_insert AFTER INSERT ON xapian_files
)");
}
+// Non-thread-safe unility to work around missing openat & friends.
+template<typename R> R
+with_cwd(int dfd, R errval, function<R()> work)
+{
+ int dot = open(".", O_RDONLY);
+ if (dot < 0 || fchdir(dfd) < 0)
+ return errval;
+ cleanup _c ([dot]() { fchdir(dot); close(dot); });
+ return work();
+}
+
#if !HAVE_OPENAT
-// A non-thread-safe workaround for missing openat.
#define openat fake_openat
static int
openat(int dfd, const char *entry, int mode)
{
- int dot = open(".", O_RDONLY);
- if (dot < 0)
- return -1;
- cleanup _c ([dot]() { fchdir(dot); close(dot); });
- if (fchdir(dfd) < 0)
- return -1;
- return open(entry, mode);
+ return with_cwd<int>(dfd, -1, [=]() { return open(entry, mode); });
+}
+#define fstatat fake_fstatat
+static int
+fstatat(int dfd, const char *entry, struct stat *buf, int flag)
+{
+ return with_cwd<int>(dfd, -1, [=]() { return stat(entry, buf); });
}
#endif // !HAVE_OPENAT
+#if !HAVE_FDOPENDIR
+#define fdopendir fake_fdopendir
+static DIR *
+fdopendir(int dfd)
+{
+ return with_cwd<DIR *>(dfd, nullptr, []() { return opendir("."); });
+}
+#endif // !HAVE_FDOPENDIR
+
static string
get_sha (int dfd, const char *direntry, i64 *sizep)
{