github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/testdata/testprog/syscalls_linux.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 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 // Open the magic proc status file for reading with the syscall package. 22 // We want to identify certain valid errors very precisely. 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 // Find the State line. 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 // Malformed status file? 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 // Malformed status file? 53 return false, false, fmt.Errorf("unexpected status file format: %s:\n%s", statusFile, status) 54 } 55 // Check if it's a zombie thread. 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 // Use the syscall to get the current working directory. 64 // This is imperative for checking for OS thread state 65 // after an unshare since os.Getwd might just check the 66 // environment, or use some other mechanism. 67 var buf [4096]byte 68 n, err := syscall.Getcwd(buf[:]) 69 if err != nil { 70 return "", err 71 } 72 // Subtract one for null terminator. 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 }