go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/filelock/filelock_windows.go (about)

     1  //go:build windows
     2  // +build windows
     3  
     4  /*
     5  
     6  Copyright (c) 2023 - Present. Will Charczuk. All rights reserved.
     7  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     8  
     9  */
    10  
    11  package filelock
    12  
    13  import (
    14  	"internal/syscall/windows"
    15  	"io/fs"
    16  	"syscall"
    17  )
    18  
    19  type lockType uint32
    20  
    21  const (
    22  	readLock  lockType = 0
    23  	writeLock lockType = windows.LOCKFILE_EXCLUSIVE_LOCK
    24  )
    25  
    26  const (
    27  	reserved = 0
    28  	allBytes = ^uint32(0)
    29  )
    30  
    31  func lock(f File, lt lockType) error {
    32  	// Per https://golang.org/issue/19098, “Programs currently expect the Fd
    33  	// method to return a handle that uses ordinary synchronous I/O.”
    34  	// However, LockFileEx still requires an OVERLAPPED structure,
    35  	// which contains the file offset of the beginning of the lock range.
    36  	// We want to lock the entire file, so we leave the offset as zero.
    37  	ol := new(syscall.Overlapped)
    38  
    39  	err := windows.LockFileEx(syscall.Handle(f.Fd()), uint32(lt), reserved, allBytes, allBytes, ol)
    40  	if err != nil {
    41  		return &fs.PathError{
    42  			Op:   lt.String(),
    43  			Path: f.Name(),
    44  			Err:  err,
    45  		}
    46  	}
    47  	return nil
    48  }
    49  
    50  func unlock(f File) error {
    51  	ol := new(syscall.Overlapped)
    52  	err := windows.UnlockFileEx(syscall.Handle(f.Fd()), reserved, allBytes, allBytes, ol)
    53  	if err != nil {
    54  		return &fs.PathError{
    55  			Op:   "Unlock",
    56  			Path: f.Name(),
    57  			Err:  err,
    58  		}
    59  	}
    60  	return nil
    61  }
    62  
    63  func isNotSupported(err error) bool {
    64  	switch err {
    65  	case windows.ERROR_NOT_SUPPORTED, windows.ERROR_CALL_NOT_IMPLEMENTED, ErrNotSupported:
    66  		return true
    67  	default:
    68  		return false
    69  	}
    70  }