From a9004ce32f79f2244f0882bd0e69248ea0c9c791 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Thu, 6 Nov 2014 16:06:23 +0100 Subject: 33607: Fix some minor problems in zattr module Remove the listattr call in zgetattr, it only caused no error to be output when trying to retrieve an xattr from a file with no xattrs. When a file had xattrs, it would just add an extra syscall for no good reason. Always set an array parameter in zlistattr, this makes the returned value much easier to use; in fact the _zattr completer didn't account for this and zlistattr foo on a file with only one attribute did not work. Almost all of the patch is only reindent, the only modification that's not a pure deletions is: - ret = 1 + (attr_len > val_len || attr_len < 0); + ret = 1 + ((val_len > 0 && attr_len > val_len) || attr_len < 0); which makes sure we return the correct error in the new path due to the removed listattr call. (If val_len is -1 due to no attribute existing, it doesn't mean the user should retry the call because the attribute grew in size). --- Src/Modules/attr.c | 67 ++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 37 deletions(-) (limited to 'Src/Modules/attr.c') diff --git a/Src/Modules/attr.c b/Src/Modules/attr.c index 6e08b10c5..78c1104a9 100644 --- a/Src/Modules/attr.c +++ b/Src/Modules/attr.c @@ -98,36 +98,33 @@ static int bin_getattr(char *nam, char **argv, Options ops, UNUSED(int func)) { int ret = 0; - int list_len, val_len = 0, attr_len = 0, slen; + int val_len = 0, attr_len = 0, slen; char *value, *file = argv[0], *attr = argv[1], *param = argv[2]; int symlink = OPT_ISSET(ops, 'h'); unmetafy(file, &slen); unmetafy(attr, NULL); - list_len = xlistxattr(file, NULL, 0, symlink); - if (list_len > 0) { - val_len = xgetxattr(file, attr, NULL, 0, symlink); - if (val_len == 0) { + val_len = xgetxattr(file, attr, NULL, 0, symlink); + if (val_len == 0) { + if (param) + unsetparam(param); + return 0; + } + if (val_len > 0) { + value = (char *)zalloc(val_len+1); + attr_len = xgetxattr(file, attr, value, val_len, symlink); + if (attr_len > 0 && attr_len <= val_len) { + value[attr_len] = '\0'; if (param) - unsetparam(param); - return 0; - } - if (val_len > 0) { - value = (char *)zalloc(val_len+1); - attr_len = xgetxattr(file, attr, value, val_len, symlink); - if (attr_len > 0 && attr_len <= val_len) { - value[attr_len] = '\0'; - if (param) - setsparam(param, metafy(value, attr_len, META_DUP)); - else - printf("%s\n", value); - } - zfree(value, val_len+1); + setsparam(param, metafy(value, attr_len, META_DUP)); + else + printf("%s\n", value); } + zfree(value, val_len+1); } - if (list_len < 0 || val_len < 0 || attr_len < 0 || attr_len > val_len) { + if (val_len < 0 || attr_len < 0 || attr_len > val_len) { zwarnnam(nam, "%s: %e", metafy(file, slen, META_NOALLOC), errno); - ret = 1 + (attr_len > val_len || attr_len < 0); + ret = 1 + ((val_len > 0 && attr_len > val_len) || attr_len < 0); } return ret; } @@ -189,24 +186,20 @@ bin_listattr(char *nam, char **argv, Options ops, UNUSED(int func)) if (list_len > 0 && list_len <= val_len) { char *p = value; if (param) { - if (strlen(value) + 1 == list_len) - setsparam(param, metafy(value, list_len-1, META_DUP)); - else { - int arrlen = 0; - char **array = NULL, **arrptr = NULL; + int arrlen = 0; + char **array = NULL, **arrptr = NULL; - while (p < &value[list_len]) { - arrlen++; - p += strlen(p) + 1; - } - arrptr = array = (char **)zshcalloc((arrlen+1) * sizeof(char *)); - p = value; - while (p < &value[list_len]) { - *arrptr++ = metafy(p, -1, META_DUP); - p += strlen(p) + 1; - } - setaparam(param, array); + while (p < &value[list_len]) { + arrlen++; + p += strlen(p) + 1; + } + arrptr = array = (char **)zshcalloc((arrlen+1) * sizeof(char *)); + p = value; + while (p < &value[list_len]) { + *arrptr++ = metafy(p, -1, META_DUP); + p += strlen(p) + 1; } + setaparam(param, array); } else while (p < &value[list_len]) { printf("%s\n", p); p += strlen(p) + 1; -- cgit v1.2.3