欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Golang中文件系統(tǒng)事件監(jiān)聽

 更新時間:2024年01月18日 14:06:47   作者:科目三什么時候過  
文件系統(tǒng)事件是指文件系統(tǒng)相關(guān)的各種操作和狀態(tài)變化,當(dāng)一個應(yīng)用層的進(jìn)程操作文件或目錄時,會觸發(fā)system call,內(nèi)核的notification子系統(tǒng)可以守在那里,把該進(jìn)程對文件的操作上報給應(yīng)用層的監(jiān)聽進(jìn)程,這篇文章主要介紹了Golang之文件系統(tǒng)事件監(jiān)聽,需要的朋友可以參考下

基本介紹

文件系統(tǒng)事件是指文件系統(tǒng)相關(guān)的各種操作和狀態(tài)變化,當(dāng)一個應(yīng)用層的進(jìn)程操作文件或目錄時,會觸發(fā)system call,內(nèi)核的notification子系統(tǒng)可以守在那里,把該進(jìn)程對文件的操作上報給應(yīng)用層的監(jiān)聽進(jìn)程。這些事件可以包括文件和目錄的創(chuàng)建、修改、刪除和文件權(quán)限的更改等。

Linux中常用的有兩種機制能夠監(jiān)聽這些文件事件,分別為inotify和fanotify。

inotify和fanotify最大的區(qū)別就是fanotify能夠監(jiān)聽到是哪個進(jìn)程對文件或目錄進(jìn)行操作,并且能夠阻止該操作。

fanotify

fanotify:Linux 2.6.37版本引入,能夠通知用戶哪個進(jìn)程觸發(fā)了哪些事件,并且能夠?qū)ζ溥M(jìn)行干預(yù)。

Golang中fanotify有兩個函數(shù):

func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error)
func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error)

