#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>
int daemon(int, int);
char *daemon_log = "/u01/log/daemon.log";
int add_log(char*, char*);
void sig_handler(int);
void restart_sleep(int);
int is_daemon = 1;
int is_root = 1;
int main()
{
fprintf(stdout, "daemon start\n");
int ret;
//是否切换到普通用户
if (!is_root) {
if (getuid() == 0 || geteuid() == 0) {
char *username = "flynetcn";
struct passwd *pw;
if ((pw = getpwnam(username)) == 0) {
fprintf(stderr, "can't find the user %s\n", username);
return 1;
}
if (setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) {
fprintf(stderr, "failed to assume identity of user %s\n", username);
return 1;
}
}
}
//防止僵死子进程
struct sigaction sa, oldsa;
sa.sa_handler = sig_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, &oldsa) == -1) {
fprintf(stderr, "sigaction(SIGCHLD) error\n");
return 1;
}
//切换到守护进程
if (is_daemon) {
ret = daemon(1, 0);
if (ret == -1) {
fprintf(stderr, "failed to daemon\n");
return 1;
}
}
/**
* do something
*/
int crontimers[3][2];
//task 1
crontimers[0][0] = 3;
crontimers[0][1] = 6;
//task 2
crontimers[1][0] = -1;
crontimers[1][1] = 6;
//task 3
crontimers[2][0] = -1;
crontimers[2][1] = 36;
//tasks comm
char *croncomm[3];
croncomm[0] = "echo task1 >> /dev/null 2>&1";
croncomm[1] = "echo task2 >> /dev/null 2>&1";
croncomm[2] = "echo task3 >> /dev/null 2>&1";
char buf[1024];
char tbuf[50];
time_t timestamp;
struct tm *now;
int time_left;
int cron_num;
cron_num = sizeof(croncomm)/sizeof(char*);
int hok, i;
while (1) {
timestamp = time(NULL);
now = localtime(×tamp);
strftime(tbuf, 30, "%Y-%m-%d %H:%M:%S", now);
//
sprintf(buf, "%s ------\n", tbuf);
add_log(buf, daemon_log);
for (i=0; i<cron_num; i++) {
hok=0;
sprintf(buf, "task %d :\n", i);
add_log(buf, daemon_log);
if (crontimers[i][0]==-1 || now->tm_hour==crontimers[i][0]) {
hok = 1;
add_log("hok\n", daemon_log);
} else {
continue;
}
if (crontimers[i][1]==now->tm_min && croncomm[i]) {
add_log("mok\n", daemon_log);
sprintf(buf, "run %s\n", croncomm[i]);
add_log(buf, daemon_log);
ret = fork();
if (ret == 0) {
system(croncomm[i]);
exit(0);
}
}
}
timestamp = time(NULL);
now = localtime(×tamp);
time_left = 60 - now->tm_sec;
restart_sleep(time_left);
}
/**
* end
*/
}
int add_log(char *str, char *logfile)
{
FILE *fp;
if ((fp = fopen(logfile, "a")) == NULL) {
return -1;
}
if (!(*str) || fputs(str, fp)==EOF) {
fclose(fp);
return -1;
}
fflush(fp);
fclose(fp);
return 0;
}
int daemon(int nochdir, int noclose)
{
int fd, ret;
ret = fork();
switch (ret) {
case -1: return -1;
case 0: break;
default: exit(0);
}
if (setsid() == -1)
return -1;
if (nochdir == 0) {
if(chdir("/") != 0) {
perror("chdir");
return -1;
}
}
if (noclose == 0 && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
if(dup2(fd, STDIN_FILENO) < 0) {
perror("dup2 stdin");
return -1;
}
if(dup2(fd, STDOUT_FILENO) < 0) {
perror("dup2 stdout");
return -1;
}
if(dup2(fd, STDERR_FILENO) < 0) {
perror("dup2 stderr");
return -1;
}
if (fd > STDERR_FILENO) {
if(close(fd) < 0) {
perror("close");
return -1;
}
}
}
return 0;
}
void sig_handler(int sig)
{
if (sig == SIGCHLD) {
int status;
pid_t pid;
pid = wait(&status);
}
}
//防止被信号中断
void restart_sleep(int sec)
{
int left;
left = sec;
while (left > 0) {
left = sleep(left);
}
}
|