let IO := requireModule "IO" in let FFI := requireModule "FFI" in let List := requireModule "List" in let Error := requireModule "Error" in let nil? := List.nil? in let Logic := requireModule "Logic" in let Arithmetic := requireModule "Arithmetic" in let Composition := requireModule "Composition" in let String := requireModule "String" in let Pair := requireModule "Pair" in let PATHMAX := Builtins.PATHMAX in let return! := IO.liftIO! in let (,) := Pair.(,) in let substr := String.substr in import [accumrUntil! with! liftIO! (;)] from IO in import [head map] from List in import [packRecord unpackRecord duplicateRecord! allocateRecord! recordSize allocateMemory! allocatePointer! strUntilZero environFromList listFromEnviron requireSharedLibrary] from FFI in import [(if) (else) (elif)] from Logic in import [(=) (+) (-) (*)] from Arithmetic in import [(rem) ($)] from Composition in export let strcmp := (requireSharedLibrary filename 'Cipp "strcmp") in let structTmFormat := "iiiiiiiiilZ" in let timeTFormat := "L" in let pidFormat := "L" in let statusFormat := "i" in export let time! := (requireSharedLibrary filename 'CiP "time" []) in export let localtimeR! := (\time allocateRecord! structTmFormat ;\tm let timeBox := packRecord timeTFormat [time] in requireSharedLibrary filename 'CPpp "localtime_r" timeBox tm ;\tm return! (unpackRecord structTmFormat tm) ) in export let localtime! := localtimeR! in export let gmtimeR! := (\time allocateRecord! structTmFormat ;\tm let timeBox := packRecord timeTFormat [time] in requireSharedLibrary filename 'CPpp "gmtime_r" timeBox tm ;\tm return! (unpackRecord structTmFormat tm) ) in export let gmtime! := gmtimeR! in export let mktime! := (\tm packRecord structTmFormat tm ;\tmBox mktime! tmBox ) in export let stime! := (requireSharedLibrary filename 'Cip "stime") in export let open! := (requireSharedLibrary filename 'Cipii "open") in export let openat! := (requireSharedLibrary filename 'Ciipii "openat") in export let creat! := (requireSharedLibrary filename 'Cipi "creat") in export let posixFadvise! := (requireSharedLibrary filename 'CiiLLi "posix_fadvise") in export let posixFallocate! := (requireSharedLibrary filename 'CiiLL "posix_fallocate") in export let pipe! := (allocateRecord! "ii" ;\r requireSharedLibrary filename 'Cip "pipe" r ;\rc return! (if (rc = (-1)) [] else (unpackRecord "ii" r)) ) in export let ctermid! := (requireSharedLibrary filename 'CSP "ctermid") in export let strftime! := (\format \tm duplicateRecord! "0123456789012345678901234567890" ;\buffer let tmBox := (packRecord structTmFormat tm) in requireSharedLibrary filename 'Clplpp "strftime" buffer 30 format tmBox ;\rc return! (if (rc = 0) [] else (substr buffer 0 rc)) ) in export let ttynameR! := (\FD duplicateRecord! "0123456789012345678901234567890" ;\buffer requireSharedLibrary filename 'Ciipl "ttyname_r" FD buffer 30 ;\rc return! (if (rc = 0) (strUntilZero buffer) else []) ) in export let ttyname! := ttynameR! in export let getloginR! := ( duplicateRecord! "0123456789012345678901234567890" ;\buffer requireSharedLibrary filename 'Cipl "getlogin_r" buffer 30 ;\rc return! (if (rc = 0) (strUntilZero buffer) else []) ) in export let getlogin! := getloginR! in export let execv! := (\progName \args requireSharedLibrary filename 'Cipp "execv" progName (packRecord "[p]P" [(map (\i [i]) args) []]) ) in export let execve! := (\progName \args \env requireSharedLibrary filename 'Cippp "execve" progName (packRecord "[p]P" [(map (\i [i]) args) []]) (packRecord "[p]P" [(map (\i [i]) env) []]) ) in export let execvp! := (\progName \args requireSharedLibrary filename 'Cipp "execvp" progName (packRecord "[p]P" [(map (\i [i]) args) []]) ) in export let execvpe! := (\progName \args \env requireSharedLibrary filename 'Cippp "execvpe" progName (packRecord "[p]P" [(map (\i [i]) args) []]) (packRecord "[p]P" [(map (\i [i]) env) []]) ) in export let fexecve! := (\FD \args \env requireSharedLibrary filename 'Ciipp "fexecve" FD (packRecord "[p]P" [(map (\i [i]) args) []]) (packRecord "[p]P" [(map (\i [i]) env) []]) ) in export let errno! := IO.errno! in export let syslog! := (\priority \message requireSharedLibrary filename 'Cvipp "syslog" priority "%s" message) in export let realpath! := (\path allocateMemory! PATHMAX ;\buffer requireSharedLibrary filename 'CSpp "realpath" path buffer ;\rc return! (if (nil? rc) [] else (strUntilZero rc)) ) in export let fgetsP! := (\size \stream rem "This is not overriding fgets since the user will probably rather want to do some complicated loop using the original one, filling some buffer piece by piece"$ allocateMemory! size ;\buffer requireSharedLibrary filename 'CSpip "fgets" buffer size stream ;\result return! (if (nil? result) [] (strUntilZero result)) ) in export let freadP! := (\size \nmemb \stream rem "This is not overriding freadP since the user will probably rather want to do some complicated loop using the original one, filling some buffer piece by piece"$ allocateMemory! (size*nmemb) ;\buffer requireSharedLibrary filename 'Clpllp "fread" buffer size nmemb stream ;\rc return! (if (rc = 0) [] else (substr buffer 0 rc)) ) in export let getlineP! := (\stream allocatePointer! ;\resultP allocateMemory! (recordSize "i") ;\size requireSharedLibrary filename 'Clppp "getline" resultP size stream ;\rc unpackRecord "p" resultP ;\result return! [rc (substr result 0 rc)] ) in export let getdelimP! := (\delim \stream allocatePointer! ;\resultP allocateMemory! (recordSize "i") ;\size requireSharedLibrary filename 'Clppp "getline" resultP size delim stream ;\rc unpackRecord "p" resultP ;\result return! [rc (substr result 0 rc)] ) in let posixSpawn! := (\path \fileActions \attr \args \environment allocateRecord! pidFormat ;\pid requireSharedLibrary filename 'CippPPpp "posix_spawn" pid path fileActions attr (packRecord "[p]P" [(map (\i [i]) args) []]) (packRecord "[p]P" [(map (\i [i]) environment) []]) ;\status return! (if (status = 0) (head (unpackRecord pidFormat pid)) (Error.raiseErrorWithCode 'posixSpawn! status)) ) in let posixSpawnp! := (\file \fileActions \attr \args \environment allocateRecord! pidFormat ;\pid requireSharedLibrary filename 'CippPPpp "posix_spawnp" pid file fileActions attr (packRecord "[p]P" [(map (\i [i]) args) []]) (packRecord "[p]P" [(map (\i [i]) environment) []]) ;\status return! (if (status = 0) (head (unpackRecord pidFormat pid)) (Error.raiseErrorWithCode 'posixSpawn! status)) ) in export let environ! := Builtins.environ! in export let spawn! := posixSpawn! in export let spawnp! := posixSpawnp! in export let spawnve! := (\file \args \environment posixSpawn! file [] [] args environment) in export let spawnvpe! := (\file \args \environment posixSpawnp! file [] [] args environment) in export let spawnv! := (\file \args environ! ;\environment spawnve! file args environment ) in export let spawnvp! := (\file \args environ! ;\environment spawnvpe! file args environment ) in export let mmap! := (requireSharedLibrary filename 'CPPliiiQ "mmap") in let waitpid! := (\pid \options allocateRecord! statusFormat ;\statusL waitpid! pid statusL options ;\status2 return! (if (status2 = (-1)) (Error.raiseErrorWithCode 'waitpid! status2) [(head (unpackRecord statusFormat statusL)) status2]) ) in export let Constants := requireModule "POSIX/Constants.5D" in export let getDirentSize! := Builtins.getDirentSize! in export let readdir! := \dir getDirentSize! dir ;\sz allocateMemory! sz ;\buffer allocatePointer! ;\result readdirR! dir buffer result ;\status if (status = 0) Builtins.unpackDirent! (head (unpackRecord "P" result)) else (Error.raiseErrorWithCode 'readdir! status) in let opendir! := \name (requireModule "FFI").requireSharedLibrary filename 'CPp "opendir" name ;\dir return! if (nil? dir) errno! ;\errno Error.raiseErrorWithCode 'opendir! errno else dir in export let getDirents! := \name rem "TODO proper error checking (especially bailing out in the middle)"$ with! (opendir! name) closedir! \dir getDirentSize! dir ;\sz allocateMemory! sz ;\buffer accumrUntil! nil? (:) [] allocatePointer! ;\result readdirR! dir buffer result ;\status if (status = 0) Builtins.unpackDirent! (head (unpackRecord "P" result)) else Error.raiseErrorWithCode 'getDirents! status in export let log! := \priority \message rem "one could use prioritynames[] (from syslog.h) in order to dynamically find out which is which."$ let mapPriority := (requireModule "Composition").dispatch1 [('emerg, 0) ('alert, 1) ('crit, 2) ('err, 3) ('warning, 4) ('notice, 5) ('info, 6) ('debug, 7)] in syslog! (mapPriority priority) message in export let warn! := log! 'warning in export let err! := log! 'err in