diff options
author | Wayne Davison <wayned@samba.org> | 2013-11-25 13:12:09 -0800 |
---|---|---|
committer | Wayne Davison <wayned@samba.org> | 2013-11-25 13:12:09 -0800 |
commit | 2cd87086f05d0a6d943e8fa71f7f6b53b5375d56 (patch) | |
tree | 2a79b6be4e05062c5b6a826e76f314c419576c33 /lib | |
parent | eaa4e2d1ee5518f3d785279cacf6bf794473ef16 (diff) | |
download | rsync-2cd87086f05d0a6d943e8fa71f7f6b53b5375d56.tar.gz rsync-2cd87086f05d0a6d943e8fa71f7f6b53b5375d56.tar.bz2 rsync-2cd87086f05d0a6d943e8fa71f7f6b53b5375d56.zip |
Use chunked xattr reading in OS X sys_lgetxattr().
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sysxattrs.c | 23 |
1 files changed, 22 insertions, 1 deletions
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) |