Linux Daemon Question
Linux Daemon Question
Hi
I have written lots of Windows Services using PB but have never done a Linux Service/Daemon. I am wondering if anyone has some sample code of how this should be done. It certainly would be nice if the documentation included samples for both Windows Services and Linux Daemon.
Thanks
Simon
I have written lots of Windows Services using PB but have never done a Linux Service/Daemon. I am wondering if anyone has some sample code of how this should be done. It certainly would be nice if the documentation included samples for both Windows Services and Linux Daemon.
Thanks
Simon
Simon White
dCipher Computing
dCipher Computing
Re: Linux Daemon Question
Hi,
it's the same like in C
Bernd
it's the same like in C
Code: Select all
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
Global.i Exit, HUP, USR1, USR2
Procedure Logging(Text$)
Protected.i File
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
;-main
Define.l PID
Define PIDFile$
Define *SignalSet
PIDFile$ = "/var/run/" + GetFilePart(ProgramFilename()) + ".pid"
If FileSize(PIDFile$) > 0
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("Started")
If CreateFile(0, PIDFile$)
WriteStringN(0, Str(getpid_()))
CloseFile(0)
EndIf
OpenPreferences("/etc/" + GetFilePart(ProgramFilename()))
; read your preferences
ClosePreferences()
;- signal stuff
*SignalSet = AllocateMemory(1024)
sigfillset_(*SignalSet)
sigdelset_(*SignalSet, #SIGHUP)
sigdelset_(*SignalSet, #SIGTERM)
sigdelset_(*SignalSet, #SIGUSR1)
sigdelset_(*SignalSet, #SIGUSR2)
sigprocmask_(#SIG_BLOCK, *SignalSet, #Null)
signal_(#SIGHUP, @SigHandler())
signal_(#SIGTERM, @SigHandler())
signal_(#SIGUSR1, @SigHandler())
signal_(#SIGUSR2, @SigHandler())
;-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
If FileSize(PIDFile$) > 0
DeleteFile(PIDFile$)
EndIf
Logging("Terminated")
Last edited by infratec on Thu Oct 12, 2017 2:50 pm, edited 4 times in total.
Re: Linux Daemon Question
Thanks
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Linux Daemon Question
Thank-you for your sample code for a Linux Daemon. I will give it a try.
Simon
Simon
Simon White
dCipher Computing
dCipher Computing
Re: Linux Daemon Question
Hi
I have developed and tested my code as a Windows service and am ready to convert it to a Linux Daemon. I have several questions regarding Signals and which ones I should handle. I also read in the LinuxProgrammingBlog.com the signal_ is deprecated and that sigaction_ should be used instead.
Since I only need to start and stop the daemon do I only handle #SIGTERM? Then how do I restart the daemon? Is it required to create a PIDFile?
I have no experience with Linux daemons so any advice would be helpful.
Thanks,
Simon
I have developed and tested my code as a Windows service and am ready to convert it to a Linux Daemon. I have several questions regarding Signals and which ones I should handle. I also read in the LinuxProgrammingBlog.com the signal_ is deprecated and that sigaction_ should be used instead.
Since I only need to start and stop the daemon do I only handle #SIGTERM? Then how do I restart the daemon? Is it required to create a PIDFile?
I have no experience with Linux daemons so any advice would be helpful.
Thanks,
Simon
Simon White
dCipher Computing
dCipher Computing
Re: Linux Daemon Question
If you want, replace my signal_() call with sigaction_() it's not very complicated.
Have you tried my code?
Is it working or not?
If not, tell me.
If working, use it.
How to launch it? Simply call it.
For an autostart you have to write a script.
Normally placed in /etc/init.d/
There should be a skelleton.
A 'start' and 'stop' is needed.
If 'reload' is needed depend on your code.
Then you have to create symbolic links in the different runlevel directories where you want to start or stop it.
And yes, I kow that this is the 'old' way, but still working.
With a pid file it is easier to send signals to the daemon.
And if you ever looked in my code: a pid file is handled.
Bernd
Have you tried my code?
Is it working or not?
If not, tell me.
If working, use it.
How to launch it? Simply call it.
For an autostart you have to write a script.
Normally placed in /etc/init.d/
There should be a skelleton.
A 'start' and 'stop' is needed.
If 'reload' is needed depend on your code.
Then you have to create symbolic links in the different runlevel directories where you want to start or stop it.
And yes, I kow that this is the 'old' way, but still working.
With a pid file it is easier to send signals to the daemon.
And if you ever looked in my code: a pid file is handled.
Bernd
Re: Linux Daemon Question
Hi
I realize after I made my post I was thinking the Windows way about starting and stopping the daemon from GUI Services Manager. I understand I can start the daemon with an autostart script and symlink.
Yes I did look at your code for the PID file but did not see how it made things any easier.
I will let you know how things work as I will be testing it tomorrow.
Thanks,
Simon
I realize after I made my post I was thinking the Windows way about starting and stopping the daemon from GUI Services Manager. I understand I can start the daemon with an autostart script and symlink.
Yes I did look at your code for the PID file but did not see how it made things any easier.
I will let you know how things work as I will be testing it tomorrow.
Thanks,
Simon
Simon White
dCipher Computing
dCipher Computing
Re: Linux Daemon Question
To send signals to a running program you use (normally) the program kill.
But kill expects the pid of the runnimg program.
But what you know is the name of the program and not the pid.
With a pid file you can do:
Bernd
But kill expects the pid of the runnimg program.
But what you know is the name of the program and not the pid.
With a pid file you can do:
This can be used in your start/stop script to stop the daemon.kill -9 `cat /var/run/myProcess.pid`
Bernd
Re: Linux Daemon Question
That is useful information .
Thank-you
Simon
Thank-you
Simon
Simon White
dCipher Computing
dCipher Computing
Re: Linux Daemon Question
I just wanted to thank-you for your help. My Linux daemon is working nicely. I still have lots to learn about Linux and daemons but I can at least test everything now under Linux.
Simon
Simon
Simon White
dCipher Computing
dCipher Computing
Re: Linux Daemon Question
But to stop the daemon you should use
9 means SIGKILL which is not handled by a program, it is handled by the system and it 'kills'
the program without giving him a chance to do some work before stopping.
Bernd
Without -9, because then it sends SIGTERM (15) and the daemon can stop by itself.kill `cat /var/run/myProcess.pid`
9 means SIGKILL which is not handled by a program, it is handled by the system and it 'kills'
the program without giving him a chance to do some work before stopping.
Bernd
Re: Linux Daemon Question
I use the OpenSuse KGuard GUI to send a SigTerm and it works well.
Simon
Simon
Simon White
dCipher Computing
dCipher Computing
Re: Linux Daemon Question
But when your daemon is running and you shutdown the system,
then all scripts are called with 'stop' as parameter.
So your start/stop script should use
Bernd
then all scripts are called with 'stop' as parameter.
So your start/stop script should use
to stop your daemon.kill `cat /var/run/myProcess.pid`
Bernd
Re: Linux Daemon Question
Hi
I did have one question as to the amount of memory assigned to the SignalSet. How did you arrive at 1024 bytes?
Thanks,
Simon
I did have one question as to the amount of memory assigned to the SignalSet. How did you arrive at 1024 bytes?
Thanks,
Simon
Simon White
dCipher Computing
dCipher Computing
Re: Linux Daemon Question
Hi,
with 1024 you are 'on the save site'.
If you check it with a small C program and sizeof() you will find something arround 520 bytes on x64.
I converted this part to sigaction.
Tomorrow I'll post it here.
But I had to create the structures by myself and not tested on a x86 system.
with 1024 you are 'on the save site'.
If you check it with a small C program and sizeof() you will find something arround 520 bytes on x64.
I converted this part to sigaction.
Tomorrow I'll post it here.
But I had to create the structures by myself and not tested on a x86 system.