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