vendor/github.com/fsnotify/fsnotify/kqueue.go
author Mikael Berthe <mikael@lilotux.net>
Tue, 23 Aug 2022 22:39:43 +0200
changeset 260 445e01aede7e
parent 242 2a9ec03fe5a1
permissions -rw-r--r--
Update vendor directory
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
// Copyright 2010 The Go Authors. All rights reserved.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
// Use of this source code is governed by a BSD-style
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
// license that can be found in the LICENSE file.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
     5
//go:build freebsd || openbsd || netbsd || dragonfly || darwin
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
// +build freebsd openbsd netbsd dragonfly darwin
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
package fsnotify
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
import (
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
	"errors"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
	"fmt"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
	"io/ioutil"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
	"os"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
	"path/filepath"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
	"sync"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
	"time"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
	"golang.org/x/sys/unix"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
// Watcher watches a set of files, delivering events to a channel.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
type Watcher struct {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
	Events chan Event
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
	Errors chan error
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
	done   chan struct{} // Channel for sending a "quit message" to the reader goroutine
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
	kq int // File descriptor (as returned by the kqueue() syscall).
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	mu              sync.Mutex        // Protects access to watcher data
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
	watches         map[string]int    // Map of watched file descriptors (key: path).
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
	externalWatches map[string]bool   // Map of watches added by user of the library.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
	dirFlags        map[string]uint32 // Map of watched directories to fflags used in kqueue.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
	paths           map[int]pathInfo  // Map file descriptors to path names for processing kqueue events.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
	fileExists      map[string]bool   // Keep track of if we know this file exists (to stop duplicate create events).
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
	isClosed        bool              // Set to true when Close() is first called
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
type pathInfo struct {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
	name  string
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
	isDir bool
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
func NewWatcher() (*Watcher, error) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
	kq, err := kqueue()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
	if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
		return nil, err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
	w := &Watcher{
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
		kq:              kq,
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
		watches:         make(map[string]int),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
		dirFlags:        make(map[string]uint32),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
		paths:           make(map[int]pathInfo),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
		fileExists:      make(map[string]bool),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
		externalWatches: make(map[string]bool),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
		Events:          make(chan Event),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
		Errors:          make(chan error),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
		done:            make(chan struct{}),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
	go w.readEvents()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
	return w, nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
// Close removes all watches and closes the events channel.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
func (w *Watcher) Close() error {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
	w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
	if w.isClosed {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
		w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
		return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
	w.isClosed = true
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
	// copy paths to remove while locked
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
	var pathsToRemove = make([]string, 0, len(w.watches))
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
	for name := range w.watches {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
		pathsToRemove = append(pathsToRemove, name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
	w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
	// unlock before calling Remove, which also locks
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	for _, name := range pathsToRemove {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
		w.Remove(name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
	// send a "quit" message to the reader goroutine
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
	close(w.done)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
	return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
// Add starts watching the named file or directory (non-recursively).
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
func (w *Watcher) Add(name string) error {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
	w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
	w.externalWatches[name] = true
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
	w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
	_, err := w.addWatch(name, noteAllEvents)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
	return err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
// Remove stops watching the the named file or directory (non-recursively).
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
func (w *Watcher) Remove(name string) error {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
	name = filepath.Clean(name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
	w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
	watchfd, ok := w.watches[name]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
	w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
	if !ok {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
		return fmt.Errorf("can't remove non-existent kevent watch for: %s", name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
	const registerRemove = unix.EV_DELETE
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
	if err := register(w.kq, []int{watchfd}, registerRemove, 0); err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
		return err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
	unix.Close(watchfd)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
	w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
	isDir := w.paths[watchfd].isDir
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
	delete(w.watches, name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
	delete(w.paths, watchfd)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
	delete(w.dirFlags, name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
	w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
	// Find all watched paths that are in this directory that are not external.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
	if isDir {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
		var pathsToRemove []string
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
		w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
		for _, path := range w.paths {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
			wdir, _ := filepath.Split(path.name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
			if filepath.Clean(wdir) == name {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
				if !w.externalWatches[path.name] {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
					pathsToRemove = append(pathsToRemove, path.name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
				}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
		w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
		for _, name := range pathsToRemove {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
			// Since these are internal, not much sense in propagating error
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
			// to the user, as that will just confuse them with an error about
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
			// a path they did not explicitly watch themselves.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
			w.Remove(name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
	return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   151
// WatchList returns the directories and files that are being monitered.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   152
func (w *Watcher) WatchList() []string {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   153
	w.mu.Lock()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   154
	defer w.mu.Unlock()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   155
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   156
	entries := make([]string, 0, len(w.watches))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   157
	for pathname := range w.watches {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   158
		entries = append(entries, pathname)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   159
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   160
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   161
	return entries
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   162
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   163
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
// Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
// keventWaitTime to block on each read from kevent
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
var keventWaitTime = durationToTimespec(100 * time.Millisecond)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
// addWatch adds name to the watched file set.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
// The flags are interpreted as described in kevent(2).
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
// Returns the real path to the file which was added, if any, which may be different from the one passed in the case of symlinks.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
	var isDir bool
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
	// Make ./name and name equivalent
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
	name = filepath.Clean(name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
	w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
	if w.isClosed {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
		w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
		return "", errors.New("kevent instance already closed")
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
	watchfd, alreadyWatching := w.watches[name]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
	// We already have a watch, but we can still override flags.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
	if alreadyWatching {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
		isDir = w.paths[watchfd].isDir
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
	w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
	if !alreadyWatching {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
		fi, err := os.Lstat(name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
		if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
			return "", err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
		// Don't watch sockets.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
		if fi.Mode()&os.ModeSocket == os.ModeSocket {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
			return "", nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   199
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   200
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
		// Don't watch named pipes.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   202
		if fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
			return "", nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   204
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   205
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   206
		// Follow Symlinks
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
		// Unfortunately, Linux can add bogus symlinks to watch list without
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
		// issue, and Windows can't do symlinks period (AFAIK). To  maintain
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
		// consistency, we will act like everything is fine. There will simply
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
		// be no file events for broken symlinks.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   211
		// Hence the returns of nil on errors.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   212
		if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
			name, err = filepath.EvalSymlinks(name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
			if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
				return "", nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   216
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   217
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   218
			w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   219
			_, alreadyWatching = w.watches[name]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   220
			w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   222
			if alreadyWatching {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   223
				return name, nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   224
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   226
			fi, err = os.Lstat(name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   227
			if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
				return "", nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   230
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   231
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   232
		watchfd, err = unix.Open(name, openMode, 0700)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   233
		if watchfd == -1 {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   234
			return "", err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   235
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   236
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   237
		isDir = fi.IsDir()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   238
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   239
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   240
	const registerAdd = unix.EV_ADD | unix.EV_CLEAR | unix.EV_ENABLE
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   241
	if err := register(w.kq, []int{watchfd}, registerAdd, flags); err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   242
		unix.Close(watchfd)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   243
		return "", err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   244
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   245
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   246
	if !alreadyWatching {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   247
		w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   248
		w.watches[name] = watchfd
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   249
		w.paths[watchfd] = pathInfo{name: name, isDir: isDir}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   250
		w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   251
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   252
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   253
	if isDir {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   254
		// Watch the directory if it has not been watched before,
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   255
		// or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   256
		w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   257
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   258
		watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE &&
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   259
			(!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   260
		// Store flags so this watch can be updated later
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   261
		w.dirFlags[name] = flags
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   262
		w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   263
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   264
		if watchDir {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   265
			if err := w.watchDirectoryFiles(name); err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   266
				return "", err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   267
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   268
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   269
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   270
	return name, nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   271
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   272
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   273
// readEvents reads from kqueue and converts the received kevents into
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   274
// Event values that it sends down the Events channel.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   275
func (w *Watcher) readEvents() {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   276
	eventBuffer := make([]unix.Kevent_t, 10)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   277
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   278
loop:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   279
	for {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   280
		// See if there is a message on the "done" channel
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   281
		select {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   282
		case <-w.done:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   283
			break loop
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   284
		default:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   285
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   286
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   287
		// Get new events
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   288
		kevents, err := read(w.kq, eventBuffer, &keventWaitTime)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   289
		// EINTR is okay, the syscall was interrupted before timeout expired.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   290
		if err != nil && err != unix.EINTR {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   291
			select {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   292
			case w.Errors <- err:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   293
			case <-w.done:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   294
				break loop
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   295
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   296
			continue
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   297
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   298
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   299
		// Flush the events we received to the Events channel
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   300
		for len(kevents) > 0 {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   301
			kevent := &kevents[0]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   302
			watchfd := int(kevent.Ident)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   303
			mask := uint32(kevent.Fflags)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   304
			w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   305
			path := w.paths[watchfd]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   306
			w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   307
			event := newEvent(path.name, mask)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   308
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   309
			if path.isDir && !(event.Op&Remove == Remove) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   310
				// Double check to make sure the directory exists. This can happen when
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   311
				// we do a rm -fr on a recursively watched folders and we receive a
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   312
				// modification event first but the folder has been deleted and later
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   313
				// receive the delete event
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   314
				if _, err := os.Lstat(event.Name); os.IsNotExist(err) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   315
					// mark is as delete event
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   316
					event.Op |= Remove
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   317
				}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   318
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   319
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   320
			if event.Op&Rename == Rename || event.Op&Remove == Remove {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   321
				w.Remove(event.Name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   322
				w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   323
				delete(w.fileExists, event.Name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   324
				w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   325
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   326
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   327
			if path.isDir && event.Op&Write == Write && !(event.Op&Remove == Remove) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   328
				w.sendDirectoryChangeEvents(event.Name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   329
			} else {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   330
				// Send the event on the Events channel.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   331
				select {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   332
				case w.Events <- event:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   333
				case <-w.done:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   334
					break loop
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   335
				}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   336
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   337
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   338
			if event.Op&Remove == Remove {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   339
				// Look for a file that may have overwritten this.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   340
				// For example, mv f1 f2 will delete f2, then create f2.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   341
				if path.isDir {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   342
					fileDir := filepath.Clean(event.Name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   343
					w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   344
					_, found := w.watches[fileDir]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   345
					w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   346
					if found {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   347
						// make sure the directory exists before we watch for changes. When we
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   348
						// do a recursive watch and perform rm -fr, the parent directory might
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   349
						// have gone missing, ignore the missing directory and let the
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   350
						// upcoming delete event remove the watch from the parent directory.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   351
						if _, err := os.Lstat(fileDir); err == nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   352
							w.sendDirectoryChangeEvents(fileDir)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   353
						}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   354
					}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   355
				} else {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   356
					filePath := filepath.Clean(event.Name)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   357
					if fileInfo, err := os.Lstat(filePath); err == nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   358
						w.sendFileCreatedEventIfNew(filePath, fileInfo)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   359
					}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   360
				}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   361
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   362
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   363
			// Move to next event
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   364
			kevents = kevents[1:]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   365
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   366
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   367
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   368
	// cleanup
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   369
	err := unix.Close(w.kq)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   370
	if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   371
		// only way the previous loop breaks is if w.done was closed so we need to async send to w.Errors.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   372
		select {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   373
		case w.Errors <- err:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   374
		default:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   375
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   376
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   377
	close(w.Events)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   378
	close(w.Errors)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   379
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   380
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   381
// newEvent returns an platform-independent Event based on kqueue Fflags.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   382
func newEvent(name string, mask uint32) Event {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   383
	e := Event{Name: name}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   384
	if mask&unix.NOTE_DELETE == unix.NOTE_DELETE {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   385
		e.Op |= Remove
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   386
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   387
	if mask&unix.NOTE_WRITE == unix.NOTE_WRITE {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   388
		e.Op |= Write
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   389
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   390
	if mask&unix.NOTE_RENAME == unix.NOTE_RENAME {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   391
		e.Op |= Rename
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   392
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   393
	if mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   394
		e.Op |= Chmod
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   395
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   396
	return e
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   397
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   398
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   399
func newCreateEvent(name string) Event {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   400
	return Event{Name: name, Op: Create}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   401
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   402
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   403
// watchDirectoryFiles to mimic inotify when adding a watch on a directory
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   404
func (w *Watcher) watchDirectoryFiles(dirPath string) error {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   405
	// Get all files
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   406
	files, err := ioutil.ReadDir(dirPath)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   407
	if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   408
		return err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   409
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   410
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   411
	for _, fileInfo := range files {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   412
		filePath := filepath.Join(dirPath, fileInfo.Name())
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   413
		filePath, err = w.internalWatch(filePath, fileInfo)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   414
		if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   415
			return err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   416
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   417
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   418
		w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   419
		w.fileExists[filePath] = true
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   420
		w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   421
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   422
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   423
	return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   424
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   425
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   426
// sendDirectoryEvents searches the directory for newly created files
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   427
// and sends them over the event channel. This functionality is to have
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   428
// the BSD version of fsnotify match Linux inotify which provides a
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   429
// create event for files created in a watched directory.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   430
func (w *Watcher) sendDirectoryChangeEvents(dirPath string) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   431
	// Get all files
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   432
	files, err := ioutil.ReadDir(dirPath)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   433
	if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   434
		select {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   435
		case w.Errors <- err:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   436
		case <-w.done:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   437
			return
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   438
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   439
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   440
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   441
	// Search for new files
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   442
	for _, fileInfo := range files {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   443
		filePath := filepath.Join(dirPath, fileInfo.Name())
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   444
		err := w.sendFileCreatedEventIfNew(filePath, fileInfo)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   445
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   446
		if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   447
			return
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   448
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   449
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   450
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   451
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   452
// sendFileCreatedEvent sends a create event if the file isn't already being tracked.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   453
func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInfo) (err error) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   454
	w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   455
	_, doesExist := w.fileExists[filePath]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   456
	w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   457
	if !doesExist {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   458
		// Send create event
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   459
		select {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   460
		case w.Events <- newCreateEvent(filePath):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   461
		case <-w.done:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   462
			return
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   463
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   464
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   465
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   466
	// like watchDirectoryFiles (but without doing another ReadDir)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   467
	filePath, err = w.internalWatch(filePath, fileInfo)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   468
	if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   469
		return err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   470
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   471
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   472
	w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   473
	w.fileExists[filePath] = true
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   474
	w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   475
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   476
	return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   477
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   478
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   479
func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, error) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   480
	if fileInfo.IsDir() {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   481
		// mimic Linux providing delete events for subdirectories
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   482
		// but preserve the flags used if currently watching subdirectory
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   483
		w.mu.Lock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   484
		flags := w.dirFlags[name]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   485
		w.mu.Unlock()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   486
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   487
		flags |= unix.NOTE_DELETE | unix.NOTE_RENAME
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   488
		return w.addWatch(name, flags)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   489
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   490
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   491
	// watch file to mimic Linux inotify
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   492
	return w.addWatch(name, noteAllEvents)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   493
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   494
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   495
// kqueue creates a new kernel event queue and returns a descriptor.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   496
func kqueue() (kq int, err error) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   497
	kq, err = unix.Kqueue()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   498
	if kq == -1 {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   499
		return kq, err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   500
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   501
	return kq, nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   502
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   503
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   504
// register events with the queue
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   505
func register(kq int, fds []int, flags int, fflags uint32) error {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   506
	changes := make([]unix.Kevent_t, len(fds))
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   507
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   508
	for i, fd := range fds {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   509
		// SetKevent converts int to the platform-specific types:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   510
		unix.SetKevent(&changes[i], fd, unix.EVFILT_VNODE, flags)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   511
		changes[i].Fflags = fflags
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   512
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   513
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   514
	// register the events
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   515
	success, err := unix.Kevent(kq, changes, nil, nil)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   516
	if success == -1 {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   517
		return err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   518
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   519
	return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   520
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   521
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   522
// read retrieves pending events, or waits until an event occurs.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   523
// A timeout of nil blocks indefinitely, while 0 polls the queue.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   524
func read(kq int, events []unix.Kevent_t, timeout *unix.Timespec) ([]unix.Kevent_t, error) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   525
	n, err := unix.Kevent(kq, nil, events, timeout)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   526
	if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   527
		return nil, err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   528
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   529
	return events[0:n], nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   530
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   531
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   532
// durationToTimespec prepares a timeout value
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   533
func durationToTimespec(d time.Duration) unix.Timespec {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   534
	return unix.NsecToTimespec(d.Nanoseconds())
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   535
}