守护进程检测是否运行/文件是否修改/stat函数

本文博客链接: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
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_kerneler

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值