github.com/DiversionCompany/notify@v0.9.9/notify.go (about) 1 // Copyright (c) 2014-2015 The Notify Authors. All rights reserved. 2 // Use of this source code is governed by the MIT license that can be 3 // found in the LICENSE file. 4 5 // BUG(rjeczalik): Notify does not collect watchpoints, when underlying watches 6 // were removed by their os-specific watcher implementations. Instead users are 7 // advised to listen on persistent paths to have guarantee they receive events 8 // for the whole lifetime of their applications (to discuss see #69). 9 10 // BUG(ppknap): Linux (inotify) does not support watcher behavior masks like 11 // InOneshot, InOnlydir etc. Instead users are advised to perform the filtering 12 // themselves (to discuss see #71). 13 14 // BUG(ppknap): Notify was not tested for short path name support under Windows 15 // (ReadDirectoryChangesW). 16 17 // BUG(ppknap): Windows (ReadDirectoryChangesW) cannot recognize which notification 18 // triggers FileActionModified event. (to discuss see #75). 19 20 package notify 21 22 var defaultTree = newTree() 23 24 type DoNotWatchFn func(string) bool 25 26 // Watch sets up a watchpoint on path listening for events given by the events 27 // argument. 28 // 29 // File or directory given by the path must exist, otherwise Watch will fail 30 // with non-nil error. Notify resolves, for its internal purpose, any symlinks 31 // the provided path may contain, so it may fail if the symlinks form a cycle. 32 // It does so, since not all watcher implementations treat passed paths as-is. 33 // E.g. FSEvents reports a real path for every event, setting a watchpoint 34 // on /tmp will report events with paths rooted at /private/tmp etc. 35 // 36 // The c almost always is a buffered channel. Watch will not block sending to c 37 // - the caller must ensure that c has sufficient buffer space to keep up with 38 // the expected event rate. 39 // 40 // It is allowed to pass the same channel multiple times with different event 41 // list or different paths. Calling Watch with different event lists for a single 42 // watchpoint expands its event set. The only way to shrink it, is to call 43 // Stop on its channel. 44 // 45 // Calling Watch with empty event list does not expand nor shrink watchpoint's 46 // event set. If c is the first channel to listen for events on the given path, 47 // Watch will seamlessly create a watch on the filesystem. 48 // 49 // Notify dispatches copies of single filesystem event to all channels registered 50 // for each path. If a single filesystem event contains multiple coalesced events, 51 // each of them is dispatched separately. E.g. the following filesystem change: 52 // 53 // ~ $ echo Hello > Notify.txt 54 // 55 // dispatches two events - notify.Create and notify.Write. However, it may depend 56 // on the underlying watcher implementation whether OS reports both of them. 57 // 58 // # Windows and recursive watches 59 // 60 // If a directory which path was used to create recursive watch under Windows 61 // gets deleted, the OS will not report such event. It is advised to keep in 62 // mind this limitation while setting recursive watchpoints for your application, 63 // e.g. use persistent paths like %userprofile% or watch additionally parent 64 // directory of a recursive watchpoint in order to receive delete events for it. 65 func Watch(path string, c chan<- EventInfo, events ...Event) error { 66 return defaultTree.Watch(path, c, nil, events...) 67 } 68 69 // This function works the same way as Watch. In addition it does not watch 70 // files or directories based on the return value of the argument function 71 // doNotWatch. Given a path as argument doNotWatch should return true if the 72 // file or directory should not be watched. 73 func WatchWithFilter(path string, c chan<- EventInfo, 74 doNotWatch func(string) bool, events ...Event) error { 75 return defaultTree.Watch(path, c, doNotWatch, events...) 76 } 77 78 // Stop removes all watchpoints registered for c. All underlying watches are 79 // also removed, for which c was the last channel listening for events. 80 // 81 // Stop does not close c. When Stop returns, it is guaranteed that c will 82 // receive no more signals. 83 func Stop(c chan<- EventInfo) { 84 defaultTree.Stop(c) 85 } 86 87 func Close() error { 88 return defaultTree.Close() 89 }