Initial submission

This commit is contained in:
aixiao 2020-09-11 16:40:25 +08:00
commit e166d8a830
6 changed files with 268 additions and 0 deletions

17
Makefile Normal file
View File

@ -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)

24
README.md Normal file
View File

@ -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

6
daemon.conf Normal file
View File

@ -0,0 +1,6 @@
global {
PROCESS_NAME = "frpc";
COMMAND = "ls -al";
TIME = "10";
LOFFILE = "log.txt";
}

96
main.c Normal file
View File

@ -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;
}

12
main.h Normal file
View File

@ -0,0 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <time.h>
#define PATH_SIZE 270
FILE *_popen(const char *cmdstring, const char *type);
int _pclose(FILE * fp);

113
popen.c Normal file
View File

@ -0,0 +1,113 @@
/*
* popen.c Written by W. Richard Stevens
* write 20180623 email: aixiao@aixiao.me
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/resource.h>
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 */
}