commit d54b6912f08c88f3768c165ab81dfd5adbc53210 Author: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Mon Nov 25 14:37:07 2024 +0200 initial commit: implement linux diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..038d105 --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +BSD 2-Clause License + +Copyright (c) 2024, mykola2312. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..8cd8af9 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/mykola2312/proc4unix + +go 1.23.2 diff --git a/linux_test.go b/linux_test.go new file mode 100644 index 0000000..d91eb73 --- /dev/null +++ b/linux_test.go @@ -0,0 +1,11 @@ +//go:build linux + +package proc + +import "testing" + +func TestQuery(t *testing.T) { + if _, err := Query(1); err != nil { + t.Failed() + } +} diff --git a/proc.go b/proc.go new file mode 100644 index 0000000..c3a6044 --- /dev/null +++ b/proc.go @@ -0,0 +1,16 @@ +package proc + +type ProcState int + +const ( + PROCSTATE_IDLE = 1 + PROCSTATE_STOP = 2 + PROCSTATE_RUN = 3 + PROCSTATE_UNDEAD = 4 + PROCSTATE_DEAD = 5 + PROCSTATE_LOST = 6 +) + +func Query(pid int) (ProcState, error) { + return queryInternal(pid) +} diff --git a/proc_linux.go b/proc_linux.go new file mode 100644 index 0000000..f58dda5 --- /dev/null +++ b/proc_linux.go @@ -0,0 +1,49 @@ +//go:build linux + +package proc + +import ( + "errors" + "fmt" + "os" + "strings" +) + +func queryInternal(pid int) (ProcState, error) { + status, err := os.ReadFile(fmt.Sprintf("/proc/%d/status", pid)) + if err != nil { + return 0, err + } + + for _, line := range strings.Split((string)(status), "\n") { + kv := strings.Fields(line) + if len(kv) < 2 { + continue + } + + if kv[0] == "State:" { + switch kv[1] { + case "D": + return PROCSTATE_IDLE, nil + case "I": + return PROCSTATE_IDLE, nil + case "R": + return PROCSTATE_RUN, nil + case "S": + return PROCSTATE_IDLE, nil + case "T": + return PROCSTATE_STOP, nil + case "t": + return PROCSTATE_STOP, nil + case "X": + return PROCSTATE_DEAD, nil + case "Z": + return PROCSTATE_LOST, nil + default: + return 0, errors.New("unknown linux state: " + kv[1]) + } + } + } + + return 0, errors.New("no state field in linux proc") +}