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 clear(sa.raw[14 : 14+IFNAMSIZ])
805 copy(sa.raw[14:], sa.Dev)
806 return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
807 }
808
809
810
811 type SockaddrTIPC struct {
812
813
814 Scope int
815
816
817
818
819
820
821
822
823 Addr TIPCAddr
824
825 raw RawSockaddrTIPC
826 }
827
828
829
830
831 type TIPCAddr interface {
832 tipcAddrtype() uint8
833 tipcAddr() [12]byte
834 }
835
836 func (sa *TIPCSocketAddr) tipcAddr() [12]byte {
837 var out [12]byte
838 copy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:])
839 return out
840 }
841
842 func (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR }
843
844 func (sa *TIPCServiceRange) tipcAddr() [12]byte {
845 var out [12]byte
846 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:])
847 return out
848 }
849
850 func (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE }
851
852 func (sa *TIPCServiceName) tipcAddr() [12]byte {
853 var out [12]byte
854 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:])
855 return out
856 }
857
858 func (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR }
859
860 func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) {
861 if sa.Addr == nil {
862 return nil, 0, EINVAL
863 }
864 sa.raw.Family = AF_TIPC
865 sa.raw.Scope = int8(sa.Scope)
866 sa.raw.Addrtype = sa.Addr.tipcAddrtype()
867 sa.raw.Addr = sa.Addr.tipcAddr()
868 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
869 }
870
871
872 type SockaddrL2TPIP struct {
873 Addr [4]byte
874 ConnId uint32
875 raw RawSockaddrL2TPIP
876 }
877
878 func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {
879 sa.raw.Family = AF_INET
880 sa.raw.Conn_id = sa.ConnId
881 sa.raw.Addr = sa.Addr
882 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil
883 }
884
885
886 type SockaddrL2TPIP6 struct {
887 Addr [16]byte
888 ZoneId uint32
889 ConnId uint32
890 raw RawSockaddrL2TPIP6
891 }
892
893 func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {
894 sa.raw.Family = AF_INET6
895 sa.raw.Conn_id = sa.ConnId
896 sa.raw.Scope_id = sa.ZoneId
897 sa.raw.Addr = sa.Addr
898 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
899 }
900
901
902 type SockaddrIUCV struct {
903 UserID string
904 Name string
905 raw RawSockaddrIUCV
906 }
907
908 func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
909 sa.raw.Family = AF_IUCV
910
911
912
913 for i := range 8 {
914 sa.raw.Nodeid[i] = ' '
915 sa.raw.User_id[i] = ' '
916 sa.raw.Name[i] = ' '
917 }
918 if len(sa.UserID) > 8 || len(sa.Name) > 8 {
919 return nil, 0, EINVAL
920 }
921 for i, b := range []byte(sa.UserID[:]) {
922 sa.raw.User_id[i] = int8(b)
923 }
924 for i, b := range []byte(sa.Name[:]) {
925 sa.raw.Name[i] = int8(b)
926 }
927 return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil
928 }
929
930 type SockaddrNFC struct {
931 DeviceIdx uint32
932 TargetIdx uint32
933 NFCProtocol uint32
934 raw RawSockaddrNFC
935 }
936
937 func (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) {
938 sa.raw.Sa_family = AF_NFC
939 sa.raw.Dev_idx = sa.DeviceIdx
940 sa.raw.Target_idx = sa.TargetIdx
941 sa.raw.Nfc_protocol = sa.NFCProtocol
942 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil
943 }
944
945 type SockaddrNFCLLCP struct {
946 DeviceIdx uint32
947 TargetIdx uint32
948 NFCProtocol uint32
949 DestinationSAP uint8
950 SourceSAP uint8
951 ServiceName string
952 raw RawSockaddrNFCLLCP
953 }
954
955 func (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) {
956 sa.raw.Sa_family = AF_NFC
957 sa.raw.Dev_idx = sa.DeviceIdx
958 sa.raw.Target_idx = sa.TargetIdx
959 sa.raw.Nfc_protocol = sa.NFCProtocol
960 sa.raw.Dsap = sa.DestinationSAP
961 sa.raw.Ssap = sa.SourceSAP
962 if len(sa.ServiceName) > len(sa.raw.Service_name) {
963 return nil, 0, EINVAL
964 }
965 copy(sa.raw.Service_name[:], sa.ServiceName)
966 sa.raw.SetServiceNameLen(len(sa.ServiceName))
967 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil
968 }
969
970 var socketProtocol = func(fd int) (int, error) {
971 return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
972 }
973
974 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
975 switch rsa.Addr.Family {
976 case AF_NETLINK:
977 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
978 sa := new(SockaddrNetlink)
979 sa.Family = pp.Family
980 sa.Pad = pp.Pad
981 sa.Pid = pp.Pid
982 sa.Groups = pp.Groups
983 return sa, nil
984
985 case AF_PACKET:
986 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
987 sa := new(SockaddrLinklayer)
988 sa.Protocol = pp.Protocol
989 sa.Ifindex = int(pp.Ifindex)
990 sa.Hatype = pp.Hatype
991 sa.Pkttype = pp.Pkttype
992 sa.Halen = pp.Halen
993 sa.Addr = pp.Addr
994 return sa, nil
995
996 case AF_UNIX:
997 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
998 sa := new(SockaddrUnix)
999 if pp.Path[0] == 0 {
1000
1001
1002
1003
1004
1005 pp.Path[0] = '@'
1006 }
1007
1008
1009
1010
1011
1012
1013 n := 0
1014 for n < len(pp.Path) && pp.Path[n] != 0 {
1015 n++
1016 }
1017 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
1018 return sa, nil
1019
1020 case AF_INET:
1021 proto, err := socketProtocol(fd)
1022 if err != nil {
1023 return nil, err
1024 }
1025
1026 switch proto {
1027 case IPPROTO_L2TP:
1028 pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))
1029 sa := new(SockaddrL2TPIP)
1030 sa.ConnId = pp.Conn_id
1031 sa.Addr = pp.Addr
1032 return sa, nil
1033 default:
1034 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
1035 sa := new(SockaddrInet4)
1036 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1037 sa.Port = int(p[0])<<8 + int(p[1])
1038 sa.Addr = pp.Addr
1039 return sa, nil
1040 }
1041
1042 case AF_INET6:
1043 proto, err := socketProtocol(fd)
1044 if err != nil {
1045 return nil, err
1046 }
1047
1048 switch proto {
1049 case IPPROTO_L2TP:
1050 pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa))
1051 sa := new(SockaddrL2TPIP6)
1052 sa.ConnId = pp.Conn_id
1053 sa.ZoneId = pp.Scope_id
1054 sa.Addr = pp.Addr
1055 return sa, nil
1056 default:
1057 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
1058 sa := new(SockaddrInet6)
1059 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1060 sa.Port = int(p[0])<<8 + int(p[1])
1061 sa.ZoneId = pp.Scope_id
1062 sa.Addr = pp.Addr
1063 return sa, nil
1064 }
1065
1066 case AF_VSOCK:
1067 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
1068 sa := &SockaddrVM{
1069 CID: pp.Cid,
1070 Port: pp.Port,
1071 Flags: pp.Flags,
1072 }
1073 return sa, nil
1074 case AF_BLUETOOTH:
1075 proto, err := socketProtocol(fd)
1076 if err != nil {
1077 return nil, err
1078 }
1079
1080 switch proto {
1081 case BTPROTO_L2CAP:
1082 pp := (*RawSockaddrL2)(unsafe.Pointer(rsa))
1083 sa := &SockaddrL2{
1084 PSM: pp.Psm,
1085 CID: pp.Cid,
1086 Addr: pp.Bdaddr,
1087 AddrType: pp.Bdaddr_type,
1088 }
1089 return sa, nil
1090 case BTPROTO_RFCOMM:
1091 pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa))
1092 sa := &SockaddrRFCOMM{
1093 Channel: pp.Channel,
1094 Addr: pp.Bdaddr,
1095 }
1096 return sa, nil
1097 }
1098 case AF_XDP:
1099 pp := (*RawSockaddrXDP)(unsafe.Pointer(rsa))
1100 sa := &SockaddrXDP{
1101 Flags: pp.Flags,
1102 Ifindex: pp.Ifindex,
1103 QueueID: pp.Queue_id,
1104 SharedUmemFD: pp.Shared_umem_fd,
1105 }
1106 return sa, nil
1107 case AF_PPPOX:
1108 pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa))
1109 if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe {
1110 return nil, EINVAL
1111 }
1112 sa := &SockaddrPPPoE{
1113 SID: binary.BigEndian.Uint16(pp[6:8]),
1114 Remote: pp[8:14],
1115 }
1116 for i := 14; i < 14+IFNAMSIZ; i++ {
1117 if pp[i] == 0 {
1118 sa.Dev = string(pp[14:i])
1119 break
1120 }
1121 }
1122 return sa, nil
1123 case AF_TIPC:
1124 pp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa))
1125
1126 sa := &SockaddrTIPC{
1127 Scope: int(pp.Scope),
1128 }
1129
1130
1131
1132 switch pp.Addrtype {
1133 case TIPC_SERVICE_RANGE:
1134 sa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr))
1135 case TIPC_SERVICE_ADDR:
1136 sa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr))
1137 case TIPC_SOCKET_ADDR:
1138 sa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr))
1139 default:
1140 return nil, EINVAL
1141 }
1142
1143 return sa, nil
1144 case AF_IUCV:
1145 pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa))
1146
1147 var user [8]byte
1148 var name [8]byte
1149
1150 for i := range 8 {
1151 user[i] = byte(pp.User_id[i])
1152 name[i] = byte(pp.Name[i])
1153 }
1154
1155 sa := &SockaddrIUCV{
1156 UserID: string(user[:]),
1157 Name: string(name[:]),
1158 }
1159 return sa, nil
1160
1161 case AF_CAN:
1162 proto, err := socketProtocol(fd)
1163 if err != nil {
1164 return nil, err
1165 }
1166
1167 pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa))
1168
1169 switch proto {
1170 case CAN_J1939:
1171 sa := &SockaddrCANJ1939{
1172 Ifindex: int(pp.Ifindex),
1173 }
1174 name := (*[8]byte)(unsafe.Pointer(&sa.Name))
1175 for i := range 8 {
1176 name[i] = pp.Addr[i]
1177 }
1178 pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN))
1179 for i := range 4 {
1180 pgn[i] = pp.Addr[i+8]
1181 }
1182 addr := (*[1]byte)(unsafe.Pointer(&sa.Addr))
1183 addr[0] = pp.Addr[12]
1184 return sa, nil
1185 default:
1186 sa := &SockaddrCAN{
1187 Ifindex: int(pp.Ifindex),
1188 }
1189 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
1190 for i := range 4 {
1191 rx[i] = pp.Addr[i]
1192 }
1193 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
1194 for i := range 4 {
1195 tx[i] = pp.Addr[i+4]
1196 }
1197 return sa, nil
1198 }
1199 case AF_NFC:
1200 proto, err := socketProtocol(fd)
1201 if err != nil {
1202 return nil, err
1203 }
1204 switch proto {
1205 case NFC_SOCKPROTO_RAW:
1206 pp := (*RawSockaddrNFC)(unsafe.Pointer(rsa))
1207 sa := &SockaddrNFC{
1208 DeviceIdx: pp.Dev_idx,
1209 TargetIdx: pp.Target_idx,
1210 NFCProtocol: pp.Nfc_protocol,
1211 }
1212 return sa, nil
1213 case NFC_SOCKPROTO_LLCP:
1214 pp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa))
1215 if uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) {
1216 return nil, EINVAL
1217 }
1218 sa := &SockaddrNFCLLCP{
1219 DeviceIdx: pp.Dev_idx,
1220 TargetIdx: pp.Target_idx,
1221 NFCProtocol: pp.Nfc_protocol,
1222 DestinationSAP: pp.Dsap,
1223 SourceSAP: pp.Ssap,
1224 ServiceName: string(pp.Service_name[:pp.Service_name_len]),
1225 }
1226 return sa, nil
1227 default:
1228 return nil, EINVAL
1229 }
1230 }
1231 return nil, EAFNOSUPPORT
1232 }
1233
1234 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
1235 var rsa RawSockaddrAny
1236 var len _Socklen = SizeofSockaddrAny
1237 nfd, err = accept4(fd, &rsa, &len, 0)
1238 if err != nil {
1239 return
1240 }
1241 sa, err = anyToSockaddr(fd, &rsa)
1242 if err != nil {
1243 Close(nfd)
1244 nfd = 0
1245 }
1246 return
1247 }
1248
1249 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
1250 var rsa RawSockaddrAny
1251 var len _Socklen = SizeofSockaddrAny
1252 nfd, err = accept4(fd, &rsa, &len, flags)
1253 if err != nil {
1254 return
1255 }
1256 if len > SizeofSockaddrAny {
1257 panic("RawSockaddrAny too small")
1258 }
1259 sa, err = anyToSockaddr(fd, &rsa)
1260 if err != nil {
1261 Close(nfd)
1262 nfd = 0
1263 }
1264 return
1265 }
1266
1267 func Getsockname(fd int) (sa Sockaddr, err error) {
1268 var rsa RawSockaddrAny
1269 var len _Socklen = SizeofSockaddrAny
1270 if err = getsockname(fd, &rsa, &len); err != nil {
1271 return
1272 }
1273 return anyToSockaddr(fd, &rsa)
1274 }
1275
1276 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
1277 var value IPMreqn
1278 vallen := _Socklen(SizeofIPMreqn)
1279 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1280 return &value, err
1281 }
1282
1283 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
1284 var value Ucred
1285 vallen := _Socklen(SizeofUcred)
1286 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1287 return &value, err
1288 }
1289
1290 func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
1291 var value TCPInfo
1292 vallen := _Socklen(SizeofTCPInfo)
1293 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1294 return &value, err
1295 }
1296
1297
1298
1299
1300
1301
1302
1303 func GetsockoptTCPCCVegasInfo(fd, level, opt int) (*TCPVegasInfo, error) {
1304 var value [SizeofTCPCCInfo / 4]uint32
1305 vallen := _Socklen(SizeofTCPCCInfo)
1306 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
1307 out := (*TCPVegasInfo)(unsafe.Pointer(&value[0]))
1308 return out, err
1309 }
1310
1311
1312
1313
1314
1315
1316
1317 func GetsockoptTCPCCDCTCPInfo(fd, level, opt int) (*TCPDCTCPInfo, error) {
1318 var value [SizeofTCPCCInfo / 4]uint32
1319 vallen := _Socklen(SizeofTCPCCInfo)
1320 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
1321 out := (*TCPDCTCPInfo)(unsafe.Pointer(&value[0]))
1322 return out, err
1323 }
1324
1325
1326
1327
1328
1329
1330
1331 func GetsockoptTCPCCBBRInfo(fd, level, opt int) (*TCPBBRInfo, error) {
1332 var value [SizeofTCPCCInfo / 4]uint32
1333 vallen := _Socklen(SizeofTCPCCInfo)
1334 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
1335 out := (*TCPBBRInfo)(unsafe.Pointer(&value[0]))
1336 return out, err
1337 }
1338
1339
1340
1341 func GetsockoptString(fd, level, opt int) (string, error) {
1342 buf := make([]byte, 256)
1343 vallen := _Socklen(len(buf))
1344 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1345 if err != nil {
1346 if err == ERANGE {
1347 buf = make([]byte, vallen)
1348 err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1349 }
1350 if err != nil {
1351 return "", err
1352 }
1353 }
1354 return ByteSliceToString(buf[:vallen]), nil
1355 }
1356
1357 func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) {
1358 var value TpacketStats
1359 vallen := _Socklen(SizeofTpacketStats)
1360 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1361 return &value, err
1362 }
1363
1364 func GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) {
1365 var value TpacketStatsV3
1366 vallen := _Socklen(SizeofTpacketStatsV3)
1367 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1368 return &value, err
1369 }
1370
1371 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
1372 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
1373 }
1374
1375 func SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error {
1376 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
1377 }
1378
1379
1380
1381 func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error {
1382 return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog))
1383 }
1384
1385 func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error {
1386 var p unsafe.Pointer
1387 if len(filter) > 0 {
1388 p = unsafe.Pointer(&filter[0])
1389 }
1390 return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter))
1391 }
1392
1393 func SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error {
1394 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))
1395 }
1396
1397 func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error {
1398 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))
1399 }
1400
1401 func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) {
1402 if len(o) == 0 {
1403 return EINVAL
1404 }
1405 return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o)))
1406 }
1407
1408 func SetsockoptTCPMD5Sig(fd, level, opt int, s *TCPMD5Sig) error {
1409 return setsockopt(fd, level, opt, unsafe.Pointer(s), unsafe.Sizeof(*s))
1410 }
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428 func KeyctlString(cmd int, id int) (string, error) {
1429
1430
1431
1432
1433 var buffer []byte
1434 for {
1435
1436 length, err := KeyctlBuffer(cmd, id, buffer, 0)
1437 if err != nil {
1438 return "", err
1439 }
1440
1441
1442 if length <= len(buffer) {
1443
1444 return string(buffer[:length-1]), nil
1445 }
1446
1447
1448 buffer = make([]byte, length)
1449 }
1450 }
1451
1452
1453
1454
1455
1456
1457 func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) {
1458 createInt := 0
1459 if create {
1460 createInt = 1
1461 }
1462 return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0)
1463 }
1464
1465
1466
1467
1468
1469
1470 func KeyctlSetperm(id int, perm uint32) error {
1471 _, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0)
1472 return err
1473 }
1474
1475
1476
1477
1478
1479
1480 func KeyctlJoinSessionKeyring(name string) (ringid int, err error) {
1481 return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name)
1482 }
1483
1484
1485
1486
1487
1488
1489 func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) {
1490 return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid)
1491 }
1492
1493
1494
1495
1496
1497
1498
1499
1500 func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error {
1501 return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid)
1502 }
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) {
1516 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)
1517 }
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537 func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error {
1538 if keyType == "" {
1539 return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid)
1540 }
1541 return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction)
1542 }
1543
1544
1545
1546
1547 func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
1548 var msg Msghdr
1549 msg.Name = (*byte)(unsafe.Pointer(rsa))
1550 msg.Namelen = uint32(SizeofSockaddrAny)
1551 var dummy byte
1552 if len(oob) > 0 {
1553 if emptyIovecs(iov) {
1554 var sockType int
1555 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
1556 if err != nil {
1557 return
1558 }
1559
1560 if sockType != SOCK_DGRAM {
1561 var iova [1]Iovec
1562 iova[0].Base = &dummy
1563 iova[0].SetLen(1)
1564 iov = iova[:]
1565 }
1566 }
1567 msg.Control = &oob[0]
1568 msg.SetControllen(len(oob))
1569 }
1570 if len(iov) > 0 {
1571 msg.Iov = &iov[0]
1572 msg.SetIovlen(len(iov))
1573 }
1574 if n, err = recvmsg(fd, &msg, flags); err != nil {
1575 return
1576 }
1577 oobn = int(msg.Controllen)
1578 recvflags = int(msg.Flags)
1579 return
1580 }
1581
1582 func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
1583 var msg Msghdr
1584 msg.Name = (*byte)(ptr)
1585 msg.Namelen = uint32(salen)
1586 var dummy byte
1587 var empty bool
1588 if len(oob) > 0 {
1589 empty = emptyIovecs(iov)
1590 if empty {
1591 var sockType int
1592 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
1593 if err != nil {
1594 return 0, err
1595 }
1596
1597 if sockType != SOCK_DGRAM {
1598 var iova [1]Iovec
1599 iova[0].Base = &dummy
1600 iova[0].SetLen(1)
1601 iov = iova[:]
1602 }
1603 }
1604 msg.Control = &oob[0]
1605 msg.SetControllen(len(oob))
1606 }
1607 if len(iov) > 0 {
1608 msg.Iov = &iov[0]
1609 msg.SetIovlen(len(iov))
1610 }
1611 if n, err = sendmsg(fd, &msg, flags); err != nil {
1612 return 0, err
1613 }
1614 if len(oob) > 0 && empty {
1615 n = 0
1616 }
1617 return n, nil
1618 }
1619
1620
1621 func BindToDevice(fd int, device string) (err error) {
1622 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
1623 }
1624
1625
1626
1627
1628 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
1629
1630
1631
1632
1633
1634
1635 var buf [SizeofPtr]byte
1636
1637
1638
1639
1640
1641
1642 n := 0
1643 if addr%SizeofPtr != 0 {
1644 err = ptracePtr(req, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))
1645 if err != nil {
1646 return 0, err
1647 }
1648 n += copy(out, buf[addr%SizeofPtr:])
1649 out = out[n:]
1650 }
1651
1652
1653 for len(out) > 0 {
1654
1655
1656 err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
1657 if err != nil {
1658 return n, err
1659 }
1660 copied := copy(out, buf[0:])
1661 n += copied
1662 out = out[copied:]
1663 }
1664
1665 return n, nil
1666 }
1667
1668 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
1669 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
1670 }
1671
1672 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
1673 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
1674 }
1675
1676 func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) {
1677 return ptracePeek(PTRACE_PEEKUSR, pid, addr, out)
1678 }
1679
1680 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
1681
1682
1683
1684
1685 n := 0
1686 if addr%SizeofPtr != 0 {
1687 var buf [SizeofPtr]byte
1688 err = ptracePtr(peekReq, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))
1689 if err != nil {
1690 return 0, err
1691 }
1692 n += copy(buf[addr%SizeofPtr:], data)
1693 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1694 err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word)
1695 if err != nil {
1696 return 0, err
1697 }
1698 data = data[n:]
1699 }
1700
1701
1702 for len(data) > SizeofPtr {
1703 word := *((*uintptr)(unsafe.Pointer(&data[0])))
1704 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1705 if err != nil {
1706 return n, err
1707 }
1708 n += SizeofPtr
1709 data = data[SizeofPtr:]
1710 }
1711
1712
1713 if len(data) > 0 {
1714 var buf [SizeofPtr]byte
1715 err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
1716 if err != nil {
1717 return n, err
1718 }
1719 copy(buf[0:], data)
1720 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1721 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1722 if err != nil {
1723 return n, err
1724 }
1725 n += len(data)
1726 }
1727
1728 return n, nil
1729 }
1730
1731 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
1732 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
1733 }
1734
1735 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
1736 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
1737 }
1738
1739 func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) {
1740 return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data)
1741 }
1742
1743
1744
1745
1746 const elfNT_PRSTATUS = 1
1747
1748 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
1749 var iov Iovec
1750 iov.Base = (*byte)(unsafe.Pointer(regsout))
1751 iov.SetLen(int(unsafe.Sizeof(*regsout)))
1752 return ptracePtr(PTRACE_GETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
1753 }
1754
1755 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
1756 var iov Iovec
1757 iov.Base = (*byte)(unsafe.Pointer(regs))
1758 iov.SetLen(int(unsafe.Sizeof(*regs)))
1759 return ptracePtr(PTRACE_SETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
1760 }
1761
1762 func PtraceSetOptions(pid int, options int) (err error) {
1763 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
1764 }
1765
1766 func PtraceGetEventMsg(pid int) (msg uint, err error) {
1767 var data _C_long
1768 err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
1769 msg = uint(data)
1770 return
1771 }
1772
1773 func PtraceCont(pid int, signal int) (err error) {
1774 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
1775 }
1776
1777 func PtraceSyscall(pid int, signal int) (err error) {
1778 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
1779 }
1780
1781 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
1782
1783 func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) }
1784
1785 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
1786
1787 func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) }
1788
1789 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
1790
1791
1792
1793 func Reboot(cmd int) (err error) {
1794 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
1795 }
1796
1797 func direntIno(buf []byte) (uint64, bool) {
1798 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
1799 }
1800
1801 func direntReclen(buf []byte) (uint64, bool) {
1802 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
1803 }
1804
1805 func direntNamlen(buf []byte) (uint64, bool) {
1806 reclen, ok := direntReclen(buf)
1807 if !ok {
1808 return 0, false
1809 }
1810 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
1811 }
1812
1813
1814
1815 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1816
1817
1818 if data == "" {
1819 return mount(source, target, fstype, flags, nil)
1820 }
1821 datap, err := BytePtrFromString(data)
1822 if err != nil {
1823 return err
1824 }
1825 return mount(source, target, fstype, flags, datap)
1826 }
1827
1828
1829
1830
1831
1832
1833
1834 func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error {
1835 return mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr))
1836 }
1837
1838 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
1839 if raceenabled {
1840 raceReleaseMerge(unsafe.Pointer(&ioSync))
1841 }
1842 return sendfile(outfd, infd, offset, count)
1843 }
1844
1845
1846
1847
1848
1849
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870 func Dup2(oldfd, newfd int) error {
1871 return Dup3(oldfd, newfd, 0)
1872 }
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897 func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) {
1898 var keyp *byte
1899 if keyp, err = BytePtrFromString(key); err != nil {
1900 return
1901 }
1902 return fsconfig(fd, cmd, keyp, value, aux)
1903 }
1904
1905
1906
1907
1908
1909
1910 func FsconfigSetFlag(fd int, key string) (err error) {
1911 return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0)
1912 }
1913
1914
1915
1916
1917
1918
1919
1920 func FsconfigSetString(fd int, key string, value string) (err error) {
1921 var valuep *byte
1922 if valuep, err = BytePtrFromString(value); err != nil {
1923 return
1924 }
1925 return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0)
1926 }
1927
1928
1929
1930
1931
1932
1933
1934 func FsconfigSetBinary(fd int, key string, value []byte) (err error) {
1935 if len(value) == 0 {
1936 return EINVAL
1937 }
1938 return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value))
1939 }
1940
1941
1942
1943
1944
1945
1946
1947
1948 func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) {
1949 var valuep *byte
1950 if valuep, err = BytePtrFromString(path); err != nil {
1951 return
1952 }
1953 return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd)
1954 }
1955
1956
1957
1958
1959 func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) {
1960 var valuep *byte
1961 if valuep, err = BytePtrFromString(path); err != nil {
1962 return
1963 }
1964 return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd)
1965 }
1966
1967
1968
1969
1970
1971
1972
1973 func FsconfigSetFd(fd int, key string, value int) (err error) {
1974 return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value)
1975 }
1976
1977
1978
1979
1980
1981 func FsconfigCreate(fd int) (err error) {
1982 return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0)
1983 }
1984
1985
1986
1987
1988
1989 func FsconfigReconfigure(fd int) (err error) {
1990 return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0)
1991 }
1992
1993
1994
1995
1996 func Getpgrp() (pid int) {
1997 pid, _ = Getpgid(0)
1998 return
1999 }
2000
2001
2002
2003
2004
2005 func Getrandom(buf []byte, flags int) (n int, err error) {
2006 vdsoRet, supported := vgetrandom(buf, uint32(flags))
2007 if supported {
2008 if vdsoRet < 0 {
2009 return 0, errnoErr(syscall.Errno(-vdsoRet))
2010 }
2011 return vdsoRet, nil
2012 }
2013 var p *byte
2014 if len(buf) > 0 {
2015 p = &buf[0]
2016 }
2017 r, _, e := Syscall(SYS_GETRANDOM, uintptr(unsafe.Pointer(p)), uintptr(len(buf)), uintptr(flags))
2018 if e != 0 {
2019 return 0, errnoErr(e)
2020 }
2021 return int(r), nil
2022 }
2023
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 func syscall_prlimit(pid, resource int, newlimit, old *syscall.Rlimit) error
2062
2063 func Prlimit(pid, resource int, newlimit, old *Rlimit) error {
2064
2065
2066 return syscall_prlimit(pid, resource, (*syscall.Rlimit)(newlimit), (*syscall.Rlimit)(old))
2067 }
2068
2069
2070
2071
2072 func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) {
2073 ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0)
2074 if err != 0 {
2075 return 0, err
2076 }
2077 return int(ret), nil
2078 }
2079
2080 func Setuid(uid int) (err error) {
2081 return syscall.Setuid(uid)
2082 }
2083
2084 func Setgid(gid int) (err error) {
2085 return syscall.Setgid(gid)
2086 }
2087
2088 func Setreuid(ruid, euid int) (err error) {
2089 return syscall.Setreuid(ruid, euid)
2090 }
2091
2092 func Setregid(rgid, egid int) (err error) {
2093 return syscall.Setregid(rgid, egid)
2094 }
2095
2096 func Setresuid(ruid, euid, suid int) (err error) {
2097 return syscall.Setresuid(ruid, euid, suid)
2098 }
2099
2100 func Setresgid(rgid, egid, sgid int) (err error) {
2101 return syscall.Setresgid(rgid, egid, sgid)
2102 }
2103
2104
2105
2106
2107 func SetfsgidRetGid(gid int) (int, error) {
2108 return setfsgid(gid)
2109 }
2110
2111
2112
2113
2114 func SetfsuidRetUid(uid int) (int, error) {
2115 return setfsuid(uid)
2116 }
2117
2118 func Setfsgid(gid int) error {
2119 _, err := setfsgid(gid)
2120 return err
2121 }
2122
2123 func Setfsuid(uid int) error {
2124 _, err := setfsuid(uid)
2125 return err
2126 }
2127
2128 func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
2129 return signalfd(fd, sigmask, _C__NSIG/8, flags)
2130 }
2131
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 const minIovec = 8
2165
2166
2167 func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
2168 for _, b := range bs {
2169 var v Iovec
2170 v.SetLen(len(b))
2171 if len(b) > 0 {
2172 v.Base = &b[0]
2173 } else {
2174 v.Base = (*byte)(unsafe.Pointer(&_zero))
2175 }
2176 vecs = append(vecs, v)
2177 }
2178 return vecs
2179 }
2180
2181
2182 func offs2lohi(offs int64) (lo, hi uintptr) {
2183 const longBits = SizeofLong * 8
2184 return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1)
2185 }
2186
2187 func Readv(fd int, iovs [][]byte) (n int, err error) {
2188 iovecs := make([]Iovec, 0, minIovec)
2189 iovecs = appendBytes(iovecs, iovs)
2190 n, err = readv(fd, iovecs)
2191 readvRacedetect(iovecs, n, err)
2192 return n, err
2193 }
2194
2195 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
2196 iovecs := make([]Iovec, 0, minIovec)
2197 iovecs = appendBytes(iovecs, iovs)
2198 lo, hi := offs2lohi(offset)
2199 n, err = preadv(fd, iovecs, lo, hi)
2200 readvRacedetect(iovecs, n, err)
2201 return n, err
2202 }
2203
2204 func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
2205 iovecs := make([]Iovec, 0, minIovec)
2206 iovecs = appendBytes(iovecs, iovs)
2207 lo, hi := offs2lohi(offset)
2208 n, err = preadv2(fd, iovecs, lo, hi, flags)
2209 readvRacedetect(iovecs, n, err)
2210 return n, err
2211 }
2212
2213 func readvRacedetect(iovecs []Iovec, n int, err error) {
2214 if !raceenabled {
2215 return
2216 }
2217 for i := 0; n > 0 && i < len(iovecs); i++ {
2218 m := min(int(iovecs[i].Len), n)
2219 n -= m
2220 if m > 0 {
2221 raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
2222 }
2223 }
2224 if err == nil {
2225 raceAcquire(unsafe.Pointer(&ioSync))
2226 }
2227 }
2228
2229 func Writev(fd int, iovs [][]byte) (n int, err error) {
2230 iovecs := make([]Iovec, 0, minIovec)
2231 iovecs = appendBytes(iovecs, iovs)
2232 if raceenabled {
2233 raceReleaseMerge(unsafe.Pointer(&ioSync))
2234 }
2235 n, err = writev(fd, iovecs)
2236 writevRacedetect(iovecs, n)
2237 return n, err
2238 }
2239
2240 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
2241 iovecs := make([]Iovec, 0, minIovec)
2242 iovecs = appendBytes(iovecs, iovs)
2243 if raceenabled {
2244 raceReleaseMerge(unsafe.Pointer(&ioSync))
2245 }
2246 lo, hi := offs2lohi(offset)
2247 n, err = pwritev(fd, iovecs, lo, hi)
2248 writevRacedetect(iovecs, n)
2249 return n, err
2250 }
2251
2252 func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
2253 iovecs := make([]Iovec, 0, minIovec)
2254 iovecs = appendBytes(iovecs, iovs)
2255 if raceenabled {
2256 raceReleaseMerge(unsafe.Pointer(&ioSync))
2257 }
2258 lo, hi := offs2lohi(offset)
2259 n, err = pwritev2(fd, iovecs, lo, hi, flags)
2260 writevRacedetect(iovecs, n)
2261 return n, err
2262 }
2263
2264 func writevRacedetect(iovecs []Iovec, n int) {
2265 if !raceenabled {
2266 return
2267 }
2268 for i := 0; n > 0 && i < len(iovecs); i++ {
2269 m := min(int(iovecs[i].Len), n)
2270 n -= m
2271 if m > 0 {
2272 raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
2273 }
2274 }
2275 }
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288 const (
2289 mremapFixed = MREMAP_FIXED
2290 mremapDontunmap = MREMAP_DONTUNMAP
2291 mremapMaymove = MREMAP_MAYMOVE
2292 )
2293
2294
2295
2296 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
2297 var p unsafe.Pointer
2298 if len(iovs) > 0 {
2299 p = unsafe.Pointer(&iovs[0])
2300 }
2301
2302 n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0)
2303 if errno != 0 {
2304 return 0, syscall.Errno(errno)
2305 }
2306
2307 return int(n), nil
2308 }
2309
2310 func isGroupMember(gid int) bool {
2311 groups, err := Getgroups()
2312 if err != nil {
2313 return false
2314 }
2315
2316 return slices.Contains(groups, gid)
2317 }
2318
2319 func isCapDacOverrideSet() bool {
2320 hdr := CapUserHeader{Version: LINUX_CAPABILITY_VERSION_3}
2321 data := [2]CapUserData{}
2322 err := Capget(&hdr, &data[0])
2323
2324 return err == nil && data[0].Effective&(1<<CAP_DAC_OVERRIDE) != 0
2325 }
2326
2327
2328
2329
2330 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
2331 if flags == 0 {
2332 return faccessat(dirfd, path, mode)
2333 }
2334
2335 if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
2336 return err
2337 }
2338
2339
2340
2341
2342
2343
2344
2345 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
2346 return EINVAL
2347 }
2348
2349 var st Stat_t
2350 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil {
2351 return err
2352 }
2353
2354 mode &= 7
2355 if mode == 0 {
2356 return nil
2357 }
2358
2359 var uid int
2360 if flags&AT_EACCESS != 0 {
2361 uid = Geteuid()
2362 if uid != 0 && isCapDacOverrideSet() {
2363
2364
2365
2366 uid = 0
2367 }
2368 } else {
2369 uid = Getuid()
2370 }
2371
2372 if uid == 0 {
2373 if mode&1 == 0 {
2374
2375 return nil
2376 }
2377 if st.Mode&0111 != 0 {
2378
2379 return nil
2380 }
2381 return EACCES
2382 }
2383
2384 var fmode uint32
2385 if uint32(uid) == st.Uid {
2386 fmode = (st.Mode >> 6) & 7
2387 } else {
2388 var gid int
2389 if flags&AT_EACCESS != 0 {
2390 gid = Getegid()
2391 } else {
2392 gid = Getgid()
2393 }
2394
2395 if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
2396 fmode = (st.Mode >> 3) & 7
2397 } else {
2398 fmode = st.Mode & 7
2399 }
2400 }
2401
2402 if fmode&mode == mode {
2403 return nil
2404 }
2405
2406 return EACCES
2407 }
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417 type fileHandle struct {
2418 Bytes uint32
2419 Type int32
2420 }
2421
2422
2423
2424
2425 type FileHandle struct {
2426 *fileHandle
2427 }
2428
2429
2430 func NewFileHandle(handleType int32, handle []byte) FileHandle {
2431 const hdrSize = unsafe.Sizeof(fileHandle{})
2432 buf := make([]byte, hdrSize+uintptr(len(handle)))
2433 copy(buf[hdrSize:], handle)
2434 fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
2435 fh.Type = handleType
2436 fh.Bytes = uint32(len(handle))
2437 return FileHandle{fh}
2438 }
2439
2440 func (fh *FileHandle) Size() int { return int(fh.fileHandle.Bytes) }
2441 func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type }
2442 func (fh *FileHandle) Bytes() []byte {
2443 n := fh.Size()
2444 if n == 0 {
2445 return nil
2446 }
2447 return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)
2448 }
2449
2450
2451
2452 func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) {
2453 var mid _C_int
2454
2455
2456 size := uint32(32 + unsafe.Sizeof(fileHandle{}))
2457 didResize := false
2458 for {
2459 buf := make([]byte, size)
2460 fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
2461 fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{}))
2462 err = nameToHandleAt(dirfd, path, fh, &mid, flags)
2463 if err == EOVERFLOW {
2464 if didResize {
2465
2466 return
2467 }
2468 didResize = true
2469 size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{}))
2470 continue
2471 }
2472 if err != nil {
2473 return
2474 }
2475 return FileHandle{fh}, int(mid), nil
2476 }
2477 }
2478
2479
2480
2481 func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) {
2482 return openByHandleAt(mountFD, handle.fileHandle, flags)
2483 }
2484
2485
2486
2487 func Klogset(typ int, arg int) (err error) {
2488 var p unsafe.Pointer
2489 _, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg))
2490 if errno != 0 {
2491 return errnoErr(errno)
2492 }
2493 return nil
2494 }
2495
2496
2497
2498
2499
2500 type RemoteIovec struct {
2501 Base uintptr
2502 Len int
2503 }
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521 func MakeItimerval(interval, value time.Duration) Itimerval {
2522 return Itimerval{
2523 Interval: NsecToTimeval(interval.Nanoseconds()),
2524 Value: NsecToTimeval(value.Nanoseconds()),
2525 }
2526 }
2527
2528
2529
2530 type ItimerWhich int
2531
2532
2533 const (
2534 ItimerReal ItimerWhich = ITIMER_REAL
2535 ItimerVirtual ItimerWhich = ITIMER_VIRTUAL
2536 ItimerProf ItimerWhich = ITIMER_PROF
2537 )
2538
2539
2540
2541 func Getitimer(which ItimerWhich) (Itimerval, error) {
2542 var it Itimerval
2543 if err := getitimer(int(which), &it); err != nil {
2544 return Itimerval{}, err
2545 }
2546
2547 return it, nil
2548 }
2549
2550
2551
2552
2553
2554 func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
2555 var prev Itimerval
2556 if err := setitimer(int(which), &it, &prev); err != nil {
2557 return Itimerval{}, err
2558 }
2559
2560 return prev, nil
2561 }
2562
2563
2564
2565 func PthreadSigmask(how int, set, oldset *Sigset_t) error {
2566 if oldset != nil {
2567
2568 *oldset = Sigset_t{}
2569 }
2570 return rtSigprocmask(how, set, oldset, _C__NSIG/8)
2571 }
2572
2573
2574
2575
2576 func Getresuid() (ruid, euid, suid int) {
2577 var r, e, s _C_int
2578 getresuid(&r, &e, &s)
2579 return int(r), int(e), int(s)
2580 }
2581
2582 func Getresgid() (rgid, egid, sgid int) {
2583 var r, e, s _C_int
2584 getresgid(&r, &e, &s)
2585 return int(r), int(e), int(s)
2586 }
2587
2588
2589
2590 func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
2591
2592
2593
2594 var mutableTimeout *Timespec
2595 if timeout != nil {
2596 mutableTimeout = new(Timespec)
2597 *mutableTimeout = *timeout
2598 }
2599
2600
2601
2602 var kernelMask *sigset_argpack
2603 if sigmask != nil {
2604 wordBits := 32 << (^uintptr(0) >> 63)
2605
2606
2607
2608
2609 sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits)
2610
2611 sigsetBytes := uintptr(sigsetWords * (wordBits / 8))
2612 kernelMask = &sigset_argpack{
2613 ss: sigmask,
2614 ssLen: sigsetBytes,
2615 }
2616 }
2617
2618 return pselect6(nfd, r, w, e, mutableTimeout, kernelMask)
2619 }
2620
2621
2622
2623
2624
2625
2626 func SchedSetAttr(pid int, attr *SchedAttr, flags uint) error {
2627 if attr == nil {
2628 return EINVAL
2629 }
2630 attr.Size = SizeofSchedAttr
2631 return schedSetattr(pid, attr, flags)
2632 }
2633
2634
2635
2636 func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) {
2637 attr := &SchedAttr{}
2638 if err := schedGetattr(pid, attr, SizeofSchedAttr, flags); err != nil {
2639 return nil, err
2640 }
2641 return attr, nil
2642 }
2643
2644
2645
2646
View as plain text