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