From 2f383d8de322dc508be70a71ed10d8b6b9233033 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Tue, 26 Nov 2019 19:24:09 +0300 Subject: [PATCH] mdbx: use getmntent() for determine filesystem type. Change-Id: I92921c5083a822c891889668e51726e2f1ce98cd --- src/elements/osal.c | 39 ++++++++++++++++++++++++++++++++++++--- src/elements/osal.h | 5 +++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/elements/osal.c b/src/elements/osal.c index 741515a1..8f7061c6 100644 --- a/src/elements/osal.c +++ b/src/elements/osal.c @@ -962,7 +962,6 @@ static int mdbx_check_fs_local(mdbx_filehandle_t handle, int flags) { if (mdbx_GetFileInformationByHandleEx(handle, FileRemoteProtocolInfo, &RemoteProtocolInfo, sizeof(RemoteProtocolInfo))) { - if ((RemoteProtocolInfo.Flags & REMOTE_PROTOCOL_INFO_FLAG_OFFLINE) && !(flags & MDBX_RDONLY)) return ERROR_FILE_OFFLINE; @@ -1115,9 +1114,43 @@ static int mdbx_check_fs_local(mdbx_filehandle_t handle, int flags) { const char *const name = statfs_info.f_fstypename; const size_t name_len = sizeof(statfs_info.f_fstypename); #else - const char *const name = ""; - const unsigned name_len = 0; + + const char *name = ""; + unsigned name_len = 0; + + struct stat st; + if (fstat(handle, &st)) + return errno; + + char pathbuf[PATH_MAX]; + FILE *mounted = nullptr; +#if defined(__linux__) || defined(__gnu_linux__) + mounted = setmntent("/proc/mounts", "r"); +#endif /* Linux */ + if (!mounted) + mounted = setmntent("/etc/mtab", "r"); + if (mounted) { + const struct mntent *ent; +#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || \ + (defined(_DEFAULT_SOURCE) && __GLIBC_PREREQ(2, 19)) + struct mntent entbuf; + while (nullptr != + (ent = getmntent_r(mounted, &entbuf, pathbuf, sizeof(pathbuf)))) +#else + while (nullptr != (ent = getmntent(mounted)))) #endif + { + struct stat mnt; + if (!stat(ent->mnt_dir, &mnt) && mnt.st_dev == st.st_dev) { + name = + strncpy(pathbuf, ent->mnt_fsname, name_len = sizeof(pathbuf) - 1); + pathbuf[name_len] = 0; + break; + } + } + endmntent(mounted); + } +#endif /* !xBSD */ #endif if (name_len) { diff --git a/src/elements/osal.h b/src/elements/osal.h index 64d887fe..0f57cdaa 100644 --- a/src/elements/osal.h +++ b/src/elements/osal.h @@ -89,6 +89,10 @@ #include #else #include +#if !(defined(__sun) || defined(__SVR4) || defined(__svr4__) || \ + defined(_WIN32) || defined(_WIN64)) +#include +#endif /* !Solaris */ #endif /* !xBSD */ #if defined(__FreeBSD__) || __has_include() @@ -125,6 +129,7 @@ #if defined(__sun) || defined(__SVR4) || defined(__svr4__) #include +#include /* On Solaris, it's easier to add a missing prototype rather than find a * combination of #defines that break nothing. */ __extern_C key_t ftok(const char *, int);