Linux daemon using [x]Harbour :-)

Post Reply
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Linux daemon using [x]Harbour :-)

Post by Antonio Linares »

A nice and easy code to build a Linux deamon using Harbour/xHarbour:

Code: Select all

// Linux daemon source code using Harbour/xHarbour
// (c) FiveTech Software, 2009

#define SIGHUP   1
#define SIGTERM 15

#define CRLF HB_OSNewLine()

static nCalled := 0, lExit := .F.

function Main( cMode )

 if cMode == "start"
   if File( "fivetech.pid" )
      Printf( "daemon is already running" + CRLF )
      return nil
   else
      MemoWrit( "fivetech.pid", AllTrim( Str( getpid() ) ) )
   endif
 elseif cMode == "stop"
   if File( "fivetech.pid" )
      KillTerm( Val( MemoRead( "fivetech.pid" ) ) + 1 )
      return nil
   endif
 else
   Printf( CRLF + "FiveTech daemon. Syntax:" + CRLF )
   Printf( "   ./daemon start" + CRLF )
   Printf( "   ./daemon stop" + CRLF + CRLF )
   return nil
 endif

 SetSignalsHandler()

 if Fork() > 0
   return nil  // Parent process ends and child process continues
 endif

 umask( 0 ) // In order to write to any files (including logs) created by the daemon

 SetSignalAlarm()
 Alarm( 1 )

 Printf( "daemon starts" + CRLF )

 // Close standard files descriptors
 // CloseStandardFiles()

 while ! lExit
   Sleep( 30 )
 end

 Printf( CRLF + "daemon ends" + CRLF )
 FErase( "fivetech.pid" )

return nil

exit procedure Test()

  if lExit
     // Only called if the child exits
     printf( "exit function... Clean objects now! :-)" + CRLF )
  endif

return

function SignalHandler( nSignal )

  do case
     case nSignal == SIGHUP
          PrintF( "Received SIGHUP signal" + CRLF )

     case nSignal == SIGTERM
          lExit = .T.
          // PrintF( "Received SIGTERM signal" + CRLF )

     otherwise
          PrintF( "Unhandled SIGNAL " + AllTrim( Str( nSignal ) ) + CRLF )
  endcase

return nil

function CatchAlarm( cMsg )

 if ++nCalled > 9
    lExit := .T.
 else
    Alarm( 1 ) // Require a next timer event
 endif

 Alarm( 1 )

return nil

#pragma BEGINDUMP

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <signal.h>

#include <hbapi.h>
#include <hbvm.h>

HB_FUNC( FORK )
{
 hb_retnl( fork() );
}

HB_FUNC( UMASK )
{
  umask( hb_parnl( 1 ) );
}

HB_FUNC( EXIT )
{
  exit( EXIT_SUCCESS );
}

HB_FUNC( GETPPID )
{
  hb_retnl( getppid() );
}

HB_FUNC( GETPID )
{
  hb_retnl( getpid() );
}

HB_FUNC( KILLTERM )
{
  kill( hb_parnl( 1 ), SIGTERM );
}

HB_FUNC( CLOSESTANDARDFILES )
{
  close( STDIN_FILENO );
  close( STDOUT_FILENO );
  close( STDERR_FILENO );
}

void CatchAlarm( int sig )
{
 hb_vmPushSymbol( hb_dynsymGetSymbol( "CATCHALARM" ) );
 hb_vmPushNil();
 hb_vmPushString( "PRG level from C", strlen( "PRG level from C" ) );
 hb_vmFunction( 1 );
}

void SignalHandler( int sig )
{
  hb_vmPushSymbol( hb_dynsymGetSymbol( "SIGNALHANDLER" ) );
  hb_vmPushNil();
  hb_vmPushLong( sig );
  hb_vmFunction( 1 );
}

HB_FUNC( SETSIGNALALARM )
{
 signal( SIGALRM, CatchAlarm );
}

HB_FUNC( SETSIGNALSHANDLER )
{
  signal( SIGHUP, SignalHandler );
  signal( SIGTERM, SignalHandler );
  signal( SIGINT, SignalHandler );
  signal( SIGQUIT, SignalHandler );
}

HB_FUNC( ALARM )
{
 alarm( hb_parnl( 1 ) );
}

HB_FUNC( PRINTF )
{
 printf( hb_parc( 1 ) );
}

HB_FUNC( SLEEP )
{
 sleep( hb_parnl( 1 ) );
}

HB_FUNC( SYSLOG )
{
  syslog( hb_parnl( 1 ), hb_parc( 2 ), hb_parc( 3 ) );
}

HB_FUNC( TEST )
{
  hb_retnl( LOG_WARNING );
}

#pragma ENDDUMP
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply