1
2
3
4
5
6
7
8
9
10
11
12 package unix
13
14 import (
15 "encoding/binary"
16 "slices"
17 "strconv"
18 "syscall"
19 "time"
20 "unsafe"
21 )
22
23
26
27 func Access(path string, mode uint32) (err error) {
28 return Faccessat(AT_FDCWD, path, mode, 0)
29 }
30
31 func Chmod(path string, mode uint32) (err error) {
32 return Fchmodat(AT_FDCWD, path, mode, 0)
33 }
34
35 func Chown(path string, uid int, gid int) (err error) {
36 return Fchownat(AT_FDCWD, path, uid, gid, 0)
37 }
38
39 func Creat(path string, mode uint32) (fd int, err error) {
40 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
41 }
42
43 func EpollCreate(size int) (fd int, err error) {
44 if size <= 0 {
45 return -1, EINVAL
46 }
47 return EpollCreate1(0)
48 }
49
50
51
52
53 func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error) {
54 if pathname == "" {
55 return fanotifyMark(fd, flags, mask, dirFd, nil)
56 }
57 p, err := BytePtrFromString(pathname)
58 if err != nil {
59 return err
60 }
61 return fanotifyMark(fd, flags, mask, dirFd, p)
62 }
63
64
65
66
67 func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
68
69
70 if flags != 0 {
71 err := fchmodat2(dirfd, path, mode, flags)
72 if err == ENOSYS {
73
74
75 if flags&^(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
76 return EINVAL
77 } else if flags&(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
78 return EOPNOTSUPP
79 }
80 }
81 return err
82 }
83 return fchmodat(dirfd, path, mode)
84 }
85
86 func InotifyInit() (fd int, err error) {
87 return InotifyInit1(0)
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 func Link(oldpath string, newpath string) (err error) {
106 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0)
107 }
108
109 func Mkdir(path string, mode uint32) (err error) {
110 return Mkdirat(AT_FDCWD, path, mode)
111 }
112
113 func Mknod(path string, mode uint32, dev int) (err error) {
114 return Mknodat(AT_FDCWD, path, mode, dev)
115 }
116
117 func Open(path string, mode int, perm uint32) (fd int, err error) {
118 return openat(AT_FDCWD, path, mode|O_LARGEFILE, perm)
119 }
120
121
122
123 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
124 return openat(dirfd, path, flags|O_LARGEFILE, mode)
125 }
126
127
128
129 func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
130 return openat2(dirfd, path, how, SizeofOpenHow)
131 }
132
133 func Pipe(p []int) error {
134 return Pipe2(p, 0)
135 }
136
137
138
139 func Pipe2(p []int, flags int) error {
140 if len(p) != 2 {
141 return EINVAL
142 }
143 var pp [2]_C_int
144 err := pipe2(&pp, flags)
145 if err == nil {
146 p[0] = int(pp[0])
147 p[1] = int(pp[1])
148 }
149 return err
150 }
151
152
153
154 func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
155 if len(fds) == 0 {
156 return ppoll(nil, 0, timeout, sigmask)
157 }
158 return ppoll(&fds[0], len(fds), timeout, sigmask)
159 }
160
161 func Poll(fds []PollFd, timeout int) (n int, err error) {
162 var ts *Timespec
163 if timeout >= 0 {
164 ts = new(Timespec)
165 *ts = NsecToTimespec(int64(timeout) * 1e6)
166 }
167 return Ppoll(fds, ts, nil)
168 }
169
170
171
172 func Readlink(path string, buf []byte) (n int, err error) {
173 return Readlinkat(AT_FDCWD, path, buf)
174 }
175
176 func Rename(oldpath string, newpath string) (err error) {
177 return Renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath)
178 }
179
180 func Rmdir(path string) error {
181 return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
182 }
183
184
185
186 func Symlink(oldpath string, newpath string) (err error) {
187 return Symlinkat(oldpath, AT_FDCWD, newpath)
188 }
189
190 func Unlink(path string) error {
191 return Unlinkat(AT_FDCWD, path, 0)
192 }
193
194
195
196 func Utimes(path string, tv []Timeval) error {
197 if tv == nil {
198 err := utimensat(AT_FDCWD, path, nil, 0)
199 if err != ENOSYS {
200 return err
201 }
202 return utimes(path, nil)
203 }
204 if len(tv) != 2 {
205 return EINVAL
206 }
207 var ts [2]Timespec
208 ts[0] = NsecToTimespec(TimevalToNsec(tv[0]))
209 ts[1] = NsecToTimespec(TimevalToNsec(tv[1]))
210 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
211 if err != ENOSYS {
212 return err
213 }
214 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
215 }
216
217
218
219 func UtimesNano(path string, ts []Timespec) error {
220 return UtimesNanoAt(AT_FDCWD, path, ts, 0)
221 }
222
223 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
224 if ts == nil {
225 return utimensat(dirfd, path, nil, flags)
226 }
227 if len(ts) != 2 {
228 return EINVAL
229 }
230 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
231 }
232
233 func Futimesat(dirfd int, path string, tv []Timeval) error {
234 if tv == nil {
235 return futimesat(dirfd, path, nil)
236 }
237 if len(tv) != 2 {
238 return EINVAL
239 }
240 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
241 }
242
243 func Futimes(fd int, tv []Timeval) (err error) {
244
245
246 return Utimes("/proc/self/fd/"+strconv.Itoa(fd), tv)
247 }
248
249 const ImplementsGetwd = true
250
251
252
253 func Getwd() (wd string, err error) {
254 var buf [PathMax]byte
255 n, err := Getcwd(buf[0:])
256 if err != nil {
257 return "", err
258 }
259
260 if n < 1 || n > len(buf) || buf[n-1] != 0 {
261 return "", EINVAL
262 }
263
264
265
266 if buf[0] != '/' {
267 return "", ENOENT
268 }
269
270 return string(buf[0 : n-1]), nil
271 }
272
273 func Getgroups() (gids []int, err error) {
274 n, err := getgroups(0, nil)
275 if err != nil {
276 return nil, err
277 }
278 if n == 0 {
279 return nil, nil
280 }
281
282
283 if n < 0 || n > 1<<20 {
284 return nil, EINVAL
285 }
286
287 a := make([]_Gid_t, n)
288 n, err = getgroups(n, &a[0])
289 if err != nil {
290 return nil, err
291 }
292 gids = make([]int, n)
293 for i, v := range a[0:n] {
294 gids[i] = int(v)
295 }
296 return
297 }
298
299 func Setgroups(gids []int) (err error) {
300 if len(gids) == 0 {
301 return setgroups(0, nil)
302 }
303
304 a := make([]_Gid_t, len(gids))
305 for i, v := range gids {
306 a[i] = _Gid_t(v)
307 }
308 return setgroups(len(a), &a[0])
309 }
310
311 type WaitStatus uint32
312
313
314
315
316
317
318
319
320
321
322 const (
323 mask = 0x7F
324 core = 0x80
325 exited = 0x00
326 stopped = 0x7F
327 shift = 8
328 )
329
330 func (w WaitStatus) Exited() bool { return w&mask == exited }
331
332 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
333
334 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
335
336 func (w WaitStatus) Continued() bool { return w == 0xFFFF }
337
338 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
339
340 func (w WaitStatus) ExitStatus() int {
341 if !w.Exited() {
342 return -1
343 }
344 return int(w>>shift) & 0xFF
345 }
346
347 func (w WaitStatus) Signal() syscall.Signal {
348 if !w.Signaled() {
349 return -1
350 }
351 return syscall.Signal(w & mask)
352 }
353
354 func (w WaitStatus) StopSignal() syscall.Signal {
355 if !w.Stopped() {
356 return -1
357 }
358 return syscall.Signal(w>>shift) & 0xFF
359 }
360
361 func (w WaitStatus) TrapCause() int {
362 if w.StopSignal() != SIGTRAP {
363 return -1
364 }
365 return int(w>>shift) >> 8
366 }
367
368
369
370 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
371 var status _C_int
372 wpid, err = wait4(pid, &status, options, rusage)
373 if wstatus != nil {
374 *wstatus = WaitStatus(status)
375 }
376 return
377 }
378
379
380
381 func Mkfifo(path string, mode uint32) error {
382 return Mknod(path, mode|S_IFIFO, 0)
383 }
384
385 func Mkfifoat(dirfd int, path string, mode uint32) error {
386 return Mknodat(dirfd, path, mode|S_IFIFO, 0)
387 }
388
389 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
390 if sa.Port < 0 || sa.Port > 0xFFFF {
391 return nil, 0, EINVAL
392 }
393 sa.raw.Family = AF_INET
394 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
395 p[0] = byte(sa.Port >> 8)
396 p[1] = byte(sa.Port)
397 sa.raw.Addr = sa.Addr
398 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
399 }
400
401 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
402 if sa.Port < 0 || sa.Port > 0xFFFF {
403 return nil, 0, EINVAL
404 }
405 sa.raw.Family = AF_INET6
406 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
407 p[0] = byte(sa.Port >> 8)
408 p[1] = byte(sa.Port)
409 sa.raw.Scope_id = sa.ZoneId
410 sa.raw.Addr = sa.Addr
411 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
412 }
413
414 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
415 name := sa.Name
416 n := len(name)
417 if n >= len(sa.raw.Path) {
418 return nil, 0, EINVAL
419 }
420 sa.raw.Family = AF_UNIX
421 for i := range n {
422 sa.raw.Path[i] = int8(name[i])
423 }
424
425 sl := _Socklen(2)
426 if n > 0 {
427 sl += _Socklen(n) + 1
428 }
429 if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
430
431 sa.raw.Path[0] = 0
432
433 sl--
434 }
435
436 return unsafe.Pointer(&sa.raw), sl, nil
437 }
438
439
440 type SockaddrLinklayer struct {
441 Protocol uint16
442 Ifindex int
443 Hatype uint16
444 Pkttype uint8
445 Halen uint8
446 Addr [8]byte
447 raw RawSockaddrLinklayer
448 }
449
450 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
451 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
452 return nil, 0, EINVAL
453 }
454 sa.raw.Family = AF_PACKET
455 sa.raw.Protocol = sa.Protocol
456 sa.raw.Ifindex = int32(sa.Ifindex)
457 sa.raw.Hatype = sa.Hatype
458 sa.raw.Pkttype = sa.Pkttype
459 sa.raw.Halen = sa.Halen
460 sa.raw.Addr = sa.Addr
461 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
462 }
463
464
465 type SockaddrNetlink struct {
466 Family uint16
467 Pad uint16
468 Pid uint32
469 Groups uint32
470 raw RawSockaddrNetlink
471 }
472
473 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
474 sa.raw.Family = AF_NETLINK
475 sa.raw.Pad = sa.Pad
476 sa.raw.Pid = sa.Pid
477 sa.raw.Groups = sa.Groups
478 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
479 }
480
481
482
483 type SockaddrHCI struct {
484 Dev uint16
485 Channel uint16
486 raw RawSockaddrHCI
487 }
488
489 func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) {
490 sa.raw.Family = AF_BLUETOOTH
491 sa.raw.Dev = sa.Dev
492 sa.raw.Channel = sa.Channel
493 return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil
494 }
495
496
497
498 type SockaddrL2 struct {
499 PSM uint16
500 CID uint16
501 Addr [6]uint8
502 AddrType uint8
503 raw RawSockaddrL2
504 }
505
506 func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {
507 sa.raw.Family = AF_BLUETOOTH
508 psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm))
509 psm[0] = byte(sa.PSM)
510 psm[1] = byte(sa.PSM >> 8)
511 for i := range len(sa.Addr) {
512 sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i]
513 }
514 cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid))
515 cid[0] = byte(sa.CID)
516 cid[1] = byte(sa.CID >> 8)
517 sa.raw.Bdaddr_type = sa.AddrType
518 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil
519 }
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544 type SockaddrRFCOMM struct {
545
546 Addr [6]uint8
547
548
549
550 Channel uint8
551
552 raw RawSockaddrRFCOMM
553 }
554
555 func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) {
556 sa.raw.Family = AF_BLUETOOTH
557 sa.raw.Channel = sa.Channel
558 sa.raw.Bdaddr = sa.Addr
559 return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil
560 }
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579 type SockaddrCAN struct {
580 Ifindex int
581 RxID uint32
582 TxID uint32
583 raw RawSockaddrCAN
584 }
585
586 func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) {
587 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
588 return nil, 0, EINVAL
589 }
590 sa.raw.Family = AF_CAN
591 sa.raw.Ifindex = int32(sa.Ifindex)
592 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
593 for i := range 4 {
594 sa.raw.Addr[i] = rx[i]
595 }
596 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
597 for i := range 4 {
598 sa.raw.Addr[i+4] = tx[i]
599 }
600 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
601 }
602
603
604
605
606
607 type SockaddrCANJ1939 struct {
608 Ifindex int
609 Name uint64
610 PGN uint32
611 Addr uint8
612 raw RawSockaddrCAN
613 }
614
615 func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) {
616 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
617 return nil, 0, EINVAL
618 }
619 sa.raw.Family = AF_CAN
620 sa.raw.Ifindex = int32(sa.Ifindex)
621 n := (*[8]byte)(unsafe.Pointer(&sa.Name))
622 for i := range 8 {
623 sa.raw.Addr[i] = n[i]
624 }
625 p := (*[4]byte)(unsafe.Pointer(&sa.PGN))
626 for i := range 4 {
627 sa.raw.Addr[i+8] = p[i]
628 }
629 sa.raw.Addr[12] = sa.Addr
630 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
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 type SockaddrALG struct {
697 Type string
698 Name string
699 Feature uint32
700 Mask uint32
701 raw RawSockaddrALG
702 }
703
704 func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) {
705
706 if len(sa.Type) > len(sa.raw.Type)-1 {
707 return nil, 0, EINVAL
708 }
709 if len(sa.Name) > len(sa.raw.Name)-1 {
710 return nil, 0, EINVAL
711 }
712
713 sa.raw.Family = AF_ALG
714 sa.raw.Feat = sa.Feature
715 sa.raw.Mask = sa.Mask
716
717 copy(sa.raw.Type[:], sa.Type)
718 copy(sa.raw.Name[:], sa.Name)
719
720 return unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil
721 }
722
723
724
725
726
727 type SockaddrVM struct {
728
729
730
731
732
733 CID uint32
734 Port uint32
735 Flags uint8
736 raw RawSockaddrVM
737 }
738
739 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
740 sa.raw.Family = AF_VSOCK
741 sa.raw.Port = sa.Port
742 sa.raw.Cid = sa.CID
743 sa.raw.Flags = sa.Flags
744
745 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
746 }
747
748 type SockaddrXDP struct {
749 Flags uint16
750 Ifindex uint32
751 QueueID uint32
752 SharedUmemFD uint32
753 raw RawSockaddrXDP
754 }
755
756 func (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) {
757 sa.raw.Family = AF_XDP
758 sa.raw.Flags = sa.Flags
759 sa.raw.Ifindex = sa.Ifindex
760 sa.raw.Queue_id = sa.QueueID
761 sa.raw.Shared_umem_fd = sa.SharedUmemFD
762
763 return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil
764 }
765
766
767
768
769
770
771
772
773 const px_proto_oe = 0
774
775 type SockaddrPPPoE struct {
776 SID uint16
777 Remote []byte
778 Dev string
779 raw RawSockaddrPPPoX
780 }
781
782 func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {
783 if len(sa.Remote) != 6 {
784 return nil, 0, EINVAL
785 }
786 if len(sa.Dev) > IFNAMSIZ-1 {
787 return nil, 0, EINVAL
788 }
789
790 *(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX
791
792
793
794
795
796
797
798
799 binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe)
800
801
802 binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID)
803 copy(sa.raw[8:14], sa.Remote)
804 for i := 14; i < 14+IFNAMSIZ; i++ {
805 sa.raw[i] = 0
806 }
807 copy(sa.raw[14:], sa.Dev)
808 return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
809 }
810
811
812
813 type SockaddrTIPC struct {
814
815
816 Scope int
817
818
819
820
821
822
823
824
825 Addr TIPCAddr
826
827 raw RawSockaddrTIPC
828 }
829
830
831
832
833 type TIPCAddr interface {
834 tipcAddrtype() uint8
835 tipcAddr() [12]byte
836 }
837
838 func (sa *TIPCSocketAddr) tipcAddr() [12]byte {
839 var out [12]byte
840 copy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:])
841 return out
842 }
843
844 func (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR }
845
846 func (sa *TIPCServiceRange) tipcAddr() [12]byte {
847 var out [12]byte
848 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:])
849 return out
850 }
851
852 func (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE }
853
854 func (sa *TIPCServiceName) tipcAddr() [12]byte {
855 var out [12]byte
856 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:])
857 return out
858 }
859
860 func (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR }
861
862 func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) {
863 if sa.Addr == nil {
864 return nil, 0, EINVAL
865 }
866 sa.raw.Family = AF_TIPC
867 sa.raw.Scope = int8(sa.Scope)
868 sa.raw.Addrtype = sa.Addr.tipcAddrtype()
869 sa.raw.Addr = sa.Addr.tipcAddr()
870 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
871 }
872
873
874 type SockaddrL2TPIP struct {
875 Addr [4]byte
876 ConnId uint32
877 raw RawSockaddrL2TPIP
878 }
879
880 func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {
881 sa.raw.Family = AF_INET
882 sa.raw.Conn_id = sa.ConnId
883 sa.raw.Addr = sa.Addr
884 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil
885 }
886
887
888 type SockaddrL2TPIP6 struct {
889 Addr [16]byte
890 ZoneId uint32
891 ConnId uint32
892 raw RawSockaddrL2TPIP6
893 }
894
895 func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {
896 sa.raw.Family = AF_INET6
897 sa.raw.Conn_id = sa.ConnId
898 sa.raw.Scope_id = sa.ZoneId
899 sa.raw.Addr = sa.Addr
900 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
901 }
902
903
904 type SockaddrIUCV struct {
905 UserID string
906 Name string
907 raw RawSockaddrIUCV
908 }
909
910 func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
911 sa.raw.Family = AF_IUCV
912
913
914
915 for i := range 8 {
916 sa.raw.Nodeid[i] = ' '
917 sa.raw.User_id[i] = ' '
918 sa.raw.Name[i] = ' '
919 }
920 if len(sa.UserID) > 8 || len(sa.Name) > 8 {
921 return nil, 0, EINVAL
922 }
923 for i, b := range []byte(sa.UserID[:]) {
924 sa.raw.User_id[i] = int8(b)
925 }
926 for i, b := range []byte(sa.Name[:]) {
927 sa.raw.Name[i] = int8(b)
928 }
929 return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil
930 }
931
932 type SockaddrNFC struct {
933 DeviceIdx uint32
934 TargetIdx uint32
935 NFCProtocol uint32
936 raw RawSockaddrNFC
937 }
938
939 func (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) {
940 sa.raw.Sa_family = AF_NFC
941 sa.raw.Dev_idx = sa.DeviceIdx
942 sa.raw.Target_idx = sa.TargetIdx
943 sa.raw.Nfc_protocol = sa.NFCProtocol
944 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil
945 }
946
947 type SockaddrNFCLLCP struct {
948 DeviceIdx uint32
949 TargetIdx uint32
950 NFCProtocol uint32
951 DestinationSAP uint8
952 SourceSAP uint8
953 ServiceName string
954 raw RawSockaddrNFCLLCP
955 }
956
957 func (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) {
958 sa.raw.Sa_family = AF_NFC
959 sa.raw.Dev_idx = sa.DeviceIdx
960 sa.raw.Target_idx = sa.TargetIdx
961 sa.raw.Nfc_protocol = sa.NFCProtocol
962 sa.raw.Dsap = sa.DestinationSAP
963 sa.raw.Ssap = sa.SourceSAP
964 if len(sa.ServiceName) > len(sa.raw.Service_name) {
965 return nil, 0, EINVAL
966 }
967 copy(sa.raw.Service_name[:], sa.ServiceName)
968 sa.raw.SetServiceNameLen(len(sa.ServiceName))
969 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil
970 }
971
972 var socketProtocol = func(fd int) (int, error) {
973 return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
974 }
975
976 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
977 switch rsa.Addr.Family {
978 case AF_NETLINK:
979 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
980 sa := new(SockaddrNetlink)
981 sa.Family = pp.Family
982 sa.Pad = pp.Pad
983 sa.Pid = pp.Pid
984 sa.Groups = pp.Groups
985 return sa, nil
986
987 case AF_PACKET:
988 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
989 sa := new(SockaddrLinklayer)
990 sa.Protocol = pp.Protocol
991 sa.Ifindex = int(pp.Ifindex)
992 sa.Hatype = pp.Hatype
993 sa.Pkttype = pp.Pkttype
994 sa.Halen = pp.Halen
995 sa.Addr = pp.Addr
996 return sa, nil
997
998 case AF_UNIX:
999 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
1000 sa := new(SockaddrUnix)
1001 if pp.Path[0] == 0 {
1002
1003
1004
1005
1006
1007 pp.Path[0] = '@'
1008 }
1009
1010
1011
1012
1013
1014
1015 n := 0
1016 for n < len(pp.Path) && pp.Path[n] != 0 {
1017 n++
1018 }
1019 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
1020 return sa, nil
1021
1022 case AF_INET:
1023 proto, err := socketProtocol(fd)
1024 if err != nil {
1025 return nil, err
1026 }
1027
1028 switch proto {
1029 case IPPROTO_L2TP:
1030 pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))
1031 sa := new(SockaddrL2TPIP)
1032 sa.ConnId = pp.Conn_id
1033 sa.Addr = pp.Addr
1034 return sa, nil
1035 default:
1036 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
1037 sa := new(SockaddrInet4)
1038 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1039 sa.Port = int(p[0])<<8 + int(p[1])
1040 sa.Addr = pp.Addr
1041 return sa, nil
1042 }
1043
1044 case AF_INET6:
1045 proto, err := socketProtocol(fd)
1046 if err != nil {
1047 return nil, err
1048 }
1049
1050 switch proto {
1051 case IPPROTO_L2TP:
1052 pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa))
1053 sa := new(SockaddrL2TPIP6)
1054 sa.ConnId = pp.Conn_id
1055 sa.ZoneId = pp.Scope_id
1056 sa.Addr = pp.Addr
1057 return sa, nil
1058 default:
1059 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
1060 sa := new(SockaddrInet6)
1061 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1062 sa.Port = int(p[0])<<8 + int(p[1])
1063 sa.ZoneId = pp.Scope_id
1064 sa.Addr = pp.Addr
1065 return sa, nil
1066 }
1067
1068 case AF_VSOCK:
1069 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
1070 sa := &SockaddrVM{
1071 CID: pp.Cid,
1072 Port: pp.Port,
1073 Flags: pp.Flags,
1074 }
1075 return sa, nil
1076 case AF_BLUETOOTH:
1077 proto, err := socketProtocol(fd)
1078 if err != nil {
1079 return nil, err
1080 }
1081
1082 switch proto {
1083 case BTPROTO_L2CAP:
1084 pp := (*RawSockaddrL2)(unsafe.Pointer(rsa))
1085 sa := &SockaddrL2{
1086 PSM: pp.Psm,
1087 CID: pp.Cid,
1088 Addr: pp.Bdaddr,
1089 AddrType: pp.Bdaddr_type,
1090 }
1091 return sa, nil
1092 case BTPROTO_RFCOMM:
1093 pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa))
1094 sa := &SockaddrRFCOMM{
1095 Channel: pp.Channel,
1096 Addr: pp.Bdaddr,
1097 }
1098 return sa, nil
1099 }
1100 case AF_XDP:
1101 pp := (*RawSockaddrXDP)(unsafe.Pointer(rsa))
1102 sa := &SockaddrXDP{
1103 Flags: pp.Flags,
1104 Ifindex: pp.Ifindex,
1105 QueueID: pp.Queue_id,
1106 SharedUmemFD: pp.Shared_umem_fd,
1107 }
1108 return sa, nil
1109 case AF_PPPOX:
1110 pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa))
1111 if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe {
1112 return nil, EINVAL
1113 }
1114 sa := &SockaddrPPPoE{
1115 SID: binary.BigEndian.Uint16(pp[6:8]),
1116 Remote: pp[8:14],
1117 }
1118 for i := 14; i < 14+IFNAMSIZ; i++ {
1119 if pp[i] == 0 {
1120 sa.Dev = string(pp[14:i])
1121 break
1122 }
1123 }
1124 return sa, nil
1125 case AF_TIPC:
1126 pp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa))
1127
1128 sa := &SockaddrTIPC{
1129 Scope: int(pp.Scope),
1130 }
1131
1132
1133
1134 switch pp.Addrtype {
1135 case TIPC_SERVICE_RANGE:
1136 sa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr))
1137 case TIPC_SERVICE_ADDR:
1138 sa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr))
1139 case TIPC_SOCKET_ADDR:
1140 sa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr))
1141 default:
1142 return nil, EINVAL
1143 }
1144
1145 return sa, nil
1146 case AF_IUCV:
1147 pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa))
1148
1149 var user [8]byte
1150 var name [8]byte
1151
1152 for i := range 8 {
1153 user[i] = byte(pp.User_id[i])
1154 name[i] = byte(pp.Name[i])
1155 }
1156
1157 sa := &SockaddrIUCV{
1158 UserID: string(user[:]),
1159 Name: string(name[:]),
1160 }
1161 return sa, nil
1162
1163 case AF_CAN:
1164 proto, err := socketProtocol(fd)
1165 if err != nil {
1166 return nil, err
1167 }
1168
1169 pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa))
1170
1171 switch proto {
1172 case CAN_J1939:
1173 sa := &SockaddrCANJ1939{
1174 Ifindex: int(pp.Ifindex),
1175 }
1176 name := (*[8]byte)(unsafe.Pointer(&sa.Name))
1177 for i := range 8 {
1178 name[i] = pp.Addr[i]
1179 }
1180 pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN))
1181 for i := range 4 {
1182 pgn[i] = pp.Addr[i+8]
1183 }
1184 addr := (*[1]byte)(unsafe.Pointer(&sa.Addr))
1185 addr[0] = pp.Addr[12]
1186 return sa, nil
1187 default:
1188 sa := &SockaddrCAN{
1189 Ifindex: int(pp.Ifindex),
1190 }
1191 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
1192 for i := range 4 {
1193 rx[i] = pp.Addr[i]
1194 }
1195 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
1196 for i := range 4 {
1197 tx[i] = pp.Addr[i+4]
1198 }
1199 return sa, nil
1200 }
1201 case AF_NFC:
1202 proto, err := socketProtocol(fd)
1203 if err != nil {
1204 return nil, err
1205 }
1206 switch proto {
1207 case NFC_SOCKPROTO_RAW:
1208 pp := (*RawSockaddrNFC)(unsafe.Pointer(rsa))
1209 sa := &SockaddrNFC{
1210 DeviceIdx: pp.Dev_idx,
1211 TargetIdx: pp.Target_idx,
1212 NFCProtocol: pp.Nfc_protocol,
1213 }
1214 return sa, nil
1215 case NFC_SOCKPROTO_LLCP:
1216 pp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa))
1217 if uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) {
1218 return nil, EINVAL
1219 }
1220 sa := &SockaddrNFCLLCP{
1221 DeviceIdx: pp.Dev_idx,
1222 TargetIdx: pp.Target_idx,
1223 NFCProtocol: pp.Nfc_protocol,
1224 DestinationSAP: pp.Dsap,
1225 SourceSAP: pp.Ssap,
1226 ServiceName: string(pp.Service_name[:pp.Service_name_len]),
1227 }
1228 return sa, nil
1229 default:
1230 return nil, EINVAL
1231 }
1232 }
1233 return nil, EAFNOSUPPORT
1234 }
1235
1236 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
1237 var rsa RawSockaddrAny
1238 var len _Socklen = SizeofSockaddrAny
1239 nfd, err = accept4(fd, &rsa, &len, 0)
1240 if err != nil {
1241 return
1242 }
1243 sa, err = anyToSockaddr(fd, &rsa)
1244 if err != nil {
1245 Close(nfd)
1246 nfd = 0
1247 }
1248 return
1249 }
1250
1251 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
1252 var rsa RawSockaddrAny
1253 var len _Socklen = SizeofSockaddrAny
1254 nfd, err = accept4(fd, &rsa, &len, flags)
1255 if err != nil {
1256 return
1257 }
1258 if len > SizeofSockaddrAny {
1259 panic("RawSockaddrAny too small")
1260 }
1261 sa, err = anyToSockaddr(fd, &rsa)
1262 if err != nil {
1263 Close(nfd)
1264 nfd = 0
1265 }
1266 return
1267 }
1268
1269 func Getsockname(fd int) (sa Sockaddr, err error) {
1270 var rsa RawSockaddrAny
1271 var len _Socklen = SizeofSockaddrAny
1272 if err = getsockname(fd, &rsa, &len); err != nil {
1273 return
1274 }
1275 return anyToSockaddr(fd, &rsa)
1276 }
1277
1278 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
1279 var value IPMreqn
1280 vallen := _Socklen(SizeofIPMreqn)
1281 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1282 return &value, err
1283 }
1284
1285 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
1286 var value Ucred
1287 vallen := _Socklen(SizeofUcred)
1288 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1289 return &value, err
1290 }
1291
1292 func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
1293 var value TCPInfo
1294 vallen := _Socklen(SizeofTCPInfo)
1295 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1296 return &value, err
1297 }
1298
1299
1300
1301
1302
1303
1304
1305 func GetsockoptTCPCCVegasInfo(fd, level, opt int) (*TCPVegasInfo, error) {
1306 var value [SizeofTCPCCInfo / 4]uint32
1307 vallen := _Socklen(SizeofTCPCCInfo)
1308 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
1309 out := (*TCPVegasInfo)(unsafe.Pointer(&value[0]))
1310 return out, err
1311 }
1312
1313
1314
1315
1316
1317
1318
1319 func GetsockoptTCPCCDCTCPInfo(fd, level, opt int) (*TCPDCTCPInfo, error) {
1320 var value [SizeofTCPCCInfo / 4]uint32
1321 vallen := _Socklen(SizeofTCPCCInfo)
1322 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
1323 out := (*TCPDCTCPInfo)(unsafe.Pointer(&value[0]))
1324 return out, err
1325 }
1326
1327
1328
1329
1330
1331
1332
1333 func GetsockoptTCPCCBBRInfo(fd, level, opt int) (*TCPBBRInfo, error) {
1334 var value [SizeofTCPCCInfo / 4]uint32
1335 vallen := _Socklen(SizeofTCPCCInfo)
1336 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
1337 out := (*TCPBBRInfo)(unsafe.Pointer(&value[0]))
1338 return out, err
1339 }
1340
1341
1342
1343 func GetsockoptString(fd, level, opt int) (string, error) {
1344 buf := make([]byte, 256)
1345 vallen := _Socklen(len(buf))
1346 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1347 if err != nil {
1348 if err == ERANGE {
1349 buf = make([]byte, vallen)
1350 err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1351 }
1352 if err != nil {
1353 return "", err
1354 }
1355 }
1356 return ByteSliceToString(buf[:vallen]), nil
1357 }
1358
1359 func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) {
1360 var value TpacketStats
1361 vallen := _Socklen(SizeofTpacketStats)
1362 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1363 return &value, err
1364 }
1365
1366 func GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) {
1367 var value TpacketStatsV3
1368 vallen := _Socklen(SizeofTpacketStatsV3)
1369 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1370 return &value, err
1371 }
1372
1373 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
1374 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
1375 }
1376
1377 func SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error {
1378 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
1379 }
1380
1381
1382
1383 func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error {
1384 return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog))
1385 }
1386
1387 func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error {
1388 var p unsafe.Pointer
1389 if len(filter) > 0 {
1390 p = unsafe.Pointer(&filter[0])
1391 }
1392 return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter))
1393 }
1394
1395 func SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error {
1396 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))
1397 }
1398
1399 func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error {
1400 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))
1401 }
1402
1403 func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) {
1404 if len(o) == 0 {
1405 return EINVAL
1406 }
1407 return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o)))
1408 }
1409
1410 func SetsockoptTCPMD5Sig(fd, level, opt int, s *TCPMD5Sig) error {
1411 return setsockopt(fd, level, opt, unsafe.Pointer(s), unsafe.Sizeof(*s))
1412 }
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430 func KeyctlString(cmd int, id int) (string, error) {
1431
1432
1433
1434
1435 var buffer []byte
1436 for {
1437
1438 length, err := KeyctlBuffer(cmd, id, buffer, 0)
1439 if err != nil {
1440 return "", err
1441 }
1442
1443
1444 if length <= len(buffer) {
1445
1446 return string(buffer[:length-1]), nil
1447 }
1448
1449
1450 buffer = make([]byte, length)
1451 }
1452 }
1453
1454
1455
1456
1457
1458
1459 func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) {
1460 createInt := 0
1461 if create {
1462 createInt = 1
1463 }
1464 return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0)
1465 }
1466
1467
1468
1469
1470
1471
1472 func KeyctlSetperm(id int, perm uint32) error {
1473 _, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0)
1474 return err
1475 }
1476
1477
1478
1479
1480
1481
1482 func KeyctlJoinSessionKeyring(name string) (ringid int, err error) {
1483 return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name)
1484 }
1485
1486
1487
1488
1489
1490
1491 func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) {
1492 return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid)
1493 }
1494
1495
1496
1497
1498
1499
1500
1501
1502 func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error {
1503 return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid)
1504 }
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) {
1518 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)
1519 }
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539 func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error {
1540 if keyType == "" {
1541 return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid)
1542 }
1543 return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction)
1544 }
1545
1546
1547
1548
1549 func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
1550 var msg Msghdr
1551 msg.Name = (*byte)(unsafe.Pointer(rsa))
1552 msg.Namelen = uint32(SizeofSockaddrAny)
1553 var dummy byte
1554 if len(oob) > 0 {
1555 if emptyIovecs(iov) {
1556 var sockType int
1557 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
1558 if err != nil {
1559 return
1560 }
1561
1562 if sockType != SOCK_DGRAM {
1563 var iova [1]Iovec
1564 iova[0].Base = &dummy
1565 iova[0].SetLen(1)
1566 iov = iova[:]
1567 }
1568 }
1569 msg.Control = &oob[0]
1570 msg.SetControllen(len(oob))
1571 }
1572 if len(iov) > 0 {
1573 msg.Iov = &iov[0]
1574 msg.SetIovlen(len(iov))
1575 }
1576 if n, err = recvmsg(fd, &msg, flags); err != nil {
1577 return
1578 }
1579 oobn = int(msg.Controllen)
1580 recvflags = int(msg.Flags)
1581 return
1582 }
1583
1584 func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
1585 var msg Msghdr
1586 msg.Name = (*byte)(ptr)
1587 msg.Namelen = uint32(salen)
1588 var dummy byte
1589 var empty bool
1590 if len(oob) > 0 {
1591 empty = emptyIovecs(iov)
1592 if empty {
1593 var sockType int
1594 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
1595 if err != nil {
1596 return 0, err
1597 }
1598
1599 if sockType != SOCK_DGRAM {
1600 var iova [1]Iovec
1601 iova[0].Base = &dummy
1602 iova[0].SetLen(1)
1603 iov = iova[:]
1604 }
1605 }
1606 msg.Control = &oob[0]
1607 msg.SetControllen(len(oob))
1608 }
1609 if len(iov) > 0 {
1610 msg.Iov = &iov[0]
1611 msg.SetIovlen(len(iov))
1612 }
1613 if n, err = sendmsg(fd, &msg, flags); err != nil {
1614 return 0, err
1615 }
1616 if len(oob) > 0 && empty {
1617 n = 0
1618 }
1619 return n, nil
1620 }
1621
1622
1623 func BindToDevice(fd int, device string) (err error) {
1624 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
1625 }
1626
1627
1628
1629
1630 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
1631
1632
1633
1634
1635
1636
1637 var buf [SizeofPtr]byte
1638
1639
1640
1641
1642
1643
1644 n := 0
1645 if addr%SizeofPtr != 0 {
1646 err = ptracePtr(req, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))
1647 if err != nil {
1648 return 0, err
1649 }
1650 n += copy(out, buf[addr%SizeofPtr:])
1651 out = out[n:]
1652 }
1653
1654
1655 for len(out) > 0 {
1656
1657
1658 err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
1659 if err != nil {
1660 return n, err
1661 }
1662 copied := copy(out, buf[0:])
1663 n += copied
1664 out = out[copied:]
1665 }
1666
1667 return n, nil
1668 }
1669
1670 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
1671 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
1672 }
1673
1674 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
1675 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
1676 }
1677
1678 func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) {
1679 return ptracePeek(PTRACE_PEEKUSR, pid, addr, out)
1680 }
1681
1682 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
1683
1684
1685
1686
1687 n := 0
1688 if addr%SizeofPtr != 0 {
1689 var buf [SizeofPtr]byte
1690 err = ptracePtr(peekReq, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))
1691 if err != nil {
1692 return 0, err
1693 }
1694 n += copy(buf[addr%SizeofPtr:], data)
1695 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1696 err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word)
1697 if err != nil {
1698 return 0, err
1699 }
1700 data = data[n:]
1701 }
1702
1703
1704 for len(data) > SizeofPtr {
1705 word := *((*uintptr)(unsafe.Pointer(&data[0])))
1706 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1707 if err != nil {
1708 return n, err
1709 }
1710 n += SizeofPtr
1711 data = data[SizeofPtr:]
1712 }
1713
1714
1715 if len(data) > 0 {
1716 var buf [SizeofPtr]byte
1717 err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
1718 if err != nil {
1719 return n, err
1720 }
1721 copy(buf[0:], data)
1722 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1723 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1724 if err != nil {
1725 return n, err
1726 }
1727 n += len(data)
1728 }
1729
1730 return n, nil
1731 }
1732
1733 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
1734 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
1735 }
1736
1737 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
1738 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
1739 }
1740
1741 func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) {
1742 return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data)
1743 }
1744
1745
1746
1747
1748 const elfNT_PRSTATUS = 1
1749
1750 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
1751 var iov Iovec
1752 iov.Base = (*byte)(unsafe.Pointer(regsout))
1753 iov.SetLen(int(unsafe.Sizeof(*regsout)))
1754 return ptracePtr(PTRACE_GETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
1755 }
1756
1757 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
1758 var iov Iovec
1759 iov.Base = (*byte)(unsafe.Pointer(regs))
1760 iov.SetLen(int(unsafe.Sizeof(*regs)))
1761 return ptracePtr(PTRACE_SETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
1762 }
1763
1764 func PtraceSetOptions(pid int, options int) (err error) {
1765 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
1766 }
1767
1768 func PtraceGetEventMsg(pid int) (msg uint, err error) {
1769 var data _C_long
1770 err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
1771 msg = uint(data)
1772 return
1773 }
1774
1775 func PtraceCont(pid int, signal int) (err error) {
1776 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
1777 }
1778
1779 func PtraceSyscall(pid int, signal int) (err error) {
1780 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
1781 }
1782
1783 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
1784
1785 func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) }
1786
1787 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
1788
1789 func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) }
1790
1791 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
1792
1793
1794
1795 func Reboot(cmd int) (err error) {
1796 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
1797 }
1798
1799 func direntIno(buf []byte) (uint64, bool) {
1800 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
1801 }
1802
1803 func direntReclen(buf []byte) (uint64, bool) {
1804 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
1805 }
1806
1807 func direntNamlen(buf []byte) (uint64, bool) {
1808 reclen, ok := direntReclen(buf)
1809 if !ok {
1810 return 0, false
1811 }
1812 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
1813 }
1814
1815
1816
1817 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1818
1819
1820 if data == "" {
1821 return mount(source, target, fstype, flags, nil)
1822 }
1823 datap, err := BytePtrFromString(data)
1824 if err != nil {
1825 return err
1826 }
1827 return mount(source, target, fstype, flags, datap)
1828 }
1829
1830
1831
1832
1833
1834
1835
1836 func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error {
1837 return mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr))
1838 }
1839
1840 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
1841 if raceenabled {
1842 raceReleaseMerge(unsafe.Pointer(&ioSync))
1843 }
1844 return sendfile(outfd, infd, offset, count)
1845 }
1846
1847
1848
1849
1850
1851
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872 func Dup2(oldfd, newfd int) error {
1873 return Dup3(oldfd, newfd, 0)
1874 }
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899 func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) {
1900 var keyp *byte
1901 if keyp, err = BytePtrFromString(key); err != nil {
1902 return
1903 }
1904 return fsconfig(fd, cmd, keyp, value, aux)
1905 }
1906
1907
1908
1909
1910
1911
1912 func FsconfigSetFlag(fd int, key string) (err error) {
1913 return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0)
1914 }
1915
1916
1917
1918
1919
1920
1921
1922 func FsconfigSetString(fd int, key string, value string) (err error) {
1923 var valuep *byte
1924 if valuep, err = BytePtrFromString(value); err != nil {
1925 return
1926 }
1927 return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0)
1928 }
1929
1930
1931
1932
1933
1934
1935
1936 func FsconfigSetBinary(fd int, key string, value []byte) (err error) {
1937 if len(value) == 0 {
1938 return EINVAL
1939 }
1940 return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value))
1941 }
1942
1943
1944
1945
1946
1947
1948
1949
1950 func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) {
1951 var valuep *byte
1952 if valuep, err = BytePtrFromString(path); err != nil {
1953 return
1954 }
1955 return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd)
1956 }
1957
1958
1959
1960
1961 func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) {
1962 var valuep *byte
1963 if valuep, err = BytePtrFromString(path); err != nil {
1964 return
1965 }
1966 return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd)
1967 }
1968
1969
1970
1971
1972
1973
1974
1975 func FsconfigSetFd(fd int, key string, value int) (err error) {
1976 return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value)
1977 }
1978
1979
1980
1981
1982
1983 func FsconfigCreate(fd int) (err error) {
1984 return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0)
1985 }
1986
1987
1988
1989
1990
1991 func FsconfigReconfigure(fd int) (err error) {
1992 return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0)
1993 }
1994
1995
1996
1997
1998 func Getpgrp() (pid int) {
1999 pid, _ = Getpgid(0)
2000 return
2001 }
2002
2003
2004
2005
2006
2007 func Getrandom(buf []byte, flags int) (n int, err error) {
2008 vdsoRet, supported := vgetrandom(buf, uint32(flags))
2009 if supported {
2010 if vdsoRet < 0 {
2011 return 0, errnoErr(syscall.Errno(-vdsoRet))
2012 }
2013 return vdsoRet, nil
2014 }
2015 var p *byte
2016 if len(buf) > 0 {
2017 p = &buf[0]
2018 }
2019 r, _, e := Syscall(SYS_GETRANDOM, uintptr(unsafe.Pointer(p)), uintptr(len(buf)), uintptr(flags))
2020 if e != 0 {
2021 return 0, errnoErr(e)
2022 }
2023 return int(r), nil
2024 }
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063 func syscall_prlimit(pid, resource int, newlimit, old *syscall.Rlimit) error
2064
2065 func Prlimit(pid, resource int, newlimit, old *Rlimit) error {
2066
2067
2068 return syscall_prlimit(pid, resource, (*syscall.Rlimit)(newlimit), (*syscall.Rlimit)(old))
2069 }
2070
2071
2072
2073
2074 func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) {
2075 ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0)
2076 if err != 0 {
2077 return 0, err
2078 }
2079 return int(ret), nil
2080 }
2081
2082 func Setuid(uid int) (err error) {
2083 return syscall.Setuid(uid)
2084 }
2085
2086 func Setgid(gid int) (err error) {
2087 return syscall.Setgid(gid)
2088 }
2089
2090 func Setreuid(ruid, euid int) (err error) {
2091 return syscall.Setreuid(ruid, euid)
2092 }
2093
2094 func Setregid(rgid, egid int) (err error) {
2095 return syscall.Setregid(rgid, egid)
2096 }
2097
2098 func Setresuid(ruid, euid, suid int) (err error) {
2099 return syscall.Setresuid(ruid, euid, suid)
2100 }
2101
2102 func Setresgid(rgid, egid, sgid int) (err error) {
2103 return syscall.Setresgid(rgid, egid, sgid)
2104 }
2105
2106
2107
2108
2109 func SetfsgidRetGid(gid int) (int, error) {
2110 return setfsgid(gid)
2111 }
2112
2113
2114
2115
2116 func SetfsuidRetUid(uid int) (int, error) {
2117 return setfsuid(uid)
2118 }
2119
2120 func Setfsgid(gid int) error {
2121 _, err := setfsgid(gid)
2122 return err
2123 }
2124
2125 func Setfsuid(uid int) error {
2126 _, err := setfsuid(uid)
2127 return err
2128 }
2129
2130 func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
2131 return signalfd(fd, sigmask, _C__NSIG/8, flags)
2132 }
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166 const minIovec = 8
2167
2168
2169 func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
2170 for _, b := range bs {
2171 var v Iovec
2172 v.SetLen(len(b))
2173 if len(b) > 0 {
2174 v.Base = &b[0]
2175 } else {
2176 v.Base = (*byte)(unsafe.Pointer(&_zero))
2177 }
2178 vecs = append(vecs, v)
2179 }
2180 return vecs
2181 }
2182
2183
2184 func offs2lohi(offs int64) (lo, hi uintptr) {
2185 const longBits = SizeofLong * 8
2186 return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1)
2187 }
2188
2189 func Readv(fd int, iovs [][]byte) (n int, err error) {
2190 iovecs := make([]Iovec, 0, minIovec)
2191 iovecs = appendBytes(iovecs, iovs)
2192 n, err = readv(fd, iovecs)
2193 readvRacedetect(iovecs, n, err)
2194 return n, err
2195 }
2196
2197 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
2198 iovecs := make([]Iovec, 0, minIovec)
2199 iovecs = appendBytes(iovecs, iovs)
2200 lo, hi := offs2lohi(offset)
2201 n, err = preadv(fd, iovecs, lo, hi)
2202 readvRacedetect(iovecs, n, err)
2203 return n, err
2204 }
2205
2206 func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
2207 iovecs := make([]Iovec, 0, minIovec)
2208 iovecs = appendBytes(iovecs, iovs)
2209 lo, hi := offs2lohi(offset)
2210 n, err = preadv2(fd, iovecs, lo, hi, flags)
2211 readvRacedetect(iovecs, n, err)
2212 return n, err
2213 }
2214
2215 func readvRacedetect(iovecs []Iovec, n int, err error) {
2216 if !raceenabled {
2217 return
2218 }
2219 for i := 0; n > 0 && i < len(iovecs); i++ {
2220 m := min(int(iovecs[i].Len), n)
2221 n -= m
2222 if m > 0 {
2223 raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
2224 }
2225 }
2226 if err == nil {
2227 raceAcquire(unsafe.Pointer(&ioSync))
2228 }
2229 }
2230
2231 func Writev(fd int, iovs [][]byte) (n int, err error) {
2232 iovecs := make([]Iovec, 0, minIovec)
2233 iovecs = appendBytes(iovecs, iovs)
2234 if raceenabled {
2235 raceReleaseMerge(unsafe.Pointer(&ioSync))
2236 }
2237 n, err = writev(fd, iovecs)
2238 writevRacedetect(iovecs, n)
2239 return n, err
2240 }
2241
2242 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
2243 iovecs := make([]Iovec, 0, minIovec)
2244 iovecs = appendBytes(iovecs, iovs)
2245 if raceenabled {
2246 raceReleaseMerge(unsafe.Pointer(&ioSync))
2247 }
2248 lo, hi := offs2lohi(offset)
2249 n, err = pwritev(fd, iovecs, lo, hi)
2250 writevRacedetect(iovecs, n)
2251 return n, err
2252 }
2253
2254 func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
2255 iovecs := make([]Iovec, 0, minIovec)
2256 iovecs = appendBytes(iovecs, iovs)
2257 if raceenabled {
2258 raceReleaseMerge(unsafe.Pointer(&ioSync))
2259 }
2260 lo, hi := offs2lohi(offset)
2261 n, err = pwritev2(fd, iovecs, lo, hi, flags)
2262 writevRacedetect(iovecs, n)
2263 return n, err
2264 }
2265
2266 func writevRacedetect(iovecs []Iovec, n int) {
2267 if !raceenabled {
2268 return
2269 }
2270 for i := 0; n > 0 && i < len(iovecs); i++ {
2271 m := min(int(iovecs[i].Len), n)
2272 n -= m
2273 if m > 0 {
2274 raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
2275 }
2276 }
2277 }
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290 const (
2291 mremapFixed = MREMAP_FIXED
2292 mremapDontunmap = MREMAP_DONTUNMAP
2293 mremapMaymove = MREMAP_MAYMOVE
2294 )
2295
2296
2297
2298 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
2299 var p unsafe.Pointer
2300 if len(iovs) > 0 {
2301 p = unsafe.Pointer(&iovs[0])
2302 }
2303
2304 n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0)
2305 if errno != 0 {
2306 return 0, syscall.Errno(errno)
2307 }
2308
2309 return int(n), nil
2310 }
2311
2312 func isGroupMember(gid int) bool {
2313 groups, err := Getgroups()
2314 if err != nil {
2315 return false
2316 }
2317
2318 return slices.Contains(groups, gid)
2319 }
2320
2321 func isCapDacOverrideSet() bool {
2322 hdr := CapUserHeader{Version: LINUX_CAPABILITY_VERSION_3}
2323 data := [2]CapUserData{}
2324 err := Capget(&hdr, &data[0])
2325
2326 return err == nil && data[0].Effective&(1<<CAP_DAC_OVERRIDE) != 0
2327 }
2328
2329
2330
2331
2332 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
2333 if flags == 0 {
2334 return faccessat(dirfd, path, mode)
2335 }
2336
2337 if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
2338 return err
2339 }
2340
2341
2342
2343
2344
2345
2346
2347 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
2348 return EINVAL
2349 }
2350
2351 var st Stat_t
2352 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil {
2353 return err
2354 }
2355
2356 mode &= 7
2357 if mode == 0 {
2358 return nil
2359 }
2360
2361 var uid int
2362 if flags&AT_EACCESS != 0 {
2363 uid = Geteuid()
2364 if uid != 0 && isCapDacOverrideSet() {
2365
2366
2367
2368 uid = 0
2369 }
2370 } else {
2371 uid = Getuid()
2372 }
2373
2374 if uid == 0 {
2375 if mode&1 == 0 {
2376
2377 return nil
2378 }
2379 if st.Mode&0111 != 0 {
2380
2381 return nil
2382 }
2383 return EACCES
2384 }
2385
2386 var fmode uint32
2387 if uint32(uid) == st.Uid {
2388 fmode = (st.Mode >> 6) & 7
2389 } else {
2390 var gid int
2391 if flags&AT_EACCESS != 0 {
2392 gid = Getegid()
2393 } else {
2394 gid = Getgid()
2395 }
2396
2397 if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
2398 fmode = (st.Mode >> 3) & 7
2399 } else {
2400 fmode = st.Mode & 7
2401 }
2402 }
2403
2404 if fmode&mode == mode {
2405 return nil
2406 }
2407
2408 return EACCES
2409 }
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419 type fileHandle struct {
2420 Bytes uint32
2421 Type int32
2422 }
2423
2424
2425
2426
2427 type FileHandle struct {
2428 *fileHandle
2429 }
2430
2431
2432 func NewFileHandle(handleType int32, handle []byte) FileHandle {
2433 const hdrSize = unsafe.Sizeof(fileHandle{})
2434 buf := make([]byte, hdrSize+uintptr(len(handle)))
2435 copy(buf[hdrSize:], handle)
2436 fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
2437 fh.Type = handleType
2438 fh.Bytes = uint32(len(handle))
2439 return FileHandle{fh}
2440 }
2441
2442 func (fh *FileHandle) Size() int { return int(fh.fileHandle.Bytes) }
2443 func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type }
2444 func (fh *FileHandle) Bytes() []byte {
2445 n := fh.Size()
2446 if n == 0 {
2447 return nil
2448 }
2449 return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)
2450 }
2451
2452
2453
2454 func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) {
2455 var mid _C_int
2456
2457
2458 size := uint32(32 + unsafe.Sizeof(fileHandle{}))
2459 didResize := false
2460 for {
2461 buf := make([]byte, size)
2462 fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
2463 fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{}))
2464 err = nameToHandleAt(dirfd, path, fh, &mid, flags)
2465 if err == EOVERFLOW {
2466 if didResize {
2467
2468 return
2469 }
2470 didResize = true
2471 size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{}))
2472 continue
2473 }
2474 if err != nil {
2475 return
2476 }
2477 return FileHandle{fh}, int(mid), nil
2478 }
2479 }
2480
2481
2482
2483 func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) {
2484 return openByHandleAt(mountFD, handle.fileHandle, flags)
2485 }
2486
2487
2488
2489 func Klogset(typ int, arg int) (err error) {
2490 var p unsafe.Pointer
2491 _, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg))
2492 if errno != 0 {
2493 return errnoErr(errno)
2494 }
2495 return nil
2496 }
2497
2498
2499
2500
2501
2502 type RemoteIovec struct {
2503 Base uintptr
2504 Len int
2505 }
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523 func MakeItimerval(interval, value time.Duration) Itimerval {
2524 return Itimerval{
2525 Interval: NsecToTimeval(interval.Nanoseconds()),
2526 Value: NsecToTimeval(value.Nanoseconds()),
2527 }
2528 }
2529
2530
2531
2532 type ItimerWhich int
2533
2534
2535 const (
2536 ItimerReal ItimerWhich = ITIMER_REAL
2537 ItimerVirtual ItimerWhich = ITIMER_VIRTUAL
2538 ItimerProf ItimerWhich = ITIMER_PROF
2539 )
2540
2541
2542
2543 func Getitimer(which ItimerWhich) (Itimerval, error) {
2544 var it Itimerval
2545 if err := getitimer(int(which), &it); err != nil {
2546 return Itimerval{}, err
2547 }
2548
2549 return it, nil
2550 }
2551
2552
2553
2554
2555
2556 func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
2557 var prev Itimerval
2558 if err := setitimer(int(which), &it, &prev); err != nil {
2559 return Itimerval{}, err
2560 }
2561
2562 return prev, nil
2563 }
2564
2565
2566
2567 func PthreadSigmask(how int, set, oldset *Sigset_t) error {
2568 if oldset != nil {
2569
2570 *oldset = Sigset_t{}
2571 }
2572 return rtSigprocmask(how, set, oldset, _C__NSIG/8)
2573 }
2574
2575
2576
2577
2578 func Getresuid() (ruid, euid, suid int) {
2579 var r, e, s _C_int
2580 getresuid(&r, &e, &s)
2581 return int(r), int(e), int(s)
2582 }
2583
2584 func Getresgid() (rgid, egid, sgid int) {
2585 var r, e, s _C_int
2586 getresgid(&r, &e, &s)
2587 return int(r), int(e), int(s)
2588 }
2589
2590
2591
2592 func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
2593
2594
2595
2596 var mutableTimeout *Timespec
2597 if timeout != nil {
2598 mutableTimeout = new(Timespec)
2599 *mutableTimeout = *timeout
2600 }
2601
2602
2603
2604 var kernelMask *sigset_argpack
2605 if sigmask != nil {
2606 wordBits := 32 << (^uintptr(0) >> 63)
2607
2608
2609
2610
2611 sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits)
2612
2613 sigsetBytes := uintptr(sigsetWords * (wordBits / 8))
2614 kernelMask = &sigset_argpack{
2615 ss: sigmask,
2616 ssLen: sigsetBytes,
2617 }
2618 }
2619
2620 return pselect6(nfd, r, w, e, mutableTimeout, kernelMask)
2621 }
2622
2623
2624
2625
2626
2627
2628 func SchedSetAttr(pid int, attr *SchedAttr, flags uint) error {
2629 if attr == nil {
2630 return EINVAL
2631 }
2632 attr.Size = SizeofSchedAttr
2633 return schedSetattr(pid, attr, flags)
2634 }
2635
2636
2637
2638 func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) {
2639 attr := &SchedAttr{}
2640 if err := schedGetattr(pid, attr, SizeofSchedAttr, flags); err != nil {
2641 return nil, err
2642 }
2643 return attr, nil
2644 }
2645
2646
2647
2648
View as plain text