github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/repo/fsrepo/lock/lock.go (about)

     1  package lock
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"path"
     8  	"strings"
     9  	"syscall"
    10  
    11  	lock "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/camlistore/lock"
    12  	"github.com/ipfs/go-ipfs/util"
    13  )
    14  
    15  // LockFile is the filename of the repo lock, relative to config dir
    16  // TODO rename repo lock and hide name
    17  const LockFile = "repo.lock"
    18  
    19  func errPerm(path string) error {
    20  	return fmt.Errorf("failed to take lock at %s: permission denied", path)
    21  }
    22  
    23  func Lock(confdir string) (io.Closer, error) {
    24  	c, err := lock.Lock(path.Join(confdir, LockFile))
    25  	return c, err
    26  }
    27  
    28  func Locked(confdir string) (bool, error) {
    29  	if !util.FileExists(path.Join(confdir, LockFile)) {
    30  		return false, nil
    31  	}
    32  	if lk, err := Lock(confdir); err != nil {
    33  		// EAGAIN == someone else has the lock
    34  		if err == syscall.EAGAIN {
    35  			return true, nil
    36  		}
    37  		if strings.Contains(err.Error(), "can't Lock file") {
    38  			return true, nil
    39  		}
    40  
    41  		// lock fails on permissions error
    42  		if os.IsPermission(err) {
    43  			return false, errPerm(confdir)
    44  		}
    45  		if isLockCreatePermFail(err) {
    46  			return false, errPerm(confdir)
    47  		}
    48  
    49  		// otherwise, we cant guarantee anything, error out
    50  		return false, err
    51  	} else {
    52  		lk.Close()
    53  		return false, nil
    54  	}
    55  }
    56  
    57  func isLockCreatePermFail(err error) bool {
    58  	s := err.Error()
    59  	return strings.Contains(s, "Lock Create of") && strings.Contains(s, "permission denied")
    60  }