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