diff --git a/basis/io/directories/directories.factor b/basis/io/directories/directories.factor index 91401515f5..86c2778cd7 100644 --- a/basis/io/directories/directories.factor +++ b/basis/io/directories/directories.factor @@ -31,7 +31,7 @@ HOOK: make-directory io-backend ( path -- ) ! Listing directories TUPLE: directory-entry name type ; -HOOK: >directory-entry os ( byte-array -- directory-entry ) +C: directory-entry HOOK: (directory-entries) os ( path -- seq ) diff --git a/basis/io/directories/unix/linux/linux.factor b/basis/io/directories/unix/linux/linux.factor index 318a870a5b..75a6ba7a8a 100644 --- a/basis/io/directories/unix/linux/linux.factor +++ b/basis/io/directories/unix/linux/linux.factor @@ -1,11 +1,16 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: alien.c-types alien.data io.directories.unix kernel libc -system unix classes.struct unix.ffi ; +math system unix classes.struct unix.ffi ; IN: io.directories.unix.linux -M: linux find-next-file ( DIR* -- dirent ) - dirent - f void* - [ [ readdir64_r ] unix-system-call 0 = [ (io-error) ] unless ] 2keep - void* deref [ drop f ] unless ; +: next-dirent ( DIR* dirent* -- dirent* ? ) + f void* [ + readdir64_r [ dup strerror libc-error ] unless-zero + ] 2keep void* deref ; inline + +M: linux (directory-entries) ( path -- seq ) + [ + dirent + '[ _ _ next-dirent ] [ >directory-entry ] produce nip + ] with-unix-directory ; diff --git a/basis/io/directories/unix/unix.factor b/basis/io/directories/unix/unix.factor index 8170075cd1..a17a8180df 100644 --- a/basis/io/directories/unix/unix.factor +++ b/basis/io/directories/unix/unix.factor @@ -4,7 +4,7 @@ USING: accessors alien.c-types alien.data alien.strings assocs combinators continuations destructors fry io io.backend io.directories io.encodings.binary io.files.info.unix io.encodings.utf8 io.files io.pathnames io.files.types kernel -math.bitwise sequences system unix unix.stat vocabs.loader +math math.bitwise sequences system unix unix.stat vocabs.loader classes.struct unix.ffi literals libc vocabs io.files.info ; IN: io.directories.unix @@ -40,15 +40,6 @@ M: unix copy-file ( from to -- ) dupd curry swap '[ _ closedir io-error ] [ ] cleanup ] with-directory ; inline -HOOK: find-next-file os ( DIR* -- byte-array ) - -M: unix find-next-file ( DIR* -- byte-array ) - dirent - f void* - 0 set-errno - [ readdir_r 0 = [ errno 0 = [ (io-error) ] unless ] unless ] 2keep - void* deref [ drop f ] unless ; - : dirent-type>file-type ( type -- file-type ) H{ { $ DT_BLK +block-device+ } @@ -63,25 +54,22 @@ M: unix find-next-file ( DIR* -- byte-array ) ! An easy way to return +unknown+ is to mount a .iso on OSX and ! call directory-entries on the mount point. -: dirent>file-type ( dirent -- type ) - dup d_type>> dirent-type>file-type - dup +unknown+ = [ - drop d_name>> utf8 alien>string file-info type>> - ] [ - nip - ] if ; -M: unix >directory-entry ( byte-array -- directory-entry ) - { - [ d_name>> underlying>> utf8 alien>string ] - [ dirent>file-type ] - } cleave directory-entry boa ; +: next-dirent ( DIR* dirent* -- dirent* ? ) + f void* [ + readdir_r [ dup strerror libc-error ] unless-zero + ] 2keep void* deref ; inline + +: >directory-entry ( dirent* -- directory-entry ) + [ d_name>> utf8 alien>string ] + [ d_type>> dirent-type>file-type ] bi + dup +unknown+ = [ drop dup file-info type>> ] when + ; inline M: unix (directory-entries) ( path -- seq ) [ - '[ _ find-next-file dup ] - [ >directory-entry ] - produce nip + dirent + '[ _ _ next-dirent ] [ >directory-entry ] produce nip ] with-unix-directory ; os linux? [ "io.directories.unix.linux" require ] when diff --git a/basis/io/directories/windows/windows.factor b/basis/io/directories/windows/windows.factor index 46ce2ec441..2168eeffed 100644 --- a/basis/io/directories/windows/windows.factor +++ b/basis/io/directories/windows/windows.factor @@ -48,13 +48,11 @@ M: windows delete-directory ( path -- ) normalize-path RemoveDirectory win32-error=0/f ; -: find-first-file ( path -- WIN32_FIND_DATA handle ) - WIN32_FIND_DATA +: find-first-file ( path WIN32_FIND_DATA -- WIN32_FIND_DATA HANDLE ) [ nip ] [ FindFirstFile ] 2bi [ INVALID_HANDLE_VALUE = [ win32-error-string throw ] when ] keep ; -: find-next-file ( path -- WIN32_FIND_DATA/f ) - WIN32_FIND_DATA +: find-next-file ( HANDLE WIN32_FIND_DATA -- WIN32_FIND_DATA/f ) [ nip ] [ FindNextFile ] 2bi 0 = [ GetLastError ERROR_NO_MORE_FILES = [ win32-error @@ -63,23 +61,27 @@ M: windows delete-directory ( path -- ) TUPLE: windows-directory-entry < directory-entry attributes ; -M: windows >directory-entry ( byte-array -- directory-entry ) +C: windows-directory-entry + +: >windows-directory-entry ( WIN32_FIND_DATA -- directory-entry ) [ cFileName>> alien>native-string ] [ dwFileAttributes>> [ win32-file-type ] [ win32-file-attributes ] bi ] bi - dupd remove windows-directory-entry boa ; + dupd remove ; inline M: windows (directory-entries) ( path -- seq ) "\\" ?tail drop "\\*" append - find-first-file [ >directory-entry ] dip + WIN32_FIND_DATA + find-first-file over + [ >windows-directory-entry ] 2dip [ '[ - [ _ find-next-file dup ] - [ >directory-entry ] + [ _ _ find-next-file dup ] + [ >windows-directory-entry ] produce nip over name>> "." = [ nip ] [ swap prefix ] if ] - ] [ '[ _ FindClose win32-error=0/f ] ] bi [ ] cleanup ; + ] [ drop '[ _ FindClose win32-error=0/f ] ] 2bi [ ] cleanup ;