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