gonotify

package module
v3.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2024 License: MIT Imports: 11 Imported by: 0

README

Gonotify

Simple Golang inotify wrapper.

GoDoc

Provides following primitives:

  • Low level

    • Inotify - wrapper around inotify(7)
    • InotifyEvent - generated file/folder event. Contains Name (full path), Wd - watch descriptor and Mask that describes the event.
  • Higher level

    • FileWatcher - higher level utility, helps to watch the list of files for changes, creation or removal
    • DirWatcher - higher level utility, recursively watches given root folder for added, removed or changed files.
    • FileEvent - embeds InotifyEvent and keeps additional field Eof to notify user that there will be no more events.

Use FileWatcher and DirWatcher as an example and build your own utility classes.

Usage

package main

import (
  "fmt"
  "github.com/illarion/gonotify/v3"
  "time"
  "context"
)

func main() {

  ctx, cancel := context.WithCancel(context.Background())

  watcher, err := gonotify.NewDirWatcher(ctx, gonotify.IN_CREATE|gonotify.IN_CLOSE, "/tmp")
  if err != nil {
    panic(err)
  }

  main:
  for {
    select {
    case event := <-watcher.C:
      fmt.Printf("Event: %s\n", event)

      if event.Is(gonotify.IN_CREATE) {
        fmt.Printf("File created: %s\n", event.Name)
      }

      if event.IsAny(gonotify.IN_CLOSE, gonotify.IN_CLOSE_WRITE) {
        fmt.Printf("File closed: %s\n", event.Name)
      }

    case <-time.After(5 * time.Second):
      fmt.Println("Good bye!")
      cancel()
      break main
    }
  }
  
  // Wait for watcher to finish all internal goroutines
  <-watcher.Done()
  fmt.Println("Watcher is done")
  
}

License

MIT. See LICENSE file for more details.

Documentation

Index

Constants

View Source
const (
	IN_ACCESS        = uint32(syscall.IN_ACCESS)        // File was accessed
	IN_ATTRIB        = uint32(syscall.IN_ATTRIB)        // Metadata changed
	IN_CLOSE_WRITE   = uint32(syscall.IN_CLOSE_WRITE)   // File opened for writing was closed.
	IN_CLOSE_NOWRITE = uint32(syscall.IN_CLOSE_NOWRITE) // File or directory not opened for writing was closed.
	IN_CREATE        = uint32(syscall.IN_CREATE)        // File/directory created in watched directory
	IN_DELETE        = uint32(syscall.IN_DELETE)        // File/directory deleted from watched directory.
	IN_DELETE_SELF   = uint32(syscall.IN_DELETE_SELF)   // Watched file/directory was itself deleted.
	IN_MODIFY        = uint32(syscall.IN_MODIFY)        // File was modified
	IN_MOVE_SELF     = uint32(syscall.IN_MOVE_SELF)     // Watched file/directory was itself moved.
	IN_MOVED_FROM    = uint32(syscall.IN_MOVED_FROM)    // Generated for the directory containing the old filename when a file is renamed.
	IN_MOVED_TO      = uint32(syscall.IN_MOVED_TO)      // Generated for the directory containing the new filename when a file is renamed.
	IN_OPEN          = uint32(syscall.IN_OPEN)          // File or directory was opened.

	IN_ALL_EVENTS = uint32(syscall.IN_ALL_EVENTS) // bit mask of all of the above events.
	IN_MOVE       = uint32(syscall.IN_MOVE)       // Equates to IN_MOVED_FROM | IN_MOVED_TO.
	IN_CLOSE      = uint32(syscall.IN_CLOSE)      // Equates to IN_CLOSE_WRITE | IN_CLOSE_NOWRITE.

	IN_DONT_FOLLOW = uint32(syscall.IN_DONT_FOLLOW) // Don't dereference pathname if it is a symbolic link.
	IN_EXCL_UNLINK = uint32(syscall.IN_EXCL_UNLINK) // Don't generate events for children if they have been unlinked from the directory.
	IN_MASK_ADD    = uint32(syscall.IN_MASK_ADD)    // Add (OR) the events in mask to the watch mask
	IN_ONESHOT     = uint32(syscall.IN_ONESHOT)     // Monitor the filesystem object corresponding to pathname for one event, then remove from watch list.
	IN_ONLYDIR     = uint32(syscall.IN_ONLYDIR)     // Watch pathname only if it is a directory.

	IN_IGNORED    = uint32(syscall.IN_IGNORED)    // Watch was removed explicitly or automatically
	IN_ISDIR      = uint32(syscall.IN_ISDIR)      // Subject of this event is a directory.
	IN_Q_OVERFLOW = uint32(syscall.IN_Q_OVERFLOW) // Event queue overflowed (wd is -1 for this event).

	IN_UNMOUNT = uint32(syscall.IN_UNMOUNT) // Filesystem containing watched object was unmounted.
)

