func (w *Watcher) readEvents() {
	var buf [syscall.SizeofInotifyEvent * 4096]byte
	for {
		n, err := syscall.Read(w.fd, buf[0:])
		var done bool
		select {
		case done = <-w.done:
		default:
		}
		if n == 0 || done {
			err := syscall.Close(w.fd)
			if err != nil {
				w.Error <- os.NewSyscallError("close", err)
			}
			close(w.Event)
			close(w.Error)
			return
		}
		if n < 0 {
			w.Error <- os.NewSyscallError("read", err)
			continue
		}
		if n < syscall.SizeofInotifyEvent {
			w.Error <- errors.New("inotify: short read in readEvents()")
			continue
		}
		var offset uint32 = 0
		for offset <= uint32(n-syscall.SizeofInotifyEvent) {
			raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
			event := new(Event)
			event.Mask = uint32(raw.Mask)
			event.Cookie = uint32(raw.Cookie)
			nameLen := uint32(raw.Len)
			event.Name = w.paths[int(raw.Wd)]
			if nameLen > 0 {
				bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
				event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
			}
			w.Event <- event
			offset += syscall.SizeofInotifyEvent + nameLen
		}
	}
}
readEvents reads from the inotify file descriptor, converts the
received events into Event objects and sends them via the Event channel
package inotify
import (
	"errors"
	"fmt"
	"os"
	"strings"
	"syscall"
	"unsafe"
)
type Event struct {
	Mask   uint32  
	Cookie uint32  
	Name   string  
}
type watch struct {
	wd    uint32  
	flags uint32  
}
type Watcher struct {
	fd       int                
	watches  map[string]*watch  
	paths    map[int]string     
	Error    chan error         
	Event    chan *Event        
	done     chan bool          
	isClosed bool               
}
func NewWatcher() (*Watcher, error) {
	fd, errno := syscall.InotifyInit()
	if fd == -1 {
		return nil, os.NewSyscallError("inotify_init", errno)
	}
	w := &Watcher{
		fd:      fd,
		watches: make(map[string]*watch),
		paths:   make(map[int]string),
		Event:   make(chan *Event),
		Error:   make(chan error),
		done:    make(chan bool, 1),
	}
	go w.readEvents()
	return w, nil
}
func (w *Watcher) Close() error {
	if w.isClosed {
		return nil
	}
	w.isClosed = true
	w.done <- true
	for path := range w.watches {
		w.RemoveWatch(path)
	}
	return nil
}
func (w *Watcher) AddWatch(path string, flags uint32) error {
	if w.isClosed {
		return errors.New("inotify instance already closed")
	}
	watchEntry, found := w.watches[path]
	if found {
		watchEntry.flags |= flags
		flags |= syscall.IN_MASK_ADD
	}
	wd, err := syscall.InotifyAddWatch(w.fd, path, flags)
	if err != nil {
		return &os.PathError{
			Op:   "inotify_add_watch",
			Path: path,
			Err:  err,
		}
	}
	if !found {
		w.watches[path] = &watch{wd: uint32(wd), flags: flags}
		w.paths[wd] = path
	}
	return nil
}
func (w *Watcher) Watch(path string) error {
	return w.AddWatch(path, IN_ALL_EVENTS)
}
func (w *Watcher) RemoveWatch(path string) error {
	watch, ok := w.watches[path]
	if !ok {
		return errors.New(fmt.Sprintf("can't remove non-existent inotify watch for: %s", path))
	}
	success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
	if success == -1 {
		return os.NewSyscallError("inotify_rm_watch", errno)
	}
	delete(w.watches, path)
	return nil
}