Skip to content

Commit

Permalink
Merge pull request #68 from karrick/close
Browse files Browse the repository at this point in the history
added Close method and updated godoc documentation
  • Loading branch information
Karrick McDermott committed May 4, 2022
2 parents 09df44b + fc82f1b commit 9a7752c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 23 deletions.
39 changes: 27 additions & 12 deletions scandir_unix.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows

package godirwalk
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 = "", ""
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
38 changes: 27 additions & 11 deletions scandir_windows.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build windows
// +build windows

package godirwalk
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down

0 comments on commit 9a7752c

Please sign in to comment.