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_HIDDEN can reprent FILE_ATTRIBUTE_HIDDEN * UF_IMMUTABLE can represent FILE_ATTRIBUTE_READONLY (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 | 57 ++++++++++++++++++++++++++++++++++++++++++ configure.ac | 15 +++++++++-- dlls/ntdll/unix/file.c | 34 +++++++++++++++++++++++++ include/config.h.in | 12 +++++++++ 4 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/configure b/configure index 1b78fe7bcc9..e1cef83f691 100755 --- a/configure +++ b/configure @@ -9153,6 +9153,49 @@ fi
done
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/stat.h> +int +main (void) +{ +#ifndef UF_IMMUTABLE +#error no +#endif + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +printf "%s\n" "#define HAVE_UF_IMMUTABLE 1" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/stat.h> +int +main (void) +{ +#ifndef UF_HIDDEN +#error no +#endif + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +printf "%s\n" "#define HAVE_UF_HIDDEN 1" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +
DLLFLAGS=""
@@ -19691,6 +19734,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 +20765,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..ae7539492cd 100644 --- a/configure.ac +++ b/configure.ac @@ -641,6 +641,15 @@ 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)])])])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/stat.h>]], [[#ifndef UF_IMMUTABLE +#error no +#endif]])], [AC_DEFINE(HAVE_UF_IMMUTABLE, 1, [Defined if chflags function support UF_IMMUTABLE flag])]) + +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/stat.h>]], [[#ifndef UF_HIDDEN +#error no +#endif]])], [AC_DEFINE(HAVE_UF_HIDDEN, 1, [Defined if chflags function support UF_HIDDEN flag])]) + + dnl **** Check for working dll ****
AC_SUBST(DLLFLAGS,"") @@ -2005,6 +2014,7 @@ ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $BUILTINFLAG" AC_CHECK_FUNCS(\ epoll_create \ + fchflags \ fstatfs \ futimens \ futimes \ @@ -2176,7 +2186,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 +2198,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 8f7d1bfd12c..48058f12a2e 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 HAVE_UF_HIDDEN + if (st->st_flags & UF_HIDDEN) + attr |= FILE_ATTRIBUTE_HIDDEN; +#endif +#ifdef HAVE_UF_IMMUTABLE + if (st->st_flags & UF_IMMUTABLE) + attr |= FILE_ATTRIBUTE_READONLY; +#endif +#endif + return attr; }
@@ -1625,6 +1637,23 @@ static BOOL fd_set_fat_attr( int fd, ULONG attr ) #endif
+#ifdef HAVE_FCHFLAGS +static BOOL fd_set_flags( int fd, ULONG attr ) +{ + int flags = 0; +#ifdef HAVE_UF_HIDDEN + if (attr & FILE_ATTRIBUTE_HIDDEN) + flags |= UF_HIDDEN; +#endif +#ifdef HAVE_UF_IMMUTABLE + if (attr & FILE_ATTRIBUTE_READONLY) + flags |= UF_IMMUTABLE; +#endif + return fchflags( fd, flags ) == 0; +} +#endif + + static BOOL fd_set_xattr_dos_attrib( int fd, ULONG attr ) { /* do not store everything, but keep everything Samba can use */ @@ -1665,6 +1694,11 @@ NTSTATUS fd_set_file_info( 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..3d889d2af44 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
@@ -700,6 +706,12 @@ /* Define to 1 if you have the `udev' library (-ludev). */ #undef HAVE_UDEV
+/* Defined if chflags function support UF_HIDDEN flag */ +#undef HAVE_UF_HIDDEN + +/* Defined if chflags function support UF_IMMUTABLE flag */ +#undef HAVE_UF_IMMUTABLE + /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H