libc.janet (2479B)
1 (import ./utils) 2 (import ./native/nftw) 3 4 (defmacro bind [name & types] 5 (with-syms [$fn $sig] 6 ~(let [,$fn (ffi/lookup (ffi/native) ,name) 7 ,$sig (ffi/signature :default ,;types)] 8 (fn [& args] (ffi/call ,$fn ,$sig ;args))))) 9 10 (defmacro defbind [name & types] 11 ~(def ,name (bind ,(string/join [name]) ,;types))) 12 13 (defmacro bind/str [name] 14 (with-syms [$fn $sig] 15 ~(let [,$fn (ffi/lookup (ffi/native) ,name) 16 ,$sig (ffi/signature :default :string :ptr)] 17 (fn [arg] (ffi/call ,$fn ,$sig (string/join [arg])))))) 18 19 (defmacro defbind/str [name] 20 ~(def ,name (bind/str ,(string/join [name])))) 21 22 (defmacro ctry [call] 23 (with-syms [$ret] 24 ~(let [,$ret ,call] 25 (if (= ,$ret -1) 26 (error (string/join ["Function failed with:" (nftw/strerror)] " ")) 27 ,$ret)))) 28 29 (def c/glob :private (bind "glob" :int :string :int :ptr :ptr)) 30 (def c/globfree :private (bind "globfree" :void :ptr)) 31 (def c/glob_t :private (ffi/struct :size :ptr :size :int :ptr :ptr :ptr :ptr :ptr)) 32 33 (defn glob [pattern] 34 (def globbed (ffi/write c/glob_t [0 nil 0 0 nil nil nil nil nil])) 35 (if (= 0 (c/glob pattern 0 nil globbed)) 36 (let [returned (ffi/read c/glob_t globbed) 37 globlen (int/to-number (returned 0)) 38 paths (ffi/read @[:string globlen] (returned 1))] 39 (c/globfree globbed) 40 paths))) 41 42 (def c/ioctl :private (bind "ioctl" :int :int :ulong :ptr)) 43 (def c/winsize :private (ffi/struct :short :short :short :short)) 44 (def c/ioctl/args :private 45 @{:TIOCGWINSZ [21523 c/winsize [0 0 0 0]]}) 46 47 (defn ioctl [fd op] 48 (utils/letsome args (c/ioctl/args op) 49 (let [arg (ffi/write (args 1) (args 2))] 50 (c/ioctl fd (args 0) arg) 51 (ffi/read (args 1) arg)))) 52 53 (def c/sendfile :private (bind "sendfile" :ssize :int :int :ptr :size)) 54 55 (def c/lseek :private (bind "lseek" :int :int :int :int)) 56 57 (defn lseek [fd &opt whence offset] 58 (def whence_ 59 (case whence 60 :set 0 61 :cur 1 62 :end 2 63 nil 1)) 64 (def offset_ (if (nil? offset) 0 offset)) 65 (c/lseek fd offset_ whence_)) 66 67 (defn sendfile [out_fd in_fd &opt offset cnt] 68 (def offset_ (if (nil? offset) (lseek in_fd) offset)) 69 (var cnt_ (if (nil? cnt) (- (ctry (nftw/fstat in_fd :size)) offset_) cnt)) 70 (def offset/ptr @"") 71 (buffer/push-uint64 offset/ptr :native offset_) 72 (ctry (c/sendfile out_fd in_fd offset/ptr cnt_))) 73 74 (defbind get_nprocs :int) 75 (defbind isatty :int :int) 76 (defbind/str dirname) 77 (defbind/str basename) 78 (defbind/str mkdtemp) 79