📄 agent_keeper.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#define TIMEDEBUG 1
#define ERRDEBUG 2
//#define _DEBUG
extern "C" void sig_handler( int signo );
int PTrace( int, char * );
char* Get_date_str( char * );
int lockMe( const char * );
int unlockMe( const char * );
const char *lock_file = "/tmp/lock_keeperFile.txt";
pid_t main_pid;
char strLogFile[ 256 ], tmpss[ 1024 ];
char BinPath[256];
int main( int argc, char **argv )
{
pid_t pid;
int status;
char app_path[100], app_name[20],app_argv[10][128];
struct sigaction sigint; /* 终止信号处理 */
if ( argc == 2 && !strcmp( "-v", argv[1] ) )
{
printf( "agent_keeper program,Current Version 1.0.0 \n" );
printf( "Last Update Time 2004-12-30\n" );
return 0;
}
if ( argc != 3 )
{
printf( "Usage:%s TraceFile EnvFile( for QbillagentX ) \n", argv[0] );
return 0;
}
strcpy( strLogFile, argv[1] );
strcpy( app_argv[1],argv[2] );
strcpy( BinPath,argv[0] );
char *ss1 = strrchr( BinPath,'/' );
if( NULL != ss1 )
*ss1 = 0;
status = lockMe( lock_file );
if ( status < 0 )
{
exit(0);
}
else if ( status == 0 )
{
sprintf( tmpss, "The Agent Monitor Program Has Been Running..." );
PTrace( TIMEDEBUG, tmpss );
return 0;
}
/**********************创建守护进程**************************/
//产生后台子进程
switch ( fork() )
{
case 0:
break;
case - 1:
return -1;
default:
#ifdef _DEBUG
sprintf( tmpss, "The first Fork Parent pid is:%d ", getpid() );
PTrace( TIMEDEBUG, tmpss );
#endif
_exit( 0 );
}
//产生新的会话期,并失去控制终端
if ( setsid() < 0 )
{
unlockMe( lock_file );
return -1;
}
sprintf( tmpss,"Binary Path is %s",BinPath );
PTrace( TIMEDEBUG,tmpss );
//忽略SIGHUP
signal( SIGHUP, SIG_IGN );
//产生新的子进程,保证新的进程不可能重新打开控制终端。
switch ( fork() )
{
case 0:
break;
case - 1:
return -1;
default:
_exit(0);
}
//改变工作目录
//chdir("/");
//关闭所有的文件描述符
int fdlimit = sysconf( _SC_OPEN_MAX );
int fd = 0;
while ( fd < fdlimit )
{
close( fd );
fd++;
}
//打开一个空设备,将它复制到标准输出,标准错误上
open( "/dev/null", O_RDWR );
dup(0);
dup(1);
dup(2);
sprintf( tmpss, "The Agent Monitor Program Begin Running ..." );
PTrace( TIMEDEBUG, tmpss );
main_pid = getpid();
/* 终止处理函数,接收外部终止命令 */
sigint.sa_handler = sig_handler;
sigemptyset( &sigint.sa_mask );
sigint.sa_flags = 0;
/* 设置信号处理 */
if ( sigaction( SIGTERM, &sigint, NULL ) < 0 )
{
sprintf( tmpss, "Set Signal Function Fail!" );
PTrace( ERRDEBUG, tmpss );
unlockMe( lock_file );
exit(0);
}
int flag = 0;
for ( ; ; )
{
if ( (pid = fork()) < 0 )
{
sprintf( tmpss, "Can't Create Child Process,Fork Error!" );
PTrace( ERRDEBUG, tmpss );
unlockMe( lock_file );
exit(0);
}
else if ( pid == 0 )
{ //子进程
sprintf( tmpss, "The QbillagentX Program Begin Running ..." );
PTrace( TIMEDEBUG, tmpss );
getcwd( app_path, sizeof(app_path) );
strcat( app_path, "/QbillagentX" );
strcpy( app_name, "QbillagentX" );
#ifdef _DEBUG
sprintf( tmpss, "The Execl Process Id Is %d ", getpid() );
PTrace( TIMEDEBUG, tmpss );
#endif
if( access( app_path,0 ) )
{
sprintf( app_path,"%s/QbillagentX",BinPath );
}
/* 执行服务程序,execl的调用使得被调用程序占用本进程所占的内存,并覆盖之 */
if ( execl( app_path, app_name, app_argv[1], NULL ) < 0 )
{
sprintf( tmpss, "Can't Start The QbillagentX Program. excel error!" );
PTrace( ERRDEBUG, tmpss );
exit(-2);
}
}
else
{ //父进程
wait( &status );
sprintf( tmpss, "The QbillagentX End,It willl Start Again In One Miniute!" );
PTrace( TIMEDEBUG, tmpss );
sleep( 60 );
}
sleep(1);
}
if( main_pid == getpid() )
unlockMe( lock_file );
exit( 0 );
}
extern "C" void sig_handler( int signo )
{
switch ( signo )
{
case SIGTERM:
if ( getpid() == main_pid )
{
sprintf( tmpss, "The Agent Monitor Program Is End!!" );
PTrace( TIMEDEBUG, tmpss );
}
unlockMe( lock_file );
exit( 0 );
}
}
int PTrace( int flag, char *buf )
{
int i;
char tt[80];
FILE *ffp;
ffp = fopen( strLogFile, "a+" );
if ( NULL == ffp )
{
printf( "open logfile %s Err!\n", strLogFile );
exit( 0 );
}
Get_date_str( tt );
if ( flag == ERRDEBUG )
{
fprintf( ffp, "********** %s(%d) **********\n", tt, getpid() );
fprintf( ffp, "%s,errno=%d=\n\n", buf, errno );
}
else if ( flag == TIMEDEBUG )
{
fprintf( ffp, "********** %s(%d) **********\n", tt, getpid() );
fprintf( ffp, "%s\n\n", buf );
}
else
fprintf( ffp, "%s\n", buf );
fflush(ffp);
i = ftell( ffp );
if ( i >= 15*1024*1024 )
{ //一个日志文件最多15M
char logbackupfile[256];
fclose( ffp );
sprintf( logbackupfile, "%s.backup.%s", strLogFile, tt );
rename( strLogFile, logbackupfile );
ffp = fopen( strLogFile, "a+" );
if ( ffp == NULL )
exit( -1 );
else
{
fprintf( ffp, "********** Backup LogFile And Begin New Log(%d) **********\n", getpid() );
fprintf( ffp, "%s\n\n", buf );
fflush(ffp);
}
}
fclose( ffp );
return (0);
}
char* Get_date_str(char* str_date)
{
time_t td;
struct tm *s_tm;
time(&td);
s_tm = localtime(&td);
sprintf(str_date, "%04d-%02d-%02d %02d:%02d:%02d", s_tm->tm_year + 1900, s_tm->tm_mon + 1, s_tm->tm_mday,
s_tm->tm_hour, s_tm->tm_min, s_tm->tm_sec);
return str_date;
}
int lockMe( const char *lockfile )
{
FILE *fl;
int i, lcktime;
struct stat stbuf;
lcktime = 2;
for ( i = 0;i < lcktime;i++ )
{
if ( stat(lockfile, &stbuf ) < 0)
break;
sleep( 1 );
}
if ( i >= lcktime )
return ( 0 );
if ( ( fl = fopen( lockfile, "w" ) ) == NULL )
{
sprintf( tmpss, "open lockfile err!" );
PTrace( ERRDEBUG, tmpss );
return ( -1);
}
fprintf( fl, "%d", getpid( ) );
fclose( fl );
return ( 1 );
}
int unlockMe( const char *lockfile )
{
unlink(lockfile);
return ( 0 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -