Page 1 of 1

Daemon para Linux usando [x]Harbour

Posted: Tue Oct 06, 2009 2:55 pm
by Antonio Linares
Un bonito y sencillo código para construir un daemon en Linux usando 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
 

Re: Daemon para Linux usando [x]Harbour

Posted: Tue Oct 06, 2009 3:07 pm
by thefull
Se agradece a veces estas pequeñas contribuciones, por ahorrarnos MUCHO tiempo en I+D.
Muchas gracias Antonio!

Re: Daemon para Linux usando [x]Harbour

Posted: Tue Oct 06, 2009 3:32 pm
by pablovidal
Antonio,

Gracias esto era algo que me faltaba para un desarrollo que estoy haciendo...

Muchas Gracias...