From c6c7c779c4a5bc03ecd672f3bf735806ae49663a Mon Sep 17 00:00:00 2001 From: Dustin Spicuzza Date: Mon, 17 Sep 2018 00:40:05 -0400 Subject: [PATCH 1/4] Ensure files are closed upon lock error --- flock.go | 8 ++++++++ flock_unix.go | 2 ++ flock_windows.go | 2 ++ 3 files changed, 12 insertions(+) diff --git a/flock.go b/flock.go index 8f109b8..2fd1603 100644 --- a/flock.go +++ b/flock.go @@ -125,3 +125,11 @@ func (f *Flock) setFh() error { f.fh = fh return nil } + +// ensure the file handle is closed if no lock is held +func (f *Flock) ensureFhState() { + if !f.l && !f.r && f.fh != nil { + f.fh.Close() + f.fh = nil + } +} diff --git a/flock_unix.go b/flock_unix.go index 45f71a7..366a60c 100644 --- a/flock_unix.go +++ b/flock_unix.go @@ -51,6 +51,7 @@ func (f *Flock) lock(locked *bool, flag int) error { if err := f.setFh(); err != nil { return err } + defer f.ensureFhState() } if err := syscall.Flock(int(f.fh.Fd()), flag); err != nil { @@ -142,6 +143,7 @@ func (f *Flock) try(locked *bool, flag int) (bool, error) { if err := f.setFh(); err != nil { return false, err } + defer f.ensureFhState() } var retried bool diff --git a/flock_windows.go b/flock_windows.go index 9f4a5f1..ddb534c 100644 --- a/flock_windows.go +++ b/flock_windows.go @@ -46,6 +46,7 @@ func (f *Flock) lock(locked *bool, flag uint32) error { if err := f.setFh(); err != nil { return err } + defer f.ensureFhState() } if _, errNo := lockFileEx(syscall.Handle(f.fh.Fd()), flag, 0, 1, 0, &syscall.Overlapped{}); errNo > 0 { @@ -122,6 +123,7 @@ func (f *Flock) try(locked *bool, flag uint32) (bool, error) { if err := f.setFh(); err != nil { return false, err } + defer f.ensureFhState() } _, errNo := lockFileEx(syscall.Handle(f.fh.Fd()), flag|winLockfileFailImmediately, 0, 1, 0, &syscall.Overlapped{}) From 958d66434653517f8a59381b3632570ec7dca998 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Fri, 23 Aug 2019 16:42:43 +0200 Subject: [PATCH 2/4] test that a failed file lock closes the file --- flock_internal_test.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 flock_internal_test.go diff --git a/flock_internal_test.go b/flock_internal_test.go new file mode 100644 index 0000000..369e51c --- /dev/null +++ b/flock_internal_test.go @@ -0,0 +1,30 @@ +package flock + +import ( + "io/ioutil" + "os" + "testing" +) + +func Test(t *testing.T) { + tmpFileFh, err := ioutil.TempFile(os.TempDir(), "go-flock-") + tmpFileFh.Close() + tmpFile := tmpFileFh.Name() + os.Remove(tmpFile) + + lock := New(tmpFile) + locked, err := lock.TryLock() + if locked == false || err != nil { + t.Fatal("failed to lock") + } + + newLock := New(tmpFile) + locked, err = newLock.TryLock() + if locked != false || err != nil { + t.Fatal("should have failed locking") + } + + if newLock.fh != nil { + t.Fatal("file handle should have been released and be nil") + } +} From 8293fac1a3de53d59e158e0e2cacda9351fdd173 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 19 Mar 2020 09:58:24 +0100 Subject: [PATCH 3/4] Update flock_internal_test.go --- flock_internal_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flock_internal_test.go b/flock_internal_test.go index 369e51c..7ccdaca 100644 --- a/flock_internal_test.go +++ b/flock_internal_test.go @@ -15,7 +15,7 @@ func Test(t *testing.T) { lock := New(tmpFile) locked, err := lock.TryLock() if locked == false || err != nil { - t.Fatal("failed to lock") + t.Fatalf("failed to lock: locked: %t, err: %v", locked, err) } newLock := New(tmpFile) From 0eda2671edf3b61a4e064eabcf6ef2e614599aff Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 19 Mar 2020 09:59:05 +0100 Subject: [PATCH 4/4] Update flock_internal_test.go --- flock_internal_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flock_internal_test.go b/flock_internal_test.go index 7ccdaca..ff2a12a 100644 --- a/flock_internal_test.go +++ b/flock_internal_test.go @@ -21,7 +21,7 @@ func Test(t *testing.T) { newLock := New(tmpFile) locked, err = newLock.TryLock() if locked != false || err != nil { - t.Fatal("should have failed locking") + t.Fatalf("should have failed locking: locked: %t, err: %v", locked, err) } if newLock.fh != nil {