instow

:)
git clone https://git.sr.ht/~ashymad/instow
Log | Files | Refs | LICENSE

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