Recent

Author Topic: Creating Linux Daemon's  (Read 17836 times)

auRazor

  • Newbie
  • Posts: 4
Creating Linux Daemon's
« on: December 19, 2013, 06:15:38 am »
I am trying to create a linux Daemon without much success. I have used the lazdaemon code and using the cleandirs as an example. In my code I put a few log calls in and am getting nothing back. Has anyone ever created a daemon for linux if so are you able to point me to an example that works?


I am on ubuntu 13.04 using lazarus 1.0.14 and fpc 2.6.2.

I am starting the daemon from the command line using the script at http://aurawin.com/lazarus/fedora.service. The application and script are outside of the normal init.d directory.


unit gwymapper;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, DaemonApp;

type
  TCanalGatewayMapper = class(TDaemonMapper)
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  CanalGatewayMapper: TCanalGatewayMapper;

implementation

procedure RegisterMapper;
begin
  RegisterDaemonMapper(TCanalGatewayMapper)
end;

{$R *.lfm}


initialization
  RegisterMapper;
end.

########################################################################
unit gwyrun;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, DaemonApp, eventlog;

type

  { TCanalGatewayRun }

  TCanalGatewayRun = class(TDaemon)
    procedure DataModuleExecute(Sender: TCustomDaemon);
    procedure DataModuleStart(Sender: TCustomDaemon; var OK: Boolean);
    procedure DataModuleStop(Sender: TCustomDaemon; var OK: Boolean);
  private
    { private declarations }
    sConfigFile : string;
    elLog : TEventLog;
    procedure _startLog;
  public
    { public declarations }
  end;

var
  CanalGatewayRun: TCanalGatewayRun;

implementation

procedure RegisterDaemon;
begin
  RegisterDaemonClass(TCanalGatewayRun)
end;

{$R *.lfm}

procedure TCanalGatewayRun.DataModuleExecute(Sender: TCustomDaemon);
begin

end;

procedure TCanalGatewayRun.DataModuleStart(Sender: TCustomDaemon;
  var OK: Boolean);
begin
  ok := true;
  elLog.Info('Started');
end;

procedure TCanalGatewayRun.DataModuleStop(Sender: TCustomDaemon; var OK: Boolean
  );
begin
  Ok := true;
  elLog.Info('Stopped');
end;

procedure TCanalGatewayRun._startLog;
begin
  LogMessage('Message from canal');
  elLog:=Self.Logger;
  elLog.LogType := ltFile;
  elLog.FileName := '/home/rhenderson/sandbox/canal/gwy.log';
  If (sConfigFile='') then
    elLog.Error('No configuration file found !');
end;


initialization
  RegisterDaemon;
end.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8114
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Creating Linux Daemon's
« Reply #1 on: December 19, 2013, 05:29:42 pm »
Did you follow this? It works for my web application that sits as a daemon.

snorkel

  • Hero Member
  • *****
  • Posts: 799
Re: Creating Linux Daemon's
« Reply #2 on: December 19, 2013, 06:34:22 pm »
I could never get lazdaemon to work properly, so I found a pure daemon example, it was pretty out of date and I was able to get it working with some minor changes and it works great. 

http://www.filewatcher.com/p/fp-compiler-2.4.4_2.4.4-0_i386.deb.1902154/usr/share/doc/fp-compiler/2.4.4/unix/daemon.pp.gz.html
***Snorkel***
If I forget, I always use the latest stable 32bit version of Lazarus and FPC. At the time of this signature that is Laz 1.8 and FPC 3.0.4
OS: Windows 10 64 bit

jack_

  • New Member
  • *
  • Posts: 23
  • Poland
Re: Creating Linux Daemon's
« Reply #3 on: July 11, 2014, 08:09:05 pm »
It's an old topic but search function show this as a good place, so for next users
I've attach an working Daemon example as a ZIP file.

It's created visually with using Project -> New Project... -> Daemon (service) application

Created in:
Ubuntu 14.04 LTS with Cinnamon
Typhon IDE  4.8.0   Synchronize with Lazarus Source 29-3-2014 SVN Rev 44546
FreePascal  2.7.1   Source 29-3-2014 SVN Rev 27327

msapTemp.lpr
Code: [Select]
Program msapTemp;

Uses
{$IFDEF UNIX}
  CThreads,
{$ENDIF}
  DaemonApp, lazdaemonapp, DaemonMapperUnit1, DaemonUnit1
  { add your units here };

begin
  Application.Initialize;
  Application.Run;
end.

