From: "Erich E. Hoover" erich.e.hoover@gmail.com
--- configure.ac | 2 +- dlls/ntdll/unix/file.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac index d7803b875f2..3ea4c2afe0a 100644 --- a/configure.ac +++ b/configure.ac @@ -638,7 +638,7 @@ AC_CHECK_HEADERS([libprocstat.h],,,
if test "x$with_xattr" != "xno" then - AC_CHECK_HEADERS(attr/xattr.h, [HAVE_XATTR=1]) + AC_CHECK_HEADERS(attr/xattr.h sys/extattr.h, [HAVE_XATTR=1]) 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)])])]) diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 1090b5fd563..d85c69cb1bc 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -104,6 +104,10 @@ #elif defined(HAVE_SYS_XATTR_H) #include <sys/xattr.h> #endif +#ifdef HAVE_SYS_EXTATTR_H +#undef XATTR_ADDITIONAL_OPTIONS +#include <sys/extattr.h> +#endif #include <time.h> #include <unistd.h>
@@ -364,6 +368,21 @@ NTSTATUS errno_to_status( int err ) #ifndef XATTR_USER_PREFIX #define XATTR_USER_PREFIX "user." #endif +#ifndef XATTR_USER_PREFIX_LEN +#define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1) +#endif + +#ifdef HAVE_SYS_EXTATTR_H +static inline int xattr_valid_namespace( const char *name ) +{ + if (strncmp( XATTR_USER_PREFIX, name, XATTR_USER_PREFIX_LEN ) != 0) + { + errno = EPERM; + return 0; + } + return 1; +} +#endif
static int xattr_fremove( int filedes, const char *name ) { @@ -371,6 +390,9 @@ static int xattr_fremove( int filedes, const char *name ) return fremovexattr( filedes, name, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return fremovexattr( filedes, name ); +#elif defined(HAVE_SYS_EXTATTR_H) + if (!xattr_valid_namespace( name )) return -1; + return extattr_delete_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN] ); #else errno = ENOSYS; return -1; @@ -383,6 +405,10 @@ static int xattr_fset( int filedes, const char *name, void *value, size_t size ) return fsetxattr( filedes, name, value, size, 0, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return fsetxattr( filedes, name, value, size, 0 ); +#elif defined(HAVE_SYS_EXTATTR_H) + if (!xattr_valid_namespace( name )) return -1; + return extattr_set_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN], + value, size ); #else errno = ENOSYS; return -1; @@ -395,6 +421,10 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si return getxattr( path, name, value, size, 0, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return getxattr( path, name, value, size ); +#elif defined(HAVE_SYS_EXTATTR_H) + if (!xattr_valid_namespace( name )) return -1; + return extattr_get_file( path, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN], + value, size ); #else errno = ENOSYS; return -1; @@ -407,6 +437,9 @@ static int xattr_remove( const char *path, const char *name ) return removexattr( path, name, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return removexattr( path, name ); +#elif defined(HAVE_SYS_EXTATTR_H) + if (!xattr_valid_namespace( name )) return -1; + return extattr_delete_file( path, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN] ); #else errno = ENOSYS; return -1; @@ -419,6 +452,10 @@ static int xattr_set( const char *path, const char *name, void *value, size_t si return setxattr( path, name, value, size, 0, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return setxattr( path, name, value, size, 0 ); +#elif defined(HAVE_SYS_EXTATTR_H) + if (!xattr_valid_namespace( name )) return -1; + return extattr_set_file( path, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN], + value, size ); #else errno = ENOSYS; return -1;