module test_reload import StdBool import StdClass import StdFile import StdFunc import StdInt import StdString import Data.Either import Data.Maybe import Inotify /** test_reload * * This module will watch the directory it is in. Whenever the attributes of * its own binaries change, it will exit. Hence, putting it in a loop: * * while :; do ./test_reload; done * * will give a program that automatically reloads itself when its binary has * changed. * * Test it by running `make run_test_reload`, then editing `changeme` below and * running `make test_reload` to recompile. */ my_name :== "test_reload" my_dir :== "." changeme :== 42 verbose :== False :: Void = Void Start w # (io,w) = stdio w # io = io <<< changeme <<< "\n" # (ok,w) = fclose io w # (Just inot) = inotify_init Void # (Right watch,inot) = inotify_add_watch reload IN_ALL_EVENTS my_dir inot # (inot,w) = inotify_loop_forever inot w = inotify_close inot where reload :: !INEvent (Maybe String) Void !*World -> *(Void, *World) reload ev mbName _ w # w = echo (\f -> f <<< "event: " <<< ev <<< "; " <<< mbName) w | isNothing mbName = (Void, w) # (Just name) = mbName | ev bitand IN_ATTRIB <> 0 && name == my_name # w = echo (\f -> f <<< "reloading...") w # w = exit 127 w = (Void, w) = (Void, w) echo :: (*File -> *File) *World -> *World echo f w # (io,w) = stdio w # io = if verbose (flip (<<<) "\n" o f) id io # (ok,w) = fclose io w = w exit :: !Int !*World -> *World exit c w = code { ccall exit "I:V:A" } instance <<< (Maybe x) | <<< x where (<<<) f Nothing = f (<<<) f (Just x) = f <<< x