From: Dmitry Bogatov <kact...@gnu.org> * module/ice-9/xattr.scm (xattr-get): convert exception to #f if errno was ENOATTR --- module/ice-9/xattr.scm | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/module/ice-9/xattr.scm b/module/ice-9/xattr.scm index 090b233..804d374 100644 --- a/module/ice-9/xattr.scm +++ b/module/ice-9/xattr.scm @@ -101,14 +101,25 @@ (%ret = (if (port? file) (c-attr-getf (port->fdes file) attrname attrvalue valuelength flags) (c-attr-get file attrname attrvalue valuelength flags))) - (unless (zero? %ret) - (c-scm-syserror "xattr-get")) ;; No matter how long actual value is, attrvalue is bytevector ;; with length of `max-valuelen'. We need only first `valuelength' ;; from it. It is unexpectedly complicated to splice bytevectory. - (let () - (define value - (pointer->bytevector (bytevector->pointer attrvalue) valuelength)) - (if decode? - (bytevector->string value "utf-8") - (bytevector-copy value))))) + (define result + (delay + (let ((value (pointer->bytevector (bytevector->pointer attrvalue) + valuelength))) + (if decode? + (bytevector->string value "utf-8") + (bytevector-copy value))))) ; unshare with 64Kb bytevector + (define (xattr-get/syserror) (c-scm-syserror "xattr-get")) + ;; Really ugly way to get errno. We throw exception via internal + ;; Guile function 'scm_syserror' just to catch it and extract errno. + ;; If it is ENODATA (ENOATTR in manual page) it is not exceptional, + ;; and we return #f. + (if (zero? %ret) + (force result) + (catch #t xattr-get/syserror + (lambda _args + (unless (eqv? ENODATA (system-error-errno _args)) + (xattr-get/syserror)) + #f))))) -- I may be not subscribed. Please, keep me in carbon copy.