diff options
author | kali kaneko (leap communications) <kali@leap.se> | 2020-06-12 19:05:59 +0200 |
---|---|---|
committer | kali kaneko (leap communications) <kali@leap.se> | 2020-06-12 20:03:03 +0200 |
commit | 1038fa83b820bbdaa9bcf37118cf23b0e48a86c5 (patch) | |
tree | d403cffa091932c1c46ea17fd15da588c1e5a7a2 /pkg/pid | |
parent | 971c28f6563de35b1d66401d6919f86787af0611 (diff) |
[refactor] reorganize modules
bitmaskd: so long and thanks for all the fish!
Signed-off-by: kali kaneko (leap communications) <kali@leap.se>
Diffstat (limited to 'pkg/pid')
-rw-r--r-- | pkg/pid/pid.go | 114 | ||||
-rw-r--r-- | pkg/pid/pid_test.go | 21 |
2 files changed, 135 insertions, 0 deletions
diff --git a/pkg/pid/pid.go b/pkg/pid/pid.go new file mode 100644 index 0000000..1124210 --- /dev/null +++ b/pkg/pid/pid.go @@ -0,0 +1,114 @@ +// Copyright (C) 2018-2020 LEAP +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package pid + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "path/filepath" + "strconv" + "strings" + "syscall" + + "0xacab.org/leap/bitmask-vpn/pkg/config" + "github.com/keybase/go-ps" +) + +var pidFile = filepath.Join(config.Path, "systray.pid") + +func AcquirePID() error { + pid := syscall.Getpid() + current, err := getPID() + if err != nil { + return err + } + + if current != pid && pidRunning(current) { + return fmt.Errorf("Another systray is running with pid: %d", current) + } + + return setPID(pid) +} + +func ReleasePID() error { + pid := syscall.Getpid() + current, err := getPID() + if err != nil { + return err + } + if current != 0 && current != pid { + return fmt.Errorf("Can't release pid file, is not own by this process") + } + + if current == pid { + return os.Remove(pidFile) + } + return nil +} + +func getPID() (int, error) { + _, err := os.Stat(pidFile) + if os.IsNotExist(err) { + return 0, nil + } + if err != nil { + return 0, err + } + + file, err := os.Open(pidFile) + if err != nil { + return 0, err + } + defer file.Close() + + b, err := ioutil.ReadAll(file) + if err != nil { + return 0, err + } + if len(b) == 0 { + return 0, nil + } + return strconv.Atoi(string(b)) +} + +func setPID(pid int) error { + file, err := os.Create(pidFile) + if err != nil { + return err + } + defer file.Close() + + _, err = file.WriteString(fmt.Sprintf("%d", pid)) + return err +} + +func pidRunning(pid int) bool { + if pid == 0 { + return false + } + proc, err := ps.FindProcess(pid) + if err != nil { + log.Printf("An error ocurred finding process: %v", err) + return false + } + if proc == nil { + return false + } + log.Printf("There is a running process with the pid %d and executable: %s", pid, proc.Executable()) + return strings.Contains(os.Args[0], proc.Executable()) +} diff --git a/pkg/pid/pid_test.go b/pkg/pid/pid_test.go new file mode 100644 index 0000000..dbc76f3 --- /dev/null +++ b/pkg/pid/pid_test.go @@ -0,0 +1,21 @@ +package pid + +import ( + "syscall" + "testing" +) + +const ( + invalidPid = 345678 +) + +func TestPidRunning(t *testing.T) { + pid := syscall.Getpid() + if !pidRunning(pid) { + t.Errorf("pid %v is not running", pid) + } + + if pidRunning(invalidPid) { + t.Errorf("pid %v is running", invalidPid) + } +} |