diff --git a/cmds/portmaster-start/lock.go b/cmds/portmaster-start/lock.go index 673844b3..68300214 100644 --- a/cmds/portmaster-start/lock.go +++ b/cmds/portmaster-start/lock.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "log" "os" + "os/user" "path/filepath" "strconv" "strings" @@ -13,8 +14,22 @@ import ( processInfo "github.com/shirou/gopsutil/process" ) -func checkAndCreateInstanceLock(path, name string) (pid int32, err error) { - lockFilePath := filepath.Join(dataRoot.Path, path, fmt.Sprintf("%s-lock.pid", name)) +func checkAndCreateInstanceLock(path, name string, perUser bool) (pid int32, err error) { + var lockFilePath string + if perUser { + // Get user ID for per-user lock file. + var userID string + usr, err := user.Current() + if err != nil { + log.Printf("failed to get current user: %s\n", err) + userID = "no-user" + } else { + userID = usr.Uid + } + lockFilePath = filepath.Join(dataRoot.Path, path, fmt.Sprintf("%s-%s-lock.pid", name, userID)) + } else { + lockFilePath = filepath.Join(dataRoot.Path, path, fmt.Sprintf("%s-lock.pid", name)) + } // read current pid file data, err := ioutil.ReadFile(lockFilePath) diff --git a/cmds/portmaster-start/run.go b/cmds/portmaster-start/run.go index b37ba079..34c9129b 100644 --- a/cmds/portmaster-start/run.go +++ b/cmds/portmaster-start/run.go @@ -46,6 +46,7 @@ type Options struct { Identifier string // component identifier ShortIdentifier string // populated automatically LockPathPrefix string + LockPerUser bool PIDFile bool SuppressArgs bool // do not use any args AllowDownload bool // allow download of component if it is not yet available @@ -73,6 +74,7 @@ func init() { { Name: "Portmaster Notifier", Identifier: "notifier/portmaster-notifier", + LockPerUser: true, AllowDownload: false, AllowHidingWindow: true, PIDFile: true, @@ -162,7 +164,7 @@ func run(opts *Options, cmdArgs []string) (err error) { // check for duplicate instances if opts.PIDFile { - pid, err := checkAndCreateInstanceLock(opts.LockPathPrefix, opts.ShortIdentifier) + pid, err := checkAndCreateInstanceLock(opts.LockPathPrefix, opts.ShortIdentifier, opts.LockPerUser) if err != nil { return fmt.Errorf("failed to exec lock: %w", err) }