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