diff options
author | David Mazieres <dm@uun.org> | 2015-08-16 16:22:52 -0700 |
---|---|---|
committer | David Mazieres <dm@uun.org> | 2015-08-16 16:22:52 -0700 |
commit | 43ed0e7649ae46e43e47b3a1140d4b683df05eb9 (patch) | |
tree | ab4dbc105bbe0578d0395aeef3a99bcbcf9b1126 | |
parent | d3c76c74fb604c234149610f2e63ccf7c8fb0393 (diff) |
also work around missing fstatat and fdopendirmuchsync-2
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | xapian_sync.cc | 35 |
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) { |