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 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
325 sa.Name = string(bytes)
326 return sa, nil
327
328 case AF_INET:
329 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
330 sa := new(SockaddrInet4)
331 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
332 sa.Port = int(p[0])<<8 + int(p[1])
333 sa.Addr = pp.Addr
334 return sa, nil
335
336 case AF_INET6:
337 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
338 sa := new(SockaddrInet6)
339 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
340 sa.Port = int(p[0])<<8 + int(p[1])
341 sa.ZoneId = pp.Scope_id
342 sa.Addr = pp.Addr
343 return sa, nil
344 }
345 return nil, EAFNOSUPPORT
346 }
347
348
349
350 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
351 var rsa RawSockaddrAny
352 var len _Socklen = SizeofSockaddrAny
353 nfd, err = accept(fd, &rsa, &len)
354 if err != nil {
355 return
356 }
357 sa, err = anyToSockaddr(&rsa)
358 if err != nil {
359 Close(nfd)
360 nfd = 0
361 }
362 return
363 }
364
365 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
366 var msg Msghdr
367 msg.Name = (*byte)(unsafe.Pointer(rsa))
368 msg.Namelen = uint32(SizeofSockaddrAny)
369 var iov Iovec
370 if len(p) > 0 {
371 iov.Base = (*int8)(unsafe.Pointer(&p[0]))
372 iov.SetLen(len(p))
373 }
374 var dummy int8
375 if len(oob) > 0 {
376
377 if len(p) == 0 {
378 iov.Base = &dummy
379 iov.SetLen(1)
380 }
381 msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
382 msg.Accrightslen = int32(len(oob))
383 }
384 msg.Iov = &iov
385 msg.Iovlen = 1
386 if n, err = recvmsg(fd, &msg, flags); err != nil {
387 return
388 }
389 oobn = int(msg.Accrightslen)
390 return
391 }
392
393
394
395 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
396 var msg Msghdr
397 msg.Name = (*byte)(unsafe.Pointer(ptr))
398 msg.Namelen = uint32(salen)
399 var iov Iovec
400 if len(p) > 0 {
401 iov.Base = (*int8)(unsafe.Pointer(&p[0]))
402 iov.SetLen(len(p))
403 }
404 var dummy int8
405 if len(oob) > 0 {
406
407 if len(p) == 0 {
408 iov.Base = &dummy
409 iov.SetLen(1)
410 }
411 msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
412 msg.Accrightslen = int32(len(oob))
413 }
414 msg.Iov = &iov
415 msg.Iovlen = 1
416 if n, err = sendmsg(fd, &msg, flags); err != nil {
417 return 0, err
418 }
419 if len(oob) > 0 && len(p) == 0 {
420 n = 0
421 }
422 return n, nil
423 }
424
425
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
508 func Getexecname() (path string, err error) {
509 ptr, err := getexecname()
510 if err != nil {
511 return "", err
512 }
513 bytes := (*[1 << 29]byte)(ptr)[:]
514 for i, b := range bytes {
515 if b == 0 {
516 return string(bytes[:i]), nil
517 }
518 }
519 panic("unreachable")
520 }
521
522 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
523 r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
524 n = int(r0)
525 if e1 != 0 {
526 err = e1
527 }
528 return
529 }
530
531 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
532 r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_write)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
533 n = int(r0)
534 if e1 != 0 {
535 err = e1
536 }
537 return
538 }
539
540 var mapper = &mmapper{
541 active: make(map[*byte][]byte),
542 mmap: mmap,
543 munmap: munmap,
544 }
545
546 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
547 return mapper.Mmap(fd, offset, length, prot, flags)
548 }
549
550 func Munmap(b []byte) (err error) {
551 return mapper.Munmap(b)
552 }
553
554 func Utimes(path string, tv []Timeval) error {
555 if len(tv) != 2 {
556 return EINVAL
557 }
558 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
559 }
560
View as plain text