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 func Fd2path(fd int) (path string, err error) {
185 var buf [512]byte
186
187 e := fd2path(fd, buf[:])
188 if e != nil {
189 return "", e
190 }
191 return cstring(buf[:]), nil
192 }
193
194
195 func Pipe(p []int) (err error) {
196 if len(p) != 2 {
197 return NewError("bad arg in system call")
198 }
199 var pp [2]int32
200 err = pipe(&pp)
201 if err == nil {
202 p[0] = int(pp[0])
203 p[1] = int(pp[1])
204 }
205 return
206 }
207
208
209
210 func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
211
212 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
213 newoffset, e := seek(0, fd, offset, whence)
214
215 if newoffset == -1 {
216 err = NewError(e)
217 }
218 return
219 }
220
221 func Mkdir(path string, mode uint32) (err error) {
222
223
224 statbuf := make([]byte, bitSize16)
225
226
227 n := len(path)
228 for n > 1 && path[n-1] == '/' {
229 n--
230 }
231 _, err = Stat(path[0:n], statbuf)
232 if err == nil {
233 return EEXIST
234 }
235
236 fd, err := Create(path, O_RDONLY, DMDIR|mode)
237
238 if fd != -1 {
239 Close(fd)
240 }
241
242 return
243 }
244
245 type Waitmsg struct {
246 Pid int
247 Time [3]uint32
248 Msg string
249 }
250
251 func (w Waitmsg) Exited() bool { return true }
252 func (w Waitmsg) Signaled() bool { return false }
253
254 func (w Waitmsg) ExitStatus() int {
255 if len(w.Msg) == 0 {
256
257 return 0
258 }
259 return 1
260 }
261
262
263 func Await(w *Waitmsg) (err error) {
264 var buf [512]byte
265 var f [5][]byte
266
267 n, err := await(buf[:])
268
269 if err != nil || w == nil {
270 return
271 }
272
273 nf := 0
274 p := 0
275 for i := 0; i < n && nf < len(f)-1; i++ {
276 if buf[i] == ' ' {
277 f[nf] = buf[p:i]
278 p = i + 1
279 nf++
280 }
281 }
282 f[nf] = buf[p:]
283 nf++
284
285 if nf != len(f) {
286 return NewError("invalid wait message")
287 }
288 w.Pid = int(atoi(f[0]))
289 w.Time[0] = uint32(atoi(f[1]))
290 w.Time[1] = uint32(atoi(f[2]))
291 w.Time[2] = uint32(atoi(f[3]))
292 w.Msg = cstring(f[4])
293 if w.Msg == "''" {
294
295 w.Msg = ""
296 }
297 return
298 }
299
300 func Unmount(name, old string) (err error) {
301 fixwd(name, old)
302 oldp, err := BytePtrFromString(old)
303 if err != nil {
304 return err
305 }
306 oldptr := uintptr(unsafe.Pointer(oldp))
307
308 var r0 uintptr
309 var e ErrorString
310
311
312 if name == "" {
313 r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
314 } else {
315 namep, err := BytePtrFromString(name)
316 if err != nil {
317 return err
318 }
319 r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
320 }
321
322 if int32(r0) == -1 {
323 err = e
324 }
325 return
326 }
327
328 func Fchdir(fd int) (err error) {
329 path, err := Fd2path(fd)
330
331 if err != nil {
332 return
333 }
334
335 return Chdir(path)
336 }
337
338 type Timespec struct {
339 Sec int32
340 Nsec int32
341 }
342
343 type Timeval struct {
344 Sec int32
345 Usec int32
346 }
347
348 func NsecToTimeval(nsec int64) (tv Timeval) {
349 nsec += 999
350 tv.Usec = int32(nsec % 1e9 / 1e3)
351 tv.Sec = int32(nsec / 1e9)
352 return
353 }
354
355 func nsec() int64 {
356 var scratch int64
357
358 r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)
359
360 if r0 == 0 {
361 return scratch
362 }
363 return int64(r0)
364 }
365
366 func Gettimeofday(tv *Timeval) error {
367 nsec := nsec()
368 *tv = NsecToTimeval(nsec)
369 return nil
370 }
371
372 func Getegid() (egid int) { return -1 }
373 func Geteuid() (euid int) { return -1 }
374 func Getgid() (gid int) { return -1 }
375 func Getuid() (uid int) { return -1 }
376
377 func Getgroups() (gids []int, err error) {
378 return make([]int, 0), nil
379 }
380
381
382 func Open(path string, mode int) (fd int, err error) {
383 fixwd(path)
384 return open(path, mode)
385 }
386
387
388 func Create(path string, mode int, perm uint32) (fd int, err error) {
389 fixwd(path)
390 return create(path, mode, perm)
391 }
392
393
394 func Remove(path string) error {
395 fixwd(path)
396 return remove(path)
397 }
398
399
400 func Stat(path string, edir []byte) (n int, err error) {
401 fixwd(path)
402 return stat(path, edir)
403 }
404
405
406 func Bind(name string, old string, flag int) (err error) {
407 fixwd(name, old)
408 return bind(name, old, flag)
409 }
410
411
412 func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
413 fixwd(old)
414 return mount(fd, afd, old, flag, aname)
415 }
416
417
418 func Wstat(path string, edir []byte) (err error) {
419 fixwd(path)
420 return wstat(path, edir)
421 }
422
423
424
425
426
427
428
429
430
View as plain text