summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libattr/libattr.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/libattr/libattr.c b/libattr/libattr.c
index 4582e27..21ffd92 100644
--- a/libattr/libattr.c
+++ b/libattr/libattr.c
@@ -104,20 +104,27 @@ int
attr_get(const char *path, const char *attrname, char *attrvalue,
int *valuelength, int flags)
{
+ ssize_t (*get)(const char *, const char *, void *, size_t) =
+ flags & ATTR_DONTFOLLOW ? lgetxattr : getxattr;
int c, compat;
char name[MAXNAMELEN+16];
for (compat = 0; compat < 2; compat++) {
if ((c = api_convert(name, attrname, flags, compat)) < 0)
return c;
- if (flags & ATTR_DONTFOLLOW)
- c = lgetxattr(path, name, attrvalue, *valuelength);
- else
- c = getxattr(path, name, attrvalue, *valuelength);
+ c = get(path, name, attrvalue, *valuelength);
if (c < 0 && (errno == ENOATTR || errno == ENOTSUP))
continue;
break;
}
+ if (c < 0 && errno == ERANGE) {
+ int size = get(path, name, NULL, 0);
+ if (size >= 0) {
+ *valuelength = size;
+ errno = E2BIG;
+ }
+ return c;
+ }
if (c < 0)
return c;
*valuelength = c;
@@ -139,6 +146,14 @@ attr_getf(int fd, const char *attrname, char *attrvalue,
continue;
break;
}
+ if (c < 0 && errno == ERANGE) {
+ int size = fgetxattr(fd, name, NULL, 0);
+ if (size >= 0) {
+ *valuelength = size;
+ errno = E2BIG;
+ }
+ return c;
+ }
if (c < 0)
return c;
*valuelength = c;