github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/libkb/flock_nix.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  //go:build !windows
     5  // +build !windows
     6  
     7  package libkb
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"syscall"
    13  )
    14  
    15  // Lock writes the pid to filename after acquiring a lock on the file.
    16  // When the process exits, the lock will be released.
    17  func (f *LockPIDFile) Lock() (err error) {
    18  	if isIOS {
    19  		// on iOS, our share extension can have multiple copies running, and furthermore this lock
    20  		// doesn't do anything there, so let's just do nothing.
    21  		f.G().Log.Debug("Skipping PID file lock on iOS")
    22  		return nil
    23  	}
    24  
    25  	if f.file, err = os.OpenFile(f.name, os.O_CREATE|os.O_RDWR, 0600); err != nil {
    26  		return PIDFileLockError{f.name}
    27  	}
    28  
    29  	// LOCK_EX = exclusive
    30  	// LOCK_NB = nonblocking
    31  	if err = syscall.Flock(int(f.file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
    32  		f.file.Close()
    33  		f.file = nil
    34  		return PIDFileLockError{f.name}
    35  	}
    36  
    37  	pid := os.Getpid()
    38  	fmt.Fprintf(f.file, "%d", pid)
    39  	err = f.file.Sync()
    40  	if err != nil {
    41  		f.file.Close()
    42  		f.file = nil
    43  		return PIDFileLockError{f.name}
    44  	}
    45  
    46  	f.G().Log.Debug("Locked pidfile %s for pid=%d", f.name, pid)
    47  
    48  	return nil
    49  }