首先说一下Ubuntu下看门狗程序,这个程序是用在我项目中的,用来保证核心程序能够实现崩溃自启动,这对于程序的稳定运行至关重要。
话不多少,直接上代码:
(1)新建看门狗程序 daemon_upload.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <dirent.h>
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/stat.h>
#define READ_BUF_SIZE 1024
#define pidName "/home/node/nodeClient/Icardclient1/uploadFile.js"
char pid[10];
void init_daemon(void);//守护进程初始化函数
int get_pid(void);
main()
{
FILE *fp;
time_t t;
init_daemon();//初始化为Daemon
while(1)//每隔一分钟向test.log报告运行状态
{
sleep(5);//睡眠5秒钟
int i = 0;
i = get_pid();
if (i == 0 )
{
if((fp=fopen("/home/node/nodelog/uploadFile.log","a")) >=0)
{
t=time(0);
fprintf(fp,"iclient.js don't exist at %s\n",asctime(localtime(&t)));
int ret = 0;
char s[500];
char *command = "/home/node/bin/node /home/node/nodeClient/Icardclient1/uploadFile.js";
memset(s,0,sizeof(s));
strcpy(s,command);
ret = system(s);
if( ret < 0)
{
t=time(0);
fprintf(fp,"iclient.js reboot failed at %s\n",asctime(localtime(&t)));
}else
{
t=time(0);
fprintf(fp,"iclient.js reboot succeed at %s\n",asctime(localtime(&t)));
}
fclose(fp);
}
}
}
}
int get_pid(void)
{
DIR *dir;
struct dirent *next;
int i=0;
FILE *status;
char buffer[READ_BUF_SIZE];
char name[READ_BUF_SIZE];
dir=opendir("/proc");
if(!dir){
printf("Can't open /proc\n");
return 0;
}
while((next=readdir(dir))!=NULL){
if((strcmp(next->d_name,"..")==0||strcmp(next->d_name,".")==0)){
continue;
}
if(!isdigit(*next->d_name)){
continue;
}
sprintf(buffer,"/proc/%s/status",next->d_name);
if(!(status=fopen(buffer,"r"))){
continue;
}
if(fgets(buffer,READ_BUF_SIZE,status)==NULL){
fclose(status);
continue;
}
fclose(status);
sscanf(buffer,"%*s%s",name);
if(strcmp(name,pidName)==0){
//printf("%s\n",next->d_name);
strcpy(pid,next->d_name);
printf("%s\n",pid);
i = 1;
}
}
closedir(dir);
return i;
}
void init_daemon(void)
{
int pid;
int i;
if(pid=fork())
exit(0);
else if(pid< 0)
exit(1);
setsid();
if(pid=fork())
exit(0);
else if(pid< 0)
exit(1);
for(i=0;i< NOFILE;++i)
close(i);
chdir("/");
umask(0);
return;
}
注意:代码是可以直接拿来用的,不过需要修改一下代码部分地方,主要是代码中几个文件路径,你需要提前建立好文件夹以及文件。
(2)将daemon_upload.c文件通过g++编译成可执行文件node_upload
g++ -o daemon_upload.c node_upload
(3)基于.destop文件实现程序的开机自启动
ubuntu下有很多中开机自动运行程序的方法,在开机的不同过程中可以启动不同的程序.如在开机启动时自动运行程序,是通过修改放置在
/etc/rc或
/etc/rc.d 或
/etc/rc?.d
目录下的脚本文件,可以使init自动启动其它程序。例如:编辑
/etc/rc.d/rc.local 文件(该文件通常是系统最后启动的脚本),
也可以在用户登陆是启动,用户登录时,bash先自动执行系统管理员建立的全局登录script :
/ect/profile
然后bash在用户起始目录下按顺序查找三个特殊文件中的一个:
/.bash_profile、
/.bash_login、
/.profile,
但只执行最先找到的一个。
在项目中,采用的一种比较独特的方式:在/etc/xdg/autostart/文件路径下,新建node_upload,destop文件,文件内容如下:
[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=Node
X-GNOME-FullName=Node Js
GenericName=Node
Comment=Update your microblog and view others' statuses
Icon=node
Exec=/home/node/nodeClient/daemon/node_upload
#OnlyShowIn=GNOME;Unity;
X-GNOME-Autostart-enadbled=true
#AutostartCondition=GSettings org.gwibber.preferences autostart
X-GNOME-Autostart-Delay=10
NoDisplay=true
Name[en_US]=node_upload
注意这个地方是(2)中生成可执行文件的绝对路径。
至此,当设备开机时,就可以实现程序的自启动以及崩溃重启了。