函數(shù)介紹

  • func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error)

    該函數(shù)初始化了一個新的fanotify事件組,并返回與該組關(guān)聯(lián)的事件隊列的文件描述符,文件描述符用來調(diào)用FanotifyMark函數(shù),以指定應(yīng)該為其創(chuàng)建fanotify事件的文件、目錄、掛載或文件系統(tǒng),通過讀取文件描述符來接收這些事件。

    flags參數(shù)包含一個多位字段,用于定義監(jiān)聽?wèi)?yīng)用程序的通知類型,可選的值有:

    FAN_CLASS_CONTENT            = 0x4   適用于需要訪問已經(jīng)包含最終內(nèi)容的文件的事件監(jiān)聽器
    FAN_CLASS_NOTIF              = 0x0   默認(rèn)值,不需要指定,只用于監(jiān)聽,不訪問文件內(nèi)容
    FAN_CLASS_PRE_CONTENT        = 0x8   適用于需要在文件包含最終數(shù)據(jù)之前訪問文件的事件監(jiān)聽器*/
    FAN_CLOEXEC                  = 0x1   如果在程序運行時打開了一個文件描述符,并且在調(diào)用時沒有關(guān)閉,那么新程序中仍然能夠使用該文件描述符,設(shè)置這個字段,可以確保調(diào)用時關(guān)閉文件描述符
    FAN_NONBLOCK                 = 0x2   為文件描述符啟用非阻塞標(biāo)志,讀取文件描述符時不會被阻塞
    FAN_UNLIMITED_MARKS          = 0x20   取消對每個用戶的通知標(biāo)記數(shù)量的限制
    FAN_UNLIMITED_QUEUE          = 0x10   刪除對事件隊列中事件數(shù)量的限制
    FAN_REPORT_DFID_NAME         = 0xc00  這是(FAN_REPORT_DIR_FID|FAN_REPORT_NAME)的同義詞
    FAN_REPORT_DFID_NAME_TARGET  = 0x1e00 這是(FAN_REPORT_DFID_NAME|FAN_REPORT_FID|FAN_REPORT_TARGET_FID)的同義詞
    FAN_REPORT_DIR_FID           = 0x400  Linux 5.9后的功能,使用此標(biāo)志初始化的通知組的事件將包含與事件相關(guān)的目錄對象的附加信息
    FAN_REPORT_FID               = 0x200  Linux 5.1后的功能,使用此標(biāo)志初始化的通知組的事件將包含相關(guān)的底層文件系統(tǒng)對象的附加信息
    FAN_REPORT_NAME              = 0x800  Linux 5.9后的功能,使用此標(biāo)志初始化的通知組的事件將包含與事件相關(guān)的目錄條目名稱的附加信息
    FAN_REPORT_PIDFD             = 0x80   Linux 5.15后的功能,使用此標(biāo)志初始化的事件將包含一個附加的信息記錄
    FAN_REPORT_TARGET_FID        = 0x1000 Linux 5.17后的功能,使用此標(biāo)志初始化的通知組的事件將包含與目錄條目修改事件相關(guān)的子節(jié)點的附加信息
    FAN_REPORT_TID               = 0x100  Linux 4.20后的功能,報告線程ID(TID)而不是進(jìn)程ID(PID)
    FAN_ENABLE_AUDIT             = 0x40   Linux 4.15后的功能,啟用生成權(quán)限事件執(zhí)行的訪問中介的審計日志記錄

    event_f_flags參數(shù)定義了文件描述符狀態(tài),可選的值有:

    O_RDONLY               = 0x0     只讀
    O_RDWR                 = 0x2     讀寫
    O_WRONLY               = 0x1     只寫
    O_LARGEFILE            = 0x0     啟用對超過2gb的文件的支持。在32位系統(tǒng)上,
    O_CLOEXEC              = 0x80000 Linux 3.18后的功能為文件描述符啟用close-on-exec標(biāo)志
    這些也是可以的O_APPEND,O_DSYNC,O_NOATIME,O_NONBLOCK,O_SYNC
  • func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error)

    該函數(shù)在文件系統(tǒng)對象上添加、刪除或修改fanotify標(biāo)記,調(diào)用者必須對要標(biāo)記的文件系統(tǒng)對象具有讀權(quán)限。

    fd參數(shù)是由FanotifyInit函數(shù)返回的文件描述符。

    flags參數(shù)是描述要執(zhí)行的操作,可選的值有:

    FAN_MARK_ADD                                = 0x1
    FAN_MARK_DONT_FOLLOW                        = 0x4
    FAN_MARK_EVICTABLE                          = 0x200 Linux 5.19后的功能
    FAN_MARK_FILESYSTEM                         = 0x100 Linux 4.20后的功能
    FAN_MARK_FLUSH                              = 0x80
    FAN_MARK_IGNORE                             = 0x400 Linux 6.0后的功能
    FAN_MARK_IGNORED_MASK                       = 0x20
    FAN_MARK_IGNORED_SURV_MODIFY                = 0x40
    FAN_MARK_IGNORE_SURV                        = 0x440
    FAN_MARK_INODE                              = 0x0
    FAN_MARK_MOUNT                              = 0x10
    FAN_MARK_ONLYDIR                            = 0x8
    FAN_MARK_REMOVE                             = 0x2

    mask參數(shù)定義了應(yīng)該監(jiān)聽哪些事件或者忽略哪些事件,可選的值有:

    FAN_ACCESS                                  = 0x1
    FAN_ACCESS_PERM                             = 0x20000
    FAN_MODIFY                                  = 0x2
    FAN_CLOSE                                   = 0x18
    FAN_CLOSE_NOWRITE                           = 0x10
    FAN_CLOSE_WRITE                             = 0x8
    FAN_OPEN                                    = 0x20
    FAN_OPEN_EXEC                               = 0x1000     Linux 5.0后的功能
    FAN_OPEN_EXEC_PERM                          = 0x40000    Linux 5.0后的功能
    FAN_OPEN_PERM                               = 0x10000
    FAN_ATTRIB                                  = 0x4        Linux 5.1后的功能
    FAN_CREATE                                  = 0x100      Linux 5.1后的功能
    FAN_DELETE                                  = 0x200      Linux 5.1后的功能
    FAN_DELETE_SELF                             = 0x400      Linux 5.1后的功能
    FAN_FS_ERROR                                = 0x8000     Linux 5.16后的功能
    FAN_MOVE                                    = 0xc0
    FAN_MOVED_FROM                              = 0x40       Linux 5.1后的功能
    FAN_MOVED_TO                                = 0x80       Linux 5.1后的功能
    FAN_MOVE_SELF                               = 0x800      Linux 5.1后的功能
    FAN_RENAME                                  = 0x10000000 Linux 5.17后的功能
    FAN_ONDIR                                   = 0x40000000
    FAN_EVENT_ON_CHILD                          = 0x8000000

    要標(biāo)記的文件系統(tǒng)對象由文件描述符dirFd和pathname中指定的路徑名決定

    • 如果pathname為空,則由dirFd確定
    • 如果pathname為空,并且dirFd的值為AT_FDCWD,監(jiān)聽當(dāng)前工作目錄
    • 如果pathname是絕對路徑,dirFd被忽略
    • 如果pathname是相對路徑,并且dirFd不是AT_FDCWD,監(jiān)聽pathname相對于dirFd目錄的路徑
    • 如果pathname是相對路徑,并且dirFd為AT_FDCWD,監(jiān)聽pathname相對于當(dāng)前目錄的路徑

示例

