github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/file/lock_unix.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  // Copyright 2021 The TrueBlocks Authors. All rights reserved.
     5  // Use of this source code is governed by a license that can
     6  // be found in the LICENSE file.
     7  
     8  package file
     9  
    10  import (
    11  	"io"
    12  	"os"
    13  	"syscall"
    14  )
    15  
    16  // Lock asks the OS to lock a file for the current process
    17  func Lock(file *os.File) error {
    18  	// Lock configuration. We want both read (F_RDLCK) and
    19  	// write (F_WRLCK) locks, and by Start to be interpreted
    20  	// as the start of the file (Whence set to SEEK_SET).
    21  	//
    22  	// More: https://man7.org/linux/man-pages/man2/fcntl.2.html
    23  	lockConfig := &syscall.Flock_t{
    24  		Type:   syscall.F_RDLCK | syscall.F_WRLCK,
    25  		Whence: int16(io.SeekStart),
    26  		Start:  0,
    27  		Len:    0,
    28  	}
    29  
    30  	return changeLock(file, lockConfig)
    31  }
    32  
    33  // Unlock removes OS-level file lock
    34  func Unlock(file *os.File) error {
    35  	lockConfig := &syscall.Flock_t{
    36  		Type:   syscall.F_UNLCK,
    37  		Whence: int16(io.SeekStart),
    38  		Start:  0,
    39  		Len:    0,
    40  	}
    41  
    42  	return changeLock(file, lockConfig)
    43  }
    44  
    45  // changeLock is a helper function that sends the syscall to either lock or
    46  // unlock a file
    47  func changeLock(file *os.File, lockConfig *syscall.Flock_t) error {
    48  	// We use fcntl lock, which locks a file to a specific process
    49  	//
    50  	// More: https://stackoverflow.com/questions/29611352/what-is-the-difference-between-locking-with-fcntl-and-flock
    51  	return syscall.FcntlFlock(file.Fd(), syscall.F_SETLK, lockConfig)
    52  }