⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agent_keeper.cpp

📁 保持程序后台长驻的网关程序
💻 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 + -