diff --git a/scandir_unix.go b/scandir_unix.go index 33250b6..654039b 100644 --- a/scandir_unix.go +++ b/scandir_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package godirwalk @@ -22,8 +23,10 @@ type Scanner struct { fd int // file descriptor used to read entries from directory } -// NewScanner returns a new directory Scanner that lazily enumerates the -// contents of a single directory. +// NewScanner returns a new directory Scanner that lazily enumerates +// the contents of a single directory. To prevent resource leaks, +// caller must invoke either the Scanner's Close or Err method after +// it has completed scanning a directory. // // scanner, err := godirwalk.NewScanner(dirname) // if err != nil { @@ -52,10 +55,12 @@ func NewScanner(osDirname string) (*Scanner, error) { return NewScannerWithScratchBuffer(osDirname, nil) } -// NewScannerWithScratchBuffer returns a new directory Scanner that lazily -// enumerates the contents of a single directory. On platforms other than -// Windows it uses the provided scratch buffer to read from the file system. On -// Windows the scratch buffer is ignored. +// NewScannerWithScratchBuffer returns a new directory Scanner that +// lazily enumerates the contents of a single directory. On platforms +// other than Windows it uses the provided scratch buffer to read from +// the file system. On Windows the scratch buffer is ignored. To +// prevent resource leaks, caller must invoke either the Scanner's +// Close or Err method after it has completed scanning a directory. func NewScannerWithScratchBuffer(osDirname string, scratchBuffer []byte) (*Scanner, error) { dh, err := os.Open(osDirname) if err != nil { @@ -73,6 +78,13 @@ func NewScannerWithScratchBuffer(osDirname string, scratchBuffer []byte) (*Scann return scanner, nil } +// Close releases resources associated with scanning a directory. Call +// either this or the Err method when the directory no longer needs to +// be scanned. +func (s *Scanner) Close() error { + return s.Err() +} + // Dirent returns the current directory entry while scanning a directory. func (s *Scanner) Dirent() (*Dirent, error) { if s.de == nil { @@ -90,8 +102,10 @@ func (s *Scanner) done(err error) { return } - if cerr := s.dh.Close(); err == nil { - s.err = cerr + s.err = err + + if err = s.dh.Close(); s.err == nil { + s.err = err } s.osDirname, s.childName = "", "" @@ -101,9 +115,10 @@ func (s *Scanner) done(err error) { s.fd = 0 } -// Err returns any error associated with scanning a directory. It is normal to -// call Err after Scan returns false, even though they both ensure Scanner -// resources are released. Do not call until done scanning a directory. +// Err returns any error associated with scanning a directory. It is +// normal to call Err after Scan returns false, even though they both +// ensure Scanner resources are released. Call either this or the +// Close method when the directory no longer needs to be scanned. func (s *Scanner) Err() error { s.done(nil) return s.err @@ -135,7 +150,7 @@ func (s *Scanner) Scan() bool { if err == syscall.EINTR /* || err == unix.EINTR */ { continue } - s.done(err) + s.done(err) // any other error forces a stop return false } if n <= 0 { // end of directory: normal exit diff --git a/scandir_windows.go b/scandir_windows.go index a211061..338e323 100644 --- a/scandir_windows.go +++ b/scandir_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package godirwalk @@ -17,8 +18,10 @@ type Scanner struct { childMode os.FileMode } -// NewScanner returns a new directory Scanner that lazily enumerates the -// contents of a single directory. +// NewScanner returns a new directory Scanner that lazily enumerates +// the contents of a single directory. To prevent resource leaks, +// caller must invoke either the Scanner's Close or Err method after +// it has completed scanning a directory. // // scanner, err := godirwalk.NewScanner(dirname) // if err != nil { @@ -55,14 +58,24 @@ func NewScanner(osDirname string) (*Scanner, error) { return scanner, nil } -// NewScannerWithScratchBuffer returns a new directory Scanner that lazily -// enumerates the contents of a single directory. On platforms other than -// Windows it uses the provided scratch buffer to read from the file system. On -// Windows the scratch buffer parameter is ignored. +// NewScannerWithScratchBuffer returns a new directory Scanner that +// lazily enumerates the contents of a single directory. On platforms +// other than Windows it uses the provided scratch buffer to read from +// the file system. On Windows the scratch buffer parameter is +// ignored. To prevent resource leaks, caller must invoke either the +// Scanner's Close or Err method after it has completed scanning a +// directory. func NewScannerWithScratchBuffer(osDirname string, scratchBuffer []byte) (*Scanner, error) { return NewScanner(osDirname) } +// Close releases resources associated with scanning a directory. Call +// either this or the Err method when the directory no longer needs to +// be scanned. +func (s *Scanner) Close() error { + return s.Err() +} + // Dirent returns the current directory entry while scanning a directory. func (s *Scanner) Dirent() (*Dirent, error) { if s.de == nil { @@ -83,17 +96,20 @@ func (s *Scanner) done(err error) { return } - if cerr := s.dh.Close(); err == nil { - s.err = cerr + s.err = err + + if err = s.dh.Close(); s.err == nil { + s.err = err } s.childName, s.osDirname = "", "" s.de, s.dh = nil, nil } -// Err returns any error associated with scanning a directory. It is normal to -// call Err after Scan returns false, even though they both ensure Scanner -// resources are released. Do not call until done scanning a directory. +// Err returns any error associated with scanning a directory. It is +// normal to call Err after Scan returns false, even though they both +// ensure Scanner resources are released. Call either this or the +// Close method when the directory no longer needs to be scanned. func (s *Scanner) Err() error { s.done(nil) return s.err