daemonmapperunit1.pas
Code: [Select]
unit DaemonMapperUnit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, DaemonApp;

type
  TDaemonMapper1 = class(TDaemonMapper)
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  DaemonMapper1: TDaemonMapper1;

implementation

procedure RegisterMapper;
begin
  RegisterDaemonMapper(TDaemonMapper1)
end;

{$R *.lfm}


initialization
  RegisterMapper;
end.

!!! Very IMPORTANT !!! - when you create a new daemon project yourself you have to put your TDaemon class name to DaemonClassName !
You click a DaemonMapperUnit1 tab on Editor, then F12 key [sometimes 2 times].
You have an TDataModule form called DaemonMapper1 on top - click on it.
On the Object Inspector you click DaemonDefs [...] button and then on the new window click Add.
Click on the new 0[zero] position and look on the Object Inspector.
There you have to in the DaemonClassName property put your TDaemon class name - in my example you have TDaemon1.
The ZIP file and sources are working and contain above steps completed.

daemonmapperunit1.lfm
Code: [Select]
object DaemonMapper1: TDaemonMapper1
  DaemonDefs = < 
    item
      DaemonClassName = 'TDaemon1'
      Name = 'TDaemon1'
      DisplayName = 'TDaemon1'
      Options = [doAllowStop, doAllowPause]
      WinBindings.Dependencies = <>
      WinBindings.StartType = stBoot
      WinBindings.WaitHint = 0
      WinBindings.IDTag = 0
      WinBindings.ServiceType = stWin32
      WinBindings.ErrorSeverity = esIgnore
      LogStatusReport = False
    end>
  left = 364
  top = 504
end

daemonunit1.pas
Code: [Select]
unit DaemonUnit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, DaemonApp;

type

  { TDaemon1 }
  TDaemon1 = class(TDaemon)
    procedure DataModuleExecute(Sender: TCustomDaemon);
    procedure DataModuleShutDown(Sender: TCustomDaemon);
    procedure DataModuleStart(Sender: TCustomDaemon; var OK: boolean);
    procedure DataModuleStop(Sender: TCustomDaemon; var OK: boolean);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Daemon1: TDaemon1;
  Log: TextFile;

implementation

procedure RegisterDaemon;
begin
  RegisterDaemonClass(TDaemon1);
end;

{$R *.lfm}

{ TDaemon1 }

procedure TDaemon1.DataModuleExecute(Sender: TCustomDaemon);
begin
  while Self.Status = csRunning do
  begin
    sleep(1000);
    WriteLn(Log, datetimetostr(Now));
    Flush(Log);
    LogMessage(DateTimeToStr(Now));
  end;
end;

procedure TDaemon1.DataModuleShutDown(Sender: TCustomDaemon);
begin
  WriteLn(Log, 'Shutdown');
  Flush(Log);
end;

procedure TDaemon1.DataModuleStart(Sender: TCustomDaemon; var OK: boolean);
begin
  OK := True;
  WriteLn(Log, 'Start');
  Flush(Log);
end;

procedure TDaemon1.DataModuleStop(Sender: TCustomDaemon; var OK: boolean);
begin
  OK := True;
  WriteLn(Log, 'Stop');
  Flush(Log);
end;


initialization
  RegisterDaemon;
  AssignFile(Log, 'msaplog.txt');
  Rewrite(Log);
end.


daemonunit1.lfm
Code: [Select]
object Daemon1: TDaemon1
  OldCreateOrder = False
  OnStart = DataModuleStart
  OnStop = DataModuleStop
  OnShutDown = DataModuleShutDown
  OnExecute = DataModuleExecute
  Height = 172
  HorizontalOffset = 342
  VerticalOffset = 210
  Width = 193
end


After build you can run it from Terminal[you have to enter folder where executable file is] with:
Code: [Select]
# ./msapTemp --run
Search for two files as an output:
msapTemp.log [internal Daemon logging file]
and
msaplog.txt [our file for logging with WriteLn]
« Last Edit: July 11, 2014, 08:28:02 pm by jack_ »

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Creating Linux Daemon's
« Reply #4 on: July 12, 2014, 09:20:26 am »
Thanks for posting that! If you think that
http://wiki.lazarus.freepascal.org/Daemons_and_Services
should be updated, please update it...

Thanks a lot
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

AnthonyTekatch

  • Jr. Member
  • **
  • Posts: 64
Re: Creating Linux Daemon's
« Reply #5 on: November 10, 2014, 05:52:58 pm »
Search for two files as an output:
msapTemp.log [internal Daemon logging file]
and
msaplog.txt [our file for logging with WriteLn]

