From: Joel Holdsworth joel@airwebreathe.org.uk
On some BSD-like operating systems including MacOS, FreeBSD and NetBSD, the struct stat structure contains the st_flags member can carry flags of which the following can be used to represent DOS attributes:
* UF_IMMUTABLE can represent FILE_ATTRIBUTE_READONLY * UF_HIDDEN can reprent FILE_ATTRIBUTE_HIDDEN (not available on NetBSD)
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=39366 Signed-off-by: Joel Holdsworth joel@airwebreathe.org.uk --- configure | 15 +++++++++++++++ configure.ac | 7 +++++-- dlls/ntdll/unix/file.c | 34 ++++++++++++++++++++++++++++++++++ include/config.h.in | 6 ++++++ 4 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/configure b/configure index 1b78fe7bcc9..8d2718c7d01 100755 --- a/configure +++ b/configure @@ -9154,6 +9154,7 @@ fi done
+ DLLFLAGS=""
LDDLLFLAGS="" @@ -19691,6 +19692,12 @@ if test "x$ac_cv_func_epoll_create" = xyes then : printf "%s\n" "#define HAVE_EPOLL_CREATE 1" >>confdefs.h
+fi +ac_fn_c_check_func "$LINENO" "fchflags" "ac_cv_func_fchflags" +if test "x$ac_cv_func_fchflags" = xyes +then : + printf "%s\n" "#define HAVE_FCHFLAGS 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "fstatfs" "ac_cv_func_fstatfs" if test "x$ac_cv_func_fstatfs" = xyes @@ -20716,6 +20723,14 @@ then : printf "%s\n" "#define HAVE_STRUCT_STAT___ST_BIRTHTIM 1" >>confdefs.h
+fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_flags" "ac_cv_member_struct_stat_st_flags" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_flags" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_FLAGS 1" >>confdefs.h + + fi
diff --git a/configure.ac b/configure.ac index 3eb38d4c01e..96f89fc260c 100644 --- a/configure.ac +++ b/configure.ac @@ -641,6 +641,7 @@ AC_CHECK_HEADERS(sys/xattr.h, [HAVE_XATTR=1] [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/xattr.h>]], [[getxattr("", "", "", 0, 0, 0);]])], [AC_DEFINE(XATTR_ADDITIONAL_OPTIONS, 1, [Define if xattr functions take additional arguments (Mac OS X)])])])
+ dnl **** Check for working dll ****
AC_SUBST(DLLFLAGS,"") @@ -2005,6 +2006,7 @@ ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $BUILTINFLAG" AC_CHECK_FUNCS(\ epoll_create \ + fchflags \ fstatfs \ futimens \ futimes \ @@ -2176,7 +2178,7 @@ AC_CHECK_MEMBERS([struct mtget.mt_blksiz, struct mtget.mt_gstat, struct mtget.mt #include <sys/mtio.h> #endif])
-dnl Check for stat.st_blocks and ns-resolved times +dnl Check for stat.st_blocks, ns-resolved times and flags AC_CHECK_MEMBERS([ struct stat.st_mtim, struct stat.st_mtimespec, @@ -2188,7 +2190,8 @@ AC_CHECK_MEMBERS([ struct stat.st_birthtim, struct stat.st_birthtimespec, struct stat.__st_birthtime, - struct stat.__st_birthtim]) + struct stat.__st_birthtim, + struct stat.st_flags])
dnl Check for sin6_scope_id AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id],,, diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 1c3cfa96cac..c2941f00ef4 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -1532,6 +1532,18 @@ static inline ULONG get_file_attributes( const struct stat *st ) attr = FILE_ATTRIBUTE_ARCHIVE; if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) attr |= FILE_ATTRIBUTE_READONLY; + +#ifdef HAVE_STRUCT_STAT_ST_FLAGS +#ifdef UF_HIDDEN + if (st->st_flags & UF_HIDDEN) + attr |= FILE_ATTRIBUTE_HIDDEN; +#endif +#ifdef UF_IMMUTABLE + if (st->st_flags & UF_IMMUTABLE) + attr |= FILE_ATTRIBUTE_READONLY; +#endif +#endif + return attr; }
@@ -1625,6 +1637,23 @@ static int fd_set_fat_attr( int fd, ULONG attr ) #endif
+#ifdef HAVE_FCHFLAGS +static int fd_set_flags( int fd, ULONG attr ) +{ + int flags = 0; +#ifdef UF_HIDDEN + if (attr & FILE_ATTRIBUTE_HIDDEN) + flags |= UF_HIDDEN; +#endif +#ifdef UF_IMMUTABLE + if (attr & FILE_ATTRIBUTE_READONLY) + flags |= UF_IMMUTABLE; +#endif + return fchflags( fd, flags ); +} +#endif + + static int fd_set_xattr_dos_attrib( int fd, ULONG attr ) { /* do not store everything, but keep everything Samba can use */ @@ -1647,6 +1676,11 @@ static void fd_set_dos_attrib( int fd, ULONG attr ) fd_set_fat_attr( fd, attr ); #endif
+#ifdef HAVE_FCHFLAGS + /* try setting equivalent flags on MacOS X and BSD */ + fd_set_flags( fd, attr); +#endif + /* try setting DOS attributes into extended attributes */ fd_set_xattr_dos_attrib( fd, attr ); } diff --git a/include/config.h.in b/include/config.h.in index 286697fef23..b90551c694b 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -65,6 +65,9 @@ /* Define to 1 if you have the `epoll_create' function. */ #undef HAVE_EPOLL_CREATE
+/* Define to 1 if you have the `fchflags' function. */ +#undef HAVE_FCHFLAGS + /* Define to 1 if you have the <float.h> header file. */ #undef HAVE_FLOAT_H
@@ -515,6 +518,9 @@ /* Define to 1 if `st_ctimespec' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_CTIMESPEC
+/* Define to 1 if `st_flags' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_FLAGS + /* Define to 1 if `st_mtim' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_MTIM