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