Source file src/syscall/syscall_bsd.go
1
2
3
4
5
6
7
8
9
10
11
12
13 package syscall
14
15 import (
16 "runtime"
17 "unsafe"
18 )
19
20
23
24
25
26
27 func Getgroups() (gids []int, err error) {
28 n, err := getgroups(0, nil)
29 if err != nil {
30 return nil, err
31 }
32 if n == 0 {
33 return nil, nil
34 }
35
36
37 if n < 0 || n > 1000 {
38 return nil, EINVAL
39 }
40
41 a := make([]_Gid_t, n)
42 n, err = getgroups(n, &a[0])
43 if err != nil {
44 return nil, err
45 }
46 gids = make([]int, n)
47 for i, v := range a[0:n] {
48 gids[i] = int(v)
49 }
50 return
51 }
52
53 func Setgroups(gids []int) (err error) {
54 if len(gids) == 0 {
55 return setgroups(0, nil)
56 }
57
58 a := make([]_Gid_t, len(gids))
59 for i, v := range gids {
60 a[i] = _Gid_t(v)
61 }
62 return setgroups(len(a), &a[0])
63 }
64
65 func ReadDirent(fd int, buf []byte) (n int, err error) {
66
67
68
69
70 var base = (*uintptr)(unsafe.Pointer(new(uint64)))
71 return Getdirentries(fd, buf, base)
72 }
73
74
75
76
77
78
79
80 type WaitStatus uint32
81
82 const (
83 mask = 0x7F
84 core = 0x80
85 shift = 8
86
87 exited = 0
88 stopped = 0x7F
89 )
90
91 func (w WaitStatus) Exited() bool { return w&mask == exited }
92
93 func (w WaitStatus) ExitStatus() int {
94 if w&mask != exited {
95 return -1
96 }
97 return int(w >> shift)
98 }
99
100 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
101
102 func (w WaitStatus) Signal() Signal {
103 sig := Signal(w & mask)
104 if sig == stopped || sig == 0 {
105 return -1
106 }
107 return sig
108 }
109
110 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
111
112 func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
113
114 func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
115
116 func (w WaitStatus) StopSignal() Signal {
117 if !w.Stopped() {
118 return -1
119 }
120 return Signal(w>>shift) & 0xFF
121 }
122
123 func (w WaitStatus) TrapCause() int { return -1 }
124
125
126
127 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
128 var status _C_int
129 wpid, err = wait4(pid, &status, options, rusage)
130 if wstatus != nil {
131 *wstatus = WaitStatus(status)
132 }
133 return
134 }
135
136
137
138
139
140
141
142
143
144
145
146 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
147 if sa.Port < 0 || sa.Port > 0xFFFF {
148 return nil, 0, EINVAL
149 }
150 sa.raw.Len = SizeofSockaddrInet4
151 sa.raw.Family = AF_INET
152 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
153 p[0] = byte(sa.Port >> 8)
154 p[1] = byte(sa.Port)
155 for i := 0; i < len(sa.Addr); i++ {
156 sa.raw.Addr[i] = sa.Addr[i]
157 }
158 return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
159 }
160
161 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
162 if sa.Port < 0 || sa.Port > 0xFFFF {
163 return nil, 0, EINVAL
164 }
165 sa.raw.Len = SizeofSockaddrInet6
166 sa.raw.Family = AF_INET6
167 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
168 p[0] = byte(sa.Port >> 8)
169 p[1] = byte(sa.Port)
170 sa.raw.Scope_id = sa.ZoneId
171 for i := 0; i < len(sa.Addr); i++ {
172 sa.raw.Addr[i] = sa.Addr[i]
173 }
174 return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
175 }
176
177 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
178 name := sa.Name
179 n := len(name)
180 if n >= len(sa.raw.Path) || n == 0 {
181 return nil, 0, EINVAL
182 }
183 sa.raw.Len = byte(3 + n)
184 sa.raw.Family = AF_UNIX
185 for i := 0; i < n; i++ {
186 sa.raw.Path[i] = int8(name[i])
187 }
188 return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
189 }
190
191 func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
192 if sa.Index == 0 {
193 return nil, 0, EINVAL
194 }
195 sa.raw.Len = sa.Len
196 sa.raw.Family = AF_LINK
197 sa.raw.Index = sa.Index
198 sa.raw.Type = sa.Type
199 sa.raw.Nlen = sa.Nlen
200 sa.raw.Alen = sa.Alen
201 sa.raw.Slen = sa.Slen
202 for i := 0; i < len(sa.raw.Data); i++ {
203 sa.raw.Data[i] = sa.Data[i]
204 }
205 return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
206 }
207
208 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
209 switch rsa.Addr.Family {
210 case AF_LINK:
211 pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
212 sa := new(SockaddrDatalink)
213 sa.Len = pp.Len
214 sa.Family = pp.Family
215 sa.Index = pp.Index
216 sa.Type = pp.Type
217 sa.Nlen = pp.Nlen
218 sa.Alen = pp.Alen
219 sa.Slen = pp.Slen
220 for i := 0; i < len(sa.Data); i++ {
221 sa.Data[i] = pp.Data[i]
222 }
223 return sa, nil
224
225 case AF_UNIX:
226 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
227 if pp.Len < 2 || pp.Len > SizeofSockaddrUnix {
228 return nil, EINVAL
229 }
230 sa := new(SockaddrUnix)
231
232
233
234
235
236 n := int(pp.Len) - 2
237 for i := 0; i < n; i++ {
238 if pp.Path[i] == 0 {
239
240
241 n = i
242 break
243 }
244 }
245 bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
246 sa.Name = string(bytes)
247 return sa, nil
248
249 case AF_INET:
250 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
251 sa := new(SockaddrInet4)
252 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
253 sa.Port = int(p[0])<<8 + int(p[1])
254 for i := 0; i < len(sa.Addr); i++ {
255 sa.Addr[i] = pp.Addr[i]
256 }
257 return sa, nil
258
259 case AF_INET6:
260 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
261 sa := new(SockaddrInet6)
262 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
263 sa.Port = int(p[0])<<8 + int(p[1])
264 sa.ZoneId = pp.Scope_id
265 for i := 0; i < len(sa.Addr); i++ {
266 sa.Addr[i] = pp.Addr[i]
267 }
268 return sa, nil
269 }
270 return nil, EAFNOSUPPORT
271 }
272
273 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
274 var rsa RawSockaddrAny
275 var len _Socklen = SizeofSockaddrAny
276 nfd, err = accept(fd, &rsa, &len)
277 if err != nil {
278 return
279 }
280 if runtime.GOOS == "darwin" && len == 0 {
281
282
283
284
285 Close(nfd)
286 return 0, nil, ECONNABORTED
287 }
288 sa, err = anyToSockaddr(&rsa)
289 if err != nil {
290 Close(nfd)
291 nfd = 0
292 }
293 return
294 }
295
296 func Getsockname(fd int) (sa Sockaddr, err error) {
297 var rsa RawSockaddrAny
298 var len _Socklen = SizeofSockaddrAny
299 if err = getsockname(fd, &rsa, &len); err != nil {
300 return
301 }
302
303
304 if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
305 rsa.Addr.Family = AF_UNIX
306 rsa.Addr.Len = SizeofSockaddrUnix
307 }
308 return anyToSockaddr(&rsa)
309 }
310
311
312
313 func GetsockoptByte(fd, level, opt int) (value byte, err error) {
314 var n byte
315 vallen := _Socklen(1)
316 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
317 return n, err
318 }
319
320 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
321 vallen := _Socklen(4)
322 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
323 return value, err
324 }
325
326 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
327 var value IPMreq
328 vallen := _Socklen(SizeofIPMreq)
329 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
330 return &value, err
331 }
332
333 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
334 var value IPv6Mreq
335 vallen := _Socklen(SizeofIPv6Mreq)
336 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
337 return &value, err
338 }
339
340 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
341 var value IPv6MTUInfo
342 vallen := _Socklen(SizeofIPv6MTUInfo)
343 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
344 return &value, err
345 }
346
347 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
348 var value ICMPv6Filter
349 vallen := _Socklen(SizeofICMPv6Filter)
350 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
351 return &value, err
352 }
353
354
355
356
357
358 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
359 var msg Msghdr
360 var rsa RawSockaddrAny
361 msg.Name = (*byte)(unsafe.Pointer(&rsa))
362 msg.Namelen = uint32(SizeofSockaddrAny)
363 var iov Iovec
364 if len(p) > 0 {
365 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
366 iov.SetLen(len(p))
367 }
368 var dummy byte
369 if len(oob) > 0 {
370
371 if len(p) == 0 {
372 iov.Base = &dummy
373 iov.SetLen(1)
374 }
375 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
376 msg.SetControllen(len(oob))
377 }
378 msg.Iov = &iov
379 msg.Iovlen = 1
380 if n, err = recvmsg(fd, &msg, flags); err != nil {
381 return
382 }
383 oobn = int(msg.Controllen)
384 recvflags = int(msg.Flags)
385
386 if rsa.Addr.Family != AF_UNSPEC {
387 from, err = anyToSockaddr(&rsa)
388 }
389 return
390 }
391
392
393
394 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
395 _, err = SendmsgN(fd, p, oob, to, flags)
396 return
397 }
398
399 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
400 var ptr unsafe.Pointer
401 var salen _Socklen
402 if to != nil {
403 ptr, salen, err = to.sockaddr()
404 if err != nil {
405 return 0, err
406 }
407 }
408 var msg Msghdr
409 msg.Name = (*byte)(unsafe.Pointer(ptr))
410 msg.Namelen = uint32(salen)
411 var iov Iovec
412 if len(p) > 0 {
413 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
414 iov.SetLen(len(p))
415 }
416 var dummy byte
417 if len(oob) > 0 {
418
419 if len(p) == 0 {
420 iov.Base = &dummy
421 iov.SetLen(1)
422 }
423 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
424 msg.SetControllen(len(oob))
425 }
426 msg.Iov = &iov
427 msg.Iovlen = 1
428 if n, err = sendmsg(fd, &msg, flags); err != nil {
429 return 0, err
430 }
431 if len(oob) > 0 && len(p) == 0 {
432 n = 0
433 }
434 return n, nil
435 }
436
437
438
439 func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {
440 var change, event unsafe.Pointer
441 if len(changes) > 0 {
442 change = unsafe.Pointer(&changes[0])
443 }
444 if len(events) > 0 {
445 event = unsafe.Pointer(&events[0])
446 }
447 return kevent(kq, change, len(changes), event, len(events), timeout)
448 }
449
450 func Sysctl(name string) (value string, err error) {
451
452 mib, err := nametomib(name)
453 if err != nil {
454 return "", err
455 }
456
457
458 n := uintptr(0)
459 if err = sysctl(mib, nil, &n, nil, 0); err != nil {
460 return "", err
461 }
462 if n == 0 {
463 return "", nil
464 }
465
466
467 buf := make([]byte, n)
468 if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
469 return "", err
470 }
471
472
473 if n > 0 && buf[n-1] == '\x00' {
474 n--
475 }
476 return string(buf[0:n]), nil
477 }
478
479 func SysctlUint32(name string) (value uint32, err error) {
480
481 mib, err := nametomib(name)
482 if err != nil {
483 return 0, err
484 }
485
486
487 n := uintptr(4)
488 buf := make([]byte, 4)
489 if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
490 return 0, err
491 }
492 if n != 4 {
493 return 0, EIO
494 }
495 return *(*uint32)(unsafe.Pointer(&buf[0])), nil
496 }
497
498
499
500 func Utimes(path string, tv []Timeval) (err error) {
501 if len(tv) != 2 {
502 return EINVAL
503 }
504 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
505 }
506
507 func UtimesNano(path string, ts []Timespec) error {
508 if len(ts) != 2 {
509 return EINVAL
510 }
511
512 err := setattrlistTimes(path, ts)
513 if err != ENOSYS {
514 return err
515 }
516 err = utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
517 if err != ENOSYS {
518 return err
519 }
520
521
522 tv := [2]Timeval{
523 NsecToTimeval(TimespecToNsec(ts[0])),
524 NsecToTimeval(TimespecToNsec(ts[1])),
525 }
526 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
527 }
528
529
530
531 func Futimes(fd int, tv []Timeval) (err error) {
532 if len(tv) != 2 {
533 return EINVAL
534 }
535 return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
536 }
537
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
View as plain text