ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, void *value, size_t vsize) { ssize_t size = 0; char *buffer; void *ovalue = value; XattrOperations *xops; char *orig_value, *orig_value_start; ssize_t xattr_len, parsed_len = 0, attr_len; /* Get the actual len */ buffer = rpath(ctx, path); xattr_len = llistxattr(buffer, value, 0); if (xattr_len <= 0) { g_free(buffer); return xattr_len; } /* Now fetch the xattr and find the actual size */ orig_value = g_malloc(xattr_len); xattr_len = llistxattr(buffer, orig_value, xattr_len); g_free(buffer); /* store the orig pointer */ orig_value_start = orig_value; while (xattr_len > parsed_len) { xops = get_xattr_operations(ctx->xops, orig_value); if (!xops) { goto next_entry; } if (!value) { size += xops->listxattr(ctx, path, orig_value, value, vsize); } else { size = xops->listxattr(ctx, path, orig_value, value, vsize); if (size < 0) { goto err_out; } value += size; vsize -= size; } next_entry: /* Got the next entry */ attr_len = strlen(orig_value) + 1; parsed_len += attr_len; orig_value += attr_len; } if (value) { size = value - ovalue; } err_out: g_free(orig_value_start); return size; }