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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 | \ No newline at end of file | 30 | \ No newline at end of file |
app/superdaemon/superdaemon.ini
| @@ -0,0 +1,30 @@ | @@ -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 | + |