⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imonlinux.c++

📁 好东东。linux下面的文件节点、文件状态的变化监听代码
💻 C++
字号:
//  Copyright (C) 1999 Silicon Graphics, Inc.  All Rights Reserved.//  //  This program is free software; you can redistribute it and/or modify it//  under the terms of version 2 of the GNU General Public License as//  published by the Free Software Foundation.////  This program is distributed in the hope that it would be useful, but//  WITHOUT ANY WARRANTY; without even the implied warranty of//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Further, any//  license provided herein, whether implied or otherwise, is limited to//  this program in accordance with the express provisions of the GNU//  General Public License.  Patent licenses, if any, provided herein do not//  apply to combinations of this program with other product or programs, or//  any other product whatsoever.  This program is distributed without any//  warranty that the program is delivered free of the rightful claim of any//  third person by way of infringement or the like.  See the GNU General//  Public License for more details.////  You should have received a copy of the GNU General Public License along//  with this program; if not, write the Free Software Foundation, Inc., 59//  Temple Place - Suite 330, Boston MA 02111-1307, USA.#include "IMon.h"#include "Log.h"#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/ioctl.h>#include <sys/sysmacros.h>#include <linux/imon.h>#define DEV_IMON "/dev/imon"const intmask_t INTEREST_MASK = (IMON_CONTENT | IMON_ATTRIBUTE | IMON_DELETE |				 IMON_EXEC | IMON_EXIT);enum OpenStatus { OPEN_OK, OPEN_RETRY, OPEN_FAILED };static OpenStatus open_device(int& imonfd){    int major;    bool foundMajor = false;    char line[100], name[100];    FILE* dev = fopen("/proc/devices", "r");    if (!dev) {	Log::critical("can't open /proc/devices: %m");	return OPEN_FAILED;    }    while (fgets(line, sizeof line, dev) != NULL) {	if (sscanf(line, "%d %s\n", &major, name) == 2	    && strcmp(name, "imon") == 0) {	    foundMajor = true;	    break;	}    }    fclose(dev);    if (!foundMajor) {	return OPEN_RETRY;    }    (void)unlink(DEV_IMON);    if (mknod(DEV_IMON, S_IFCHR | 0600, makedev(major, 0)) == -1) {	Log::critical("can't create %s: %m", DEV_IMON);	return OPEN_FAILED;    }    int imon = open(DEV_IMON, O_RDONLY | O_NONBLOCK);    (void)unlink(DEV_IMON);    if (imon == -1) {	Log::critical("can't open %s: %m", DEV_IMON);	return OPEN_FAILED;    }    imonfd = imon;    return OPEN_OK;}static void insmod(){    pid_t pid = fork();    if (pid == 0) {	execl("/sbin/insmod", "insmod", "imon", NULL);	exit(1);    }    if (pid > 0) {	waitpid(pid, NULL, 0);    }}int IMon::imon_open(){    int imon;    OpenStatus status = open_device(imon);    if (status == OPEN_RETRY) {	insmod();	status = open_device(imon);    }    if (status == OPEN_RETRY) {	Log::critical("can't open %s: imon major number not found in /proc/devices", DEV_IMON);	return -1;    }    if (status != OPEN_OK) {	Log::critical("can't open %s: %m", DEV_IMON);	return -1;    }    return imon;}IMon::Status IMon::imon_express(const char *name, struct stat *status){    famstat_t famstat;    struct interest interest = { name, &famstat, INTEREST_MASK };    int rc = ioctl(imonfd, IMONIOC_EXPRESS, &interest);    if (rc < 0)    {        if (name[0] == '/') {            Log::info("IMONIOC_EXPRESS on \"%s\" failed (euid: %i): %m",                      name, geteuid());        } else {            char * cwd = getcwd(0, 256);            Log::info("IMONIOC_EXPRESS on \"%s\" with cwd \"%s\" failed (euid: %i): %m",                      name,cwd,geteuid());            free(cwd);        }	return BAD;    }    //    // Check for a race condition; if someone removed or changed the    // file at the same time that we are expressing interest in it,    // revoke the interest so we don't get notifications about changes    // to a recycled inode that we don't otherwise care about.    //    struct stat st;    if (status == NULL) {	status = &st;    }    if (stat(name, status) == -1) {	Log::perror("stat on \"%s\" failed", name);	revoke(name, famstat.st_dev, famstat.st_ino);	return BAD;    }    if (status->st_dev != famstat.st_dev	|| status->st_ino != famstat.st_ino) {	Log::error("File \"%s\" changed between express and stat",		   name);	revoke(name, famstat.st_dev, famstat.st_ino);	return BAD;    }	    Log::debug("told imon to monitor \"%s\" = dev %d/%d, ino %d", name,	       major(status->st_dev), minor(status->st_dev),	       status->st_ino);    return OK;}IMon::Status IMon::imon_revoke(const char *name, dev_t dev, ino_t ino){    revoke_t rv = { dev, ino, INTEREST_MASK };    int rc = ioctl(imonfd, IMONIOC_REVOKE, &rv);    if (rc < 0) {	Log::perror("IMONIOC_REVOKE on \"%s\" failed", name);	return BAD;    }    Log::debug("told imon to forget \"%s\"", name);    return OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -