Close inotify fd from watcher, not from poller
diff --git a/inotify.go b/inotify.go
index e02bf12..5aa185b 100644
--- a/inotify.go
+++ b/inotify.go
@@ -23,6 +23,7 @@
 	Events   chan Event
 	Errors   chan error
 	mu       sync.Mutex // Map access
+	fd       int
 	poller   *fdPoller
 	watches  map[string]*watch // Map of inotify watches (key: path)
 	paths    map[int]string    // Map of watched paths (key: watch descriptor)
@@ -40,9 +41,11 @@
 	// Create epoll
 	poller, err := newFdPoller(fd)
 	if err != nil {
+		syscall.Close(fd)
 		return nil, err
 	}
 	w := &Watcher{
+		fd:       fd,
 		poller:   poller,
 		watches:  make(map[string]*watch),
 		paths:    make(map[int]string),
@@ -103,7 +106,7 @@
 		watchEntry.flags |= flags
 		flags |= syscall.IN_MASK_ADD
 	}
-	wd, errno := syscall.InotifyAddWatch(w.poller.fd, name, flags)
+	wd, errno := syscall.InotifyAddWatch(w.fd, name, flags)
 	if wd == -1 {
 		return errno
 	}
@@ -129,7 +132,7 @@
 	if !ok {
 		return fmt.Errorf("can't remove non-existent inotify watch for: %s", name)
 	}
-	success, errno := syscall.InotifyRmWatch(w.poller.fd, watch.wd)
+	success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
 	if success == -1 {
 		return errno
 	}
@@ -155,6 +158,7 @@
 	defer close(w.doneresp)
 	defer close(w.Errors)
 	defer close(w.Events)
+	defer syscall.Close(w.fd)
 	defer w.poller.close()
 
 	for {
@@ -177,7 +181,7 @@
 			continue
 		}
 
-		n, errno = syscall.Read(w.poller.fd, buf[:])
+		n, errno = syscall.Read(w.fd, buf[:])
 		// If a signal interrupted execution, see if we've been asked to close, and try again.
 		// http://man7.org/linux/man-pages/man7/signal.7.html :
 		// "Before Linux 3.8, reads from an inotify(7) file descriptor were not restartable"
diff --git a/inotify_poller.go b/inotify_poller.go
index 8a95df6..2f9cb23 100644
--- a/inotify_poller.go
+++ b/inotify_poller.go
@@ -33,7 +33,6 @@
 	// Create pipe; pipe[0] is the read end, pipe[1] the write end.
 	errno = syscall.Pipe(poller.pipe[:])
 	if errno != nil {
-		syscall.Close(poller.fd)
 		syscall.Close(poller.epfd)
 		return nil, errno
 	}
@@ -45,7 +44,6 @@
 	}
 	errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.fd, &event)
 	if errno != nil {
-		syscall.Close(poller.fd)
 		syscall.Close(poller.epfd)
 		syscall.Close(poller.pipe[0])
 		syscall.Close(poller.pipe[1])
@@ -59,7 +57,6 @@
 	}
 	errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.pipe[0], &event)
 	if errno != nil {
-		syscall.Close(poller.fd)
 		syscall.Close(poller.epfd)
 		syscall.Close(poller.pipe[0])
 		syscall.Close(poller.pipe[1])
@@ -171,10 +168,9 @@
 	return nil
 }
 
-// Close all file descriptors.
+// Close all poller file descriptors, but not the one passed to it.
 func (poller *fdPoller) close() {
 	syscall.Close(poller.pipe[1])
 	syscall.Close(poller.pipe[0])
-	syscall.Close(poller.fd)
 	syscall.Close(poller.epfd)
 }
diff --git a/inotify_test.go b/inotify_test.go
index 1c26a29..9d8e120 100644
--- a/inotify_test.go
+++ b/inotify_test.go
@@ -139,6 +139,7 @@
 	// Now we try to swap the file descriptor under its nose.
 	w.Close()
 	w, err = NewWatcher()
+	defer w.Close()
 	if err != nil {
 		t.Fatalf("Failed to create second watcher: %v", err)
 	}