summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2013-10-22 18:59:58 +0200
committerAndreas Gruenbacher <agruen@linbit.com>2013-11-18 21:38:12 +0100
commit1c80572042ea4909d8487fa6eabf35d240e6c7f7 (patch)
treea4cdbc48512f306d9c2cce11b31f03028b3abd58
parentda8435b86268e29f597d748bcdf4da18900f30a6 (diff)
downloadattr-1c80572042ea4909d8487fa6eabf35d240e6c7f7.tar.gz
Make attr_get and attr_getf behave as described in the man page
This addresses bug http://savannah.nongnu.org/bugs/?40337.
-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;