1// Copyright 2012 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package fsnotify implements file system notification.
6package fsnotify
7
8import "fmt"
9
10const (
11	FSN_CREATE = 1
12	FSN_MODIFY = 2
13	FSN_DELETE = 4
14	FSN_RENAME = 8
15
16	FSN_ALL = FSN_MODIFY | FSN_DELETE | FSN_RENAME | FSN_CREATE
17)
18
19// Purge events from interal chan to external chan if passes filter
20func (w *Watcher) purgeEvents() {
21	for ev := range w.internalEvent {
22		sendEvent := false
23		w.fsnmut.Lock()
24		fsnFlags := w.fsnFlags[ev.Name]
25		w.fsnmut.Unlock()
26
27		if (fsnFlags&FSN_CREATE == FSN_CREATE) && ev.IsCreate() {
28			sendEvent = true
29		}
30
31		if (fsnFlags&FSN_MODIFY == FSN_MODIFY) && ev.IsModify() {
32			sendEvent = true
33		}
34
35		if (fsnFlags&FSN_DELETE == FSN_DELETE) && ev.IsDelete() {
36			sendEvent = true
37		}
38
39		if (fsnFlags&FSN_RENAME == FSN_RENAME) && ev.IsRename() {
40			sendEvent = true
41		}
42
43		if sendEvent {
44			w.Event <- ev
45		}
46
47		// If there's no file, then no more events for user
48		// BSD must keep watch for internal use (watches DELETEs to keep track
49		// what files exist for create events)
50		if ev.IsDelete() {
51			w.fsnmut.Lock()
52			delete(w.fsnFlags, ev.Name)
53			w.fsnmut.Unlock()
54		}
55	}
56
57	close(w.Event)
58}
59
60// Watch a given file path
61func (w *Watcher) Watch(path string) error {
62	w.fsnmut.Lock()
63	w.fsnFlags[path] = FSN_ALL
64	w.fsnmut.Unlock()
65	return w.watch(path)
66}
67
68// Watch a given file path for a particular set of notifications (FSN_MODIFY etc.)
69func (w *Watcher) WatchFlags(path string, flags uint32) error {
70	w.fsnmut.Lock()
71	w.fsnFlags[path] = flags
72	w.fsnmut.Unlock()
73	return w.watch(path)
74}
75
76// Remove a watch on a file
77func (w *Watcher) RemoveWatch(path string) error {
78	w.fsnmut.Lock()
79	delete(w.fsnFlags, path)
80	w.fsnmut.Unlock()
81	return w.removeWatch(path)
82}
83
84// String formats the event e in the form
85// "filename: DELETE|MODIFY|..."
86func (e *FileEvent) String() string {
87	var events string = ""
88
89	if e.IsCreate() {
90		events += "|" + "CREATE"
91	}
92
93	if e.IsDelete() {
94		events += "|" + "DELETE"
95	}
96
97	if e.IsModify() {
98		events += "|" + "MODIFY"
99	}
100
101	if e.IsRename() {
102		events += "|" + "RENAME"
103	}
104
105	if e.IsAttrib() {
106		events += "|" + "ATTRIB"
107	}
108
109	if len(events) > 0 {
110		events = events[1:]
111	}
112
113	return fmt.Sprintf("%q: %s", e.Name, events)
114}
115