用Linux守护进程检测某个程序是否运行2
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:Fedora12
目标板:SC6410
目标板LINUX内核版本:2.6.36
说明:
第一版程序(参考http://blog.csdn.net/jdh99/article/details/7300641)已经可以正常工作,不过在运行一个月后发现有两台平板出现不能启动的问题,检查后发现是nand flash坏块很多,导致系统不能启动。究其原因,因该是对flash频繁的写操作造成的。上一版本的守护程序每分钟会写操作一次,这样一天的写操作就达千次。在这一版本中,判断需要守护的进程是否存在,是通过读取/proc/pid目录来判断的。参考链接:http://kb.cnblogs.com/a/2360817/
驱动源代码:
daemon_service.c:
- //守护进程,守护AlarmInterface进程
- //作者:jdh
- //时间:2012-2-27
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <syslog.h>
- #include <dirent.h>
- //程序名字
- #define NAME "AlarmInterface"
- //要运行的程序
- #define RUN_NAME "DuiJiang &"
- #define READ_BUF_SIZE 100
- //#define DIR_OUT_FILE "/rf/out"
- //#define NAME "gnome-keyring"
- //#define NAME_FIND "gnome"
- //#define DIR_OUT_FILE "/root/test/out"
- int daemon(int nochdir,int noclose)
- {
- pid_t pid;
- //让init进程成为新产生进程的父进程
- pid = fork();
- //如果创建进程失败
- if (pid < 0)
- {
- perror("fork");
- return -1;
- }
- //父进程退出运行
- if (pid != 0)
- {
- exit(0);
- }
- //创建新的会话
- pid = setsid();
- if (pid < -1)
- {
- perror("set sid");
- return -1;
- }
- //更改当前工作目录,将工作目录修改成根目录
- if (!nochdir)
- {
- chdir("/");
- }
- //关闭文件描述符,并重定向标准输入,输出合错误输出
- //将标准输入输出重定向到空设备
- if (!noclose)
- {
- int fd;
- fd = open("/dev/null",O_RDWR,0);
- if (fd != -1)
- {
- dup2(fd,STDIN_FILENO);
- dup2(fd,STDOUT_FILENO);
- dup2(fd,STDERR_FILENO);
- if (fd > 2)
- {
- close(fd);
- }
- }
- }
- //设置守护进程的文件权限创建掩码
- umask(0027);
- return 0;
- }
- //存在返回1,不存在返回0
- int judge_pid_exist(char* pidName)
- {
- DIR *dir;
- struct dirent *next;
- //long* pidList=NULL;
- int i=0;
- FILE *status;
- char filename[READ_BUF_SIZE];
- char buffer[READ_BUF_SIZE];
- char name[READ_BUF_SIZE];
- ///proc中包括当前的进程信息,读取该目录
- dir = opendir("/proc");
- if (!dir)
- {
- printf("Cannot open /proc\n");
- return 0;
- }
- //遍历
- while ((next = readdir(dir)) != NULL)
- {
- /* Must skip ".." since that is outside /proc */
- if (strcmp(next->d_name, "..") == 0)
- {
- continue;
- }
- /* If it isn't a number, we don't want it */
- if (!isdigit(*next->d_name))
- {
- continue;
- }
- //设置进程
- sprintf(filename, "/proc/%s/status", next->d_name);
- if (! (status = fopen(filename, "r")) )
- {
- continue;
- }
- if (fgets(buffer, READ_BUF_SIZE-1, status) == NULL)
- {
- fclose(status);
- continue;
- }
- fclose(status);
- //得到进程id
- /* Buffer should contain a string like "Name: binary_name" */
- sscanf(buffer, "%*s %s", name);
- if (strcmp(name, pidName) == 0)
- {
- //pidList=realloc( pidList, sizeof(long) * (i+2));
- //pidList[i++]=strtol(next->d_name, NULL, 0);
- //printf("hello,%s\n",next->d_name);
- return 1;
- }
- }
- //if (pidList)
- //{
- //pidList[i]=0;
- //}
- return 0;
- }
- int main(int argc,char *argv[])
- {
- int fd = 0;
- char buf[100];
- //开启守护进程
- daemon(0,0);
- while (1)
- {
- //打开日志
- //openlog(argv[0],LOG_CONS|LOG_PID,LOG_USER);
- //判断是否有程序文件运行
- if (judge_pid_exist(NAME))
- {
- //syslog(LOG_INFO,"jdh success!!!!!!!!!!");
- //printf("hello,jdh,exist\n");
- }
- else
- {
- //syslog(LOG_INFO,"jdh fail!!!!!!!!!!");
- //运行程序
- system(RUN_NAME);
- //printf("hello,jdh,oh,no\n");
- }
- //休眠
- sleep(60);
- }
- //关闭日志
- //closelog();
- return 0;
- }