用一个程序启动另一个程序,并实现周期性执行服务程序。
思路:
procectl执行完后退出,子进程被1号进程接管,运行在后台。
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
if(argc<3)
{
printf("Using:./procctl timetvl program argvs ...\n");
printf("Example:/project/tools1/bin/procctl 5 /usr/bin/tar zcvf /tmp/tmp.tgz /usr/include\n\n");
printf("timetvl 运行周期,单位:秒。被调度的程序运行结束后,在timetvl秒后会被procctl重新启动。\n");
printf("program 被调度的程序名,必须使用全路径。\n");
printf("argvs 被调度的程序的参数。\n");
printf("注意,本程序不会被kill杀死,但可以用kill -9强行杀死。\n\n\n");
return -1;
}
// 关闭信号和IO,本程序不希望被打扰
// 信号的取值是64,关信号和关io用了同一个循环,实际上io并没有64那么多,只有0、1、2,但是,代码这么写也没有问题,没必要再用一个循环。
for(int ii=0;ii<64;ii++)
{
signal(ii,SIG_IGN); close(ii);
}
// 分叉了,生成子进程继续往后执行代码,父进程退出,让程序运行在后台,由系统1号进程托管。(子进程变成孤儿进程, 其父进程变为1号进程)
if (fork()!=0) exit(0);
// 启用SIGCHLD信号,让父进程可以wait子进程退出的状态。
signal(SIGCHLD,SIG_DFL);
char *pargv[argc];
for(int ii=2;ii<argc;ii++)
pargv[ii-2] = argv[ii];
pargv[argc-2] = NULL;
while(true)
{
if(fork()==0)
{
execv(argv[2],pargv); // 执行成功,就去执行别的进程,后面代码不执行
exit(0); // 如果execv执行失败就退出
}
else
{
int status;
wait(&status);
sleep(atoi(argv[1]));
}
}
}