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