Source file
src/syscall/syscall_solaris.go
1
2
3
4
5
6
7
8
9
10
11
12
13 package syscall
14
15 import "unsafe"
16
17 const _F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
18
19 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
20 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
21 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
22 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
23
24
25 func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
26 func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
27
28 type SockaddrDatalink struct {
29 Family uint16
30 Index uint16
31 Type uint8
32 Nlen uint8
33 Alen uint8
34 Slen uint8
35 Data [244]int8
36 raw RawSockaddrDatalink
37 }
38
39 func direntIno(buf []byte) (uint64, bool) {
40 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
41 }
42
43 func direntReclen(buf []byte) (uint64, bool) {
44 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
45 }
46
47 func direntNamlen(buf []byte) (uint64, bool) {
48 reclen, ok := direntReclen(buf)
49 if !ok {
50 return 0, false
51 }
52 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
53 }
54
55 func Pipe(p []int) (err error) {
56 return Pipe2(p, 0)
57 }
58
59
60
61 func Pipe2(p []int, flags int) error {
62 if len(p) != 2 {
63 return EINVAL
64 }
65 var pp [2]_C_int
66 err := pipe2(&pp, flags)
67 if err == nil {
68 p[0] = int(pp[0])
69 p[1] = int(pp[1])
70 }
71 return err
72 }
73
74
75
76 func Accept4(fd int, flags int) (int, Sockaddr, error) {
77 var rsa RawSockaddrAny
78 var addrlen _Socklen = SizeofSockaddrAny
79 nfd, err := accept4(fd, &rsa, &addrlen, flags)
80 if err != nil {
81 return 0, nil, err
82 }
83 if addrlen > SizeofSockaddrAny {
84 panic("RawSockaddrAny too small")
85 }
86 sa, err := anyToSockaddr(&rsa)
87 if err != nil {
88 Close(nfd)
89 return 0, nil, err
90 }
91 return nfd, sa, nil
92 }
93
94 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
95 if sa.Port < 0 || sa.Port > 0xFFFF {
96 return nil, 0, EINVAL
97 }
98 sa.raw.Family = AF_INET
99 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
100 p[0] = byte(sa.Port >> 8)
101 p[1] = byte(sa.Port)
102 sa.raw.Addr = sa.Addr
103 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
104 }
105
106 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
107 if sa.Port < 0 || sa.Port > 0xFFFF {
108 return nil, 0, EINVAL
109 }
110 sa.raw.Family = AF_INET6
111 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
112 p[0] = byte(sa.Port >> 8)
113 p[1] = byte(sa.Port)
114 sa.raw.Scope_id = sa.ZoneId
115 sa.raw.Addr = sa.Addr
116 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
117 }
118
119 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
120 name := sa.Name
121 n := len(name)
122 if n >= len(sa.raw.Path) {
123 return nil, 0, EINVAL
124 }
125 sa.raw.Family = AF_UNIX
126 for i := 0; i < n; i++ {
127 sa.raw.Path[i] = int8(name[i])
128 }
129
130 sl := _Socklen(2)
131 if n > 0 {
132 sl += _Socklen(n) + 1
133 }
134 if sa.raw.Path[0] == '@' {
135 sa.raw.Path[0] = 0
136
137 sl--
138 }
139
140 return unsafe.Pointer(&sa.raw), sl, nil
141 }
142
143 func Getsockname(fd int) (sa Sockaddr, err error) {
144 var rsa RawSockaddrAny
145 var len _Socklen = SizeofSockaddrAny
146 if err = getsockname(fd, &rsa, &len); err != nil {
147 return
148 }
149 return anyToSockaddr(&rsa)
150 }
151
152 const ImplementsGetwd = true
153
154
155
156 func Getwd() (wd string, err error) {
157 var buf [PathMax]byte
158
159 _, err = Getcwd(buf[0:])
160 if err != nil {
161 return "", err
162 }
163 n := clen(buf[:])
164 if n < 1 {
165 return "", EINVAL
166 }
167 return string(buf[:n]), nil
168 }
169
170
173
174
175
176
177 func Getgroups() (gids []int, err error) {
178 n, err := getgroups(0, nil)
179 if err != nil {
180 return nil, err
181 }
182 if n == 0 {
183 return nil, nil
184 }
185
186
187 if n < 0 || n > 1000 {
188 return nil, EINVAL
189 }
190
191 a := make([]_Gid_t, n)
192 n, err = getgroups(n, &a[0])
193 if err != nil {
194 return nil, err
195 }
196 gids = make([]int, n)
197 for i, v := range a[0:n] {
198 gids[i] = int(v)
199 }
200 return
201 }
202
203 func Setgroups(gids []int) (err error) {
204 if len(gids) == 0 {
205 return setgroups(0, nil)
206 }
207
208 a := make([]_Gid_t, len(gids))
209 for i, v := range gids {
210 a[i] = _Gid_t(v)
211 }
212 return setgroups(len(a), &a[0])
213 }
214
215 func ReadDirent(fd int, buf []byte) (n int, err error) {
216
217
218 return Getdents(fd, buf, new(uintptr))
219 }
220
221
222
223
224
225
226
227 type WaitStatus uint32
228
229 const (
230 mask = 0x7F
231 core = 0x80
232 shift = 8
233
234 exited = 0
235 stopped = 0x7F
236 )
237
238 func (w WaitStatus) Exited() bool { return w&mask == exited }
239
240 func (w WaitStatus) ExitStatus() int {
241 if w&mask != exited {
242 return -1
243 }
244 return int(w >> shift)
245 }
246
247 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
248
249 func (w WaitStatus) Signal() Signal {
250 sig := Signal(w & mask)
251 if sig == stopped || sig == 0 {
252 return -1
253 }
254 return sig
255 }
256
257 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
258
259 func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
260
261 func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
262
263 func (w WaitStatus) StopSignal() Signal {
264 if !w.Stopped() {
265 return -1
266 }
267 return Signal(w>>shift) & 0xFF
268 }
269
270 func (w WaitStatus) TrapCause() int { return -1 }
271
272 func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr)
273
274 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
275 r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage)
276 if e1 != 0 {
277 err = Errno(e1)
278 }
279 return int(r0), err
280 }
281
282 func gethostname() (name string, err uintptr)
283
284 func Gethostname() (name string, err error) {
285 name, e1 := gethostname()
286 if e1 != 0 {
287 err = Errno(e1)
288 }
289 return name, err
290 }
291
292 func UtimesNano(path string, ts []Timespec) error {
293 if len(ts) != 2 {
294 return EINVAL
295 }
296 return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
297 }
298
299
300
301
302 func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
303 _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
304 if e1 != 0 {
305 return e1
306 }
307 return nil
308 }
309
310 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
311 switch rsa.Addr.Family {
312 case AF_UNIX:
313 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
314 sa := new(SockaddrUnix)
315
316
317
318
319
320 n := 0
321 for n < len(pp.Path) && pp.Path[n] != 0 {
322 n++
323 }
324 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
325 return sa, nil
326
327 case AF_INET:
328 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
329 sa := new(SockaddrInet4)
330 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
331 sa.Port = int(p[0])<<8 + int(p[1])
332 sa.Addr = pp.Addr
333 return sa, nil
334
335 case AF_INET6:
336 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
337 sa := new(SockaddrInet6)
338 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
339 sa.Port = int(p[0])<<8 + int(p[1])
340 sa.ZoneId = pp.Scope_id
341 sa.Addr = pp.Addr
342 return sa, nil
343 }
344 return nil, EAFNOSUPPORT
345 }
346
347
348
349 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
350 var rsa RawSockaddrAny
351 var len _Socklen = SizeofSockaddrAny
352 nfd, err = accept(fd, &rsa, &len)
353 if err != nil {
354 return
355 }
356 sa, err = anyToSockaddr(&rsa)
357 if err != nil {
358 Close(nfd)
359 nfd = 0
360 }
361 return
362 }
363
364 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
365 var msg Msghdr
366 msg.Name = (*byte)(unsafe.Pointer(rsa))
367 msg.Namelen = uint32(SizeofSockaddrAny)
368 var iov Iovec
369 if len(p) > 0 {
370 iov.Base = (*int8)(unsafe.Pointer(&p[0]))
371 iov.SetLen(len(p))
372 }
373 var dummy int8
374 if len(oob) > 0 {
375
376 if len(p) == 0 {
377 iov.Base = &dummy
378 iov.SetLen(1)
379 }
380 msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
381 msg.Accrightslen = int32(len(oob))
382 }
383 msg.Iov = &iov
384 msg.Iovlen = 1
385 if n, err = recvmsg(fd, &msg, flags); err != nil {
386 return
387 }
388 oobn = int(msg.Accrightslen)
389 return
390 }
391
392
393
394 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
395 var msg Msghdr
396 msg.Name = (*byte)(unsafe.Pointer(ptr))
397 msg.Namelen = uint32(salen)
398 var iov Iovec
399 if len(p) > 0 {
400 iov.Base = (*int8)(unsafe.Pointer(&p[0]))
401 iov.SetLen(len(p))
402 }
403 var dummy int8
404 if len(oob) > 0 {
405
406 if len(p) == 0 {
407 iov.Base = &dummy
408 iov.SetLen(1)
409 }
410 msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
411 msg.Accrightslen = int32(len(oob))
412 }
413 msg.Iov = &iov
414 msg.Iovlen = 1
415 if n, err = sendmsg(fd, &msg, flags); err != nil {
416 return 0, err
417 }
418 if len(oob) > 0 && len(p) == 0 {
419 n = 0
420 }
421 return n, nil
422 }
423
424
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507 func Getexecname() (path string, err error) {
508 ptr, err := getexecname()
509 if err != nil {
510 return "", err
511 }
512 bytes := (*[1 << 29]byte)(ptr)[:]
513 for i, b := range bytes {
514 if b == 0 {
515 return string(bytes[:i]), nil
516 }
517 }
518 panic("unreachable")
519 }
520
521 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
522 r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
523 n = int(r0)
524 if e1 != 0 {
525 err = e1
526 }
527 return
528 }
529
530 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
531 r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_write)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
532 n = int(r0)
533 if e1 != 0 {
534 err = e1
535 }
536 return
537 }
538
539 var mapper = &mmapper{
540 active: make(map[*byte][]byte),
541 mmap: mmap,
542 munmap: munmap,
543 }
544
545 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
546 return mapper.Mmap(fd, offset, length, prot, flags)
547 }
548
549 func Munmap(b []byte) (err error) {
550 return mapper.Munmap(b)
551 }
552
553 func Utimes(path string, tv []Timeval) error {
554 if len(tv) != 2 {
555 return EINVAL
556 }
557 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
558 }
559
View as plain text