diff --git a/gui/components/InitErrors.qml b/gui/components/InitErrors.qml index aaf9897b8bbc4bcef23bd597325f608afc1fa202..0481cae35d379eceda4c67c4940c8b7963795f21 100644 --- a/gui/components/InitErrors.qml +++ b/gui/components/InitErrors.qml @@ -44,6 +44,19 @@ ErrorBox { errorText: qsTr("Could not find polkit agent.") visible: true } + }, + State { + name: "alreadyrunning" + when: root.error == "alreadyrunning" + PropertyChanges { + target: splashProgress + visible: false + } + PropertyChanges { + target: splashErrorBox + errorText: qsTr("Application is going to quit as another instance is already running. Please use the system tray icon to open it") + visible: true + } } ] } diff --git a/pkg/backend/init.go b/pkg/backend/init.go index 7be8b19afb5c1b7f8ecc567462cc6f6bf2dcb305..83aa512b55ddb5b1899dc3541878b3f7d48ec6ac 100644 --- a/pkg/backend/init.go +++ b/pkg/backend/init.go @@ -1,6 +1,10 @@ package backend import ( + "errors" + "os" + "time" + "github.com/rs/zerolog/log" "0xacab.org/leap/bitmask-vpn/pkg/bitmask" @@ -61,10 +65,15 @@ func initializeBitmask(errCh chan string, opts *InitOpts) { ctx.UseUDP = ctx.cfg.UDP err := pid.AcquirePID() - if err != nil { - log.Fatal(). + if err != nil && errors.Is(err, pid.AlreadyRunningErr) { + log.Error(). Err(err). Msg("Could not acquire PID") + errCh <- "alreadyrunning" + // would be better to quit the app from cpp land + // using go trigger(OnInitPidError) + time.Sleep(10 * time.Second) + os.Exit(1) } b, err := bitmask.InitializeBitmask(ctx.cfg) diff --git a/pkg/pid/pid.go b/pkg/pid/pid.go index 7f0e5c0e6da5a64d34f30d273405c4dcc13d8225..beec22accc6f385ae05ba0d15af2dbf485738276 100644 --- a/pkg/pid/pid.go +++ b/pkg/pid/pid.go @@ -16,6 +16,7 @@ package pid import ( + "errors" "fmt" "io/ioutil" "os" @@ -30,17 +31,20 @@ import ( "github.com/keybase/go-ps" ) -var pidFile = filepath.Join(config.Path, "systray.pid") +var ( + pidFile = filepath.Join(config.Path, "systray.pid") + AlreadyRunningErr = errors.New("another instance is already running") +) func AcquirePID() error { pid := syscall.Getpid() current, err := getPID() if err != nil { - log.Print("Error reading pid file:", err) + log.Err(err).Msg("Error reading pid file") } if current != pid && pidRunning(current) { - return fmt.Errorf("Another systray is running with pid: %d", current) + return fmt.Errorf("%w, pid: %d", AlreadyRunningErr, current) } return setPID(pid)