Source file
src/syscall/syscall_plan9.go
1
2
3
4
5
6
7
8
9
10
11
12 package syscall
13
14 import (
15 "errors"
16 "internal/oserror"
17 "internal/strconv"
18 "runtime"
19 "unsafe"
20 )
21
22 const ImplementsGetwd = true
23 const bitSize16 = 2
24
25
26
27
28
29
30
31
32 type Errno uintptr
33
34 func (e Errno) Error() string { return "errno " + strconv.Itoa(int(e)) }
35 func (e Errno) Temporary() bool { return false }
36 func (e Errno) Timeout() bool { return false }
37
38
39
40
41
42
43
44
45 type ErrorString string
46
47 func (e ErrorString) Error() string { return string(e) }
48
49
50 func NewError(s string) error { return ErrorString(s) }
51
52 func (e ErrorString) Is(target error) bool {
53 switch target {
54 case oserror.ErrPermission:
55 return checkErrMessageContent(e, "permission denied")
56 case oserror.ErrExist:
57 return checkErrMessageContent(e, "exists", "is a directory")
58 case oserror.ErrNotExist:
59 return checkErrMessageContent(e, "does not exist", "not found",
60 "has been removed", "no parent")
61 case errors.ErrUnsupported:
62 return checkErrMessageContent(e, "not supported")
63 }
64 return false
65 }
66
67
68 func checkErrMessageContent(e ErrorString, msgs ...string) bool {
69 for _, msg := range msgs {
70 if contains(string(e), msg) {
71 return true
72 }
73 }
74 return false
75 }
76
77
78 func contains(s, sep string) bool {
79 n := len(sep)
80 c := sep[0]
81 for i := 0; i+n <= len(s); i++ {
82 if s[i] == c && s[i:i+n] == sep {
83 return true
84 }
85 }
86 return false
87 }
88
89 func (e ErrorString) Temporary() bool {
90 return e == EINTR || e == EMFILE || e.Timeout()
91 }
92
93 func (e ErrorString) Timeout() bool {
94 return e == EBUSY || e == ETIMEDOUT
95 }
96
97 var emptystring string
98
99
100
101 type Note string
102
103 func (n Note) Signal() {}
104
105 func (n Note) String() string {
106 return string(n)
107 }
108
109 var (
110 Stdin = 0
111 Stdout = 1
112 Stderr = 2
113 )
114
115
116
117 var SocketDisableIPv6 bool
118
119
120
121
122
123
124
125
126 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString)
127 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString)
128 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
129 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
130
131
132 func atoi(b []byte) (n uint) {
133 n = 0
134 for i := 0; i < len(b); i++ {
135 n = n*10 + uint(b[i]-'0')
136 }
137 return
138 }
139
140 func cstring(s []byte) string {
141 for i := range s {
142 if s[i] == 0 {
143 return string(s[0:i])
144 }
145 }
146 return string(s)
147 }
148
149 func errstr() string {
150 var buf [ERRMAX]byte
151
152 RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
153
154 buf[len(buf)-1] = 0
155 return cstring(buf[:])
156 }
157
158 func readnum(path string) (uint, error) {
159 var b [12]byte
160
161 fd, e := Open(path, O_RDONLY)
162 if e != nil {
163 return 0, e
164 }
165 defer Close(fd)
166
167 n, e := Pread(fd, b[:], 0)
168
169 if e != nil {
170 return 0, e
171 }
172
173 m := 0
174 for ; m < n && b[m] == ' '; m++ {
175 }
176
177 return atoi(b[m : n-1]), nil
178 }
179
180 func Getpid() (pid int) {
181 n, _ := readnum("#c/pid")
182 return int(n)
183 }
184
185 func Getppid() (ppid int) {
186 n, _ := readnum("#c/ppid")
187 return int(n)
188 }
189
190 func Read(fd int, p []byte) (n int, err error) {
191 return Pread(fd, p, -1)
192 }
193
194 func Write(fd int, p []byte) (n int, err error) {
195 if faketime && (fd == 1 || fd == 2) {
196 n = faketimeWrite(fd, p)
197 if n < 0 {
198 return 0, ErrorString("error")
199 }
200 return n, nil
201 }
202
203 return Pwrite(fd, p, -1)
204 }
205
206 var ioSync int64
207
208
209
210 func Fd2path(fd int) (path string, err error) {
211 var buf [512]byte
212
213 e := fd2path(fd, buf[:])
214 if e != nil {
215 return "", e
216 }
217 return cstring(buf[:]), nil
218 }
219
220
221
222 func Pipe(p []int) (err error) {
223 if len(p) != 2 {
224 return NewError("bad arg in system call")
225 }
226 var pp [2]int32
227 err = pipe(&pp)
228 if err == nil {
229 p[0] = int(pp[0])
230 p[1] = int(pp[1])
231 }
232 return
233 }
234
235
236
237
238
239
240
241 func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
242
243 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
244 newoffset, e := seek(0, fd, offset, whence)
245
246 if newoffset == -1 {
247 err = NewError(e)
248 }
249 return
250 }
251
252 func Mkdir(path string, mode uint32) (err error) {
253
254
255 statbuf := make([]byte, bitSize16)
256
257
258 n := len(path)
259 for n > 1 && path[n-1] == '/' {
260 n--
261 }
262 _, err = Stat(path[0:n], statbuf)
263 if err == nil {
264 return EEXIST
265 }
266
267 fd, err := Create(path, O_RDONLY, DMDIR|mode)
268
269 if fd != -1 {
270 Close(fd)
271 }
272
273 return
274 }
275
276 type Waitmsg struct {
277 Pid int
278 Time [3]uint32
279 Msg string
280 }
281
282 func (w Waitmsg) Exited() bool { return true }
283 func (w Waitmsg) Signaled() bool { return false }
284
285 func (w Waitmsg) ExitStatus() int {
286 if len(w.Msg) == 0 {
287
288 return 0
289 }
290 return 1
291 }
292
293
294
295 func Await(w *Waitmsg) (err error) {
296 var buf [512]byte
297 var f [5][]byte
298
299 n, err := await(buf[:])
300
301 if err != nil || w == nil {
302 return
303 }
304
305 nf := 0
306 p := 0
307 for i := 0; i < n && nf < len(f)-1; i++ {
308 if buf[i] == ' ' {
309 f[nf] = buf[p:i]
310 p = i + 1
311 nf++
312 }
313 }
314 f[nf] = buf[p:]
315 nf++
316
317 if nf != len(f) {
318 return NewError("invalid wait message")
319 }
320 w.Pid = int(atoi(f[0]))
321 w.Time[0] = uint32(atoi(f[1]))
322 w.Time[1] = uint32(atoi(f[2]))
323 w.Time[2] = uint32(atoi(f[3]))
324 w.Msg = cstring(f[4])
325 if w.Msg == "''" {
326
327 w.Msg = ""
328 }
329 return
330 }
331
332 func Unmount(name, old string) (err error) {
333 if fixwd(name, old) {
334 defer runtime.UnlockOSThread()
335 }
336 oldp, err := BytePtrFromString(old)
337 if err != nil {
338 return err
339 }
340 oldptr := uintptr(unsafe.Pointer(oldp))
341
342 var r0 uintptr
343 var e ErrorString
344
345
346 if name == "" {
347 r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
348 } else {
349 namep, err := BytePtrFromString(name)
350 if err != nil {
351 return err
352 }
353 r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
354 }
355
356 if int32(r0) == -1 {
357 err = e
358 }
359 return
360 }
361
362 func Fchdir(fd int) (err error) {
363 path, err := Fd2path(fd)
364
365 if err != nil {
366 return
367 }
368
369 return Chdir(path)
370 }
371
372 type Timespec struct {
373 Sec int32
374 Nsec int32
375 }
376
377 type Timeval struct {
378 Sec int32
379 Usec int32
380 }
381
382 func NsecToTimeval(nsec int64) (tv Timeval) {
383 nsec += 999
384 tv.Usec = int32(nsec % 1e9 / 1e3)
385 tv.Sec = int32(nsec / 1e9)
386 return
387 }
388
389 func nsec() int64 {
390 var scratch int64
391
392 r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)
393
394 if r0 == 0 {
395 return scratch
396 }
397 return int64(r0)
398 }
399
400 func Gettimeofday(tv *Timeval) error {
401 nsec := nsec()
402 *tv = NsecToTimeval(nsec)
403 return nil
404 }
405
406 func Getegid() (egid int) { return -1 }
407 func Geteuid() (euid int) { return -1 }
408 func Getgid() (gid int) { return -1 }
409 func Getuid() (uid int) { return -1 }
410
411 func Getgroups() (gids []int, err error) {
412 return make([]int, 0), nil
413 }
414
415
416
417 func Open(path string, mode int) (fd int, err error) {
418 if fixwd(path) {
419 defer runtime.UnlockOSThread()
420 }
421 return open(path, mode)
422 }
423
424
425
426 func Create(path string, mode int, perm uint32) (fd int, err error) {
427 if fixwd(path) {
428 defer runtime.UnlockOSThread()
429 }
430 return create(path, mode, perm)
431 }
432
433
434
435 func Remove(path string) error {
436 if fixwd(path) {
437 defer runtime.UnlockOSThread()
438 }
439 return remove(path)
440 }
441
442
443
444 func Stat(path string, edir []byte) (n int, err error) {
445 if fixwd(path) {
446 defer runtime.UnlockOSThread()
447 }
448 return stat(path, edir)
449 }
450
451
452
453 func Bind(name string, old string, flag int) (err error) {
454 if fixwd(name, old) {
455 defer runtime.UnlockOSThread()
456 }
457 return bind(name, old, flag)
458 }
459
460
461
462 func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
463 if fixwd(old) {
464 defer runtime.UnlockOSThread()
465 }
466 return mount(fd, afd, old, flag, aname)
467 }
468
469
470
471 func Wstat(path string, edir []byte) (err error) {
472 if fixwd(path) {
473 defer runtime.UnlockOSThread()
474 }
475 return wstat(path, edir)
476 }
477
478
479
480
481
482
483
484
485
View as plain text