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