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