Source file
src/os/exec/read3.go
Documentation: os/exec
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package main
15
16 import (
17 "fmt"
18 "internal/poll"
19 "io"
20 "os"
21 "os/exec"
22 "runtime"
23 "strings"
24 )
25
26 func main() {
27 fd3 := os.NewFile(3, "fd3")
28 bs, err := io.ReadAll(fd3)
29 if err != nil {
30 fmt.Printf("ReadAll from fd 3: %v\n", err)
31 os.Exit(1)
32 }
33
34
35
36
37
38
39
40
41 var files []*os.File
42 for wantfd := uintptr(4); wantfd <= 100; wantfd++ {
43 if poll.IsPollDescriptor(wantfd) {
44 continue
45 }
46 f, err := os.Open(os.Args[0])
47 if err != nil {
48 fmt.Printf("error opening file with expected fd %d: %v", wantfd, err)
49 os.Exit(1)
50 }
51 if got := f.Fd(); got != wantfd {
52 fmt.Printf("leaked parent file. fd = %d; want %d\n", got, wantfd)
53 fdfile := fmt.Sprintf("/proc/self/fd/%d", wantfd)
54 link, err := os.Readlink(fdfile)
55 fmt.Printf("readlink(%q) = %q, %v\n", fdfile, link, err)
56 var args []string
57 switch runtime.GOOS {
58 case "plan9":
59 args = []string{fmt.Sprintf("/proc/%d/fd", os.Getpid())}
60 case "aix", "solaris", "illumos":
61 args = []string{fmt.Sprint(os.Getpid())}
62 default:
63 args = []string{"-p", fmt.Sprint(os.Getpid())}
64 }
65
66
67 ofcmd := "lsof"
68 switch runtime.GOOS {
69 case "dragonfly", "freebsd", "netbsd", "openbsd":
70 ofcmd = "fstat"
71 case "plan9":
72 ofcmd = "/bin/cat"
73 case "aix":
74 ofcmd = "procfiles"
75 case "solaris", "illumos":
76 ofcmd = "pfiles"
77 }
78
79 cmd := exec.Command(ofcmd, args...)
80 out, err := cmd.CombinedOutput()
81 if err != nil {
82 fmt.Fprintf(os.Stderr, "%s failed: %v\n", strings.Join(cmd.Args, " "), err)
83 }
84 fmt.Printf("%s", out)
85 os.Exit(1)
86 }
87 files = append(files, f)
88 }
89
90 for _, f := range files {
91 f.Close()
92 }
93
94
95
96
97
98
99 fd3.Close()
100
101 os.Stdout.Write(bs)
102 }
103
View as plain text