summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--guix/build/syscalls.scm27
-rw-r--r--tests/syscalls.scm8
2 files changed, 35 insertions, 0 deletions
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index 3bb4545c04..ff008c5b78 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -79,6 +79,7 @@
fdatasync
pivot-root
scandir*
+ getxattr
setxattr
fcntl-flock
@@ -724,6 +725,32 @@ backend device."
(list (strerror err))
(list err))))))
+(define getxattr
+ (let ((proc (syscall->procedure ssize_t "getxattr"
+ `(* * * ,size_t))))
+ (lambda (file key)
+ "Get the extended attribute value for KEY on FILE."
+ (let-values (((size err)
+ ;; Get size of VALUE for buffer.
+ (proc (string->pointer/utf-8 file)
+ (string->pointer key)
+ (string->pointer "")
+ 0)))
+ (cond ((< size 0) #f)
+ ((zero? size) "")
+ ;; Get VALUE in buffer of SIZE. XXX actual size can race.
+ (else (let*-values (((buf) (make-bytevector size))
+ ((size err)
+ (proc (string->pointer/utf-8 file)
+ (string->pointer key)
+ (bytevector->pointer buf)
+ size)))
+ (if (>= size 0)
+ (utf8->string buf)
+ (throw 'system-error "getxattr" "~S: ~A"
+ (list file key (strerror err))
+ (list err))))))))))
+
(define setxattr
(let ((proc (syscall->procedure int "setxattr"
`(* * * ,size_t ,int))))
diff --git a/tests/syscalls.scm b/tests/syscalls.scm
index 7fe0cd1545..3823de7c1e 100644
--- a/tests/syscalls.scm
+++ b/tests/syscalls.scm
@@ -271,6 +271,14 @@
(scandir directory (const #t) string<?))))
(false-if-exception (delete-file temp-file))
+(test-assert "getxattr, setxattr"
+ (let ((key "user.translator")
+ (value "/hurd/pfinet\0")
+ (file (open-file temp-file "w0")))
+ (setxattr temp-file key value)
+ (string=? (getxattr temp-file key) value)))
+
+(false-if-exception (delete-file temp-file))
(test-equal "fcntl-flock wait"
42 ; the child's exit status
(let ((file (open-file temp-file "w0b")))