It’s a morbid title, I agree but it is quite important. Unix daemons really need to listen to the messages (read as: signals) being sent to them and responding correctly. At the very least, if every daemon implemented the following it’d be a breath of fresh air:
/** Responds to signals of interest */voiddaemon_signalhandler(intsig){switch(sig){caseSIGHUP:/* this should just refresh configs and restart */break;caseSIGTERM:/* mark the server as no longer running */break;}}
This block of code by itself is pretty useless. The other half of the equation is attaching this function to the signals of interest as well as ignoring signals we’re not interested in (or that we’re not interested in those signals turning our daemon to toast).
/* attach the signal handlers now */signal(SIGCHLD,SIG_IGN);signal(SIGTSTP,SIG_IGN);signal(SIGTTOU,SIG_IGN);signal(SIGTTIN,SIG_IGN);signal(SIGHUP,daemon_signalhandler);signal(SIGTERM,daemon_signalhandler);
I need to crawl before I can walk, so a lot of “toy code” is being written using Haskell. It’s taken me a while to get to this point, but I now have cards being shuffled to players:
moduleCardswhereimportSystem.RandomimportData.MaybeimportData.ListimportData.FunctionimportTest.HUnitimportTest.QuickCheck-- | Card values for uno cardsdataCardValue=Naught|One|Two|Three|Four|Five|Six|Seven|Eight|Nine|Skip|Reverse|DrawTwo|Wild|WildDrawFourderiving(Show,Eq,Enum)-- | Possible card coloursdataCardColour=Red|Blue|Green|Yellowderiving(Show,Eq,Enum)-- | Defines the attributes of a carddataCard=CardCardValue(MaybeCardColour)deriving(Show)-- | Seeds a list of cards with a random valueseedCards::StdGen->[Card]->[(Card,Int)]seedCardsg[]=[]seedCardsg(c:cs)=x:seedCardsngcswhere(seed,ng)=randomR(1,10000)g::(Int,StdGen)x=(c,seed)-- | Makes a randomly shuffled deck of cardsmakeShuffledDeck::StdGen->[Card]makeShuffledDeckg=[x|c<-sorted,letx=fstc]wherecards=seedCardsgdecksorted=sortBy(compare`on`snd)cardsdeck=val++take10(cyclespec)val=[Cardv(Justc)|v<-[Naught..DrawTwo],c<-[Red..Yellow]]spec=[CardvNothing|v<-[Wild..WildDrawFour]]tests=TestList$mapTestCase[assertEqual"add tests here"11]prop_emptyc1=(c1::Int)==c1runTests=dorunTestTTtestsquickCheckprop_empty-- | Main entry pointmain::IO()main=runTests
There is a lot more to do before this becomes of use. The real think work being conducted here is really between seedCards and makeShuffledDeck. These two functions alone provide randomization to the ordered deck so it can be shuffled.
I hope to post some more on this topic, but I’d like to have a fully functional (or close to) application before I do so.