equal
deleted
inserted
replaced
1 // Copyright 2011 The Go Authors. All rights reserved. |
1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style |
2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. |
3 // license that can be found in the LICENSE file. |
4 |
4 |
|
5 //go:build windows |
5 // +build windows |
6 // +build windows |
6 |
7 |
7 package fsnotify |
8 package fsnotify |
8 |
9 |
9 import ( |
10 import ( |
10 "errors" |
11 "errors" |
11 "fmt" |
12 "fmt" |
12 "os" |
13 "os" |
13 "path/filepath" |
14 "path/filepath" |
|
15 "reflect" |
14 "runtime" |
16 "runtime" |
15 "sync" |
17 "sync" |
16 "syscall" |
18 "syscall" |
17 "unsafe" |
19 "unsafe" |
18 ) |
20 ) |
91 w.input <- in |
93 w.input <- in |
92 if err := w.wakeupReader(); err != nil { |
94 if err := w.wakeupReader(); err != nil { |
93 return err |
95 return err |
94 } |
96 } |
95 return <-in.reply |
97 return <-in.reply |
|
98 } |
|
99 |
|
100 // WatchList returns the directories and files that are being monitered. |
|
101 func (w *Watcher) WatchList() []string { |
|
102 w.mu.Lock() |
|
103 defer w.mu.Unlock() |
|
104 |
|
105 entries := make([]string, 0, len(w.watches)) |
|
106 for _, entry := range w.watches { |
|
107 for _, watchEntry := range entry { |
|
108 entries = append(entries, watchEntry.path) |
|
109 } |
|
110 } |
|
111 |
|
112 return entries |
96 } |
113 } |
97 |
114 |
98 const ( |
115 const ( |
99 // Options for AddWatch |
116 // Options for AddWatch |
100 sysFSONESHOT = 0x80000000 |
117 sysFSONESHOT = 0x80000000 |
449 break |
466 break |
450 } |
467 } |
451 |
468 |
452 // Point "raw" to the event in the buffer |
469 // Point "raw" to the event in the buffer |
453 raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset])) |
470 raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset])) |
454 buf := (*[syscall.MAX_PATH]uint16)(unsafe.Pointer(&raw.FileName)) |
471 // TODO: Consider using unsafe.Slice that is available from go1.17 |
455 name := syscall.UTF16ToString(buf[:raw.FileNameLength/2]) |
472 // https://stackoverflow.com/questions/51187973/how-to-create-an-array-or-a-slice-from-an-array-unsafe-pointer-in-golang |
|
473 // instead of using a fixed syscall.MAX_PATH buf, we create a buf that is the size of the path name |
|
474 size := int(raw.FileNameLength / 2) |
|
475 var buf []uint16 |
|
476 sh := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) |
|
477 sh.Data = uintptr(unsafe.Pointer(&raw.FileName)) |
|
478 sh.Len = size |
|
479 sh.Cap = size |
|
480 name := syscall.UTF16ToString(buf) |
456 fullname := filepath.Join(watch.path, name) |
481 fullname := filepath.Join(watch.path, name) |
457 |
482 |
458 var mask uint64 |
483 var mask uint64 |
459 switch raw.Action { |
484 switch raw.Action { |
460 case syscall.FILE_ACTION_REMOVED: |
485 case syscall.FILE_ACTION_REMOVED: |