From: Wayne Davison Date: Mon, 25 Nov 2013 21:12:09 +0000 (-0800) Subject: Use chunked xattr reading in OS X sys_lgetxattr(). X-Git-Tag: v3.1.1pre1~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2cd87086f05d0a6d943e8fa71f7f6b53b5375d56;p=thirdparty%2Frsync.git Use chunked xattr reading in OS X sys_lgetxattr(). --- diff --git a/lib/sysxattrs.c b/lib/sysxattrs.c index d55ee0c2..ba1a2905 100644 --- a/lib/sysxattrs.c +++ b/lib/sysxattrs.c @@ -24,6 +24,10 @@ #ifdef SUPPORT_XATTRS +#ifdef HAVE_OSX_XATTRS +#define GETXATTR_FETCH_LIMIT (64*1024*1024) +#endif + #if defined HAVE_LINUX_XATTRS ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size) @@ -55,7 +59,24 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size) ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size) { - return getxattr(path, name, value, size, 0, XATTR_NOFOLLOW); + ssize_t len = getxattr(path, name, value, size, 0, XATTR_NOFOLLOW); + + /* If we're retrieving data, handle resource forks > 64MB specially */ + if (value != NULL && len == GETXATTR_FETCH_LIMIT && (size_t)len < size) { + /* getxattr will only return 64MB of data at a time, need to call again with a new offset */ + u_int32_t offset = len; + size_t data_retrieved = len; + while (data_retrieved < size) { + len = getxattr(path, name, value + offset, size - data_retrieved, offset, XATTR_NOFOLLOW); + if (len <= 0) + break; + data_retrieved += len; + offset += (u_int32_t)len; + } + len = data_retrieved; + } + + return len; } ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)