Daemon para Linux usando [x]Harbour
Posted: Tue Oct 06, 2009 2:55 pm
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