Where is msapTemp.log stored? I cannot find any such file. I am using Linux.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3655
  • I like bugs.
Re: Creating Linux Daemon's
« Reply #6 on: November 11, 2014, 12:38:52 am »
Could somebody please see what is wrong with the CleanDirs example which uses LazDaemon.
I believe it has worked at some moment in the past but not anymore.

motaz

  • Hero Member
  • *****
  • Posts: 508
    • http://code.sd
Re: Creating Linux Daemon's
« Reply #7 on: November 11, 2014, 05:49:06 am »
For Linux background services I  used to write normal console applications that has no text output, then I write small shell script to run, stop and check status of this service and put it /etc/init.d/ directory

Check this blog:
http://freepascalanswers.wordpress.com/2013/12/12/service-app/

snorkel

  • Hero Member
  • *****
  • Posts: 799
Re: Creating Linux Daemon's
« Reply #8 on: November 13, 2014, 05:41:29 pm »
For Linux background services I  used to write normal console applications that has no text output, then I write small shell script to run, stop and check status of this service and put it /etc/init.d/ directory

Check this blog:
http://freepascalanswers.wordpress.com/2013/12/12/service-app/

Hi Motaz,

nice example and good for simple services, but it does not handle signals, so you can't send it a signal to reload config for example.
***Snorkel***
If I forget, I always use the latest stable 32bit version of Lazarus and FPC. At the time of this signature that is Laz 1.8 and FPC 3.0.4
OS: Windows 10 64 bit

motaz

  • Hero Member
  • *****
  • Posts: 508
    • http://code.sd
Re: Creating Linux Daemon's
« Reply #9 on: November 15, 2014, 12:44:16 pm »
Quote
but it does not handle signals,
Yes you are right snorkel, it can only start, stop, and check status of service

jack_

  • New Member
  • *
  • Posts: 23
  • Poland
Re: Creating Linux Daemon's
« Reply #10 on: February 07, 2015, 12:32:48 am »
Search for two files as an output:
msapTemp.log [internal Daemon logging file]
and
msaplog.txt [our file for logging with WriteLn]

Where is msapTemp.log stored? I cannot find any such file. I am using Linux.

This is an internal logger file place in the same directory in which you have compiled binary file.
File is created first time when you run daemon using -r or --run command.

robsoft

  • New member
  • *
  • Posts: 9
Re: Creating Linux Daemon's
« Reply #11 on: March 09, 2015, 11:40:44 pm »
This is an internal logger file place in the same directory in which you have compiled binary file.
File is created first time when you run daemon using -r or --run command.

Jack_, thanks for this - that's got me started at last. I couldn't for the life of me figure out what was going on with the LazDaemon stuff, but I think you've given me a push in the right direction. Many thanks!

I'm trying to write something that takes incoming serial data on the raspberry pi, and broadcasts it over the network - or possibly just allows incoming socket connections for 'subscribers' to the data stream. I've never written anything on the Pi before, never used Lazarus before, hardly done much Linux and even my day job is more C# than Delphi these days... an interesting challenge :-)

richard_rtech

  • New Member
  • *
  • Posts: 35
Re: Creating Linux Daemon's
« Reply #12 on: March 09, 2015, 11:47:04 pm »
This is an internal logger file place in the same directory in which you have compiled binary file.
File is created first time when you run daemon using -r or --run command.

Jack_, thanks for this - that's got me started at last. I couldn't for the life of me figure out what was going on with the LazDaemon stuff, but I think you've given me a push in the right direction. Many thanks!

I'm trying to write something that takes incoming serial data on the raspberry pi, and broadcasts it over the network - or possibly just allows incoming socket connections for 'subscribers' to the data stream. I've never written anything on the Pi before, never used Lazarus before, hardly done much Linux and even my day job is more C# than Delphi these days... an interesting challenge :-)

Look at SOCAT, you are making work for yourself ;)

robsoft

  • New member
  • *
  • Posts: 9
Re: Creating Linux Daemon's
« Reply #13 on: March 10, 2015, 12:19:12 am »
Look at SOCAT, you are making work for yourself ;)

Aaah.... <googles>.... ok, thanks. That looks interesting. Thanks!

richard_rtech

  • New Member
  • *
  • Posts: 35
Re: Creating Linux Daemon's
« Reply #14 on: March 10, 2015, 12:26:25 am »
I was looking at the same thing months back and have used that instead. I have a custom serial bus system we use and that was used to replace a nuked serial <-> ethernet bridge in an emergency.