With the introduction of the Linux target for Delphi, a wide range of possibilities is opened up to Delphi developers, to Create Linux server applications. Unfortunately there is currently a limited number of project types available from the RAD Studio IDE, and those does not in Clude Creating a service (or Daemon as it ' s called in the Linux World).
*note* in this post I am assuming you is already configured to deploy a application to Linux and understand what to Launc H it from the Linux command line. If This isn't the case, see my earlier posts covering these subjects:
- http://chapmanworld.com/2017/02/28/embarcadero-delphi-linux-bootcamp/
- http://chapmanworld.com/2016/12/29/configure-delphi-and-redhat-or-ubuntu-for-linux-development/
Under the Linux operating system, a Daemon is simply an executable which continues running while ignoring the standard INP UT and output streams. That-is, they does not accept input from the keyboard, and they does not present data to the screens (except in special circums tances). Application which simply continues to run in the background without using the standard input and output, is a Daemon .
One other property of a Daemon application are that it runs in the background. Applications run from the terminal windows in Linux is provided with the standard input and output streams, and therefore The terminal becomes unusable until the application terminates. To demonstrate, create a new command line application and set it's source code to read as follows ...
Program Project1; {$APPTYPE CONSOLE} {$R *.res}uses system.sysutils;begin try while true do sleep (+); Except on e:exception do writeln (e.classname, ': ', e.message); End;end.
If you run this application from the command line, you'll find the it enters into a infinite loop (the while loop), and You don't regain control of the terminal window until you issue [CTRL] + [C] to abort the application.
Lets now turn this application into a Daemon. Alter your source code to read as follows ...
Program Project1; {$APPTYPE CONSOLE} {$R *.res}uses system.sysutils, posix.unistd;begin try if fork () <>0 then begin exit; End; While true, do sleep (+); Except on e:exception do writeln (e.classname, ': ', e.message); End;end.
Now, if you attempt to run this application from the command line, it'll immediately exit. It would appear as though the application did nothing. However, issue the instruction:
Ps-e
And you should see something like this:
You'll notice that "Project1" is actually still running, it ' s simply been moved to the background.
As a side note, you can kill the application by making a note of it's process ID (in my case 16898 from the screenshot) an D issuing the appropriate kill instruction:
Kill 16898
You could now replace the infinite and loop with whatever application logic you need within your daemon.
How does this work?
The key to this working are the "fork ()" method, which can be found in the unit "POSIX.UNISTD". The fork method is a part of the standard POSIX API, who's documentation may be found HERE:HTTPS://LINUX.DIE.NET/MAN/3/FO Rk
What fork does are to create a copy of the which-ever process calls it, in our case Project1.
So at the moment fork is called, we application execution either continues in the originating process, or it continues in The copy process.
The return value of the call to Fork tells us which instance of the process we is executing in. A return value of zero tells us that we is executing in the child process (the copy), and any other value tells us that W E is executing in the parent process (the originator). In fact, when the return of the fork was not zero, it was the process ID of the newly created child process. We simply call ' exit ' to exit the application if we determine that we're in the parent process and allowing the child copy To proceed the infinite while loop.
Conclusion
At the this is able to create daemon applications. wish to the "the Linux (POSIX) API ' s in a little more detail to see how to handle ' signals ' which To gracefully terminate your application, rather than using the brute force termination of a kill instruction. You might also want some-to-communicate with your daemon process. There is many ways to communicate and the process, but possibly the very familiar to a Delphi developer would is to use Tcp / ip. Turning your service into a TCP/IP server would allow for send data and instructions to it.
Regardless of what is decide to does with your daemon, I hope you found this brief instructional useful.
http://chapmanworld.com/2017/04/05/creating-a-linux-daemon-service-in-delphi/
Creating a Linux Daemon (service) in Delphi