Module: wine Branch: master Commit: 6a512200f4719ea6b0be6de83cac632112a38b36 URL: https://gitlab.winehq.org/wine/wine/-/commit/6a512200f4719ea6b0be6de83cac632...
Author: Brendan Shanks bshanks@codeweavers.com Date: Thu May 30 15:34:34 2024 -0700
ntdll: On macOS, check for xattr existence before calling getxattr.
---
dlls/ntdll/unix/file.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index d1a6573ed69..1cafe7aa8b7 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -408,8 +408,42 @@ static int xattr_fset( int filedes, const char *name, const void *value, size_t }
+/* On macOS, getxattr() is significantly slower than listxattr() + * (even for files with no extended attributes). + */ +#ifdef __APPLE__ +static BOOL xattr_exists( const char **path, int *filedes, const char *name ) +{ + char xattrs[1024]; + ssize_t i = 0, ret; + + if (path) + ret = listxattr( *path, xattrs, sizeof(xattrs), 0 ); + else + ret = flistxattr( *filedes, xattrs, sizeof(xattrs), 0 ); + if (ret == -1) + return errno == ERANGE; + + while (i < ret) + { + if (!strcmp( name, &xattrs[i] )) + return TRUE; + i += strlen(&xattrs[i]) + 1; + } + + errno = ENOATTR; + return FALSE; +} +#endif + + static int xattr_get( const char *path, const char *name, void *value, size_t size ) { +#ifdef __APPLE__ + if (!xattr_exists( &path, NULL, name )) + return -1; +#endif + #ifdef HAVE_SYS_XATTR_H # ifdef XATTR_ADDITIONAL_OPTIONS return getxattr( path, name, value, size, 0, 0 ); @@ -428,6 +462,11 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si
static int xattr_fget( int filedes, const char *name, void *value, size_t size ) { +#ifdef __APPLE__ + if (!xattr_exists( NULL, &filedes, name )) + return -1; +#endif + #ifdef HAVE_SYS_XATTR_H # ifdef XATTR_ADDITIONAL_OPTIONS return fgetxattr( filedes, name, value, size, 0, 0 );