From f361c293c02c92eab9830b83f2107eeff962d9c1 Mon Sep 17 00:00:00 2001 From: Stefan Israelsson Tampe Date: Sun, 11 Mar 2018 22:02:10 +0100 Subject: stat module finished and walkings --- modules/language/python/module/os.scm | 211 ++++++++++++++++++++++++++++++++ modules/language/python/module/stat.scm | 99 +++++++++++++-- 2 files changed, 300 insertions(+), 10 deletions(-) (limited to 'modules') diff --git a/modules/language/python/module/os.scm b/modules/language/python/module/os.scm index ad4d2e3..1dbe30e 100644 --- a/modules/language/python/module/os.scm +++ b/modules/language/python/module/os.scm @@ -1082,3 +1082,214 @@ (bytevector-u64-ref bv 8 (native-endianness)) (bytevector-u64-ref bv 9 (native-endianness)) (bytevector-u64-ref bv 10 (native-endianness))))))) + +(define symlink + (let ((fat (pointer->procedure int + (dynamic-func "symlinkat" (dynamic-link)) + (list '* int '*)))) + + (lambda* (src dst #:key (target_is_directory #f) (dir_fd None)) + (rm (fat ((string->pointer (path-it dst)) + (if (eq? dir_fd None) AT_FDCWD dir_fd) + (string->pointer (path-it src)))))))) + +(define truncate + (let ((ff (pointer->procedure int + (dynamic-func "ftruncate" (dynamic-link)) + (list int long))) + (f (pointer->procedure int + (dynamic-func "truncate" (dynamic-link)) + (list '* long)))) + + (lambda (path length) + (rm (if (number? path) + (ff path length) + (f (string->pointer (path-it path)) + length)))))) + +(define UTIME_NOW (- (ash 1 30) 1)) +(define utime + (let ((ff (pointer->procedure int + (dynamic-func "futimens" (dynamic-link)) + (int '*))) + (fat (pointer->procedure int + (dynamic-func "futimensat" (dynamic-link)) + (int '* '* int))) + + (lambda* (path #:optional (times None) (ns #f) #:key (dir_fd None) + (follow_symlinks #t)) + (let* ((bv (make-bytevector 32)) + (bvp (byteector->pointer bv))) + (if (eq? ns None) + (if (eq? times None) + (let () + (bytevector-s64-set! bv 0 0 + (native-endianness)) + (bytevector-s64-set! bv 1 0 UTIME_NOW + (native-endianness)) + (bytevector-s64-set! bv 2 0 + (native-endianness)) + (bytevector-s64-set! bv 3 UTIME_NOW + (native-endianness))) + (let ((x1 (pylist-ref ns 0)) + (x2 (pylist-ref ns 1))) + (bytevector-s64-set! bv 0 (floor-quotient x1 1000000000) + (native-endianness)) + (bytevector-s64-set! bv 1 (modulo x1 1000000000) + (native-endianness)) + (bytevector-s64-set! bv 2 (floor-quotient x2 1000000000) + (native-endianness)) + (bytevector-s64-set! bv 3 (modulo x2 1000000000) + (native-endianness)))) + (if (eq? times None) + (begin + (bytevector-s64-set! bv 0 (pylist-ref times 0) + (native-endianness)) + (bytevector-s64-set! bv 1 0 + (native-endianness)) + (bytevector-s64-set! bv 2 (pylist-ref times 1) + (native-endianness)) + (bytevector-s64-set! bv 3 0 + (native-endianness))) + (raise error "utime cannot set both s and ns"))) + (rm (if (number? path) + (ff path bvp) + (fat (if (eq? dir_fd AT_FDCWD None) dir_fd) bvp + (string->pointer (path-it path)) + (if follow_symlinks + 0 + AT_SYMLINK_NOFOLLOW))))))))) + + +(define* (walk top #:key (topdown #t) (onerror None) (followlinks #f)) + ((make-generator () + (lambda (yield) + (let/ec ret + (define dirs (py-list)) + (define nondirs (py-list)) + (define entries #f) + + (try + (lambda () + (set! entries (py-list (scandir top)))) + (#except error => + (lambda (x . _) + (if onerror (onerror x) (ret))))) + + (for ((entry : entries)) () + (define is_dir (try + (lambda ((ref entry 'is_dir))) + (#:except error => (lambda x #f)))) + (if is_dir + (pylist-append! dirs (ref entry 'name)) + (pylist-append! nondirs (ref entry 'name))) + + (if (and (not topdown) is_dir) + (let ((walk-into + (if followlinks + #t + (not + (try + (lambda () ((ref entry 'is_symlink))) + (#:except error => (lambda x #f))))))) + (if walk_into + (for ((a b c : (walk (ref entry 'path) topdown + onerror followlinks))) () + (yield a b c))))) + + (if topdown + (begin + (yield top dirs nondirs) + + (let ((islink (ref path 'islink)) + (join (ref path 'join))) + (for ((dirname : dirs)) () + (let ((new_path (join top dirname))) + (if (or followlinks (not (islink new_path))) + (for ((a b c : (walk new_path topdown onerror + followlinks))) () + (yield a b c))))))) + (yield top dirs nondirs)))))))) + + +(define (_fwalk topfd toppath topdown onerror follow_symlinks) + ((make-generator () + (lambda (yield) + (define names (listdir topfd)) + (define dir (py-list)) + (define nondirs (py-list)) + + (for ((name : names)) () + (try + (lambda () + (if (S_ISDIR (ref (stat name #:dir_fd topfd) 'st_mode)) + (pylist-append! dirs name) + (pylist-append! nondirs name))) + (#:except error => + (lambda x + (try + (lambda () + (if (S_ISLNK (ref (stat name #:dir_fd topfd + #:follow_symlinks #f) + 'st_mode)) + (pylist-append! nondirs name))) + (#:except error => (lambda x (values)))))))) + + (if topdown + (yield toppath dirs nondirs topfd)) + + (for continue ((name : dirs)) () + (call-with-values + (lambda () + (try + (lambda () + (values (stat name #:dir_fd topfd + #:follow_symlinks follow_symlinks)) + (open name O_RDONLY #:dir_fd topfd)) + (#:except errpr => + (lambda (err . l) + (if (not (eq? onerror None)) + (onerror err) + (continue)))))) + (lambda (orig_st dirfd) + (try + (lambda () + (if (or follow_symlinks (path:samestat orig_st (stat dirfd))) + (let ((dirpath (path:join toppath name))) + (for ((a b c d : + (_fwalk dirfd dirpath topdown onerror + follow_symlinks))) () + (yield a b c d))))) + (#:finally + (close dirfd)))))) + + (if not topdown + (yield toppath dirs nondirs topfd)))))) + +(define* (fwalk #:optinal (top ".") (topdown #t) (onerror #t) + #:key (follow_symlinks #f) (dir_fd None)) + ((make-generator () + (lambda (yield) + (define orig_st (stat top #:follow_symlinks #f #:dir_fd dir_fd)) + (define topfd (open top O_RDONLY #:dir_fd dir_fd)) + + (try + (if (or follow_symlinks or (and (S_ISDIR (ref orig_st 'st_mode)) + (path:samestat orig_st (stat topfd)))) + (for ((a b c d : (_fwalk topfd top topdown onerror follow_symlinks))) + () + (yield a b c d))) + (#:finally: + (close topfd))))))) + + +(define supprts_dir_fs + (set '())) + +(define support_effective_ids + (set '())) + +(define supports_fd + (set '())) + + diff --git a/modules/language/python/module/stat.scm b/modules/language/python/module/stat.scm index cb314b7..a430562 100644 --- a/modules/language/python/module/stat.scm +++ b/modules/language/python/module/stat.scm @@ -1,10 +1,29 @@ (define-module (language python module stat) - #:export ()) + #:export (ST_MODE ST_INO ST_DEV ST_NLINK ST_UID ST_GID ST_SIZE ST_ATIME + ST_MTIME ST_CTIME S_ISUID S_ISGID S_ENFMT S_ISVTX S_IREAD + S_IWRITE S_IEXEC S_IRWXU S_IRUSR S_IWUSR S_IXUSR S_IRGRP + S_IWGRP S_IXGRP S_IRWXG S_IROTH S_IWOTH S_IXOTH S_IRWXO + S_IFDIR S_IFREG S_IFLNK S_IFCHR S_IFBLK S_IFIFO S_IFSOC + UF_NODUMP UF_IMMUTABLE UF_APPEND UF_OPAQUE UF_NOUNLINK + UF_COMPRESSED UF_HIDDEN SF_ARCHIVED SF_IMMUTABLE SF_APPEND + SF_NOUNLINK SF_SNAPSHOT S_ISDIR S_ISREG S_ISLNK S_ISCHR + S_ISBLK S_ISFIFO S_ISSOCK S_IMODE S_IFMT + filemode)) +(define ST_MODE 0) +(define ST_INO 1) +(define ST_DEV 2) +(define ST_NLINK 3) +(define ST_UID 4) +(define ST_GID 5) +(define ST_SIZE 6) +(define ST_ATIME 7) +(define ST_MTIME 8) +(define ST_CTIME 9) (define S_ISUID #o04000) (define S_ISGID #o02000) -(define S_ENFMT "error") +(define S_ENFMT S_ISGID) (define S_ISVTX #o01000) (define S_IREAD #o00400) (define S_IWRITE #o00200) @@ -22,17 +41,77 @@ (define S_IXOTH #o00001) (define S_IRWXO (logior S_IXOTH S_IWOTH S_IROTH)) +;;Internal +(define SS_IFMT #o170000) + + (define S_IFDIR #o040000) -(define S_IFMT #o170000) (define S_IFREG #o100000) (define S_IFLNK #o120000) (define S_IFCHR #o020000) (define S_IFBLK #o060000) (define S_IFIFO #o010000) - -(define (is-dir? x) (= (logand x S_IFMT) S_IFDIR)) -(define (is-reg? x) (= (logand x S_IFMT) S_IFREG)) -(define (is-lnk? x) (= (logand x S_IFMT) S_IFLNK)) -(define (is-chr? x) (= (logand x S_IFMT) S_IFCHR)) -(define (is-blk? x) (= (logand x S_IFMT) S_IFBLK)) -(define (is-fif? x) (= (logand x S_IFMT) S_IFIFO)) +(define S_IFSOCK #o140000) + +(define (S_ISDIR x) (= (logand x SS_IFMT) S_IFDIR)) +(define (S_ISREG x) (= (logand x SS_IFMT) S_IFREG)) +(define (S_ISLNK x) (= (logand x SS_IFMT) S_IFLNK)) +(define (S_ISCHR x) (= (logand x SS_IFMT) S_IFCHR)) +(define (S_ISBLK x) (= (logand x SS_IFMT) S_IFBLK)) +(define (S_ISFIFO x) (= (logand x SS_IFMT) S_IFIFO)) +(define (S_ISSOCK x) (= (logand x SS_IFMT) S_IFSOCK)) +(define (S_IMODE x) (logand x #o7777)) +(define (S_IFMT x) (logand x SS_IFMT)) + +(define UF_NODUMP #x00000001) +(define UF_IMMUTABLE #x00000002) +(define UF_APPEND #x00000004) +(define UF_OPAQUE #x00000008) +(define UF_NOUNLINK #x00000010) +(define UF_COMPRESSED #x00000020) +(define UF_HIDDEN #x00008000) +(define SF_ARCHIVED #x00010000) +(define SF_IMMUTABLE #x00020000) +(define SF_APPEND #x00040000) +(define SF_NOUNLINK #x00100000) +(define SF_SNAPSHOT #x00200000) + +(define _filemode_table + `(((,S_IFLNK "l") + (,S_IFREG "-") + (,S_IFBLK "b") + (,S_IFDIR "d") + (,S_IFCHR "c") + (,S_IFIFO "p")) + + ((,S_IRUSR "r")) + ((,S_IWUSR "w")) + ((,(logior S_IXUSR S_ISUID) "s") + (,S_ISUID "S") + (,S_IXUSR "x")) + + ((,S_IRGRP "r")) + ((,S_IWGRP "w")) + ((,(logior S_IXGRP S_ISGID) "s") + (,S_ISGID "S") + (,S_IXGRP "x")) + + ((,S_IROTH "r"),) + ((,S_IWOTH "w"),) + ((,(logior S_IXOTH S_ISVTX) "t") + (,S_ISVTX "T") + (,S_IXOTH "x")))) + +(define (filemode mode) + """Convert a file's mode to a string of the form '-rwxrwxrwx'.""" + (define perm (py-list)) + + (for ((table : _filemode_table)) () + (for ((bit char : table)) () + (if (= (logand mode bit) bit) + (pylist-append! perm char) + (break)) + #:final + (pylist-append! perm "-"))) + + (py-string-join "" perm)) -- cgit v1.2.3