github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/io/lockfile.go (about) 1 package io 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/lmorg/murex/lang" 10 "github.com/lmorg/murex/lang/types" 11 "github.com/lmorg/murex/utils/consts" 12 ) 13 14 func init() { 15 lang.DefineFunction("lockfile", cmdLockfile, types.Null) 16 } 17 18 func cmdLockfile(p *lang.Process) (err error) { 19 p.Stdout.SetDataType(types.Null) 20 21 method, err := p.Parameters.String(0) 22 if err != nil { 23 return err 24 } 25 26 name, err := p.Parameters.String(1) 27 if err != nil { 28 return err 29 } 30 31 lockfile := lockFilePath(name) 32 33 switch method { 34 case "lock": 35 if fileExists(lockfile) { 36 return errors.New("lockfile already exists") 37 } 38 39 file, err := os.Create(lockfile) 40 if err != nil { 41 return err 42 } 43 44 file.WriteString(fmt.Sprintf("%d:%d", os.Getpid(), p.Scope.Id)) 45 file.Close() 46 47 case "unlock": 48 if !fileExists(lockfile) { 49 return errors.New("lockfile does not exist") 50 } 51 return os.Remove(lockfile) 52 53 case "wait": 54 for { 55 if !fileExists(lockfile) { 56 return nil 57 } 58 time.Sleep(100 * time.Millisecond) 59 } 60 61 case "path": 62 _, err = p.Stdout.Write([]byte(lockfile)) 63 return err 64 65 default: 66 return errors.New("That isn't a valid parameter: " + method) 67 } 68 69 return nil 70 } 71 72 func fileExists(path string) bool { 73 if _, err := os.Stat(path); os.IsNotExist(err) { 74 return false 75 } 76 return true 77 } 78 79 func lockFilePath(key string) string { 80 return consts.TempDir + key + ".lockfile" 81 }