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] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
135
136 sa.raw.Path[0] = 0
137
138 sl--
139 }
140
141 return unsafe.Pointer(&sa.raw), sl, nil
142 }
143
144 func Getsockname(fd int) (sa Sockaddr, err error) {
145 var rsa RawSockaddrAny
146 var len _Socklen = SizeofSockaddrAny
147 if err = getsockname(fd, &rsa, &len); err != nil {
148 return
149 }
150 return anyToSockaddr(&rsa)
151 }
152
153 const ImplementsGetwd = true
154
155
156
157 func Getwd() (wd string, err error) {
158 var buf [PathMax]byte
159
160 _, err = Getcwd(buf[0:])
161 if err != nil {
162 return "", err
163 }
164 n := clen(buf[:])
165 if n < 1 {
166 return "", EINVAL
167 }
168 return string(buf[:n]), nil
169 }
170
171
174
175
176
177
178 func Getgroups() (gids []int, err error) {
179 n, err := getgroups(0, nil)
180 if err != nil {
181 return nil, err
182 }
183 if n == 0 {
184 return nil, nil
185 }
186
187
188 if n < 0 || n > 1000 {
189 return nil, EINVAL
190 }
191
192 a := make([]_Gid_t, n)
193 n, err = getgroups(n, &a[0])
194 if err != nil {
195 return nil, err
196 }
197 gids = make([]int, n)
198 for i, v := range a[0:n] {
199 gids[i] = int(v)
200 }
201 return
202 }
203
204 func Setgroups(gids []int) (err error) {
205 if len(gids) == 0 {
206 return setgroups(0, nil)
207 }
208
209 a := make([]_Gid_t, len(gids))
210 for i, v := range gids {
211 a[i] = _Gid_t(v)
212 }
213 return setgroups(len(a), &a[0])
214 }
215
216 func ReadDirent(fd int, buf []byte) (n int, err error) {
217
218
219 return Getdents(fd, buf, new(uintptr))
220 }
221
222
223
224
225
226
227
228 type WaitStatus uint32
229
230 const (
231 mask = 0x7F
232 core = 0x80
233 shift = 8
234
235 exited = 0
236 stopped = 0x7F
237 )
238
239 func (w WaitStatus) Exited() bool { return w&mask == exited }
240
241 func (w WaitStatus) ExitStatus() int {
242 if w&mask != exited {
243 return -1
244 }
245 return int(w >> shift)
246 }
247
248 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
249
250 func (w WaitStatus) Signal() Signal {
251 sig := Signal(w & mask)
252 if sig == stopped || sig == 0 {
253 return -1
254 }
255 return sig
256 }
257
258 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
259
260 func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
261
262 func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
263
264 func (w WaitStatus) StopSignal() Signal {
265 if !w.Stopped() {
266 return -1
267 }
268 return Signal(w>>shift) & 0xFF
269 }
270
271 func (w WaitStatus) TrapCause() int { return -1 }
272
273 func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr)
274
275 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
276 r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage)
277 if e1 != 0 {
278 err = Errno(e1)
279 }
280 return int(r0), err
281 }
282
283 func gethostname() (name string, err uintptr)
284
285 func Gethostname() (name string, err error) {
286 name, e1 := gethostname()
287 if e1 != 0 {
288 err = Errno(e1)
289 }
290 return name, err
291 }
292
293 func UtimesNano(path string, ts []Timespec) error {
294 if len(ts) != 2 {
295 return EINVAL
296 }
297 return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
298 }
299
300
301
302
303 func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
304 _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
305 if e1 != 0 {
306 return e1
307 }
308 return nil
309 }
310
311 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
312 switch rsa.Addr.Family {
313 case AF_UNIX:
314 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
315 sa := new(SockaddrUnix)
316
317
318
319
320
321 n := 0
322 for n < len(pp.Path) && pp.Path[n] != 0 {
323 n++
324 }
325 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
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 var mapper = &mmapper{
532 active: make(map[*byte][]byte),
533 mmap: mmap,
534 munmap: munmap,
535 }
536
537 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
538 return mapper.Mmap(fd, offset, length, prot, flags)
539 }
540
541 func Munmap(b []byte) (err error) {
542 return mapper.Munmap(b)
543 }
544
545 func Utimes(path string, tv []Timeval) error {
546 if len(tv) != 2 {
547 return EINVAL
548 }
549 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
550 }
551
View as plain text