本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
//守护进程,守护AlarmInterface进程
//作者:jdh
//时间:2012-4-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 1024
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;
int i = 0;
FILE *status;
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)
{
//跳过"."和".."两个文件名
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);
//读取PID对应的程序名,格式为Name: 程序名
sscanf(buffer,"%*s %s",name);
//判断程序名是否符合预期
if (strcmp(name,pidName) == 0)
{
//符合
closedir(dir);
return 1;
}
}
closedir(dir);
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;
}
转:https://www.cnblogs.com/sylar5/p/6491033.html
转 :https://blog.csdn.net/windanchaos/article/details/80991089
文件是否修改
Access函数: 文件最近一次被访问的时间
确定文件或文件夹的访问权限。即,检查某个文件的存取方式,比如说是只读方式、只写方式等。如果指定的存取方式有效,则函数返回0,否则函数返回-1。
change time函数: 文件属性最近一次被修改的时间
是文档的索引节点(inode)发生了改变(比如位置、用户属性、组属性等);叫做状态改动时间。通过chmod、chown命令修改一次文件属性,这个时间就会更新。
modify time函数:文件内容最近一次被改变的时间
是文件本身的内容发生了变化。[文档的modify时间也叫时间戳(timestamp).]
核心命令:stat
如下函数,判断文件是否更新,传入文件路径,间隔时间(秒s),则输入文件在多少秒内是否被更新过。
函数会持续等待文件不再变化后停止。
local file_path=${1}
local check_time=${2}
while [[ true ]]; do
file_old_stat="`stat ${file_path}|grep Size`"
sleep ${check_time}
file_new_stat="`stat ${file_path}|grep Size`"
if [[ `echo ${file_old_stat}` == `echo ${file_new_stat}` ]]; then
echo "### In ${check_time}s ,${file_path} does not change ###"
break
else
echo "#### Wait ${check_time}s ####"
fi
done
}
stat 函数 介绍
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main() {
struct stat buf;
stat("/etc/hosts", &buf);
printf("/etc/hosts file size = %d\n", buf.st_size);
}
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
先前所描述的st_mode 则定义了下列数种情况:
S_IFMT 0170000 文件类型的位遮罩
S_IFSOCK 0140000 scoket
S_IFLNK 0120000 符号连接
S_IFREG 0100000 一般文件
S_IFBLK 0060000 区块装置
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符装置
S_IFIFO 0010000 先进先出
S_ISUID 04000 文件的(set user-id on execution)位
S_ISGID 02000 文件的(set group-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其他用户具可读取权限
S_IWOTH 00002 其他用户具可写入权限
S_IXOTH 00001 其他用户具可执行权限
上述的文件类型在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode) 判断是否为符号连接
S_ISREG (st_mode) 是否为一般文件
S_ISDIR (st_mode) 是否为目录
S_ISCHR (st_mode) 是否为字符装置文件
S_ISBLK (s3e) 是否为先进先出
S_ISSOCK (st_mode) 是否为socket
若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、此目录所有者或root来删除或改名。
struct statfs {
long f_type; //文件系统类型
long f_bsize; //块大小
long f_blocks; //块多少
long f_bfree; //空闲的块
long f_bavail; //可用块
long f_files; //总文件节点
long f_ffree; //空闲文件节点
fsid_t f_fsid; //文件系统id
long f_namelen; //文件名的最大长度
long f_spare[6]; //spare for later
};