Commit 8f39550cea77eef1054b1febe7e647f96ac523c2
1 parent
3061c73f69
Exists in
master
and in
2 other branches
superdaemon 추가
Showing
7 changed files
with
547 additions
and
0 deletions
Show diff stats
app/superdaemon/Makefile
| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | +CC = arm-buildroot-linux-gnueabihf-gcc | |
| 2 | +OBJS = main.o projectinc.o | |
| 3 | +TARGET = superdaemon | |
| 4 | + | |
| 5 | +all: $(TARGET) | |
| 6 | + | |
| 7 | +$(TARGET): $(OBJS) | |
| 8 | + $(CC) -lm -o $@ $^ | |
| 9 | + | |
| 10 | +%.o:%.c | |
| 11 | + @echo "Compiling $< ..." | |
| 12 | + $(CC) -c $< | |
| 13 | + | |
| 14 | +clean: | |
| 15 | + rm $(OBJS) $(TARGET) | ... | ... |
app/superdaemon/main.c
| ... | ... | @@ -0,0 +1,392 @@ |
| 1 | +/********************************************************************* | |
| 2 | + 이 름 : superdaemon - 등록된 프로그램을 실행 및 관리 | |
| 3 | + 버 전 : 1.0.2 | |
| 4 | + - get_execinfo() 함수 추가 | |
| 5 | + - read_task_list() 함수에서 task_t 정보를 모두 구성하도록 수정 | |
| 6 | + 1.0.1 | |
| 7 | + - 자시 프로세스에서 프로그램을 식행하기 전에 | |
| 8 | + 부모 프로세스의 타스크 정보에 생성한 프로세스의 ID를 | |
| 9 | + 지정하는 시간을 벌어 주기 위해 sleep()함수를 호출 | |
| 10 | + 1.0.0 | |
| 11 | +*********************************************************************/ | |
| 12 | +#include <stdio.h> | |
| 13 | +#include <stdlib.h> | |
| 14 | +#include <signal.h> | |
| 15 | +#include <string.h> | |
| 16 | +#include <sys/types.h> | |
| 17 | +#include <sys/wait.h> | |
| 18 | +#include <unistd.h> | |
| 19 | +#include "main.h" | |
| 20 | +#include "projectinc.h" | |
| 21 | + | |
| 22 | +#define PATH_SIZE 255 | |
| 23 | +#define TASK_ARRAY_SIZE 20 | |
| 24 | + | |
| 25 | +task_t ary_task[TASK_ARRAY_SIZE]; // 타스크 배열 | |
| 26 | +int cnt_task; // 실행한 타스크의 개수 | |
| 27 | + | |
| 28 | +//-------------------------------------------------------------------- | |
| 29 | +// desc 차일드 프로세스가 종료되면 발생하는 이벤트 핸들러 | |
| 30 | +// params sig | |
| 31 | +// ref 종료된 차일드 프로세스에 해당하는 ary_task 의 아이템 값을 | |
| 32 | +// 수정한다. | |
| 33 | +// | |
| 34 | +// ary_task 아이템 값을 수정하면, main() 에서 check_task_list() | |
| 35 | +// 를 호출함으로써 다시 실행하게 된다. | |
| 36 | +//-------------------------------------------------------------------- | |
| 37 | +void on_check_child( int sig) | |
| 38 | +{ | |
| 39 | + pid_t pid; | |
| 40 | + int result; | |
| 41 | + int ndx; | |
| 42 | + | |
| 43 | + // 종료된 차일드 프로세스에 해당하는 ary_task 아이템을 찾는다. | |
| 44 | + // task_t 아이템의 pid 를 0 으로 설정하면 check_task_lisk() 에서 | |
| 45 | + // count_down 값을 감소하고, 0 이되면 다시 실행하게 된다. | |
| 46 | + | |
| 47 | + while( 0 < ( pid = waitpid( -1, &result, WNOHANG))) | |
| 48 | + { dp( "killed child pid=%d", pid); | |
| 49 | + for ( ndx= 0; ndx < cnt_task; ndx++) | |
| 50 | + { dp( "checked child pid=%d %s", ary_task[ndx].pid, ary_task[ndx].full_filename); | |
| 51 | + if ( pid == ary_task[ndx].pid) | |
| 52 | + { | |
| 53 | + ary_task[ndx].count_down = ary_task[ndx].interval; // 다시 실행하기 까지의 대기 시간(초) | |
| 54 | + ary_task[ndx].pid = 0; // check_task_list() 의 대상이 되도록 0 으로 초기화 | |
| 55 | + } | |
| 56 | + } | |
| 57 | + } | |
| 58 | +} | |
| 59 | + | |
| 60 | +//-------------------------------------------------------------------- | |
| 61 | +// desc _str 에서 첫번째 공백 문자 전까지 | |
| 62 | +// 또는 공백 문자가 없을 때에는 문자열 끝까지를 _rst | |
| 63 | +// 에 복사한다. | |
| 64 | +// params _str 원본 문자열을 가지고 있는 변수 | |
| 65 | +// _rst 문자열을 복사 받을 변수 | |
| 66 | +// ret 복사 문자열 다음의 문자 위치의 포인터 | |
| 67 | +//-------------------------------------------------------------------- | |
| 68 | +char *str_spc( char *_str, char *_rst) | |
| 69 | +{ | |
| 70 | + char *pos; | |
| 71 | + | |
| 72 | + *_rst = '\0'; // NULL 을 대입 | |
| 73 | + pos = index(_str, ' '); | |
| 74 | + if ( !pos) // 공백 구분자가 없다면 다음 루프로 | |
| 75 | + { | |
| 76 | + strcpy(_rst, _str); | |
| 77 | + } | |
| 78 | + else | |
| 79 | + { | |
| 80 | + strncpy(_rst, _str, pos-_str); | |
| 81 | + _rst[pos-_str] = '\0'; | |
| 82 | + while ( ' ' == *pos) // 앞에 있는 공백 삭제 | |
| 83 | + pos++; | |
| 84 | + } | |
| 85 | + return( pos); | |
| 86 | +} | |
| 87 | + | |
| 88 | +//-------------------------------------------------------------------- | |
| 89 | +// desc _task 의 내용에 따라 새 프로세스를 만들어서 실행한다. | |
| 90 | +// params _task : 실행 파일에 대한 정보 | |
| 91 | +// ref 1. | |
| 92 | +// _task 의 task 로부터 실행파일과 인수를 구한다. | |
| 93 | +// 실행이나 인수에서 문제가 있다면 에러를 출력하고, | |
| 94 | +// _task 의 error 에 에러코드를 넣어 다음 호출에도 실행이 | |
| 95 | +// 되지 않도록 한다. | |
| 96 | +// 2. | |
| 97 | +// 인수는 20개까지 처리한다. | |
| 98 | +// | |
| 99 | +// 3. | |
| 100 | +// 인수의 개수는 프로그램에 따라 다르므로, | |
| 101 | +// *[] 를 사용하는 execv() 를 사용한다. | |
| 102 | +//-------------------------------------------------------------------- | |
| 103 | +void exec_task( task_t *_task) | |
| 104 | +{ | |
| 105 | + pid_t pid; | |
| 106 | + | |
| 107 | + if ( ERR_NONE != _task->error) | |
| 108 | + { | |
| 109 | + return; | |
| 110 | + } | |
| 111 | + | |
| 112 | + pid = fork(); | |
| 113 | + if ( 0 == pid) // 자식 프로세서 라면 | |
| 114 | + { dp( "1 sec wait and exec %s", _task->full_filename); | |
| 115 | + sleep( 1); // 프모 프로세스에서 _task->pid = pid 가 실행이 되도록 sleep | |
| 116 | + execv(_task->full_filename, _task->params); // 프로그램을 실행한다. | |
| 117 | + } | |
| 118 | + else if ( 0 < pid) // fork 실행에 이상이 없었다면 | |
| 119 | + { dp( "********** task= %s New Pid= %d", _task->full_filename, pid); | |
| 120 | + _task->pid = pid; | |
| 121 | + } | |
| 122 | + else // 만일 fork() 실행에 실패했다면 | |
| 123 | + { dp( "Reset Counter %d", _task->interval); | |
| 124 | + _task->count_down = _task->interval; | |
| 125 | + } | |
| 126 | +} | |
| 127 | + | |
| 128 | +//-------------------------------------------------------------------- | |
| 129 | +// desc ary_task 목록을 확인해서 종료된 차일드가 있는지를 확인한다. | |
| 130 | +// 종료된 차일드가 있다면 실행여부(에러 상태)를 확인하고, | |
| 131 | +// 재 실행 시킨다. | |
| 132 | +//-------------------------------------------------------------------- | |
| 133 | +void check_task_list( void) | |
| 134 | +{ | |
| 135 | + int ndx; | |
| 136 | + | |
| 137 | + // ary_task 목록에서 pid 가 0 인 항목은 | |
| 138 | + // 종료된 차일드 이다. | |
| 139 | + // | |
| 140 | + | |
| 141 | + for ( ndx = 0; ndx < cnt_task; ndx++) | |
| 142 | + { | |
| 143 | + if ( ( !ary_task[ndx].pid) // 타스크가 실행 전이고 | |
| 144 | + && ( ERR_NONE == ary_task[ndx].error)) // 에러가 없다면 | |
| 145 | + { | |
| 146 | + if ( 0 < ary_task[ndx].count_down) // 아직 카우트 다운 중이라면 | |
| 147 | + { dp( "count down :%d", ary_task[ndx].count_down); | |
| 148 | + ary_task[ndx].count_down--; | |
| 149 | + } | |
| 150 | + else // 카운트 다운을 완료 | |
| 151 | + { | |
| 152 | + exec_task( &ary_task[ndx]); | |
| 153 | + } | |
| 154 | + } | |
| 155 | + } | |
| 156 | + return; | |
| 157 | +} | |
| 158 | + | |
| 159 | +//-------------------------------------------------------------------- | |
| 160 | +// 파일의 문자열에서 task_t 의 정보중 프로그램 이름과 인수를 구한다. | |
| 161 | +// | |
| 162 | +// _data : 파일에서 읽어 들인 내용중 디렉토리 위치부터의 문자열 | |
| 163 | +// _task : 실행 파일에 대한 정보 | |
| 164 | +// | |
| 165 | +// typedef struct | |
| 166 | +// { | |
| 167 | +// char *full_filename; <- 디렉토리 포함 전체 파일 이름을 구한다. | |
| 168 | +// char *params[20]; <- 프로그램 실행을 위한 인수 배열을 구한다. | |
| 169 | +// : | |
| 170 | +// int error; <- 내용을 구성 중에 에러가 있다면 에러 정보 | |
| 171 | +// : | |
| 172 | +// } task_t; | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | +// ref 1. | |
| 177 | +// _task 의 task 로부터 실행파일과 인수를 구한다. | |
| 178 | +// 실행이나 인수에서 문제가 있다면 에러를 출력하고, | |
| 179 | +// _task 의 error 에 에러코드를 넣어 다음 호출에도 실행이 | |
| 180 | +// 되지 않도록 한다. | |
| 181 | +// 2. | |
| 182 | +// 인수는 20개까지 처리한다. | |
| 183 | +// | |
| 184 | +// 3. | |
| 185 | +// 인수의 개수는 프로그램에 따라 다르므로, | |
| 186 | +// *[] 를 사용하는 execv() 를 사용한다. | |
| 187 | +//-------------------------------------------------------------------- | |
| 188 | +void get_execinfo( char *_data, task_t *_task) | |
| 189 | +{ | |
| 190 | + char buf[PACKET_SIZE]; | |
| 191 | + char exe_path[PATH_SIZE+5]; // 에러 대비 +5 | |
| 192 | + char exe_name[PATH_SIZE+5]; // 에러 대비 +5 | |
| 193 | + int nparam; | |
| 194 | + int sz_str; | |
| 195 | + pid_t pid; | |
| 196 | + | |
| 197 | + // 경로 명을 구한다. | |
| 198 | + // 경로 명의 끝에 '/' 이 없다면 추가한다. | |
| 199 | + | |
| 200 | + _data = str_spc(_data, buf); | |
| 201 | + if ( PATH_SIZE < strlen( buf)) // 경로명의 길이가 너무 길다. | |
| 202 | + { | |
| 203 | + printf( "%s : path is too long!!\n", buf); | |
| 204 | + _task->error = ERR_PATH_TOO_LONG; | |
| 205 | + return; | |
| 206 | + } | |
| 207 | + strcpy( exe_path, buf); // exe_path <- 경로명 | |
| 208 | + | |
| 209 | + // 경로 명의 끝의 '/' 를 확인한다. | |
| 210 | + | |
| 211 | + sz_str = strlen( exe_path); | |
| 212 | + if ( '/' != exe_path[sz_str-1]) // 끝에 / 를 반드시 포함 | |
| 213 | + { | |
| 214 | + exe_path[sz_str ] = '/'; | |
| 215 | + exe_path[sz_str+1] = '\0'; | |
| 216 | + } | |
| 217 | + | |
| 218 | + // 실행 파일의 전체 이름을 구한다. | |
| 219 | + | |
| 220 | + _data = str_spc(_data, buf); | |
| 221 | + if ( PATH_SIZE < strlen( exe_path)+strlen( buf)) // 경로와 실행파일의 이름 길이 합이 너무 길다. | |
| 222 | + { | |
| 223 | + printf( "%s/%s : full name is too long!!\n", exe_path, buf); | |
| 224 | + _task->error = ERR_PATH_TOO_LONG; | |
| 225 | + return; | |
| 226 | + } | |
| 227 | + strcpy( exe_name, buf); | |
| 228 | + strcat( exe_path, exe_name); // exe_path <- 경로/실행파일이름 | |
| 229 | + _task->full_filename = malloc( strlen( exe_path)+1); | |
| 230 | + strcpy( _task->full_filename, exe_path); | |
| 231 | + | |
| 232 | + // 실행 파일의 존재 유무를 확인한다. | |
| 233 | + | |
| 234 | + if ( 0 != access(_task->full_filename, F_OK)) | |
| 235 | + { | |
| 236 | + printf( "%s is not exists!!\n",_task->full_filename); | |
| 237 | + _task->error = ERR_PATH_TOO_LONG; | |
| 238 | + return; | |
| 239 | + } | |
| 240 | + | |
| 241 | + // 실행에 필요한 인수를 배열로 구성한다. | |
| 242 | + // 첫번째 인수는 실행파일 이름으로 한다. | |
| 243 | + // 마지막 인수는 NULL 이 되도록 한다. | |
| 244 | + | |
| 245 | + _task->params[0] = malloc( strlen( exe_name)+1); | |
| 246 | + strcpy(_task->params[0], exe_name); | |
| 247 | + | |
| 248 | + // [0] 인수는 실행 파일의 이름이므로, | |
| 249 | + // [1] 부터 프로그램의 인수를 대입한다. | |
| 250 | + // params는 *[20]로 선언되어 있으므로 | |
| 251 | + // 인수 개수가 19 개를 넘지 못하게 한다. | |
| 252 | + | |
| 253 | + nparam = 1; | |
| 254 | + while (_data) | |
| 255 | + { | |
| 256 | + _data = str_spc(_data, buf); // 다음 인수값을 구한다. | |
| 257 | + _task->params[nparam] = malloc( strlen( buf)+1); // param[nparam] <- 인수값 | |
| 258 | + strcpy(_task->params[nparam], buf); | |
| 259 | + nparam++; | |
| 260 | + if ( 19 == nparam) // 인수가 너무 많다면 | |
| 261 | + { | |
| 262 | + printf( "%s has too many params!!\n", exe_name); | |
| 263 | + _task->error = ERR_TOO_MANY_PARAMS; | |
| 264 | + return; | |
| 265 | + } | |
| 266 | + } | |
| 267 | + _task->params[nparam] = ( char *)0; // 마지막 아이템은 NULL | |
| 268 | + _task->error = ERR_NONE; // 에러 없음 | |
| 269 | +} | |
| 270 | + | |
| 271 | +//-------------------------------------------------------------------- | |
| 272 | +// ini 파일에서 실행할 파일의 정보를 읽어 들이고, | |
| 273 | +// ary_task 목록을 작성한다. | |
| 274 | +//-------------------------------------------------------------------- | |
| 275 | +void read_task_list( void) | |
| 276 | +{ | |
| 277 | + FILE *fp; | |
| 278 | + char *tag; | |
| 279 | + char *pos; | |
| 280 | + char buf[PACKET_SIZE]; | |
| 281 | + char item[255]; | |
| 282 | + | |
| 283 | + cnt_task = 0; // 실행할 작업 개수 초기화 | |
| 284 | + | |
| 285 | + fp = fopen( "./superdaemon.ini", "r"); // 환경파일 open; | |
| 286 | + if ( NULL == fp) | |
| 287 | + { // 읽어 들일 타스크가 없음 | |
| 288 | + return; | |
| 289 | + } | |
| 290 | + else | |
| 291 | + { | |
| 292 | + while( NULL != fgets( buf, PACKET_SIZE, fp)) | |
| 293 | + { | |
| 294 | + tag = buf; | |
| 295 | + remove_white_char( tag); // 문장에 라인피드와 같은 화이트 문자를 없앤다. | |
| 296 | + | |
| 297 | + // 프로그램 종료 시 다음 시작까지의 시간 간격을 구한다. | |
| 298 | + | |
| 299 | + while ( ' ' == *tag) // 앞에 있는 공백 삭제 | |
| 300 | + { | |
| 301 | + tag++; | |
| 302 | + } | |
| 303 | + | |
| 304 | + if ( ( ' ' > *tag) || // 문장의 끝이거나 | |
| 305 | + ( !strncmp( tag, "//", 2)) ) // 주석문이라면 다음 행으로 | |
| 306 | + { | |
| 307 | + continue; | |
| 308 | + } | |
| 309 | + // 행의 첫 번째 데이터는 대기 시간 정보이다. | |
| 310 | + // 첫번째 문자열에서 시간 정보를 구한다. | |
| 311 | + | |
| 312 | + tag = str_spc( tag, item); | |
| 313 | + ary_task[cnt_task].interval = atoi( item); | |
| 314 | + | |
| 315 | + // 프로그램의 실행 정보를 구한다. | |
| 316 | + // 실행 정보에는 경로와 프로그램 명이 있어야 하므로 | |
| 317 | + // 최소 공백 문자가 하나 있어야 한다. | |
| 318 | + // 인수에 공백 문자가 없다면 취소한다. | |
| 319 | + | |
| 320 | + if ( ( ' ' > *tag) || // 문장의 끝이거나 | |
| 321 | + ( !strncmp( tag, "//", 2)) ) // 주석문이라면 다음 행으로 | |
| 322 | + { | |
| 323 | + continue; | |
| 324 | + } | |
| 325 | + | |
| 326 | + pos = index( tag, ' '); // 공백 문자가 없다면 취소한다. | |
| 327 | + if (!pos) | |
| 328 | + { | |
| 329 | + continue; | |
| 330 | + } | |
| 331 | + | |
| 332 | + get_execinfo( tag, &ary_task[cnt_task]); | |
| 333 | + | |
| 334 | + // task 의 초기값을 초기화 한다. | |
| 335 | + | |
| 336 | + ary_task[cnt_task].count_down = 0; | |
| 337 | + ary_task[cnt_task].pid = 0; | |
| 338 | + cnt_task++; | |
| 339 | + if ( TASK_ARRAY_SIZE == cnt_task) | |
| 340 | + { | |
| 341 | + printf( "***** Task list is over %d. *****\n", TASK_ARRAY_SIZE); | |
| 342 | + break; | |
| 343 | + } | |
| 344 | + } | |
| 345 | + } | |
| 346 | + fclose( fp); | |
| 347 | +} | |
| 348 | + | |
| 349 | +//-------------------------------------------------------------------- | |
| 350 | +// 차일드 프로세서의 죽음을 확인하는 시그널 등록 | |
| 351 | +//-------------------------------------------------------------------- | |
| 352 | +void reg_child_signal( void) | |
| 353 | +{ | |
| 354 | + struct sigaction sig_child; // 차일드의 죽음을 알기 위한 시그털 | |
| 355 | + | |
| 356 | + sig_child.sa_handler = on_check_child; | |
| 357 | + sigemptyset( &sig_child.sa_mask); | |
| 358 | + sig_child.sa_flags = 0; | |
| 359 | + sigaction( SIGCHLD, &sig_child, 0); | |
| 360 | +} | |
| 361 | + | |
| 362 | +//-------------------------------------------------------------------- | |
| 363 | +// main procedure | |
| 364 | +//-------------------------------------------------------------------- | |
| 365 | +int main( int argc, char **argv) | |
| 366 | +{ | |
| 367 | +#ifdef NDEBUG | |
| 368 | + | |
| 369 | + pid_t pid_daemon; // release 모드일 때만 endif 사이의 내용이 실행된다. | |
| 370 | + | |
| 371 | + pid_daemon = fork(); | |
| 372 | + if ( 0 > pid_daemon) // fork() 실행에 실패했다면 | |
| 373 | + { | |
| 374 | + printf( "ERR: fork() failed\n"); // 실행 에러를 알린다. | |
| 375 | + exit( 1); | |
| 376 | + } | |
| 377 | + else if( 0 != pid_daemon) // 부모 프로세스 라면 | |
| 378 | + { | |
| 379 | + exit( 0); // 종료한다. | |
| 380 | + } | |
| 381 | + | |
| 382 | +#endif | |
| 383 | + | |
| 384 | + reg_child_signal(); // child 시그널 등록 | |
| 385 | + read_task_list(); // 실행할 정보 목록을 작성한다. | |
| 386 | + | |
| 387 | + while( 1 ) | |
| 388 | + { | |
| 389 | + check_task_list(); // 작업 상태를 확인한다. | |
| 390 | + sleep( 1); // 1 초를 대기 | |
| 391 | + } | |
| 392 | +} | ... | ... |
app/superdaemon/main.h
| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | +#ifndef MAIN_H | |
| 2 | +#define MAIN_H | |
| 3 | + | |
| 4 | +#include <sys/types.h> | |
| 5 | + | |
| 6 | +#define TRUE 1 | |
| 7 | +#define FALSE 0 | |
| 8 | + | |
| 9 | +#define ERR_NONE 0 | |
| 10 | +#define ERR_PATH_TOO_LONG -1 | |
| 11 | +#define ERR_EXE_TOO_LONG -2 | |
| 12 | +#define ERR_PARAMS_TO0_LONG -3; | |
| 13 | +#define ERR_TOO_MANY_PARAMS -4; | |
| 14 | +#define ERR_EXECUTE -5; | |
| 15 | + | |
| 16 | +typedef struct | |
| 17 | +{ | |
| 18 | + char *full_filename; | |
| 19 | + char *params[20]; | |
| 20 | + int interval; | |
| 21 | + int count_down; | |
| 22 | + int error; | |
| 23 | + pid_t pid; | |
| 24 | +} task_t; | |
| 25 | + | |
| 26 | + | |
| 27 | +#endif | ... | ... |
app/superdaemon/projectinc.c
| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | +#include <stdio.h> | |
| 2 | +#include <stdlib.h> | |
| 3 | +#include <string.h> | |
| 4 | +#include "projectinc.h" | |
| 5 | + | |
| 6 | +//-------------------------------------------------------------------- | |
| 7 | +// desc 문자열에서 /t /n /f 와 같은 화이트 문자를 NULL 코드로 | |
| 8 | +// 바꾸어 준다. | |
| 9 | +//-------------------------------------------------------------------- | |
| 10 | +void remove_white_char( char *_str) | |
| 11 | +{ | |
| 12 | + int ndx; | |
| 13 | + | |
| 14 | + for ( ndx = 0; ndx < strlen(_str); ndx++) | |
| 15 | + { | |
| 16 | + if (' ' > _str[ndx]) | |
| 17 | + { | |
| 18 | + _str[ndx] = '\0'; | |
| 19 | + } | |
| 20 | + } | |
| 21 | +} | |
| 22 | + | |
| 23 | +//-------------------------------------------------------------------- | |
| 24 | +// desc 메시지를 전송하고 실행을 중지한다. | |
| 25 | +//-------------------------------------------------------------------- | |
| 26 | +void error_handling(char *message) | |
| 27 | +{ | |
| 28 | + fputs( message, stderr); | |
| 29 | + fputc( '\n', stderr); | |
| 30 | + exit(1); | |
| 31 | +} | |
| 32 | + | |
| 33 | + | ... | ... |
app/superdaemon/projectinc.h
| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | +#ifndef _PROJECTINC_ | |
| 2 | +#define _PROJECTINC_ | |
| 3 | + | |
| 4 | +#define NDEBUG | |
| 5 | + | |
| 6 | +#ifndef NDEBUG | |
| 7 | +#define dp(fmt,args...) printf( fmt, ## args ); putchar( '\n') | |
| 8 | +#define dlp(fmt,args...) printf( "[%s %d]" fmt, __FILE__,__LINE__, ## args ) | |
| 9 | +#else | |
| 10 | +#define dp(fmt,args...) | |
| 11 | +#define dlp(fmt,args...) | |
| 12 | +#endif | |
| 13 | + | |
| 14 | +extern void remove_white_char( char *); | |
| 15 | +extern void error_handling(char *message); | |
| 16 | + | |
| 17 | +//----- SysManager --------------------------------------------------- | |
| 18 | + | |
| 19 | +#define PACKET_SIZE 1024 | |
| 20 | + | |
| 21 | +#endif | ... | ... |
app/superdaemon/readme.txt
| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | +prj name : superdaemon - 등록된 프로그램을 실행 및 관리 | |
| 2 | +descript : | |
| 3 | + | |
| 4 | + 1. superdaemon.ini 에 등록된 프로그램을 실행하고 | |
| 5 | + 프로그램 종료를 계속 확인하면서, | |
| 6 | + 종료되면 지정된 시간 후 다시 실행하게 한다. | |
| 7 | + | |
| 8 | + 2. 추후, watch dog 기능을 추가한다. | |
| 9 | + | |
| 10 | +version : | |
| 11 | + 0.0.1 superdaemon.ini 에 등록된 프로그램을 실행 | |
| 12 | + 0.0.2 execl() 사용하여 구성 | |
| 13 | + 0.0.3 1. | |
| 14 | + execl() 을 execv() 로 재 구성 | |
| 15 | + ref | |
| 16 | + execl() 은 인수가 ( ) | |
| 17 | + 2. | |
| 18 | + 실행파일 정보 문자열에 이상이 없을 때에만 | |
| 19 | + fork() 실행하도록 수정 | |
| 20 | + 1.0.0 1. | |
| 21 | + 파일을 실행할 때, 파일의 존재 유무를 확인하는 | |
| 22 | + 코드를 추가 | |
| 23 | + 2. | |
| 24 | + 환경 파일에서 경로명에 '/' 이 없을 때 발생하던 | |
| 25 | + 오류를 잡음 | |
| 26 | + | |
| 27 | + | |
| 28 | + 장길석, goguryeo@gmail.com | |
| 29 | + | |
| 0 | 30 | \ No newline at end of file | ... | ... |
app/superdaemon/superdaemon.ini
| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | +// superdaemon 에서 사용되는 환경파일입니다. | |
| 2 | + | |
| 3 | +// 아래의 리스트는 superdaemon 에서 실행되며, | |
| 4 | +// 프로그램이 종료되더라도 지정된 시간(초) 후에 다시 | |
| 5 | +// 자동으로 실행됩니다. | |
| 6 | + | |
| 7 | +// 작성 방법은 공백 문자로 분리가 되며, | |
| 8 | +// [시간] [경로] [실행파일 이름] [인수1] [인수2].... | |
| 9 | +// 식으로 한개의 행에 하나의 프로그램 실행 정보를 넣어주면 됩니다. | |
| 10 | + | |
| 11 | +// 실행 경로와 실행파일의 이름을 합쳐서 255자 이내이어야 하며, | |
| 12 | +// 인수는 20 개 이상이 될 수 없습니다. | |
| 13 | + | |
| 14 | +1 /bin/ ls -al 123 234 456 | |
| 15 | +3 /bin/ ls -al /tmp 678 90 | |
| 16 | +5 /bin/ ls -al /usr abc def | |
| 17 | + | |
| 18 | +//2 ./ tcp2rx /dev/ttyS05 22549 | |
| 19 | +//2 ./ tcp2rx /dev/ttyS04 22559 | |
| 20 | +//2 ./ tcp2rx /dev/ttyS03 22569 | |
| 21 | + | |
| 22 | +//2 ./ udp2rx /dev/ttyS06 22539 192.168.10.2 | |
| 23 | +//2 ./ udp2rx /dev/ttyS05 22549 192.168.10.2 | |
| 24 | +//2 ./ udp2rx /dev/ttyS04 22559 192.168.10.2 | |
| 25 | +//2 ./ udp2rx /dev/ttyS03 22569 192.168.10.2 | |
| 26 | + | |
| 27 | +//5 . child 1 | |
| 28 | +//5 ./ child 1 2 | |
| 29 | +//5 ./ child 1 2 3 | |
| 30 | + | ... | ... |