func watch(p string, event chan<- EventItem) { watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } dir := path.Dir(p) err = watcher.Watch(dir) if err != nil { log.Fatal(err) } register(p) go func() { defer watcher.Close() for { select { case ev := <-watcher.Event: if ev.Mask&(inotify.IN_CLOSE_WRITE) > 0 && p == ev.Name { event <- diff(p) } case err := <-watcher.Error: log.Println("error:", err) } } }() }
func Watch(restart string, done <-chan struct{}, change func()) error { lastStat, err := os.Stat(restart) if err != nil { return err } watcher, err := inotify.NewWatcher() if err != nil { return err } err = watcher.AddWatch(restart, inotify.IN_ATTRIB|inotify.IN_MODIFY) if err != nil { return err } defer watcher.Close() for { select { case <-watcher.Event: cur, err := os.Stat(restart) if err != nil { return err } if cur.ModTime().After(lastStat.ModTime()) { change() } case <-done: return nil } } }
func init() { // Generate the reverse of our enum so we can work backwards and reload // a file with the name instead of the enum. // // The issue arises because we've decided to use an array instead of a map // to describe our in-memory templates. While this is more efficient, it // causes issues with our hot reloading because the name of the file // given to us from inotify is the string representation of the file's // name, and we can't match that up with the enum on the fly (or generate // code that does that using //go: generate). So, we run an init func that // generates a map of the names to the enum so we can work backwards to // reload the file. for i := 0; i < len(_TmplName_index)-1; i++ { key := _TmplName_name[_TmplName_index[i]:_TmplName_index[i+1]] TmplMap[key] = TmplName(i) } // Set up our watcher for hot reloads of modified files. watcher, err := inotify.NewWatcher() if err != nil { glog.Fatalln(err) } err = watcher.Watch(templatePath) if err != nil { glog.Fatalln(err) } Tmpls.Watcher = watcher Tmpls.Watch() cleanup.Register("reload", watcher.Close) // Close watcher. }
func ExampleNewWatcher() { watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() done := make(chan bool) go func() { for { select { case ev := <-watcher.Event: //log.Println("event:", ev.Name) log.Println("event:", ev.Name, ev.Mask, ev.Cookie) log.Println("event:", ev) case err := <-watcher.Error: log.Println("error:", err) } } }() //err = watcher.Add("./testDir") //watcher.Watch("/testDir") watcher.AddWatch("./testDir", inotify.IN_CLOSE_WRITE) if err != nil { log.Fatal(err) } <-done }
//watch filesystem, execute command on changes func main() { if len(os.Args) == 3 { watchpath = os.Args[1] command = os.Args[2] } else { fmt.Println("Usage: reloader <path> <command> &") return } watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } err = watcher.Watch(watchpath) if err != nil { log.Fatal(err) } log.Println("watching:", watchpath) for { select { case ev := <-watcher.Event: if ev.Mask == syscall.IN_CLOSE_WRITE || ev.Mask == syscall.IN_DELETE { if hasExt(path.Ext(ev.Name)) { log.Println("Reloader:", command) doCmd(command) } } case err := <-watcher.Error: log.Println("error:", err) } } }
//NewWatcher creates a new RecursiveWatcher and returns any errors func NewWatcher() (*RecursiveWatcher, error) { watcher, err := inotify.NewWatcher() if err != nil { return nil, err } rw := &RecursiveWatcher{watcher: watcher, Event: make(chan *inotify.Event, 100), Error: make(chan error, 10), done: make(chan bool)} go func() { for { select { case <-rw.done: return case event := <-rw.watcher.Event: //We need to intercept create events and add watches for them. Removal is handled by inotify on deletion if event.Mask&inotify.IN_CREATE == inotify.IN_CREATE || event.Mask&inotify.IN_MOVED_FROM == inotify.IN_MOVED_FROM || event.Mask&inotify.IN_MOVED_TO == inotify.IN_MOVED_TO { rw.Watch(event.Name) } rw.Event <- event case err := <-rw.watcher.Error: rw.Error <- err } } }() return rw, err }
func (u *NetNSTopoUpdater) start() { runtime.LockOSThread() defer runtime.UnlockOSThread() watcher, err := inotify.NewWatcher() if err != nil { logging.GetLogger().Error("Unable to create a new Watcher: %s", err.Error()) return } err = watcher.Watch(runBaseDir) if err != nil { logging.GetLogger().Error("Unable to Watch %s: %s", runBaseDir, err.Error()) return } u.initialize() for { select { case ev := <-watcher.Event: if ev.Mask&inotify.IN_CREATE > 0 { u.onNetNsCreated(ev.Name) } if ev.Mask&inotify.IN_DELETE > 0 { u.onNetNsDeleted(ev.Name) } case err := <-watcher.Error: logging.GetLogger().Error("Error while watching network namespace: %s", err.Error()) } } }
func main() { var stop bool sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) watcher, err := inotify.NewWatcher() check(err) err = watcher.Watch("/tmp") check(err) for { select { case ev := <-watcher.Event: log.Println("event:", ev) case err := <-watcher.Error: log.Println("error:", err) case <-time.After(time.Second * 1): log.Println("-- timeout --") case <-sigs: log.Println("got signal") stop = true } if true == stop { break } } err = watcher.Close() check(err) log.Println("bye!") }
// NewFeatureMonitor watches the specified state directory, or the default // state directory if an empty string is given. The directory must exist. The // logger is used for I/O errors, unless nil. func NewFeatureMonitor(stateDir string, logger Logger) (m *FeatureMonitor, err error) { if stateDir == "" { stateDir = DefaultStateDir } featureDir := filepath.Join(stateDir, "features") if err = os.Mkdir(featureDir, 0755); err != nil { if info, statErr := os.Stat(featureDir); statErr != nil || !info.IsDir() { return } err = nil } if featureDir, err = filepath.Abs(featureDir); err != nil { return } if featureDir, err = filepath.EvalSymlinks(featureDir); err != nil { return } watcher, err := inotify.NewWatcher() if err != nil { return } if err = watcher.AddWatch(featureDir, inotify.IN_ONLYDIR|inotify.IN_CREATE|inotify.IN_DELETE|inotify.IN_DELETE_SELF); err != nil { watcher.Close() return } c := make(chan *Feature) boot := make(chan struct{}) m = &FeatureMonitor{ C: c, Boot: boot, logger: logger, closed: make(chan struct{}, 1), watcher: watcher, } if infos, err := ioutil.ReadDir(featureDir); err == nil { for _, info := range infos { m.addFeature(filepath.Join(featureDir, info.Name())) } } else { m.log(err) } m.queued = append(m.queued, nil) // indicates end of boot go m.watchLoop(c, boot, featureDir) return }
// eventloop prepares the inotify events and waits for them func eventloop(mongo MongoInserter) { var currentlog LogFileReader // open current file if logtype == ALPS { currentlog = newAlpsLogfile(todayname(), mongo) } else { currentlog = newTorqueLogfile(todayname(), mongo) } watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } err = watcher.Watch(config.WatchDirectory) if err != nil { log.Fatal(err) } // endless event loop, can be ended by QUIT channel for { select { case ev := <-watcher.Event: if (ev.Mask & inotify.IN_CREATE) > 0 { // if a file is created, check if it is same file or not, and if it could be // todays file //if ev.Name != currentlog.name && ev.Name == "testdata/apsched-c2-0c0s0n1-20160820" { if ev.Name != currentlog.getName() && ev.Name == todayname() { currentlog.readToEnd() // read rest of file in case we missed something if logtype == ALPS { currentlog = newAlpsLogfile(ev.Name, mongo) } else { currentlog = newTorqueLogfile(ev.Name, mongo) } } } else if (ev.Mask & inotify.IN_MODIFY) > 0 { // if a file is updated, read file to end if it is current file if ev.Name == currentlog.getName() { currentlog.readToEnd() } } else { // log.Println("inotify event:", ev) } case err := <-watcher.Error: log.Println("inotify error:", err) case <-QUIT: // end for testing return } } }
func NewInotifyWatcher() (*InotifyWatcher, error) { w, err := inotify.NewWatcher() if err != nil { return nil, err } return &InotifyWatcher{ watcher: w, containersWatched: make(map[string]map[string]bool), }, nil }
func inotifySetup(dir string) *inotify.Watcher { watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } err = watcher.Watch(dir) if err != nil { log.Fatal(err) } return watcher }
func main() { configFile := flag.String("c", "config.toml", "Config file path") flag.Parse() findSocatBinary() services := parseConfig(*configFile) for _, s := range services { if !s.Enabled { log.Println(fmt.Sprintf("Service %s is disabled", s.Name)) } else { s.Start() } } var watch *inotify.Watcher var err error if watch, err = inotify.NewWatcher(); err != nil { log.Println(fmt.Sprintf("Could not create a watcher: %s. Changes will need a restart to become effective", err)) } else { setWatch(watch, filepath.Dir(*configFile)) } for { select { case ev := <-watch.Event: if filepath.Base(ev.Name) == *configFile { log.Println("Change on the config file detected. Reloading services...") unsetWatch(watch, filepath.Dir(*configFile)) for _, s := range services { s.Stop() } <-time.NewTimer(time.Millisecond * 500).C services = parseConfig(*configFile) for _, s := range services { if !s.Enabled { log.Println(fmt.Sprintf("Service %s is disabled", s.Name)) } else { s.Start() } } setWatch(watch, filepath.Dir(*configFile)) } } } }
// NewTail starts opens the given file and watches it for deletion/rotation func NewTail(filename string) (*Tail, error) { t := &Tail{ filename: filename, } var err error t.stop = make(chan bool) t.watcher, err = inotify.NewWatcher() if err != nil { return nil, fmt.Errorf("inotify init failed on %s: %v", t.filename, err) } go t.watchLoop() return t, nil }
func (b *builder) watchDir(ctx context.Context, dir string, f func(*inotify.Event)) error { infos, err := ioutil.ReadDir(dir) if err != nil { return err } ctx, cancel := context.WithCancel(ctx) defer cancel() errc := make(chan error) for _, info := range infos { if !info.IsDir() { continue } go func(info os.FileInfo) { fn := func(ev *inotify.Event) { ev.Name = filepath.Join(dir, ev.Name) f(ev) } select { case errc <- b.watchDir(ctx, filepath.Join(dir, info.Name()), fn): case <-ctx.Done(): } }(info) } w, err := inotify.NewWatcher() if err != nil { return err } defer w.Close() if err := w.AddWatch(dir, flags); err != nil { return err } for { select { case ev := <-w.Event: if ignore(ev.Name) { continue } f(ev) case err := <-w.Error: return err case err := <-errc: return err case <-ctx.Done(): return ctx.Err() } } }
func main() { hiddenPtr := flag.Bool("h", false, "include hidden") recursivePtr := flag.Bool("r", false, "recursive watcher") flag.Parse() args := flag.Args() if len(args) < 2 { fmt.Printf("Usage: %s PATH ACTION\n", os.Args[0]) return } watcher, err := inotify.NewWatcher() if err != nil { fmt.Fprintln(os.Stderr, err) return } err = addWatch(args[0], *recursivePtr, *hiddenPtr, watcher) if err != nil { fmt.Fprintln(os.Stderr, err) return } acceptRate := int64(250) // multiple events are sent at once now := timestamp() child := make(chan error, 1) var cmd *exec.Cmd for { select { case <-watcher.Event: curr := timestamp() if curr-now > acceptRate { now = curr cmd = waitNext(cmd, args[1]) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr go func() { child <- cmd.Run() }() } case err := <-watcher.Error: fmt.Fprintln(os.Stderr, err) return case err := <-child: if err != nil { fmt.Fprintln(os.Stderr, err) } } } }
// newTail creates a Tail object. func newTail(filename string) (*Tail, error) { t := &Tail{ filename: filename, } var err error t.stop = make(chan bool) t.watcher, err = inotify.NewWatcher() if err != nil { return nil, fmt.Errorf("inotify init failed on %s: %v", t.filename, err) } // Initialize readerErr as io.EOF, so that the reader can work properly // during initialization. t.readerErr = io.EOF return t, nil }
func NewWatcher() (*Watcher, error) { w, err := inotify.NewWatcher() if err != nil { return nil, err } res := &Watcher{ watcher: w, Event: make(chan *Event), Error: make(chan error), globs: make([]string, 0), } go res.watchEvent() return res, nil }
func initWatcher() (watcher *inotify.Watcher, err error) { LogWriter.Info("Initializing paxrat watcher") watcher, err = inotify.NewWatcher() if err != nil { return } for path, setting := range (*Conf).Settings { addWatchToClosestPath(watcher, path) err = setFlagsWatchMode(watcher, path, setting.Flags, setting.Nonroot) if err != nil { msg := fmt.Sprintf("setFlags error in initWatcher: %s", err) LogWriter.Err(msg) } } return }
/* This is where we do the actual location monitoring. This is started as a concurent go routine, and monitors loc_id indefinatly. - loc_id is the index to the config.Locations array to monitor*/ func monitor(loc_id int, cont chan bool) { log.Println("Spinning up monitor on location ID:", loc_id) stop := false location := config.Locations[loc_id] if st, err := checkPermissions(location); err != nil { log.Error(err) return } else { log.Infoln("Permissions check for", location, "passed:", st.Mode()) } watcher, err := inotify.NewWatcher() if err != nil { log.Error(err) return } err = watcher.Watch(location) if err != nil { log.Error(err) return } log.Infoln("Watcher up; monitoring:", location) for !stop { cached_id := uuid.New().String() //cache a new uuid select { case ev := <-watcher.Event: log.Debugln("monitored directory event:", ev) if ev.Mask == inotify.IN_CLOSE_WRITE { log.Info("Found; ", path.Base(ev.Name), " Moving to staging") os.Rename(ev.Name, config.Staging_loc+"/"+cached_id) var op Operation op.Code = ProcessFile op.Id = cached_id op.Name = path.Base(ev.Name) op.Location = path.Dir(ev.Name) op.Overwrite = false //TODO determine if this should be gleamed from the file name meta.stash <- op } case err := <-watcher.Error: log.Error("Monitor error;", err) continue case stop = <-cont: log.Infoln("Spinning down monitor on ", location) break } } }
func TestWatch(t *testing.T) { log.SetLevel(log.DebugLevel) watcher, err := inotify.NewWatcher() if err != nil { t.Fatal(err) } watch(watcher, []string{testdataDir}, inotify.IN_ALL_EVENTS, false, true) if err := watcher.RemoveWatch(testdataDir); err != nil { t.Fatal(err) } if err := watcher.RemoveWatch(filepath.Join(testdataDir, "rec")); err == nil { t.Fatal("Should not watch recursively!") } }
func DirectoryWatcher(dir string) { watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } err = watcher.AddWatch(dir, inotify.IN_CLOSE_WRITE) if err != nil { log.Fatal(err) } for { select { case ev := <-watcher.Event: directoryWatcherFile(dir, ev.Name) case err := <-watcher.Error: log.Printf("directory watch: %s", err) } } }
func watchDir(name string) { watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } err = watcher.AddWatch(name, inotify.IN_CREATE) if err != nil { log.Fatal(err) } for { select { case ev := <-watcher.Event: watchEventChannel <- ev case err := <-watcher.Error: log.Println("error:", err) } } }
func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } keybind.Initialize(X) currentuser, err := user.Current() if err != nil { log.Fatal(err) } configfile := currentuser.HomeDir + "/.config/hotkeys.conf.json" watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } err = watcher.AddWatch(configfile, inotify.IN_CLOSE_WRITE) if err != nil { log.Fatal(err) } go func() { for { select { case ev := <-watcher.Event: log.Println(ev) err := bindall(configfile, X) if err != nil { log.Println(err) continue } case err := <-watcher.Error: log.Println("error:", err) } } }() err = bindall(configfile, X) if err != nil { log.Panicln(err) } xevent.Main(X) }
func monitorDHCPLeases() { watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } err = watcher.AddWatch(dhcp_lease_file, inotify.IN_CLOSE_WRITE) if err != nil { log.Fatal(err) } for { select { case <-watcher.Event: log.Println("file modified, attempting to refresh DHCP") refreshConnectedClients() case err := <-watcher.Error: log.Println("error with DHCP file system watcher:", err) } } }
func Watch() { watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } paths, err := filepath.Glob(fmt.Sprintf("%s/*/*", *index)) if err != nil { log.Fatal(err) } for _, path := range paths { fmt.Printf("watching %s\n", path) err = watcher.AddWatch(path, inotify.IN_MODIFY|inotify.IN_DELETE_SELF) if err != nil { log.Fatal(err) } } go func() { for { select { case ev := <-watcher.Event: if ev == nil { continue } log.Println("file was updated, reloading:", ev) LoadTemplates() BuildCache() if ev.Mask&inotify.IN_DELETE_SELF != 0 { log.Println("file was deleted, restartig:", ev) watcher.Close() Watch() } case <-watcher.Error: break } } }() }
func (u *NetNSProbe) start() { runtime.LockOSThread() defer runtime.UnlockOSThread() watcher, err := inotify.NewWatcher() if err != nil { logging.GetLogger().Errorf("Unable to create a new Watcher: %s", err.Error()) return } // wait for the path creation for { _, err := os.Stat(runBaseDir) if err == nil { break } time.Sleep(5 * time.Second) } err = watcher.Watch(runBaseDir) if err != nil { logging.GetLogger().Errorf("Unable to Watch %s: %s", runBaseDir, err.Error()) return } u.initialize() for { select { case ev := <-watcher.Event: if ev.Mask&inotify.IN_CREATE > 0 { u.Register(ev.Name, nil) } if ev.Mask&inotify.IN_DELETE > 0 { u.Unregister(ev.Name) } case err := <-watcher.Error: logging.GetLogger().Errorf("Error while watching network namespace: %s", err.Error()) } } }
func main() { flags, err := config.LoadFlags("enqueued", &conf) if err != nil { log.Fatal(err) } flags.Parse(os.Args[1:]) os.Chdir(conf.Root) if conf.Templates != "" { enqueuedMailer, err = mailer.NewMailer(conf.Templates) if err != nil { log.Fatal(err) } } files, err := ioutil.ReadDir(conf.Root) if err != nil { log.Fatal(err) } watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } for _, file := range files { if err := Watch(watcher, file); err != nil { log.Fatal(err) } } for { select { case ev := <-watcher.Event: if ev.Mask^inotify.IN_CLOSE_WRITE != 0 || !strings.HasSuffix(ev.Name, ".changes") { continue } Process(ev.Name) } } }
func run(c *cli.Context) { var ( flag uint32 tpl *template.Template ctx = context.Background() ) if !c.Args().Present() { cli.ShowAppHelp(c) return } log.SetLevel(log.Level(c.Int("verbose"))) watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } // Format. if fmtString := c.String("format"); fmtString != "" { tpl = template.Must(template.New("event-format").Parse(fmtString)) } // Event flags. for _, event := range c.StringSlice("event") { flag |= parseEvent(event) } if flag == 0 { flag = inotify.IN_ALL_EVENTS } watch(watcher, c.Args(), flag, c.Bool("recursive"), true) // Configure timeout. if timeout := time.Duration(c.Int("timeout")) * time.Second; timeout > 0 { ctx, _ = context.WithTimeout(ctx, timeout) } match := buildMatcherFunc(c.StringSlice("exclude"), c.StringSlice("include")) waitForWatcher(ctx, watcher, match, tpl, c.Bool("monitor")) }
// sysWatcher starts the watcher. func sysWatcher(cmdTocompile string, pkgTowatch []string, logg *log.Logger) (*pkgWatcher, error) { watcher, err := inotify.NewWatcher() if err != nil { logg.Print("FAIL! sysWatcher: ", err) return nil, errWatcher } ok := true // Watch every path for _, path := range pkgTowatch { if err = watcher.AddWatch(path, inotify.IN_MODIFY); err != nil { logg.Print("FAIL! sysWatcher: ", err) ok = false } } if !ok { return nil, errWatcher } return &pkgWatcher{watcher, logg, cmdTocompile}, nil }