From 8f39550cea77eef1054b1febe7e647f96ac523c2 Mon Sep 17 00:00:00 2001 From: victor Date: Thu, 22 Jun 2017 17:27:41 +0900 Subject: [PATCH] =?UTF-8?q?superdaemon=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/superdaemon/Makefile | 15 ++ app/superdaemon/main.c | 392 ++++++++++++++++++++++++++++++++++++++++ app/superdaemon/main.h | 27 +++ app/superdaemon/projectinc.c | 33 ++++ app/superdaemon/projectinc.h | 21 +++ app/superdaemon/readme.txt | 29 +++ app/superdaemon/superdaemon.ini | 30 +++ 7 files changed, 547 insertions(+) create mode 100644 app/superdaemon/Makefile create mode 100644 app/superdaemon/main.c create mode 100644 app/superdaemon/main.h create mode 100644 app/superdaemon/projectinc.c create mode 100644 app/superdaemon/projectinc.h create mode 100644 app/superdaemon/readme.txt create mode 100644 app/superdaemon/superdaemon.ini diff --git a/app/superdaemon/Makefile b/app/superdaemon/Makefile new file mode 100644 index 0000000..dee6914 --- /dev/null +++ b/app/superdaemon/Makefile @@ -0,0 +1,15 @@ +CC = arm-buildroot-linux-gnueabihf-gcc +OBJS = main.o projectinc.o +TARGET = superdaemon + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) -lm -o $@ $^ + +%.o:%.c + @echo "Compiling $< ..." + $(CC) -c $< + +clean: + rm $(OBJS) $(TARGET) diff --git a/app/superdaemon/main.c b/app/superdaemon/main.c new file mode 100644 index 0000000..c3d0ffb --- /dev/null +++ b/app/superdaemon/main.c @@ -0,0 +1,392 @@ +/********************************************************************* + : superdaemon - ϵ α׷ + : 1.0.2 + - get_execinfo() Լ ߰ + - read_task_list() Լ task_t ϵ + 1.0.1 + - ڽ μ α׷ ϱ + θ μ Ÿũ μ ID + ϴ ð ֱ sleep()Լ ȣ + 1.0.0 +*********************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include "main.h" +#include "projectinc.h" + +#define PATH_SIZE 255 +#define TASK_ARRAY_SIZE 20 + +task_t ary_task[TASK_ARRAY_SIZE]; // Ÿũ 迭 +int cnt_task; // Ÿũ + +//-------------------------------------------------------------------- +// desc ϵ μ Ǹ ߻ϴ ̺Ʈ ڵ鷯 +// params sig +// ref ϵ μ شϴ ary_task +// Ѵ. +// +// ary_task ϸ, main() check_task_list() +// ȣν ٽ ϰ ȴ. +//-------------------------------------------------------------------- +void on_check_child( int sig) +{ + pid_t pid; + int result; + int ndx; + + // ϵ μ شϴ ary_task ã´. + // task_t pid 0 ϸ check_task_lisk() + // count_down ϰ, 0 ̵Ǹ ٽ ϰ ȴ. + + while( 0 < ( pid = waitpid( -1, &result, WNOHANG))) + { dp( "killed child pid=%d", pid); + for ( ndx= 0; ndx < cnt_task; ndx++) + { dp( "checked child pid=%d %s", ary_task[ndx].pid, ary_task[ndx].full_filename); + if ( pid == ary_task[ndx].pid) + { + ary_task[ndx].count_down = ary_task[ndx].interval; // ٽ ϱ ð() + ary_task[ndx].pid = 0; // check_task_list() ǵ 0 ʱȭ + } + } + } +} + +//-------------------------------------------------------------------- +// desc _str ù° +// Ǵ ڰ ڿ _rst +// Ѵ. +// params _str ڿ ִ +// _rst ڿ +// ret ڿ ġ +//-------------------------------------------------------------------- +char *str_spc( char *_str, char *_rst) +{ + char *pos; + + *_rst = '\0'; // NULL + pos = index(_str, ' '); + if ( !pos) // ڰ ٸ + { + strcpy(_rst, _str); + } + else + { + strncpy(_rst, _str, pos-_str); + _rst[pos-_str] = '\0'; + while ( ' ' == *pos) // տ ִ + pos++; + } + return( pos); +} + +//-------------------------------------------------------------------- +// desc _task 뿡 μ  Ѵ. +// params _task : Ͽ +// ref 1. +// _task task κ ϰ μ Ѵ. +// ̳ μ ִٸ ϰ, +// _task error ڵ带 ־ ȣ⿡ +// ʵ Ѵ. +// 2. +// μ 20 óѴ. +// +// 3. +// μ α׷ ٸǷ, +// *[] ϴ execv() Ѵ. +//-------------------------------------------------------------------- +void exec_task( task_t *_task) +{ + pid_t pid; + + if ( ERR_NONE != _task->error) + { + return; + } + + pid = fork(); + if ( 0 == pid) // ڽ μ + { dp( "1 sec wait and exec %s", _task->full_filename); + sleep( 1); // μ _task->pid = pid ǵ sleep + execv(_task->full_filename, _task->params); // α׷ Ѵ. + } + else if ( 0 < pid) // fork ࿡ ̻ ٸ + { dp( "********** task= %s New Pid= %d", _task->full_filename, pid); + _task->pid = pid; + } + else // fork() ࿡ ߴٸ + { dp( "Reset Counter %d", _task->interval); + _task->count_down = _task->interval; + } +} + +//-------------------------------------------------------------------- +// desc ary_task Ȯؼ ϵ尡 ִ ȮѴ. +// ϵ尡 ִٸ ࿩( ) Ȯϰ, +// Ų. +//-------------------------------------------------------------------- +void check_task_list( void) +{ + int ndx; + + // ary_task Ͽ pid 0 ׸ + // ϵ ̴. + // + + for ( ndx = 0; ndx < cnt_task; ndx++) + { + if ( ( !ary_task[ndx].pid) // Ÿũ ̰ + && ( ERR_NONE == ary_task[ndx].error)) // ٸ + { + if ( 0 < ary_task[ndx].count_down) // īƮ ٿ ̶ + { dp( "count down :%d", ary_task[ndx].count_down); + ary_task[ndx].count_down--; + } + else // īƮ ٿ Ϸ + { + exec_task( &ary_task[ndx]); + } + } + } + return; +} + +//-------------------------------------------------------------------- +// ڿ task_t α׷ ̸ μ Ѵ. +// +// _data : Ͽ о 丮 ġ ڿ +// _task : Ͽ +// +// typedef struct +// { +// char *full_filename; <- 丮 ü ̸ Ѵ. +// char *params[20]; <- α׷ μ 迭 Ѵ. +// : +// int error; <- ߿ ִٸ +// : +// } task_t; + + + +// ref 1. +// _task task κ ϰ μ Ѵ. +// ̳ μ ִٸ ϰ, +// _task error ڵ带 ־ ȣ⿡ +// ʵ Ѵ. +// 2. +// μ 20 óѴ. +// +// 3. +// μ α׷ ٸǷ, +// *[] ϴ execv() Ѵ. +//-------------------------------------------------------------------- +void get_execinfo( char *_data, task_t *_task) +{ + char buf[PACKET_SIZE]; + char exe_path[PATH_SIZE+5]; // +5 + char exe_name[PATH_SIZE+5]; // +5 + int nparam; + int sz_str; + pid_t pid; + + // Ѵ. + // '/' ٸ ߰Ѵ. + + _data = str_spc(_data, buf); + if ( PATH_SIZE < strlen( buf)) // θ ̰ ʹ . + { + printf( "%s : path is too long!!\n", buf); + _task->error = ERR_PATH_TOO_LONG; + return; + } + strcpy( exe_path, buf); // exe_path <- θ + + // '/' ȮѴ. + + sz_str = strlen( exe_path); + if ( '/' != exe_path[sz_str-1]) // / ݵ + { + exe_path[sz_str ] = '/'; + exe_path[sz_str+1] = '\0'; + } + + // ü ̸ Ѵ. + + _data = str_spc(_data, buf); + if ( PATH_SIZE < strlen( exe_path)+strlen( buf)) // ο ̸ ʹ . + { + printf( "%s/%s : full name is too long!!\n", exe_path, buf); + _task->error = ERR_PATH_TOO_LONG; + return; + } + strcpy( exe_name, buf); + strcat( exe_path, exe_name); // exe_path <- /̸ + _task->full_filename = malloc( strlen( exe_path)+1); + strcpy( _task->full_filename, exe_path); + + // ȮѴ. + + if ( 0 != access(_task->full_filename, F_OK)) + { + printf( "%s is not exists!!\n",_task->full_filename); + _task->error = ERR_PATH_TOO_LONG; + return; + } + + // ࿡ ʿ μ 迭 Ѵ. + // ù° μ ̸ Ѵ. + // μ NULL ǵ Ѵ. + + _task->params[0] = malloc( strlen( exe_name)+1); + strcpy(_task->params[0], exe_name); + + // [0] μ ̸̹Ƿ, + // [1] α׷ μ Ѵ. + // params *[20] Ǿ Ƿ + // μ 19 ϰ Ѵ. + + nparam = 1; + while (_data) + { + _data = str_spc(_data, buf); // μ Ѵ. + _task->params[nparam] = malloc( strlen( buf)+1); // param[nparam] <- μ + strcpy(_task->params[nparam], buf); + nparam++; + if ( 19 == nparam) // μ ʹ ٸ + { + printf( "%s has too many params!!\n", exe_name); + _task->error = ERR_TOO_MANY_PARAMS; + return; + } + } + _task->params[nparam] = ( char *)0; // NULL + _task->error = ERR_NONE; // +} + +//-------------------------------------------------------------------- +// ini Ͽ о ̰, +// ary_task ۼѴ. +//-------------------------------------------------------------------- +void read_task_list( void) +{ + FILE *fp; + char *tag; + char *pos; + char buf[PACKET_SIZE]; + char item[255]; + + cnt_task = 0; // ۾ ʱȭ + + fp = fopen( "./superdaemon.ini", "r"); // ȯ open; + if ( NULL == fp) + { // о Ÿũ + return; + } + else + { + while( NULL != fgets( buf, PACKET_SIZE, fp)) + { + tag = buf; + remove_white_char( tag); // 忡 ǵ ȭƮ ڸ ش. + + // α׷ ۱ ð Ѵ. + + while ( ' ' == *tag) // տ ִ + { + tag++; + } + + if ( ( ' ' > *tag) || // ̰ų + ( !strncmp( tag, "//", 2)) ) // ̶ּ + { + continue; + } + // ù ° ʹ ð ̴. + // ù° ڿ ð Ѵ. + + tag = str_spc( tag, item); + ary_task[cnt_task].interval = atoi( item); + + // α׷ Ѵ. + // ο α׷ ־ ϹǷ + // ּ ڰ ϳ ־ Ѵ. + // μ ڰ ٸ Ѵ. + + if ( ( ' ' > *tag) || // ̰ų + ( !strncmp( tag, "//", 2)) ) // ̶ּ + { + continue; + } + + pos = index( tag, ' '); // ڰ ٸ Ѵ. + if (!pos) + { + continue; + } + + get_execinfo( tag, &ary_task[cnt_task]); + + // task ʱⰪ ʱȭ Ѵ. + + ary_task[cnt_task].count_down = 0; + ary_task[cnt_task].pid = 0; + cnt_task++; + if ( TASK_ARRAY_SIZE == cnt_task) + { + printf( "***** Task list is over %d. *****\n", TASK_ARRAY_SIZE); + break; + } + } + } + fclose( fp); +} + +//-------------------------------------------------------------------- +// ϵ μ Ȯϴ ñ׳ +//-------------------------------------------------------------------- +void reg_child_signal( void) +{ + struct sigaction sig_child; // ϵ ˱ ñ + + sig_child.sa_handler = on_check_child; + sigemptyset( &sig_child.sa_mask); + sig_child.sa_flags = 0; + sigaction( SIGCHLD, &sig_child, 0); +} + +//-------------------------------------------------------------------- +// main procedure +//-------------------------------------------------------------------- +int main( int argc, char **argv) +{ +#ifdef NDEBUG + + pid_t pid_daemon; // release endif ȴ. + + pid_daemon = fork(); + if ( 0 > pid_daemon) // fork() ࿡ ߴٸ + { + printf( "ERR: fork() failed\n"); // ˸. + exit( 1); + } + else if( 0 != pid_daemon) // θ μ + { + exit( 0); // Ѵ. + } + +#endif + + reg_child_signal(); // child ñ׳ + read_task_list(); // ۼѴ. + + while( 1 ) + { + check_task_list(); // ۾ ¸ ȮѴ. + sleep( 1); // 1 ʸ + } +} diff --git a/app/superdaemon/main.h b/app/superdaemon/main.h new file mode 100644 index 0000000..f6ffa97 --- /dev/null +++ b/app/superdaemon/main.h @@ -0,0 +1,27 @@ +#ifndef MAIN_H +#define MAIN_H + +#include + +#define TRUE 1 +#define FALSE 0 + +#define ERR_NONE 0 +#define ERR_PATH_TOO_LONG -1 +#define ERR_EXE_TOO_LONG -2 +#define ERR_PARAMS_TO0_LONG -3; +#define ERR_TOO_MANY_PARAMS -4; +#define ERR_EXECUTE -5; + +typedef struct +{ + char *full_filename; + char *params[20]; + int interval; + int count_down; + int error; + pid_t pid; +} task_t; + + +#endif diff --git a/app/superdaemon/projectinc.c b/app/superdaemon/projectinc.c new file mode 100644 index 0000000..fc62e09 --- /dev/null +++ b/app/superdaemon/projectinc.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include "projectinc.h" + +//-------------------------------------------------------------------- +// desc ڿ /t /n /f ȭƮ ڸ NULL ڵ +// ٲپ ش. +//-------------------------------------------------------------------- +void remove_white_char( char *_str) +{ + int ndx; + + for ( ndx = 0; ndx < strlen(_str); ndx++) + { + if (' ' > _str[ndx]) + { + _str[ndx] = '\0'; + } + } +} + +//-------------------------------------------------------------------- +// desc ޽ ϰ Ѵ. +//-------------------------------------------------------------------- +void error_handling(char *message) +{ + fputs( message, stderr); + fputc( '\n', stderr); + exit(1); +} + + diff --git a/app/superdaemon/projectinc.h b/app/superdaemon/projectinc.h new file mode 100644 index 0000000..85d8fcc --- /dev/null +++ b/app/superdaemon/projectinc.h @@ -0,0 +1,21 @@ +#ifndef _PROJECTINC_ +#define _PROJECTINC_ + +#define NDEBUG + +#ifndef NDEBUG +#define dp(fmt,args...) printf( fmt, ## args ); putchar( '\n') +#define dlp(fmt,args...) printf( "[%s %d]" fmt, __FILE__,__LINE__, ## args ) +#else +#define dp(fmt,args...) +#define dlp(fmt,args...) +#endif + +extern void remove_white_char( char *); +extern void error_handling(char *message); + +//----- SysManager --------------------------------------------------- + +#define PACKET_SIZE 1024 + +#endif diff --git a/app/superdaemon/readme.txt b/app/superdaemon/readme.txt new file mode 100644 index 0000000..d3ff7c3 --- /dev/null +++ b/app/superdaemon/readme.txt @@ -0,0 +1,29 @@ +prj name : superdaemon - 등록된 프로그램을 실행 및 관리 +descript : + + 1. superdaemon.ini 에 등록된 프로그램을 실행하고 + 프로그램 종료를 계속 확인하면서, + 종료되면 지정된 시간 후 다시 실행하게 한다. + + 2. 추후, watch dog 기능을 추가한다. + +version : + 0.0.1 superdaemon.ini 에 등록된 프로그램을 실행 + 0.0.2 execl() 사용하여 구성 + 0.0.3 1. + execl() 을 execv() 로 재 구성 + ref + execl() 은 인수가 ( ) + 2. + 실행파일 정보 문자열에 이상이 없을 때에만 + fork() 실행하도록 수정 + 1.0.0 1. + 파일을 실행할 때, 파일의 존재 유무를 확인하는 + 코드를 추가 + 2. + 환경 파일에서 경로명에 '/' 이 없을 때 발생하던 + 오류를 잡음 + + + 장길석, goguryeo@gmail.com + \ No newline at end of file diff --git a/app/superdaemon/superdaemon.ini b/app/superdaemon/superdaemon.ini new file mode 100644 index 0000000..54dcd46 --- /dev/null +++ b/app/superdaemon/superdaemon.ini @@ -0,0 +1,30 @@ +// superdaemon 에서 사용되는 환경파일입니다. + +// 아래의 리스트는 superdaemon 에서 실행되며, +// 프로그램이 종료되더라도 지정된 시간(초) 후에 다시 +// 자동으로 실행됩니다. + +// 작성 방법은 공백 문자로 분리가 되며, +// [시간] [경로] [실행파일 이름] [인수1] [인수2].... +// 식으로 한개의 행에 하나의 프로그램 실행 정보를 넣어주면 됩니다. + +// 실행 경로와 실행파일의 이름을 합쳐서 255자 이내이어야 하며, +// 인수는 20 개 이상이 될 수 없습니다. + +1 /bin/ ls -al 123 234 456 +3 /bin/ ls -al /tmp 678 90 +5 /bin/ ls -al /usr abc def + +//2 ./ tcp2rx /dev/ttyS05 22549 +//2 ./ tcp2rx /dev/ttyS04 22559 +//2 ./ tcp2rx /dev/ttyS03 22569 + +//2 ./ udp2rx /dev/ttyS06 22539 192.168.10.2 +//2 ./ udp2rx /dev/ttyS05 22549 192.168.10.2 +//2 ./ udp2rx /dev/ttyS04 22559 192.168.10.2 +//2 ./ udp2rx /dev/ttyS03 22569 192.168.10.2 + +//5 . child 1 +//5 ./ child 1 2 +//5 ./ child 1 2 3 + -- 2.1.4