From 1c80572042ea4909d8487fa6eabf35d240e6c7f7 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Tue, 22 Oct 2013 18:59:58 +0200 Subject: Make attr_get and attr_getf behave as described in the man page This addresses bug http://savannah.nongnu.org/bugs/?40337. --- libattr/libattr.c | 23 +++++++++++++++++++---- 1 file 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; -- cgit v1.2.1