blob: 80e0e947be78e28730bf388eb9c74a2cd6a10105 [file] [log] [blame]
Abhay Kumara61c5222025-11-10 07:32:50 +00001// Copyright 2022 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package procfs
15
16import (
17 "fmt"
18 "os"
19 "strconv"
20
21 fsi "github.com/prometheus/procfs/internal/fs"
22)
23
24// Provide access to /proc/PID/task/TID files, for thread specific values. Since
25// such files have the same structure as /proc/PID/ ones, the data structures
26// and the parsers for the latter may be reused.
27
28// AllThreads returns a list of all currently available threads under /proc/PID.
29func AllThreads(pid int) (Procs, error) {
30 fs, err := NewFS(DefaultMountPoint)
31 if err != nil {
32 return Procs{}, err
33 }
34 return fs.AllThreads(pid)
35}
36
37// AllThreads returns a list of all currently available threads for PID.
38func (fs FS) AllThreads(pid int) (Procs, error) {
39 taskPath := fs.proc.Path(strconv.Itoa(pid), "task")
40 d, err := os.Open(taskPath)
41 if err != nil {
42 return Procs{}, err
43 }
44 defer d.Close()
45
46 names, err := d.Readdirnames(-1)
47 if err != nil {
48 return Procs{}, fmt.Errorf("%w: could not read %q: %w", ErrFileRead, d.Name(), err)
49 }
50
51 t := Procs{}
52 for _, n := range names {
53 tid, err := strconv.ParseInt(n, 10, 64)
54 if err != nil {
55 continue
56 }
57
58 t = append(t, Proc{PID: int(tid), fs: FS{fsi.FS(taskPath), fs.isReal}})
59 }
60
61 return t, nil
62}
63
64// Thread returns a process for a given PID, TID.
65func (fs FS) Thread(pid, tid int) (Proc, error) {
66 taskPath := fs.proc.Path(strconv.Itoa(pid), "task")
67 if _, err := os.Stat(taskPath); err != nil {
68 return Proc{}, err
69 }
70 return Proc{PID: tid, fs: FS{fsi.FS(taskPath), fs.isReal}}, nil
71}
72
73// Thread returns a process for a given TID of Proc.
74func (proc Proc) Thread(tid int) (Proc, error) {
75 tfs := FS{fsi.FS(proc.path("task")), proc.fs.isReal}
76 if _, err := os.Stat(tfs.proc.Path(strconv.Itoa(tid))); err != nil {
77 return Proc{}, err
78 }
79 return Proc{PID: tid, fs: tfs}, nil
80}