Linux Daemon Question

Just starting out? Need help? Post your questions and find answers here.
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Linux Daemon Question

Post by swhite »

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
Simon White
dCipher Computing
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Linux Daemon Question

Post by infratec »

Hi,

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")
Bernd
Last edited by infratec on Thu Oct 12, 2017 2:50 pm, edited 4 times in total.
User avatar
mk-soft
Always Here
Always Here
Posts: 5333
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Linux Daemon Question

Post by mk-soft »

Thanks :wink:
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
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: Linux Daemon Question

Post by swhite »

Thank-you for your sample code for a Linux Daemon. I will give it a try.

Simon
Simon White
dCipher Computing
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: Linux Daemon Question

Post by swhite »

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
Simon White
dCipher Computing
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Linux Daemon Question

Post by infratec »

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
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: Linux Daemon Question

Post by swhite »

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
Simon White
dCipher Computing
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Linux Daemon Question

Post by infratec »

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:
kill -9 `cat /var/run/myProcess.pid`
This can be used in your start/stop script to stop the daemon.

Bernd
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: Linux Daemon Question

Post by swhite »

That is useful information .

Thank-you
Simon
Simon White
dCipher Computing
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: Linux Daemon Question

Post by swhite »

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 White
dCipher Computing
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Linux Daemon Question

Post by infratec »

But to stop the daemon you should use
kill `cat /var/run/myProcess.pid`
Without -9, because then it sends SIGTERM (15) and the daemon can stop by itself.
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
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: Linux Daemon Question

Post by swhite »

I use the OpenSuse KGuard GUI to send a SigTerm and it works well.

Simon
Simon White
dCipher Computing
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Linux Daemon Question

Post by infratec »

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
kill `cat /var/run/myProcess.pid`
to stop your daemon.

Bernd
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: Linux Daemon Question

Post by swhite »

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
Simon White
dCipher Computing
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Linux Daemon Question

Post by infratec »

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.
Post Reply