From e166d8a830ab0bb0760e46d6e3ac7615b9d93665 Mon Sep 17 00:00:00 2001 From: aixiao Date: Fri, 11 Sep 2020 16:40:25 +0800 Subject: [PATCH] Initial submission --- Makefile | 17 ++++++++ README.md | 24 +++++++++++ daemon.conf | 6 +++ main.c | 96 ++++++++++++++++++++++++++++++++++++++++++++ main.h | 12 ++++++ popen.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 268 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 daemon.conf create mode 100644 main.c create mode 100644 main.h create mode 100644 popen.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..96218ec --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CROSS_COMPILE ?= +CC := $(CROSS_COMPILE)gcc +STRIP := $(CROSS_COMPILE)strip +CFLAGS += -g -O2 -Wall -I../libconf -L../libconf +LIBS = -lconf -static +OBJ := daemon + +all: popen.o main.o + $(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS) + $(STRIP) $(OBJ) + -chmod a+x $(OBJ) +.c.o: + $(CC) $(CFLAGS) -c $< $(LIBS) + +clean: + rm -rf *.o + rm $(OBJ) diff --git a/README.md b/README.md new file mode 100644 index 0000000..55e6ef4 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +### Daemon + 根据程序名称和时间为判断条件的进程守护程序. + 配置文件默认 daemon.conf + global { + PROCESS_NAME = "frpc"; //进程名称条件变量 + COMMAND = "ls -al"; //进程名称条件变量不成立执行的命令 + TIME = "10"; //时间条件变量, 单位秒 + LOFFILE = "log.txt"; //日志记录 + } + +### Build + Linux编译: + git clone https://github.com/niuyuling/daemon.git + git clone https://github.com/niuyuling/libconf.git + cd libconf + make clean; make + cd ../daemon + make clean; make + +### Help + #启动 + ./daemon + #关闭 + killall daemon \ No newline at end of file diff --git a/daemon.conf b/daemon.conf new file mode 100644 index 0000000..483ed8e --- /dev/null +++ b/daemon.conf @@ -0,0 +1,6 @@ +global { + PROCESS_NAME = "frpc"; + COMMAND = "ls -al"; + TIME = "10"; + LOFFILE = "log.txt"; +} \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..f2b3034 --- /dev/null +++ b/main.c @@ -0,0 +1,96 @@ +#include "main.h" +#include "libconf.h" + +int get_process_pid(char *proces_name) +{ + char bufer[PATH_SIZE]; + char comm[PATH_SIZE]; + char proc_comm_name[PATH_SIZE]; + int num[PATH_SIZE] = { 0 }; + int n = 0; + FILE *fp; + DIR *dir; + struct dirent *ptr; + dir = opendir("/proc"); + while ((ptr = readdir(dir)) != NULL) { + if (ptr->d_type == 4 && strcasecmp(ptr->d_name, ".") && strcasecmp(ptr->d_name, "..")) { + bzero(bufer, 0); + sprintf(comm, "/proc/%s/comm", ptr->d_name); + if (access(comm, F_OK) == 0) { + fp = fopen(comm, "r"); + if (fgets(bufer, PATH_SIZE - 1, fp) == NULL) { + fclose(fp); + continue; + } + sscanf(bufer, "%s", proc_comm_name); + if (!strcmp(proces_name, proc_comm_name)) { + num[n] = atoi(ptr->d_name); + n += 1; + } + fclose(fp); + } + } + + } + + n -= 1; // 去除最后一个搜索时的本身进程 + closedir(dir); + if (num[0] > 0) + return num[0]; + else + return 0; +} + +char *times() +{ + time_t t; + struct tm *timeinfo; //结构体 + time(&t); + timeinfo = localtime(&t); + return asctime(timeinfo); //以字符串形式输出localtime本地时间 +} + +int logs(char *str) +{ + FILE *fp = NULL; + fp = fopen(read_conf("daemon.conf", "global", "LOFFILE"), "a+"); + fprintf(fp, str); + return fclose(fp); +} + +int loop() +{ + FILE *fp; + char buffer[PATH_SIZE]; + while (1) { + if (get_process_pid(read_conf("daemon.conf", "global", "PROCESS_NAME")) <= 0) { + logs(times()); + logs("没有运行\n"); + fp = _popen(read_conf("daemon.conf", "global", "COMMAND"), "r"); + + logs(times()); + logs("执行结果\n"); + while (fgets(buffer, sizeof(buffer), fp)) { + //printf("%s", buffer); + logs(buffer); + } + _pclose(fp); + } else { + logs(times()); + logs("运行\n"); + } + sleep(atoi(read_conf("daemon.conf", "global", "TIME"))); + } +} + +int main(int argc, char **argv) +{ + if (daemon(1, 1)) { + perror("daemon"); + return 1; + } + + loop(); + + return 0; +} diff --git a/main.h b/main.h new file mode 100644 index 0000000..791b4c8 --- /dev/null +++ b/main.h @@ -0,0 +1,12 @@ +#include +#include +#include +#include +#include +#include +#include + +#define PATH_SIZE 270 + +FILE *_popen(const char *cmdstring, const char *type); +int _pclose(FILE * fp); diff --git a/popen.c b/popen.c new file mode 100644 index 0000000..1bf52f5 --- /dev/null +++ b/popen.c @@ -0,0 +1,113 @@ +/* + * popen.c Written by W. Richard Stevens + * write 20180623 email: aixiao@aixiao.me + */ + +#include +#include +#include +#include +#include +#include +#include + +static pid_t *childpid = NULL; + /* ptr to array allocated at run-time */ +static int maxfd; /* from our open_max(), {Prog openmax} */ + +#define SHELL "/bin/sh" + +FILE *_popen(const char *cmdstring, const char *type) +{ + int i, pfd[2]; + pid_t pid; + FILE *fp; + + /* only allow "r" or "w" */ + if ((type[0] != 'r' && type[0] != 'w') || type[1] != 0) { + errno = EINVAL; /* required by POSIX.2 */ + return (NULL); + } + + if (childpid == NULL) { /* first time through */ + /* allocate zeroed out array for child pids */ +#if 0 + maxfd = open_max(); +#else + /* OPEN_MAX is canceled after linux-2.6.24, and become a part of RLIMIT_NOFILE. + Execute shell 'ulimit -a' to get more information */ + struct rlimit limit; + if (getrlimit(RLIMIT_NOFILE, &limit) == -1) { + perror("getrlimit fail"); + return (NULL); + } + maxfd = limit.rlim_cur; + //print("rlimit = %d.\n", maxfd); +#endif + if ((childpid = calloc(maxfd, sizeof(pid_t))) == NULL) + return (NULL); + } + + if (pipe(pfd) < 0) + return (NULL); /* errno set by pipe() */ + + if ((pid = fork()) < 0) + return (NULL); /* errno set by fork() */ + else if (pid == 0) { /* child */ + if (*type == 'r') { + close(pfd[0]); + if (pfd[1] != STDOUT_FILENO) { + dup2(pfd[1], STDOUT_FILENO); + close(pfd[1]); + } + } else { + close(pfd[1]); + if (pfd[0] != STDIN_FILENO) { + dup2(pfd[0], STDIN_FILENO); + close(pfd[0]); + } + } + /* close all descriptors in childpid[] */ + for (i = 0; i < maxfd; i++) + if (childpid[i] > 0) + close(i); + + execl(SHELL, "sh", "-c", cmdstring, (char *)0); + exit(127); + } + /* parent */ + if (*type == 'r') { + close(pfd[1]); + if ((fp = fdopen(pfd[0], type)) == NULL) + return (NULL); + } else { + close(pfd[0]); + if ((fp = fdopen(pfd[1], type)) == NULL) + return (NULL); + } + childpid[fileno(fp)] = pid; /* remember child pid for this fd */ + return (fp); +} + +int _pclose(FILE * fp) +{ + int fd, stat; + pid_t pid; + + if (childpid == NULL) + return (-1); /* popen() has never been called */ + + fd = fileno(fp); + if ((pid = childpid[fd]) == 0) + return (-1); /* fp wasn't opened by popen() */ + + childpid[fd] = 0; + if (fclose(fp) == EOF) + return (-1); + + while (waitpid(pid, &stat, 0) < 0) + if (errno != EINTR) + return (-1); /* error other than EINTR from waitpid() */ + + return (stat); /* return child's termination status */ +}