1
2
3
4
5
6
7
8
9
10
11
12
13 package unix
14
15 import (
16 "fmt"
17 "syscall"
18 "unsafe"
19 )
20
21
22
23
24 func fdopendir(fd int) (dir uintptr, err error) {
25 r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
26 dir = uintptr(r0)
27 if e1 != 0 {
28 err = errnoErr(e1)
29 }
30 return
31 }
32
33 var libc_fdopendir_trampoline_addr uintptr
34
35
36
37 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
38
39
40
41
42
43
44
45 skip, err := Seek(fd, 0, 1 )
46 if err != nil {
47 return 0, err
48 }
49
50
51
52
53
54
55
56 fd2, err := Openat(fd, ".", O_RDONLY, 0)
57 if err != nil {
58 return 0, err
59 }
60 d, err := fdopendir(fd2)
61 if err != nil {
62 Close(fd2)
63 return 0, err
64 }
65 defer closedir(d)
66
67 var cnt int64
68 for {
69 var entry Dirent
70 var entryp *Dirent
71 e := readdir_r(d, &entry, &entryp)
72 if e != 0 {
73 return n, errnoErr(e)
74 }
75 if entryp == nil {
76 break
77 }
78 if skip > 0 {
79 skip--
80 cnt++
81 continue
82 }
83
84 reclen := int(entry.Reclen)
85 if reclen > len(buf) {
86
87
88
89
90 break
91 }
92
93
94 s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
95 copy(buf, s)
96
97 buf = buf[reclen:]
98 n += reclen
99 cnt++
100 }
101
102
103 _, err = Seek(fd, cnt, 0 )
104 if err != nil {
105 return n, err
106 }
107
108 return n, nil
109 }
110
111
112 type SockaddrDatalink struct {
113 Len uint8
114 Family uint8
115 Index uint16
116 Type uint8
117 Nlen uint8
118 Alen uint8
119 Slen uint8
120 Data [12]int8
121 raw RawSockaddrDatalink
122 }
123
124
125 type SockaddrCtl struct {
126 ID uint32
127 Unit uint32
128 raw RawSockaddrCtl
129 }
130
131 func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {
132 sa.raw.Sc_len = SizeofSockaddrCtl
133 sa.raw.Sc_family = AF_SYSTEM
134 sa.raw.Ss_sysaddr = AF_SYS_CONTROL
135 sa.raw.Sc_id = sa.ID
136 sa.raw.Sc_unit = sa.Unit
137 return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
138 }
139
140
141
142
143
144 type SockaddrVM struct {
145
146
147
148
149
150 CID uint32
151 Port uint32
152 raw RawSockaddrVM
153 }
154
155 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
156 sa.raw.Len = SizeofSockaddrVM
157 sa.raw.Family = AF_VSOCK
158 sa.raw.Port = sa.Port
159 sa.raw.Cid = sa.CID
160
161 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
162 }
163
164 func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
165 switch rsa.Addr.Family {
166 case AF_SYSTEM:
167 pp := (*RawSockaddrCtl)(unsafe.Pointer(rsa))
168 if pp.Ss_sysaddr == AF_SYS_CONTROL {
169 sa := new(SockaddrCtl)
170 sa.ID = pp.Sc_id
171 sa.Unit = pp.Sc_unit
172 return sa, nil
173 }
174 case AF_VSOCK:
175 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
176 sa := &SockaddrVM{
177 CID: pp.Cid,
178 Port: pp.Port,
179 }
180 return sa, nil
181 }
182 return nil, EAFNOSUPPORT
183 }
184
185
186
187
188 const SYS___SYSCTL = SYS_SYSCTL
189
190
191 func nametomib(name string) (mib []_C_int, err error) {
192 const siz = unsafe.Sizeof(mib[0])
193
194
195
196
197
198
199
200
201 var buf [CTL_MAXNAME + 2]_C_int
202 n := uintptr(CTL_MAXNAME) * siz
203
204 p := (*byte)(unsafe.Pointer(&buf[0]))
205 bytes, err := ByteSliceFromString(name)
206 if err != nil {
207 return nil, err
208 }
209
210
211
212 if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
213 return nil, err
214 }
215 return buf[0 : n/siz], nil
216 }
217
218 func direntIno(buf []byte) (uint64, bool) {
219 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
220 }
221
222 func direntReclen(buf []byte) (uint64, bool) {
223 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
224 }
225
226 func direntNamlen(buf []byte) (uint64, bool) {
227 return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
228 }
229
230 func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
231 func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
232 func PtraceDenyAttach() (err error) { return ptrace(PT_DENY_ATTACH, 0, 0, 0) }
233
234
235
236 func Pipe(p []int) (err error) {
237 if len(p) != 2 {
238 return EINVAL
239 }
240 var x [2]int32
241 err = pipe(&x)
242 if err == nil {
243 p[0] = int(x[0])
244 p[1] = int(x[1])
245 }
246 return
247 }
248
249 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
250 var _p0 unsafe.Pointer
251 var bufsize uintptr
252 if len(buf) > 0 {
253 _p0 = unsafe.Pointer(&buf[0])
254 bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
255 }
256 return getfsstat(_p0, bufsize, flags)
257 }
258
259 func xattrPointer(dest []byte) *byte {
260
261
262
263
264
265 var destp *byte
266 if len(dest) > 0 {
267 destp = &dest[0]
268 }
269 return destp
270 }
271
272
273
274 func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
275 return getxattr(path, attr, xattrPointer(dest), len(dest), 0, 0)
276 }
277
278 func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
279 return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW)
280 }
281
282
283
284 func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
285 return fgetxattr(fd, attr, xattrPointer(dest), len(dest), 0, 0)
286 }
287
288
289
290 func Setxattr(path string, attr string, data []byte, flags int) (err error) {
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317 return setxattr(path, attr, xattrPointer(data), len(data), 0, flags)
318 }
319
320 func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
321 return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW)
322 }
323
324
325
326 func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
327 return fsetxattr(fd, attr, xattrPointer(data), len(data), 0, 0)
328 }
329
330
331
332 func Removexattr(path string, attr string) (err error) {
333
334
335
336 return removexattr(path, attr, 0)
337 }
338
339 func Lremovexattr(link string, attr string) (err error) {
340 return removexattr(link, attr, XATTR_NOFOLLOW)
341 }
342
343
344
345 func Fremovexattr(fd int, attr string) (err error) {
346 return fremovexattr(fd, attr, 0)
347 }
348
349
350
351 func Listxattr(path string, dest []byte) (sz int, err error) {
352 return listxattr(path, xattrPointer(dest), len(dest), 0)
353 }
354
355 func Llistxattr(link string, dest []byte) (sz int, err error) {
356 return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW)
357 }
358
359
360
361 func Flistxattr(fd int, dest []byte) (sz int, err error) {
362 return flistxattr(fd, xattrPointer(dest), len(dest), 0)
363 }
364
365
366
367
370
371
372
373
374
375 func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
376
377
378
379
380 func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error {
381 return ioctlPtr(fd, CTLIOCGINFO, unsafe.Pointer(ctlInfo))
382 }
383
384
385 type IfreqMTU struct {
386 Name [IFNAMSIZ]byte
387 MTU int32
388 }
389
390
391
392 func IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) {
393 var ifreq IfreqMTU
394 copy(ifreq.Name[:], ifname)
395 err := ioctlPtr(fd, SIOCGIFMTU, unsafe.Pointer(&ifreq))
396 return &ifreq, err
397 }
398
399
400
401 func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error {
402 return ioctlPtr(fd, SIOCSIFMTU, unsafe.Pointer(ifreq))
403 }
404
405
406
407 func RenamexNp(from string, to string, flag uint32) (err error) {
408 return renamexNp(from, to, flag)
409 }
410
411
412
413 func RenameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) {
414 return renameatxNp(fromfd, from, tofd, to, flag)
415 }
416
417
418
419 func Uname(uname *Utsname) error {
420 mib := []_C_int{CTL_KERN, KERN_OSTYPE}
421 n := unsafe.Sizeof(uname.Sysname)
422 if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
423 return err
424 }
425
426 mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
427 n = unsafe.Sizeof(uname.Nodename)
428 if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
429 return err
430 }
431
432 mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
433 n = unsafe.Sizeof(uname.Release)
434 if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
435 return err
436 }
437
438 mib = []_C_int{CTL_KERN, KERN_VERSION}
439 n = unsafe.Sizeof(uname.Version)
440 if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
441 return err
442 }
443
444
445
446 for i, b := range uname.Version {
447 if b == '\n' || b == '\t' {
448 if i == len(uname.Version)-1 {
449 uname.Version[i] = 0
450 } else {
451 uname.Version[i] = ' '
452 }
453 }
454 }
455
456 mib = []_C_int{CTL_HW, HW_MACHINE}
457 n = unsafe.Sizeof(uname.Machine)
458 if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
459 return err
460 }
461
462 return nil
463 }
464
465 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
466 if raceenabled {
467 raceReleaseMerge(unsafe.Pointer(&ioSync))
468 }
469 var length = int64(count)
470 err = sendfile(infd, outfd, *offset, &length, nil, 0)
471 written = int(length)
472 return
473 }
474
475 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
476 var value IPMreqn
477 vallen := _Socklen(SizeofIPMreqn)
478 errno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
479 return &value, errno
480 }
481
482 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
483 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
484 }
485
486
487
488 func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
489 x := new(Xucred)
490 vallen := _Socklen(SizeofXucred)
491 err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)
492 return x, err
493 }
494
495 func GetsockoptTCPConnectionInfo(fd, level, opt int) (*TCPConnectionInfo, error) {
496 var value TCPConnectionInfo
497 vallen := _Socklen(SizeofTCPConnectionInfo)
498 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
499 return &value, err
500 }
501
502 func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
503 mib, err := sysctlmib(name, args...)
504 if err != nil {
505 return nil, err
506 }
507
508 var kinfo KinfoProc
509 n := uintptr(SizeofKinfoProc)
510 if err := sysctl(mib, (*byte)(unsafe.Pointer(&kinfo)), &n, nil, 0); err != nil {
511 return nil, err
512 }
513 if n != SizeofKinfoProc {
514 return nil, EIO
515 }
516 return &kinfo, nil
517 }
518
519 func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
520 mib, err := sysctlmib(name, args...)
521 if err != nil {
522 return nil, err
523 }
524
525 for {
526
527 n := uintptr(0)
528 if err := sysctl(mib, nil, &n, nil, 0); err != nil {
529 return nil, err
530 }
531 if n == 0 {
532 return nil, nil
533 }
534 if n%SizeofKinfoProc != 0 {
535 return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
536 }
537
538
539 buf := make([]KinfoProc, n/SizeofKinfoProc)
540 if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
541 if err == ENOMEM {
542
543 continue
544 }
545 return nil, err
546 }
547 if n%SizeofKinfoProc != 0 {
548 return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
549 }
550
551
552
553 return buf[:n/SizeofKinfoProc], nil
554 }
555 }
556
557
558
559 func PthreadChdir(path string) (err error) {
560 return pthread_chdir_np(path)
561 }
562
563
564
565 func PthreadFchdir(fd int) (err error) {
566 return pthread_fchdir_np(fd)
567 }
568
569
570
571
572
573
574
575
576
577
578 func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocID, flags uint32, iov []Iovec, connid *SaeConnID) (n uintptr, err error) {
579 endpoints := SaEndpoints{
580 Srcif: srcIf,
581 }
582
583 if srcAddr != nil {
584 addrp, addrlen, err := srcAddr.sockaddr()
585 if err != nil {
586 return 0, err
587 }
588 endpoints.Srcaddr = (*RawSockaddr)(addrp)
589 endpoints.Srcaddrlen = uint32(addrlen)
590 }
591
592 if dstAddr != nil {
593 addrp, addrlen, err := dstAddr.sockaddr()
594 if err != nil {
595 return 0, err
596 }
597 endpoints.Dstaddr = (*RawSockaddr)(addrp)
598 endpoints.Dstaddrlen = uint32(addrlen)
599 }
600
601 err = connectx(fd, &endpoints, associd, flags, iov, &n, connid)
602 return
603 }
604
605
606
607
608
609
610
611
612
613
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
View as plain text