package main
import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"unsafe"
	"golang.org/x/sys/unix"
)
func handle_perm(initFd int, fanfd int32) error {
	fd := unix.FanotifyResponse{
		Fd:       fanfd,
		Response: uint32(unix.FAN_DENY),
	}
	buf := new(bytes.Buffer)
	err := binary.Write(buf, binary.LittleEndian, fd)
	if err != nil {
		log.Println(err)
	}
	ret, err := unix.Write(initFd, buf.Bytes())
	if err != nil {
		log.Println("handle_perm:err", err)
	}
	if ret < 0 {
		return err
	}
	return nil
}
func main() {
	path := "/root/testapp2/"
	name := filepath.Clean(path)
	initFd, err := unix.FanotifyInit(unix.FAN_CLOEXEC|unix.FAN_NONBLOCK|unix.FAN_CLASS_PRE_CONTENT, unix.O_RDONLY)
	if err != nil {
		log.Panicln("FanotifyInit err : ", err)
	}
	inotifyFile := os.NewFile(uintptr(initFd), "")
	if initFd == -1 {
		log.Println("fanFd err", err)
	}
	defer unix.Close(initFd)
	mask := uint64(unix.FAN_EVENT_ON_CHILD | unix.FAN_OPEN_PERM)
	err = unix.FanotifyMark(initFd, unix.FAN_MARK_ADD, mask, unix.AT_FDCWD, name)
	if err != nil {
		log.Panicln("FanotifyMark err : ", err)
	}
	fmt.Println("start:")
	fmt.Println("監(jiān)控目錄:", name)
	var (
		buf [unix.FAN_EVENT_METADATA_LEN * 4096]byte
	)
	for {
		n, err := inotifyFile.Read(buf[:])
		if err != nil {
			continue
		}
		if n < unix.FAN_EVENT_METADATA_LEN {
			if n == 0 {
				err = io.EOF
			} else if n < 0 {
				err = errors.New("notify: short ")
			} else {
				err = errors.New("notify: short read in readEvents()")
			}
			continue
		}
		var offset int
		for offset <= int(n-unix.FAN_EVENT_METADATA_LEN) {
			var (
				raw       = (*unix.FanotifyEventMetadata)(unsafe.Pointer(&buf[offset]))
				pid       = int32(raw.Pid)
				event_len = uint32(raw.Event_len)
				fd        = int32(raw.Fd)
			)
			fdPath := fmt.Sprintf("/proc/self/fd/%d", fd)
			f, err := os.Readlink(fdPath)
			if err != nil {
				log.Println(err)
			} else {
				fmt.Println("fdpath:", f)
			}
			proName := fmt.Sprintf("/proc/%d/comm", pid)
			pN, err := os.ReadFile(proName)
			if err != nil {
				log.Println(err)
				continue
			}
			if err := handle_perm(initFd, fd); err != nil {
				continue
			}
			fmt.Printf("阻止程序: %v", string(pN))
			offset += int(unix.FAN_EVENT_METADATA_LEN + event_len)
		}
	}
}

示例代碼能夠拒絕程序打開該目錄下文件

升級成為會員

« 上一篇: tool

posted @ 2024-01-18 13:49  科目三什么時候過  閱讀(17)  評論(0)  編輯  收藏  舉報

會員力量,點亮園子希望

相關(guān)文章

  • golang的空標(biāo)識符理解

    golang的空標(biāo)識符理解

    今天小編就為大家分享一篇關(guān)于golang的空標(biāo)識符理解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • Golang中List的實現(xiàn)方法示例詳解

    Golang中List的實現(xiàn)方法示例詳解

    最近決定復(fù)習(xí)下Go,所以下面這篇文章主要給大家介紹了關(guān)于Golang中List的實現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • Go語言bufio庫的全面指南與實戰(zhàn)技巧詳解

    Go語言bufio庫的全面指南與實戰(zhàn)技巧詳解

    這篇文章主要為大家全面介紹一下?bufio?庫的核心組件與功能,包括?Reader、Writer?和?Scanner?等并深入探討它們在實際編程中的運用場景和技巧,感興趣的可以了解下
    2024-01-01
  • Go?語言中運行?C程序?代碼?

    Go?語言中運行?C程序?代碼?

    這篇文章主要介紹了Go?語言中運行?C程序代碼,通過直接在?Go?代碼中寫入?C?程序運行,下面操作過程需要的小伙伴可以參考一下
    2022-03-03
  • Golang信號量設(shè)計實現(xiàn)示例詳解

    Golang信號量設(shè)計實現(xiàn)示例詳解

    這篇文章主要為大家介紹了Golang信號量設(shè)計實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • golang?基于?mysql?簡單實現(xiàn)分布式讀寫鎖

    golang?基于?mysql?簡單實現(xiàn)分布式讀寫鎖

    這篇文章主要介紹了golang?基于mysql簡單實現(xiàn)分布式讀寫鎖,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Golang匯編之控制流深入分析講解

    Golang匯編之控制流深入分析講解

    這篇文章主要介紹了Golang匯編之控制流,程序執(zhí)行的流程主要有順序、分支和循環(huán)幾種執(zhí)行流程,本節(jié)主要討論如何將Go語言的控制流比較直觀地轉(zhuǎn)譯為匯編程序,或者說如何以匯編思維來編寫Go語言代碼,感興趣的同學(xué)可以參考下文
    2023-05-05
  • goland 設(shè)置注釋模板的過程圖文詳解

    goland 設(shè)置注釋模板的過程圖文詳解

    這篇文章主要介紹了goland 設(shè)置注釋模板的過程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2020-12-12
  • 詳解MongoDB?Go?Driver如何記錄日志

    詳解MongoDB?Go?Driver如何記錄日志

    這篇文章主要為大家介紹了MongoDB?Go?Driver如何記錄日志詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Golang 正則匹配效率詳解

    Golang 正則匹配效率詳解

    這篇文章主要介紹了Golang 正則匹配效率詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評論