1
2
3
4
5 package main
6
7 import (
8 "bytes"
9 "fmt"
10 "internal/testenv"
11 "io"
12 "os"
13 "syscall"
14 )
15
16 func gettid() int {
17 return syscall.Gettid()
18 }
19
20 func tidExists(tid int) (exists, supported bool, err error) {
21
22
23 statusFile := fmt.Sprintf("/proc/self/task/%d/status", tid)
24 fd, err := syscall.Open(statusFile, syscall.O_RDONLY, 0)
25 if errno, ok := err.(syscall.Errno); ok {
26 if errno == syscall.ENOENT || errno == syscall.ESRCH {
27 return false, true, nil
28 }
29 }
30 if err != nil {
31 return false, false, err
32 }
33 status, err := io.ReadAll(os.NewFile(uintptr(fd), statusFile))
34 if err != nil {
35 return false, false, err
36 }
37 lines := bytes.Split(status, []byte{'\n'})
38
39 stateLineIdx := -1
40 for i, line := range lines {
41 if bytes.HasPrefix(line, []byte("State:")) {
42 stateLineIdx = i
43 break
44 }
45 }
46 if stateLineIdx < 0 {
47
48 return false, false, fmt.Errorf("unexpected status file format: %s:\n%s", statusFile, status)
49 }
50 stateLine := bytes.SplitN(lines[stateLineIdx], []byte{':'}, 2)
51 if len(stateLine) != 2 {
52
53 return false, false, fmt.Errorf("unexpected status file format: %s:\n%s", statusFile, status)
54 }
55
56 return !bytes.Contains(stateLine[1], []byte{'Z'}), true, nil
57 }
58
59 func getcwd() (string, error) {
60 if !syscall.ImplementsGetwd {
61 return "", nil
62 }
63
64
65
66
67 var buf [4096]byte
68 n, err := syscall.Getcwd(buf[:])
69 if err != nil {
70 return "", err
71 }
72
73 return string(buf[:n-1]), nil
74 }
75
76 func unshareFs() error {
77 err := syscall.Unshare(syscall.CLONE_FS)
78 if testenv.SyscallIsNotSupported(err) {
79 return errNotPermitted
80 }
81 return err
82 }
83
84 func chdir(path string) error {
85 return syscall.Chdir(path)
86 }
87
View as plain text