Avoid shelling out for chown lookups
ober
8645f1e3f4c9c55e1fc3804bf20f5047c43e32e5
--- a/lib/jerboa-coreutils/chown.sls +++ b/lib/jerboa-coreutils/chown.sls @@ -19,44 +19,19 @@ (foreign-procedure "chown" (string int int) int)) (define ffi-lchown (foreign-procedure "lchown" (string int int) int)) + (define ffi-getpwnam-uid-c + (foreign-procedure "coreutils_getpwnam_uid" (string) int)) + (define ffi-getgrnam-gid-c + (foreign-procedure "coreutils_getgrnam_gid" (string) int)) (def (ffi-stat-isdir path) (if (file-directory? path) 1 0)) (def (ffi-getpwnam-uid name) (with-catch (lambda (e) -1) - (lambda () - (let-values ([(to-stdin from-stdout from-stderr pid) - (open-process-ports - (string-append "id -u " name " 2>/dev/null") - (buffer-mode block) - (native-transcoder))]) - (close-port to-stdin) - (let ([result (get-line from-stdout)]) - (close-port from-stdout) - (close-port from-stderr) - (if (and result (not (eof-object? result))) - (let ([n (string->number result)]) - (if n (inexact->exact n) -1)) - -1)))))) + (lambda () (ffi-getpwnam-uid-c name)))) (def (ffi-getgrnam-gid name) (with-catch (lambda (e) -1) - (lambda () - (let-values ([(to-stdin from-stdout from-stderr pid) - (open-process-ports - (string-append - "getent group " - name - " 2>/dev/null | cut -d: -f3") - (buffer-mode block) - (native-transcoder))]) - (close-port to-stdin) - (let ([result (get-line from-stdout)]) - (close-port from-stdout) - (close-port from-stderr) - (if (and result (not (eof-object? result))) - (let ([n (string->number result)]) - (if n (inexact->exact n) -1)) - -1)))))) + (lambda () (ffi-getgrnam-gid-c name)))) (def (string-find-char str ch) (let loop ([i 0]) (cond --- a/src/jerboa-coreutils/chown.ss +++ b/src/jerboa-coreutils/chown.ss @@ -16,6 +16,8 @@ (define ffi-chown (foreign-procedure "chown" (string int int) int)) (define ffi-lchown (foreign-procedure "lchown" (string int int) int)) +(define ffi-getpwnam-uid-c (foreign-procedure "coreutils_getpwnam_uid" (string) int)) +(define ffi-getgrnam-gid-c (foreign-procedure "coreutils_getgrnam_gid" (string) int)) (def (ffi-stat-isdir path) (if (file-directory? path) 1 0)) @@ -23,38 +25,12 @@ (def (ffi-getpwnam-uid name) (with-catch (lambda (e) -1) - (lambda () - (let-values (((to-stdin from-stdout from-stderr pid) - (open-process-ports - (string-append "id -u " name " 2>/dev/null") - (buffer-mode block) - (native-transcoder)))) - (close-port to-stdin) - (let ((result (get-line from-stdout))) - (close-port from-stdout) - (close-port from-stderr) - (if (and result (not (eof-object? result))) - (let ((n (string->number result))) - (if n (inexact->exact n) -1)) - -1)))))) + (lambda () (ffi-getpwnam-uid-c name)))) (def (ffi-getgrnam-gid name) (with-catch (lambda (e) -1) - (lambda () - (let-values (((to-stdin from-stdout from-stderr pid) - (open-process-ports - (string-append "getent group " name " 2>/dev/null | cut -d: -f3") - (buffer-mode block) - (native-transcoder)))) - (close-port to-stdin) - (let ((result (get-line from-stdout))) - (close-port from-stdout) - (close-port from-stderr) - (if (and result (not (eof-object? result))) - (let ((n (string->number result))) - (if n (inexact->exact n) -1)) - -1)))))) + (lambda () (ffi-getgrnam-gid-c name)))) (def (string-find-char str ch) (let loop ((i 0)) --- a/support/libcoreutils.c +++ b/support/libcoreutils.c @@ -62,7 +62,7 @@ int coreutils_getgrnam_gid(const char *name) { /* ========== stat helpers ========== */ -static struct stat stat_result_buf; +static __thread struct stat stat_result_buf; int coreutils_stat_call(const char *path, int follow) { int rc = follow ? stat(path, &stat_result_buf) : lstat(path, &stat_result_buf); @@ -117,7 +117,7 @@ long coreutils_du_stat(const char *path, int field) { /* ========== df / statvfs helpers ========== */ -static struct statvfs statvfs_result_buf; +static __thread struct statvfs statvfs_result_buf; int coreutils_statvfs(const char *path) { if (statvfs(path, &statvfs_result_buf) < 0) return -1;