Variables

This section is empty.

Functions

func InMaskToString

func InMaskToString(in_mask uint32) string

Types

type DirWatcher

type DirWatcher struct {
	C chan FileEvent
	// contains filtered or unexported fields
}

DirWatcher recursively watches the given root folder, waiting for file events. Events can be masked by providing fileMask. DirWatcher does not generate events for folders or subfolders.

func NewDirWatcher

func NewDirWatcher(ctx context.Context, fileMask uint32, root string) (*DirWatcher, error)

NewDirWatcher creates DirWatcher recursively waiting for events in the given root folder and emitting FileEvents in channel C, that correspond to fileMask. Folder events are ignored (having IN_ISDIR set to 1)

func (*DirWatcher) Done

func (dw *DirWatcher) Done() <-chan struct{}

Done returns a channel that is closed when DirWatcher is done

type FileEvent

type FileEvent struct {
	InotifyEvent
	Eof bool
}

FileEvent is the wrapper around InotifyEvent with additional Eof marker. Reading from FileEvents from DirWatcher.C or FileWatcher.C may end with Eof when underlying inotify is closed

func (FileEvent) GoString

func (f FileEvent) GoString() string

func (FileEvent) String

func (f FileEvent) String() string

type FileWatcher

type FileWatcher struct {
	C chan FileEvent
	// contains filtered or unexported fields
}

FileWatcher waits for events generated by filesystem for a specific list of file paths, including IN_CREATE for not yet existing files and IN_DELETE for removed.

func NewFileWatcher

func NewFileWatcher(ctx context.Context, mask uint32, files ...string) (*FileWatcher, error)

NewFileWatcher creates FileWatcher with provided inotify mask and list of files to wait events for.

func (*FileWatcher) Done

func (f *FileWatcher) Done() <-chan struct{}

Done returns a channel that is closed when the FileWatcher is done.

type Inotify

type Inotify struct {
	// contains filtered or unexported fields
}

Inotify is the low level wrapper around inotify_init(), inotify_add_watch() and inotify_rm_watch()

func NewInotify

func NewInotify(ctx context.Context) (*Inotify, error)

NewInotify creates new inotify instance

func (*Inotify) AddWatch

func (i *Inotify) AddWatch(pathName string, mask uint32) (int, error)

AddWatch adds given path to list of watched files / folders

func (*Inotify) Done

func (i *Inotify) Done() <-chan struct{}

Done returns a channel that is closed when Inotify is done

func (*Inotify) Read

func (i *Inotify) Read() ([]InotifyEvent, error)

Read reads portion of InotifyEvents and may fail with an error. If no events are available, it will wait forever, until context is cancelled.

func (*Inotify) ReadDeadline

func (i *Inotify) ReadDeadline(deadline time.Time) ([]InotifyEvent, error)

ReadDeadline waits for InotifyEvents until deadline is reached, or context is cancelled. If deadline is reached, it will return all events read until that point.

func (*Inotify) RmWatch

func (i *Inotify) RmWatch(pathName string) error

RmWatch removes watch by pathName

func (*Inotify) RmWd

func (i *Inotify) RmWd(wd int) error

RmWd removes watch by watch descriptor

type InotifyEvent

type InotifyEvent struct {
	// Watch descriptor
	Wd int
	// File or directory name
	Name string
	// Contains bits that describe the event that occurred
	Mask uint32
	// Usually 0, but if events (like IN_MOVED_FROM and IN_MOVED_TO) are linked then they will have equal cookie
	Cookie uint32
}

InotifyEvent is the go representation of inotify_event found in sys/inotify.h

func (InotifyEvent) GoString

func (i InotifyEvent) GoString() string

func (InotifyEvent) Is

func (i InotifyEvent) Is(in_mask uint32) bool

func (InotifyEvent) IsAll

func (i InotifyEvent) IsAll(in_mask ...uint32) bool

IsAll returns true if all the in_masks is set in the event

func (InotifyEvent) IsAny

func (i InotifyEvent) IsAny(in_mask ...uint32) bool

IsAny returns true if any of the in_mask is set in the event

func (InotifyEvent) String

func (i InotifyEvent) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL