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