This service is a kind of angel service that ensures three other applications are running. These other applications start network servers and access the Postgres database. The actual code for this angel service is shown below so perhaps it will help give you more of a clue. It never seems to get to the point of launching the other applications before it fails with the SIGTERM. This service was originally designed to work in Windows which it did perfectly so I am now trying to get it to work in Linux.
Code: Select all
;
; FWHostAuth.pb - Fuelwize Host Authorization Service
;
;
; Constants
EnableExplicit
#dCLogFile = "FWHostAuth.log"
#dCMaskOn = 1
#dCNoNulls = 0
#dCSMTPFrom = "FWHostAuth@fuelwise.ca"
#dCServiceName = "FWHostAuth"
#dCServiceAppName = "FWHostAuth.exe"
#dCServiceDisplayName = "Fuelwize Host Authorization"
#dCLogRetension = 6 ; Months
#dCAppPath = "/home/fwhostsrvc/Projects/"
;
; Use a structure when Windows API use an array of strings
;
Structure SrvParam
Param1.s
Param2.s
EndStructure
;
; This structure hold the time when the program should be run and the
; program handle used to identify the running program
;
Structure Sched
time.s
prg.i
ran.s
EndStructure
ImportC "/usr/lib64/libsystemd.so"
; sd_notify.i(environ.i,status.p-ascii)
sd_notify.i(environ.i,*status)
EndImport
Declare Main()
Declare ErrorHandler()
Declare SendeMail(tcMsg.s)
Global ghStatus.i,gnStop.i
XIncludeFile #dCAppPath+"PB_Lib/dCSettings.pb"
XIncludeFile #dCAppPath+"PB_Lib/dC_Wait.pb"
XIncludeFile #dCAppPath+"PB_Lib/dC_Logging.pb"
;XIncludeFile #dCAppPath+"PB_Lib/dC_SigHandler.pb"
CompilerIf Not Defined(sigset_t, #PB_Structure)
Structure sigset_t Align #PB_Structure_AlignC
__bits.l[32]
EndStructure
CompilerEndIf
CompilerIf Not Defined(sigaction, #PB_Structure)
Structure sigaction Align #PB_Structure_AlignC
StructureUnion
*sa_handler
*sa_sigaction
EndStructureUnion
sa_mask.sigset_t
sa_flags.l
*sa_restorer
EndStructure
CompilerEndIf
ProcedureC SigHandler(Signal.i)
Select Signal
Case #SIGHUP
CompilerIf Defined(goParam,#PB_Variable)
goParam\Stop = #True
CompilerElseIf Defined(gnStop,#PB_Variable)
gnStop = #True
CompilerEndIf
WriteToLog("Service Stopped by SigHandler(SIGHUP)")
Case #SIGABRT
CompilerIf Defined(goParam,#PB_Variable)
goParam\Stop = #True
CompilerElseIf Defined(gnStop,#PB_Variable)
gnStop = #True
CompilerEndIf
WriteToLog("Service Stopped by SigHandler(SIGABRT)")
Case #SIGTERM
CompilerIf Defined(goParam,#PB_Variable)
goParam\Stop = #True
CompilerElseIf Defined(gnStop,#PB_Variable)
gnStop = #True
CompilerEndIf
WriteToLog("Service Stopped by SigHandler(SIGTERM)")
Case #SIGKILL
CompilerIf Defined(goParam,#PB_Variable)
goParam\Stop = #True
CompilerElseIf Defined(gnStop,#PB_Variable)
gnStop = #True
CompilerEndIf
WriteToLog("Service Stopped by SigHandler(SIGKILL)")
Case #SIGSTOP
CompilerIf Defined(goParam,#PB_Variable)
goParam\Stop = #True
CompilerElseIf Defined(gnStop,#PB_Variable)
gnStop = #True
CompilerEndIf
WriteToLog("Service Stopped by SigHandler(SIGSTOP)")
Case #SIGUSR1
Case #SIGUSR2
EndSelect
EndProcedure
Define sa.sigaction
sa\sa_handler = @SigHandler()
sa\sa_flags = #SA_RESTART
sigfillset_(@sa\sa_mask)
sigaction_(#SIGSTOP, @sa, #Null)
sigaction_(#SIGABRT, @sa, #Null)
sigaction_(#SIGKILL, @sa, #Null)
sigaction_(#SIGTERM, @sa, #Null)
sigaction_(#SIGUSR1, @sa, #Null)
sigaction_(#SIGUSR2, @sa, #Null)
sigaction_(#SIGHUP, @sa, #Null)
If ProgramParameter(0) = "debug"
SetCurrentDirectory(ProgramParameter(1))
gcStartIn = GetCurrentDirectory()
gnDebug = 1
Else
SetCurrentDirectory(GetPathPart(ProgramFilename()))
gcStartIn = GetCurrentDirectory()
EndIf
WriteToLog(gcStartin)
Procedure ErrorHandler()
ErrorToLog("Service stopped due to "+ErrorMessage()+" on line "+Str(ErrorLine())+" in "+ErrorFile())
SendeMail(ErrorMessage())
gnStop = 1
EndProcedure
If Not ClearLog()
End
ElseIf gnDebug
OnErrorCall(@ErrorHandler())
Main()
Goto Finish
EndIf
WriteToLog(gcStartIn)
Select fork_()
Case -1
ErrorToLog("Failed to fork")
End 1
Case 0
WriteToLog("Fork 0")
Default
ErrorToLog("Fork <> 0")
End 0
EndSelect
OnErrorCall(@ErrorHandler())
Main()
Finish:
If IsFile(#dCLogFileNo)
CloseFile(#dCLogFileNo)
EndIf
End
;
; Send an eMail
;
Procedure SendeMail(tcMsg.s)
If CreateMail(#dCeMailNo,#dCSMTPFrom,"Fuelwize Host Authorization Error - "+ComputerName())
AddMailRecipient(#dCeMailNo,#dCSMTPTechSup,#PB_Mail_Cc)
SetMailBody(#dCeMailNo,"The following error occurred:<br><br>"+tcMsg)
If SendMail(#dCeMailNo,#dCSMTPHost,#dCSMTPPort,#DCSMTPSSL,#dCSMTPUsr,#dCSMTPPwd)=0
ErrorToLog("eMail failed to send: "+tcMsg)
Else
WriteToLog("eMail Sent: "+tcMsg)
EndIf
FreeMail(#dCeMailNo)
Else
ErrorToLog("CreateMail Failed.")
EndIf
EndProcedure
Procedure ShutDownServices(Map tmSrv.sched())
WriteToLog("Stopping Services")
ForEach tmSrv()
If IsProgram(tmSrv()\Prg) And ProgramRunning(tmSrv()\Prg)
CreateFile(1,gcStartIn+#dCCmdFolder+MapKey(tmSrv())+".stop")
CloseFile(1)
WriteToLog(gcStartIn+#dCCmdFolder+MapKey(tmSrv())+".stop")
CloseProgram(tmSrv()\Prg)
EndIf
Next
EndProcedure
;
; Main Service
;
Procedure Main()
Define lnDateTime.i,lcTime.s,lcDay.s,lnMonth.i ,*Status
NewMap lmServices.sched() ; The order in which the services are started is important so we cannot use a Map()
; *status=UTF8("READY=1")
; sd_notify(0,*status)
OnErrorCall(@ErrorHandler())
If gnDebug
WriteToLog("Main(Start) with debugging")
Else
WriteToLog("Main(Start) without debugging")
EndIf
;
; Remove any commands left over in the command folder
;
If ExamineDirectory(0,gcStartIn+#dCCmdFolder, "*.*")
While NextDirectoryEntry(0)
If DirectoryEntryType(0) = #PB_DirectoryEntry_File
DeleteFile(gcStartIn+#dCCmdFolder+DirectoryEntryName(0),#PB_FileSystem_Force)
EndIf
Wend
FinishDirectory(0)
EndIf
;
; Start service if preferences exist
;
If Not OpenPreferences(gcStartin+"FWMain.ini") Or Not PreferenceGroup("FWHostAuth")
ErrorToLog("FWHostAuth could not start because of '[FWHostAuth]' section missing in FWMain.ini")
Else
If ExaminePreferenceKeys()
Repeat
If UCase(Left(PreferenceKeyName(),6)) = "FWHOST"
; lmServices(LCase(PreferenceKeyName()))\Time = PreferenceKeyValue()
; lmServices(LCase(PreferenceKeyName()))\Prg = 0
lmServices(PreferenceKeyName())\Time = PreferenceKeyValue()
lmServices(PreferenceKeyName())\Prg = 0
EndIf
Until Not NextPreferenceKey()
EndIf
ClosePreferences()
If gnDebug
OpenConsole()
PrintN("Press Escape to exit.")
PrintN(gcStartIn+#dCLogFile)
EndIf
While (Not gnDebug And Not gnStop ) Or (gnDebug And Inkey() <> Chr(27))
lnDateTime = Date()
;
; Check every 30 seconds that the required services are running
;
If Second(lnDateTime) = 0 Or Second(lnDateTime) = 30
lcTime = FormatDate("%hh:%ii",Date())
ForEach lmServices()
lcDay = StringField(lmServices()\Time,DayOfWeek(Date())+1,",")
If lmServices()\Prg And IsProgram(lmServices()\Prg) And ProgramRunning(lmServices()\Prg) And (lcDay = "" Or (lcTime >= Left(lcDay,5) And lcTime <= Right(lcDay,5)))
; Nothing to do
Else
;
; Close connection to non-running program before re-starting it.
;
If IsProgram(lmServices()\Prg)
If CreateFile(#dCTmpFileNo,gcStartIn+#dCCmdFolder+MapKey(lmServices())+".stop")
CloseFile(#dCTmpFileNo)
EndIf
CloseProgram(lmServices()\Prg)
lmServices()\Prg = 0
EndIf
If lcDay = "" Or (lcDay <> "00:00-00:00" And lcTime >= Left(lcDay,5) And lcTime <= Right(lcDay,5))
lmServices()\Prg = RunProgram(gcStartIn+MapKey(lmServices()),"",gcStartIn,#PB_Program_Open)
If Not lmServices()\Prg Or Not IsProgram(lmServices()\Prg) Or Not ProgramRunning(lmServices()\Prg)
WriteToLog(gcStartIn+MapKey(lmServices())+"("+Str(lmServices()\Prg)+") failed To start. "+lcDay)
Else
WriteToLog(gcStartIn+MapKey(lmServices())+"("+Str(lmServices()\Prg)+") started. "+lcDay)
EndIf
EndIf
EndIf
Next
EndIf
;
; Remove Old Log Files
;
If Month(Date()) <> lnMonth
If ExamineDirectory(0, gcStartIn+#dCLogFolder,"*.log")
While NextDirectoryEntry(0)
If DirectoryEntryDate(0,#PB_Date_Created) < AddDate(Date(),#PB_Date_Month,-#dCLogRetension)
If Not DeleteFile(gcStartIn+#dCLogFolder+DirectoryEntryName(0),#PB_FileSystem_Force)
ErrorToLog("Unable to delete "+gcStartIn+#dCLogFolder+DirectoryEntryName(0))
EndIf
EndIf
Wend
FinishDirectory(0)
Else
ErrorToLog("Unable delete old log files")
EndIf
lnMonth = Month(Date())
EndIf
ClearLog()
Delay(1000)
Wend
ShutDownServices(lmServices())
If gnDebug
CloseConsole()
EndIf
EndIf
WriteToLog("Main(End)")
EndProcedure