;http://www.purebasic.fr/english/viewtopic.php?f=13&t=68919
;EnableExplicit
; Signals
#SIGHUP = 1
#SIGINT = 2
#SIGQUIT = 3
#SIGILL = 4
#SIGTRAP = 5
#SIGABRT = 6
#SIGIOT = 6
#SIGBUS = 7
#SIGFPE = 8
#SIGKILL = 9
#SIGUSR1 = 10
#SIGSEGV = 11
#SIGUSR2 = 12
#SIGPIPE = 13
#SIGALRM = 14
#SIGTERM = 15
#SIGSTKFLT = 16
#SIGCHLD = 17
#SIGCONT = 18
#SIGSTOP = 19
#SIGTSTP = 20
#SIGTTIN = 21
#SIGTTOU = 22
#SIGURG = 23
#SIGXCPU = 24
#SIGXFSZ = 25
#SIGVTALRM = 26
#SIGPROF = 27
#SIGWINCH = 28
#SIGIO = 29
#SIGPOLL = 29
#SIGPWR = 30
#SIGSYS = 31
#SIGUNUSED = 31
#SIG_BLOCK = 0
#SIG_UNBLOCK = 1
#SIG_SETMASK = 2
#SA_NOCLDSTOP = $00000001
#SA_NOCLDWAIT = $00000002
#SA_SIGINFO = $00000004
#SA_ONSTACK = $08000000
#SA_RESTART = $10000000
#SA_NODEFER = $40000000
#SA_RESETHAND = $80000000
XIncludeFile("inc.l.userinfo.pbi") ; https://www.purebasic.fr/english/viewtopic.php?f=15&t=49074&hilit=userid+userid
Global PIDFile$, oldPid$, daemonName$
Global PID.l
Global.i Exit, HUP, USR1, USR2,i
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
Procedure Logging(Text$)
Protected.i File
RunProgram("bash", "-c "+#DQUOTE$+"logger -t " + GetFilePart(ProgramFilename()) + " -- '" + Text$ + "'"+#DQUOTE$+"", "", #PB_Program_Open | #PB_Program_Hide)
File = OpenFile(#PB_Any, "/var/log/" + GetFilePart(ProgramFilename()), #PB_File_Append|#PB_UTF8)
If File
WriteStringN(File, FormatDate("%yyyy.%mm.%dd %hh:%ii:%ss ", Date()) + Text$)
CloseFile(File)
EndIf
EndProcedure
ProcedureC SigHandler(Signal.l)
Select Signal
Case #SIGTERM
Exit = #True
Case #SIGHUP
HUP = #True
Case #SIGUSR1
USR1 = #True
Case #SIGUSR2
USR2 = #True
EndSelect
EndProcedure
Procedure.b checkPIDRunning(PID2Chk.s)
Compiler = RunProgram("bash", "-c "+#DQUOTE$+"ps aux | grep " + PID2Chk + " | grep -v grep | grep " + GetFilePart(ProgramFilename()), "", #PB_Program_Open | #PB_Program_Read)
Output$ = ""
If Compiler
While ProgramRunning(Compiler)
If AvailableProgramOutput(Compiler)
Output$ + ReadProgramString(Compiler) + Chr(13)
EndIf
Wend
CloseProgram(Compiler) ; Close the connection to the program
EndIf
If Output$
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure checkDaemon(verbose.b=#False)
If oldPid$ = ""
ProcedureReturn #False
ElseIf kill_(Val(oldPid$),0) = 0
If verbose
PrintN(daemonName$ +" is running.")
EndIf
ProcedureReturn #True
ElseIf checkPIDRunning(oldPid$)
;If verbose
PrintN(daemonName$ +" is running (maybe different user).")
;EndIf
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure statusDaemon()
If checkDaemon() = #False
PrintN(daemonName$ +" isn't running.")
EndIf
EndProcedure
Procedure stopDaemon() ; Stop the daemon.
If checkDaemon() = #False
PrintN("Error: " + daemonName$ +" isn't running.")
End
EndIf
PrintN(" * Stopping " + daemonName$)
Logging(daemonName$ +" stopped.")
If oldPid$
kill_(Val(oldPid$),9)
If FileSize(PIDFile$) > 0
DeleteFile(PIDFile$)
EndIf
EndIf
EndProcedure
Global sa.sigaction
Procedure startDaemon() ; Start the daemon.
If checkDaemon()
PrintN("Error: " + daemonName$ +" is already running.")
Logging(Str(#PB_Compiler_Line) + " - " + "Program is already running! (/var/run/...)")
End
EndIf
PID = fork_()
If PID = -1
PrintN("Was not able to fork")
End
ElseIf PID <> 0
End
EndIf
Logging("Starting up " + daemonName$ +".")
If CreateFile(0, PIDFile$)
WriteStringN(0, Str(getpid_()))
CloseFile(0)
EndIf
PrintN(" * Starting " + daemonName$ +" With PID: " + Str(getpid_()))
OpenPreferences("/etc/" + GetFilePart(ProgramFilename()))
; read your preferences
ClosePreferences()
;- signal stuff
sa\sa_handler = @SigHandler()
sa\sa_flags = #SA_RESTART
sigfillset_(@sa\sa_mask)
sigaction_(#SIGHUP, @sa, #Null)
sigaction_(#SIGTERM, @sa, #Null)
sigaction_(#SIGUSR1, @sa, #Null)
sigaction_(#SIGUSR2, @sa, #Null)
;-main_loop
Repeat
Delay(10)
If HUP
Logging("HUP received")
HUP = #False
EndIf
If USR1
Logging("USR1 received")
USR1 = #False
EndIf
If USR2
Logging("USR2 received")
USR2 = #False
EndIf
Until Exit
stopDaemon()
; If FileSize(PIDFile$) > 0
; DeleteFile(PIDFile$)
; EndIf
EndProcedure
Procedure restartDaemon() ; Restart the daemon.
If checkDaemon() = #False
PrintN("Error: " + daemonName$ +" isn't running.")
End
EndIf
stopDaemon()
Delay(100)
startDaemon()
EndProcedure
;-main
PIDFile$ = "/var/run/user/"+Str(UserID())+"/" + GetFilePart(ProgramFilename()) + ".pid"
daemonName$ = GetFilePart(ProgramFilename())
If FileSize(PIDFile$) > 0
If OpenFile(0, PIDFile$) ; if the file could be read, we continue...
oldPid$ = ReadString(0) ; display line by line in the debug window
CloseFile(0) ; close the previously opened file
EndIf
EndIf
;https://gist.githubusercontent.com/shawnrice/11076762/raw/48cbc4686e91ca058985d197ed57834aac57c969/skeleton-daemon.sh
;checkDaemon()
If CountProgramParameters() = 0
PrintN("Error: usage " + GetFilePart(ProgramFilename()) + " { start | stop | restart | status }")
Else
Select ProgramParameter(0)
Case "start"
startDaemon()
Case "stop"
stopDaemon()
Case "status"
statusDaemon()
Case "restart"
restartDaemon()
Default
PrintN("Error: usage " + GetFilePart(ProgramFilename()) + " { start | stop | restart | status }")
End
EndSelect
EndIf
Logging("Terminated")
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA