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