{-# LANGUAGE CPP #-}{-# LANGUAGE ForeignFunctionInterface #-}{- |
Compatibility code for things that need to be done differently
on different systems.
-}moduleConfig.Dyre.Compat(customExec,getPIDString)whereimportConfig.Dyre.Options(customOptions)#if defined(mingw32_HOST_OS) || defined(__MINGW32__)importSystem.Win32importSystem.ProcessimportSystem.ExitimportSystem.Mem-- This can be removed as soon as a 'getProcessID' function-- gets added to 'System.Win32'foreignimportstdcallunsafe"winbase.h GetCurrentProcessId"c_GetCurrentProcessID::IODWORDgetPIDString=fmapshowc_GetCurrentProcessIDcustomExecbinarymArgs=doargs<-customOptionsmArgs-- This whole thing is a terrible, ugly hack. Since Windows-- is too braindead to provide an exec() system call for us-- to use, we simply create a new process that inherits-- the stdio handles.(_,_,_,child)<-createProcess$CreateProcess{cmdspec=RawCommandbinaryargs,cwd=Nothing,env=Nothing,std_in=Inherit,std_out=Inherit,std_err=Inherit,close_fds=True}-- Do some garbage collection in an optimistic attempt to-- offset some of the memory we waste here.performGC-- And to prevent terminal apps from losing IO, we have to-- sit around waiting for the child to exit.exitCode<-waitForProcesschildcaseexitCodeofExitSuccess->c_ExitProcess0ExitFailurec->c_ExitProcess(fromIntegralc)foreignimportstdcallunsafe"winbase.h ExitProcess"c_ExitProcess::UINT->IO()#elseimportSystem.Posix.Process(executeFile,getProcessID)getPIDString=fmapshowgetProcessIDcustomExecbinarymArgs=doargs<-customOptionsmArgsexecuteFilebinaryFalseargsNothing#endif-- | Called whenever execution needs to be transferred over to-- a different binary.customExec::FilePath->Maybe[String]->IO()-- | What it says on the tin. Gets the current PID as a string.-- Used to determine the name for the state file during restarts.getPIDString::IOString