1 package main
2
3 import (
4 "bytes"
5 "errors"
6 "fmt"
7 "io"
8 "io/fs"
9 "net"
10 "net/http"
11 "os"
12 "strconv"
13 "strings"
14 "sync"
15 "syscall"
16 "time"
17 )
18
19 func main() {
20 switch os.Args[1] {
21 case "ls":
22 var repeat bool
23 if len(os.Args) == 4 {
24 repeat = os.Args[3] == "repeat"
25 }
26
27
28 if err := mainLs(os.Args[2], repeat); errors.Is(err, syscall.EBADF) {
29 fmt.Println("ENOTDIR")
30 } else if err != nil {
31 panic(err)
32 }
33 case "stat":
34 if err := mainStat(); err != nil {
35 panic(err)
36 }
37 case "sock":
38 if err := mainSock(); err != nil {
39 panic(err)
40 }
41 case "nonblock":
42 if err := mainNonblock(os.Args[2], os.Args[3:]); err != nil {
43 panic(err)
44 }
45 }
46
47
48 switch os.Args[1] {
49 case "http":
50 if err := mainHTTP(); err != nil {
51 panic(err)
52 }
53 case "stdin":
54 if err := mainStdin(); err != nil {
55 panic(err)
56 }
57 case "stdout":
58 mainStdout()
59 case "largestdout":
60 mainLargeStdout()
61 }
62 }
63
64 func mainLs(path string, repeat bool) error {
65 d, err := os.Open(path)
66 if err != nil {
67 return err
68 }
69 defer d.Close()
70
71 if err = printFileNames(d); err != nil {
72 return err
73 } else if repeat {
74
75 if _, err = d.Seek(0, io.SeekStart); err != nil {
76 return err
77 }
78 return printFileNames(d)
79 }
80 return nil
81 }
82
83 func printFileNames(d *os.File) error {
84 if names, err := d.Readdirnames(-1); err != nil {
85 return err
86 } else {
87 for _, n := range names {
88 fmt.Println("./" + n)
89 }
90 }
91 return nil
92 }
93
94 func mainStat() error {
95 var isatty = func(name string, fd uintptr) error {
96 f := os.NewFile(fd, "")
97 if st, err := f.Stat(); err != nil {
98 return err
99 } else {
100 ttyMode := fs.ModeDevice | fs.ModeCharDevice
101 isatty := st.Mode()&ttyMode == ttyMode
102 fmt.Println(name, "isatty:", isatty)
103 return nil
104 }
105 }
106
107 for fd, name := range []string{"stdin", "stdout", "stderr", "/"} {
108 if err := isatty(name, uintptr(fd)); err != nil {
109 return err
110 }
111 }
112 return nil
113 }
114
115
116 func mainSock() error {
117
118
119 f := os.NewFile(3, "")
120 l, err := net.FileListener(f)
121 defer f.Close()
122 if err != nil {
123 return err
124 }
125 defer l.Close()
126
127
128 conn, err := l.Accept()
129 if err != nil {
130 return err
131 }
132 defer conn.Close()
133
134
135
136 var buf [32]byte
137 n, err := conn.Read(buf[:])
138 if err != nil {
139 return err
140 }
141 fmt.Println(string(buf[:n]))
142 return nil
143 }
144
145
146
147 func mainNonblock(mode string, files []string) error {
148 ready := make(chan struct{})
149
150 var wg sync.WaitGroup
151 for _, path := range files {
152 f, err := os.Open(path)
153 if err != nil {
154 return err
155 }
156 switch mode {
157 case "open":
158 case "create":
159 fd := f.Fd()
160 if err = syscall.SetNonblock(int(fd), true); err != nil {
161 return err
162 }
163 f = os.NewFile(fd, path)
164 default:
165 return fmt.Errorf("invalid test mode")
166 }
167
168 spawnWait := make(chan struct{})
169
170 wg.Add(1)
171 go func(f *os.File) {
172 defer f.Close()
173 defer wg.Done()
174
175
176 close(spawnWait)
177
178
179 <-ready
180
181 var buf [256]byte
182
183 if n, err := f.Read(buf[:]); err != nil {
184 panic(err)
185 } else {
186 os.Stderr.Write(buf[:n])
187 }
188 }(f)
189
190
191 <-spawnWait
192 }
193
194 println("waiting")
195 close(ready)
196 wg.Wait()
197 return nil
198 }
199
200
201
202 func mainHTTP() error {
203
204
205
206 listenerFD := 3
207 f := os.NewFile(uintptr(listenerFD), "")
208
209
210
211
212 if err := syscall.SetNonblock(listenerFD, true); err != nil {
213 return err
214 }
215
216
217
218 ln, err := net.FileListener(f)
219 defer f.Close()
220 if err != nil {
221 return err
222 }
223 defer ln.Close()
224
225
226 h := &echoOnce{ch: make(chan struct{}, 1)}
227 go http.Serve(ln, h)
228 <-h.ch
229 return nil
230 }
231
232 type echoOnce struct {
233 ch chan struct{}
234 }
235
236 func (e echoOnce) ServeHTTP(w http.ResponseWriter, r *http.Request) {
237
238
239 var buf [32]byte
240 if n, err := r.Body.Read(buf[:]); err != nil && err != io.EOF {
241 panic(err)
242 } else if n, err = w.Write(append(buf[:n], '\n')); err != nil {
243 panic(err)
244 }
245
246 close(e.ch)
247 }
248
249
250 func mainStdin() error {
251 go func() {
252 time.Sleep(1 * time.Second)
253 os.Stdout.WriteString("waiting for stdin...\n")
254 }()
255
256 b, err := io.ReadAll(os.Stdin)
257 if err != nil {
258 return err
259 }
260 os.Stdout.Write(b)
261 return nil
262 }
263
264 func mainStdout() {
265 os.Stdout.WriteString("test")
266 }
267
268 func mainLargeStdout() {
269 const ntest = 1024
270
271 var decls, calls bytes.Buffer
272
273 for i := 1; i <= ntest; i++ {
274 s := strconv.Itoa(i)
275 decls.WriteString(strings.Replace(decl, "$", s, -1))
276 calls.WriteString(strings.Replace("call(test$)\n\t", "$", s, -1))
277 }
278
279 program = strings.Replace(program, "$DECLS", decls.String(), 1)
280 program = strings.Replace(program, "$CALLS", calls.String(), 1)
281 fmt.Print(program)
282 }
283
284 var program = `package main
285
286 var count int
287
288 func call(f func() bool) {
289 if f() {
290 count++
291 }
292 }
293
294 $DECLS
295
296 func main() {
297 $CALLS
298 if count != 0 {
299 println("failed", count, "case(s)")
300 }
301 }
302 `
303
304 const decl = `
305 type T$ [$]uint8
306 func test$() bool {
307 v := T${1}
308 return v == [$]uint8{2} || v != [$]uint8{1}
309 }`
310
View as plain text