From fd662ee848df0226b6edeadec5858a96c1e2d2d5 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 14 Nov 2017 12:01:00 -0800 Subject: [PATCH] tst: passthrough-fuse: BSD flags support --- tst/passthrough-fuse/passthrough-fuse.c | 73 ++++++++++--------- tst/passthrough-fuse/passthrough-fuse.vcxproj | 8 +- tst/passthrough-fuse/winposix.c | 57 ++++++++++++++- tst/passthrough-fuse/winposix.h | 1 + 4 files changed, 99 insertions(+), 40 deletions(-) diff --git a/tst/passthrough-fuse/passthrough-fuse.c b/tst/passthrough-fuse/passthrough-fuse.c index 5669e938..ef24fc6b 100644 --- a/tst/passthrough-fuse/passthrough-fuse.c +++ b/tst/passthrough-fuse/passthrough-fuse.c @@ -212,6 +212,10 @@ static void *ptfs_init(struct fuse_conn_info *conn) conn->want |= (conn->capable & FSP_FUSE_CAP_READDIR_PLUS); #endif +#if defined(FSP_FUSE_USE_STAT_EX) && defined(FSP_FUSE_CAP_STAT_EX) + conn->want |= (conn->capable & FSP_FUSE_CAP_STAT_EX); +#endif + #if defined(FSP_FUSE_CAP_CASE_INSENSITIVE) conn->want |= (conn->capable & FSP_FUSE_CAP_CASE_INSENSITIVE); #endif @@ -242,43 +246,42 @@ static int ptfs_fgetattr(const char *path, struct fuse_stat *stbuf, struct fuse_ return -1 != fstat(fd, stbuf) ? 0 : -errno; } +#if defined(FSP_FUSE_USE_STAT_EX) +static int ptfs_chflags(const char *path, uint32_t flags) +{ + ptfs_impl_fullpath(path); + + return -1 != lchflags(path, flags) ? 0 : -errno; +} +#endif + static struct fuse_operations ptfs_ops = { - ptfs_getattr, - 0, //getdir - 0, //readlink - 0, //mknod - ptfs_mkdir, - ptfs_unlink, - ptfs_rmdir, - 0, //symlink - ptfs_rename, - 0, //link - ptfs_chmod, - ptfs_chown, - ptfs_truncate, - ptfs_utime, - ptfs_open, - ptfs_read, - ptfs_write, - ptfs_statfs, - 0, //flush - ptfs_release, - ptfs_fsync, - 0, //setxattr - 0, //getxattr - 0, //listxattr - 0, //removexattr - ptfs_opendir, - ptfs_readdir, - ptfs_releasedir, - 0, //fsyncdir - ptfs_init, - 0, //destroy - 0, //access - ptfs_create, - ptfs_ftruncate, - ptfs_fgetattr, + .getattr = ptfs_getattr, + .mkdir = ptfs_mkdir, + .unlink = ptfs_unlink, + .rmdir = ptfs_rmdir, + .rename = ptfs_rename, + .chmod = ptfs_chmod, + .chown = ptfs_chown, + .truncate = ptfs_truncate, + .utime = ptfs_utime, + .open = ptfs_open, + .read = ptfs_read, + .write = ptfs_write, + .statfs = ptfs_statfs, + .release = ptfs_release, + .fsync = ptfs_fsync, + .opendir = ptfs_opendir, + .readdir = ptfs_readdir, + .releasedir = ptfs_releasedir, + .init = ptfs_init, + .create = ptfs_create, + .ftruncate = ptfs_ftruncate, + .fgetattr = ptfs_fgetattr, +#if defined(FSP_FUSE_USE_STAT_EX) + .chflags = ptfs_chflags, +#endif }; static void usage(void) diff --git a/tst/passthrough-fuse/passthrough-fuse.vcxproj b/tst/passthrough-fuse/passthrough-fuse.vcxproj index 1d0c6a5e..f411ca40 100644 --- a/tst/passthrough-fuse/passthrough-fuse.vcxproj +++ b/tst/passthrough-fuse/passthrough-fuse.vcxproj @@ -99,7 +99,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + FSP_FUSE_USE_STAT_EX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(MSBuildProgramFiles32)\WinFsp\inc\fuse;$(MSBuildProgramFiles32)\WinFsp\inc MultiThreaded @@ -118,7 +118,7 @@ Level3 Disabled - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + FSP_FUSE_USE_STAT_EX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(MSBuildProgramFiles32)\WinFsp\inc\fuse;$(MSBuildProgramFiles32)\WinFsp\inc MultiThreaded @@ -139,7 +139,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + FSP_FUSE_USE_STAT_EX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(MSBuildProgramFiles32)\WinFsp\inc\fuse;$(MSBuildProgramFiles32)\WinFsp\inc MultiThreaded @@ -162,7 +162,7 @@ MaxSpeed true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + FSP_FUSE_USE_STAT_EX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(MSBuildProgramFiles32)\WinFsp\inc\fuse;$(MSBuildProgramFiles32)\WinFsp\inc MultiThreaded diff --git a/tst/passthrough-fuse/winposix.c b/tst/passthrough-fuse/winposix.c index c7c7edc2..cada2977 100644 --- a/tst/passthrough-fuse/winposix.c +++ b/tst/passthrough-fuse/winposix.c @@ -1,5 +1,5 @@ /** - * @file passthrough-fuse.c + * @file winposix.c * * @copyright 2015-2017 Bill Zissimopoulos */ @@ -36,6 +36,40 @@ struct _DIR char path[]; }; +#if defined(FSP_FUSE_USE_STAT_EX) +static inline uint32_t MapFileAttributesToFlags(UINT32 FileAttributes) +{ + uint32_t flags = 0; + + if (FileAttributes & FILE_ATTRIBUTE_READONLY) + flags |= FSP_FUSE_UF_READONLY; + if (FileAttributes & FILE_ATTRIBUTE_HIDDEN) + flags |= FSP_FUSE_UF_HIDDEN; + if (FileAttributes & FILE_ATTRIBUTE_SYSTEM) + flags |= FSP_FUSE_UF_SYSTEM; + if (FileAttributes & FILE_ATTRIBUTE_ARCHIVE) + flags |= FSP_FUSE_UF_ARCHIVE; + + return flags; +} + +static inline UINT32 MapFlagsToFileAttributes(uint32_t flags) +{ + UINT32 FileAttributes = 0; + + if (flags & FSP_FUSE_UF_READONLY) + FileAttributes |= FILE_ATTRIBUTE_READONLY; + if (flags & FSP_FUSE_UF_HIDDEN) + FileAttributes |= FILE_ATTRIBUTE_HIDDEN; + if (flags & FSP_FUSE_UF_SYSTEM) + FileAttributes |= FILE_ATTRIBUTE_SYSTEM; + if (flags & FSP_FUSE_UF_ARCHIVE) + FileAttributes |= FILE_ATTRIBUTE_ARCHIVE; + + return FileAttributes; +} +#endif + static int maperror(int winerrno); static inline void *error0(void) @@ -173,6 +207,9 @@ int fstat(int fd, struct fuse_stat *stbuf) stbuf->st_ctim.tv_nsec = LastWriteTime % 10000000 * 100; stbuf->st_birthtim.tv_sec = CreationTime / 10000000; stbuf->st_birthtim.tv_nsec = CreationTime % 10000000 * 100; +#if defined(FSP_FUSE_USE_STAT_EX) + stbuf->st_flags = MapFileAttributesToFlags(FileInfo.dwFileAttributes); +#endif return 0; } @@ -272,6 +309,21 @@ int lchown(const char *path, fuse_uid_t uid, fuse_gid_t gid) return 0; } +int lchflags(const char *path, uint32_t flags) +{ +#if defined(FSP_FUSE_USE_STAT_EX) + UINT32 FileAttributes = MapFlagsToFileAttributes(flags); + + if (0 == FileAttributes) + FileAttributes = FILE_ATTRIBUTE_NORMAL; + + if (!SetFileAttributesA(path, FileAttributes)) + return error(); +#endif + + return 0; +} + int truncate(const char *path, fuse_off_t size) { HANDLE h = CreateFileA(path, @@ -424,6 +476,9 @@ struct dirent *readdir(DIR *dirp) stbuf->st_ctim.tv_nsec = LastWriteTime % 10000000 * 100; stbuf->st_birthtim.tv_sec = CreationTime / 10000000; stbuf->st_birthtim.tv_nsec = CreationTime % 10000000 * 100; +#if defined(FSP_FUSE_USE_STAT_EX) + stbuf->st_flags = MapFileAttributesToFlags(FindData.dwFileAttributes); +#endif strcpy(dirp->de.d_name, FindData.cFileName); diff --git a/tst/passthrough-fuse/winposix.h b/tst/passthrough-fuse/winposix.h index 5bc09660..a7f8cff2 100644 --- a/tst/passthrough-fuse/winposix.h +++ b/tst/passthrough-fuse/winposix.h @@ -50,6 +50,7 @@ int close(int fd); int lstat(const char *path, struct fuse_stat *stbuf); int chmod(const char *path, fuse_mode_t mode); int lchown(const char *path, fuse_uid_t uid, fuse_gid_t gid); +int lchflags(const char *path, uint32_t flags); int truncate(const char *path, fuse_off_t size); int utime(const char *path, const struct fuse_utimbuf *timbuf); int unlink(const char *path);