68 |
68 |
69 //sys ioctl(fd int, req uint, arg uintptr) (err error) |
69 //sys ioctl(fd int, req uint, arg uintptr) (err error) |
70 |
70 |
71 // ioctl itself should not be exposed directly, but additional get/set |
71 // ioctl itself should not be exposed directly, but additional get/set |
72 // functions for specific types are permissible. |
72 // functions for specific types are permissible. |
73 |
73 // These are defined in ioctl.go and ioctl_linux.go. |
74 // IoctlRetInt performs an ioctl operation specified by req on a device |
|
75 // associated with opened file descriptor fd, and returns a non-negative |
|
76 // integer that is returned by the ioctl syscall. |
|
77 func IoctlRetInt(fd int, req uint) (int, error) { |
|
78 ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0) |
|
79 if err != 0 { |
|
80 return 0, err |
|
81 } |
|
82 return int(ret), nil |
|
83 } |
|
84 |
|
85 // IoctlSetPointerInt performs an ioctl operation which sets an |
|
86 // integer value on fd, using the specified request number. The ioctl |
|
87 // argument is called with a pointer to the integer value, rather than |
|
88 // passing the integer value directly. |
|
89 func IoctlSetPointerInt(fd int, req uint, value int) error { |
|
90 v := int32(value) |
|
91 return ioctl(fd, req, uintptr(unsafe.Pointer(&v))) |
|
92 } |
|
93 |
|
94 func IoctlSetRTCTime(fd int, value *RTCTime) error { |
|
95 err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value))) |
|
96 runtime.KeepAlive(value) |
|
97 return err |
|
98 } |
|
99 |
|
100 func IoctlGetUint32(fd int, req uint) (uint32, error) { |
|
101 var value uint32 |
|
102 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
|
103 return value, err |
|
104 } |
|
105 |
|
106 func IoctlGetRTCTime(fd int) (*RTCTime, error) { |
|
107 var value RTCTime |
|
108 err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value))) |
|
109 return &value, err |
|
110 } |
|
111 |
74 |
112 //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) |
75 //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) |
113 |
76 |
114 func Link(oldpath string, newpath string) (err error) { |
77 func Link(oldpath string, newpath string) (err error) { |
115 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0) |
78 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0) |
129 |
92 |
130 //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) |
93 //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) |
131 |
94 |
132 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { |
95 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { |
133 return openat(dirfd, path, flags|O_LARGEFILE, mode) |
96 return openat(dirfd, path, flags|O_LARGEFILE, mode) |
|
97 } |
|
98 |
|
99 //sys openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) |
|
100 |
|
101 func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) { |
|
102 return openat2(dirfd, path, how, SizeofOpenHow) |
134 } |
103 } |
135 |
104 |
136 //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) |
105 //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) |
137 |
106 |
138 func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { |
107 func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { |
586 } |
555 } |
587 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) |
556 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) |
588 for i := 0; i < 4; i++ { |
557 for i := 0; i < 4; i++ { |
589 sa.raw.Addr[i+4] = tx[i] |
558 sa.raw.Addr[i+4] = tx[i] |
590 } |
559 } |
|
560 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil |
|
561 } |
|
562 |
|
563 // SockaddrCANJ1939 implements the Sockaddr interface for AF_CAN using J1939 |
|
564 // protocol (https://en.wikipedia.org/wiki/SAE_J1939). For more information |
|
565 // on the purposes of the fields, check the official linux kernel documentation |
|
566 // available here: https://www.kernel.org/doc/Documentation/networking/j1939.rst |
|
567 type SockaddrCANJ1939 struct { |
|
568 Ifindex int |
|
569 Name uint64 |
|
570 PGN uint32 |
|
571 Addr uint8 |
|
572 raw RawSockaddrCAN |
|
573 } |
|
574 |
|
575 func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) { |
|
576 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { |
|
577 return nil, 0, EINVAL |
|
578 } |
|
579 sa.raw.Family = AF_CAN |
|
580 sa.raw.Ifindex = int32(sa.Ifindex) |
|
581 n := (*[8]byte)(unsafe.Pointer(&sa.Name)) |
|
582 for i := 0; i < 8; i++ { |
|
583 sa.raw.Addr[i] = n[i] |
|
584 } |
|
585 p := (*[4]byte)(unsafe.Pointer(&sa.PGN)) |
|
586 for i := 0; i < 4; i++ { |
|
587 sa.raw.Addr[i+8] = p[i] |
|
588 } |
|
589 sa.raw.Addr[12] = sa.Addr |
591 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil |
590 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil |
592 } |
591 } |
593 |
592 |
594 // SockaddrALG implements the Sockaddr interface for AF_ALG type sockets. |
593 // SockaddrALG implements the Sockaddr interface for AF_ALG type sockets. |
595 // SockaddrALG enables userspace access to the Linux kernel's cryptography |
594 // SockaddrALG enables userspace access to the Linux kernel's cryptography |
696 // machines. |
695 // machines. |
697 type SockaddrVM struct { |
696 type SockaddrVM struct { |
698 // CID and Port specify a context ID and port address for a VM socket. |
697 // CID and Port specify a context ID and port address for a VM socket. |
699 // Guests have a unique CID, and hosts may have a well-known CID of: |
698 // Guests have a unique CID, and hosts may have a well-known CID of: |
700 // - VMADDR_CID_HYPERVISOR: refers to the hypervisor process. |
699 // - VMADDR_CID_HYPERVISOR: refers to the hypervisor process. |
|
700 // - VMADDR_CID_LOCAL: refers to local communication (loopback). |
701 // - VMADDR_CID_HOST: refers to other processes on the host. |
701 // - VMADDR_CID_HOST: refers to other processes on the host. |
702 CID uint32 |
702 CID uint32 |
703 Port uint32 |
703 Port uint32 |
704 raw RawSockaddrVM |
704 Flags uint8 |
|
705 raw RawSockaddrVM |
705 } |
706 } |
706 |
707 |
707 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) { |
708 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) { |
708 sa.raw.Family = AF_VSOCK |
709 sa.raw.Family = AF_VSOCK |
709 sa.raw.Port = sa.Port |
710 sa.raw.Port = sa.Port |
710 sa.raw.Cid = sa.CID |
711 sa.raw.Cid = sa.CID |
|
712 sa.raw.Flags = sa.Flags |
711 |
713 |
712 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil |
714 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil |
713 } |
715 } |
714 |
716 |
715 type SockaddrXDP struct { |
717 type SockaddrXDP struct { |
837 sa.raw.Addr = sa.Addr.tipcAddr() |
839 sa.raw.Addr = sa.Addr.tipcAddr() |
838 |
840 |
839 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil |
841 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil |
840 } |
842 } |
841 |
843 |
|
844 // SockaddrL2TPIP implements the Sockaddr interface for IPPROTO_L2TP/AF_INET sockets. |
|
845 type SockaddrL2TPIP struct { |
|
846 Addr [4]byte |
|
847 ConnId uint32 |
|
848 raw RawSockaddrL2TPIP |
|
849 } |
|
850 |
|
851 func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) { |
|
852 sa.raw.Family = AF_INET |
|
853 sa.raw.Conn_id = sa.ConnId |
|
854 for i := 0; i < len(sa.Addr); i++ { |
|
855 sa.raw.Addr[i] = sa.Addr[i] |
|
856 } |
|
857 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil |
|
858 } |
|
859 |
|
860 // SockaddrL2TPIP6 implements the Sockaddr interface for IPPROTO_L2TP/AF_INET6 sockets. |
|
861 type SockaddrL2TPIP6 struct { |
|
862 Addr [16]byte |
|
863 ZoneId uint32 |
|
864 ConnId uint32 |
|
865 raw RawSockaddrL2TPIP6 |
|
866 } |
|
867 |
|
868 func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) { |
|
869 sa.raw.Family = AF_INET6 |
|
870 sa.raw.Conn_id = sa.ConnId |
|
871 sa.raw.Scope_id = sa.ZoneId |
|
872 for i := 0; i < len(sa.Addr); i++ { |
|
873 sa.raw.Addr[i] = sa.Addr[i] |
|
874 } |
|
875 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil |
|
876 } |
|
877 |
|
878 // SockaddrIUCV implements the Sockaddr interface for AF_IUCV sockets. |
|
879 type SockaddrIUCV struct { |
|
880 UserID string |
|
881 Name string |
|
882 raw RawSockaddrIUCV |
|
883 } |
|
884 |
|
885 func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) { |
|
886 sa.raw.Family = AF_IUCV |
|
887 // These are EBCDIC encoded by the kernel, but we still need to pad them |
|
888 // with blanks. Initializing with blanks allows the caller to feed in either |
|
889 // a padded or an unpadded string. |
|
890 for i := 0; i < 8; i++ { |
|
891 sa.raw.Nodeid[i] = ' ' |
|
892 sa.raw.User_id[i] = ' ' |
|
893 sa.raw.Name[i] = ' ' |
|
894 } |
|
895 if len(sa.UserID) > 8 || len(sa.Name) > 8 { |
|
896 return nil, 0, EINVAL |
|
897 } |
|
898 for i, b := range []byte(sa.UserID[:]) { |
|
899 sa.raw.User_id[i] = int8(b) |
|
900 } |
|
901 for i, b := range []byte(sa.Name[:]) { |
|
902 sa.raw.Name[i] = int8(b) |
|
903 } |
|
904 return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil |
|
905 } |
|
906 |
|
907 type SockaddrNFC struct { |
|
908 DeviceIdx uint32 |
|
909 TargetIdx uint32 |
|
910 NFCProtocol uint32 |
|
911 raw RawSockaddrNFC |
|
912 } |
|
913 |
|
914 func (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) { |
|
915 sa.raw.Sa_family = AF_NFC |
|
916 sa.raw.Dev_idx = sa.DeviceIdx |
|
917 sa.raw.Target_idx = sa.TargetIdx |
|
918 sa.raw.Nfc_protocol = sa.NFCProtocol |
|
919 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil |
|
920 } |
|
921 |
|
922 type SockaddrNFCLLCP struct { |
|
923 DeviceIdx uint32 |
|
924 TargetIdx uint32 |
|
925 NFCProtocol uint32 |
|
926 DestinationSAP uint8 |
|
927 SourceSAP uint8 |
|
928 ServiceName string |
|
929 raw RawSockaddrNFCLLCP |
|
930 } |
|
931 |
|
932 func (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) { |
|
933 sa.raw.Sa_family = AF_NFC |
|
934 sa.raw.Dev_idx = sa.DeviceIdx |
|
935 sa.raw.Target_idx = sa.TargetIdx |
|
936 sa.raw.Nfc_protocol = sa.NFCProtocol |
|
937 sa.raw.Dsap = sa.DestinationSAP |
|
938 sa.raw.Ssap = sa.SourceSAP |
|
939 if len(sa.ServiceName) > len(sa.raw.Service_name) { |
|
940 return nil, 0, EINVAL |
|
941 } |
|
942 copy(sa.raw.Service_name[:], sa.ServiceName) |
|
943 sa.raw.SetServiceNameLen(len(sa.ServiceName)) |
|
944 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil |
|
945 } |
|
946 |
|
947 var socketProtocol = func(fd int) (int, error) { |
|
948 return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) |
|
949 } |
|
950 |
842 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { |
951 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { |
843 switch rsa.Addr.Family { |
952 switch rsa.Addr.Family { |
844 case AF_NETLINK: |
953 case AF_NETLINK: |
845 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) |
954 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) |
846 sa := new(SockaddrNetlink) |
955 sa := new(SockaddrNetlink) |
887 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] |
996 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] |
888 sa.Name = string(bytes) |
997 sa.Name = string(bytes) |
889 return sa, nil |
998 return sa, nil |
890 |
999 |
891 case AF_INET: |
1000 case AF_INET: |
892 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) |
1001 proto, err := socketProtocol(fd) |
893 sa := new(SockaddrInet4) |
1002 if err != nil { |
894 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) |
1003 return nil, err |
895 sa.Port = int(p[0])<<8 + int(p[1]) |
1004 } |
896 for i := 0; i < len(sa.Addr); i++ { |
1005 |
897 sa.Addr[i] = pp.Addr[i] |
1006 switch proto { |
898 } |
1007 case IPPROTO_L2TP: |
899 return sa, nil |
1008 pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa)) |
|
1009 sa := new(SockaddrL2TPIP) |
|
1010 sa.ConnId = pp.Conn_id |
|
1011 for i := 0; i < len(sa.Addr); i++ { |
|
1012 sa.Addr[i] = pp.Addr[i] |
|
1013 } |
|
1014 return sa, nil |
|
1015 default: |
|
1016 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) |
|
1017 sa := new(SockaddrInet4) |
|
1018 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) |
|
1019 sa.Port = int(p[0])<<8 + int(p[1]) |
|
1020 for i := 0; i < len(sa.Addr); i++ { |
|
1021 sa.Addr[i] = pp.Addr[i] |
|
1022 } |
|
1023 return sa, nil |
|
1024 } |
900 |
1025 |
901 case AF_INET6: |
1026 case AF_INET6: |
902 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) |
1027 proto, err := socketProtocol(fd) |
903 sa := new(SockaddrInet6) |
1028 if err != nil { |
904 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) |
1029 return nil, err |
905 sa.Port = int(p[0])<<8 + int(p[1]) |
1030 } |
906 sa.ZoneId = pp.Scope_id |
1031 |
907 for i := 0; i < len(sa.Addr); i++ { |
1032 switch proto { |
908 sa.Addr[i] = pp.Addr[i] |
1033 case IPPROTO_L2TP: |
909 } |
1034 pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa)) |
910 return sa, nil |
1035 sa := new(SockaddrL2TPIP6) |
|
1036 sa.ConnId = pp.Conn_id |
|
1037 sa.ZoneId = pp.Scope_id |
|
1038 for i := 0; i < len(sa.Addr); i++ { |
|
1039 sa.Addr[i] = pp.Addr[i] |
|
1040 } |
|
1041 return sa, nil |
|
1042 default: |
|
1043 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) |
|
1044 sa := new(SockaddrInet6) |
|
1045 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) |
|
1046 sa.Port = int(p[0])<<8 + int(p[1]) |
|
1047 sa.ZoneId = pp.Scope_id |
|
1048 for i := 0; i < len(sa.Addr); i++ { |
|
1049 sa.Addr[i] = pp.Addr[i] |
|
1050 } |
|
1051 return sa, nil |
|
1052 } |
911 |
1053 |
912 case AF_VSOCK: |
1054 case AF_VSOCK: |
913 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) |
1055 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) |
914 sa := &SockaddrVM{ |
1056 sa := &SockaddrVM{ |
915 CID: pp.Cid, |
1057 CID: pp.Cid, |
916 Port: pp.Port, |
1058 Port: pp.Port, |
|
1059 Flags: pp.Flags, |
917 } |
1060 } |
918 return sa, nil |
1061 return sa, nil |
919 case AF_BLUETOOTH: |
1062 case AF_BLUETOOTH: |
920 proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) |
1063 proto, err := socketProtocol(fd) |
921 if err != nil { |
1064 if err != nil { |
922 return nil, err |
1065 return nil, err |
923 } |
1066 } |
924 // only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections |
1067 // only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections |
925 switch proto { |
1068 switch proto { |
984 default: |
1127 default: |
985 return nil, EINVAL |
1128 return nil, EINVAL |
986 } |
1129 } |
987 |
1130 |
988 return sa, nil |
1131 return sa, nil |
|
1132 case AF_IUCV: |
|
1133 pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa)) |
|
1134 |
|
1135 var user [8]byte |
|
1136 var name [8]byte |
|
1137 |
|
1138 for i := 0; i < 8; i++ { |
|
1139 user[i] = byte(pp.User_id[i]) |
|
1140 name[i] = byte(pp.Name[i]) |
|
1141 } |
|
1142 |
|
1143 sa := &SockaddrIUCV{ |
|
1144 UserID: string(user[:]), |
|
1145 Name: string(name[:]), |
|
1146 } |
|
1147 return sa, nil |
|
1148 |
|
1149 case AF_CAN: |
|
1150 proto, err := socketProtocol(fd) |
|
1151 if err != nil { |
|
1152 return nil, err |
|
1153 } |
|
1154 |
|
1155 pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa)) |
|
1156 |
|
1157 switch proto { |
|
1158 case CAN_J1939: |
|
1159 sa := &SockaddrCANJ1939{ |
|
1160 Ifindex: int(pp.Ifindex), |
|
1161 } |
|
1162 name := (*[8]byte)(unsafe.Pointer(&sa.Name)) |
|
1163 for i := 0; i < 8; i++ { |
|
1164 name[i] = pp.Addr[i] |
|
1165 } |
|
1166 pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN)) |
|
1167 for i := 0; i < 4; i++ { |
|
1168 pgn[i] = pp.Addr[i+8] |
|
1169 } |
|
1170 addr := (*[1]byte)(unsafe.Pointer(&sa.Addr)) |
|
1171 addr[0] = pp.Addr[12] |
|
1172 return sa, nil |
|
1173 default: |
|
1174 sa := &SockaddrCAN{ |
|
1175 Ifindex: int(pp.Ifindex), |
|
1176 } |
|
1177 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) |
|
1178 for i := 0; i < 4; i++ { |
|
1179 rx[i] = pp.Addr[i] |
|
1180 } |
|
1181 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) |
|
1182 for i := 0; i < 4; i++ { |
|
1183 tx[i] = pp.Addr[i+4] |
|
1184 } |
|
1185 return sa, nil |
|
1186 } |
|
1187 case AF_NFC: |
|
1188 proto, err := socketProtocol(fd) |
|
1189 if err != nil { |
|
1190 return nil, err |
|
1191 } |
|
1192 switch proto { |
|
1193 case NFC_SOCKPROTO_RAW: |
|
1194 pp := (*RawSockaddrNFC)(unsafe.Pointer(rsa)) |
|
1195 sa := &SockaddrNFC{ |
|
1196 DeviceIdx: pp.Dev_idx, |
|
1197 TargetIdx: pp.Target_idx, |
|
1198 NFCProtocol: pp.Nfc_protocol, |
|
1199 } |
|
1200 return sa, nil |
|
1201 case NFC_SOCKPROTO_LLCP: |
|
1202 pp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa)) |
|
1203 if uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) { |
|
1204 return nil, EINVAL |
|
1205 } |
|
1206 sa := &SockaddrNFCLLCP{ |
|
1207 DeviceIdx: pp.Dev_idx, |
|
1208 TargetIdx: pp.Target_idx, |
|
1209 NFCProtocol: pp.Nfc_protocol, |
|
1210 DestinationSAP: pp.Dsap, |
|
1211 SourceSAP: pp.Ssap, |
|
1212 ServiceName: string(pp.Service_name[:pp.Service_name_len]), |
|
1213 } |
|
1214 return sa, nil |
|
1215 default: |
|
1216 return nil, EINVAL |
|
1217 } |
989 } |
1218 } |
990 return nil, EAFNOSUPPORT |
1219 return nil, EAFNOSUPPORT |
991 } |
1220 } |
992 |
1221 |
993 func Accept(fd int) (nfd int, sa Sockaddr, err error) { |
1222 func Accept(fd int) (nfd int, sa Sockaddr, err error) { |
994 var rsa RawSockaddrAny |
1223 var rsa RawSockaddrAny |
995 var len _Socklen = SizeofSockaddrAny |
1224 var len _Socklen = SizeofSockaddrAny |
996 nfd, err = accept(fd, &rsa, &len) |
1225 // Try accept4 first for Android, then try accept for kernel older than 2.6.28 |
|
1226 nfd, err = accept4(fd, &rsa, &len, 0) |
|
1227 if err == ENOSYS { |
|
1228 nfd, err = accept(fd, &rsa, &len) |
|
1229 } |
997 if err != nil { |
1230 if err != nil { |
998 return |
1231 return |
999 } |
1232 } |
1000 sa, err = anyToSockaddr(fd, &rsa) |
1233 sa, err = anyToSockaddr(fd, &rsa) |
1001 if err != nil { |
1234 if err != nil { |
1245 return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid) |
1478 return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid) |
1246 } |
1479 } |
1247 return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction) |
1480 return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction) |
1248 } |
1481 } |
1249 |
1482 |
1250 //sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL |
1483 //sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL |
1251 //sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL |
1484 //sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL |
1252 |
1485 |
1253 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
1486 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
1254 var msg Msghdr |
1487 var msg Msghdr |
1255 var rsa RawSockaddrAny |
1488 var rsa RawSockaddrAny |
1256 msg.Name = (*byte)(unsafe.Pointer(&rsa)) |
1489 msg.Name = (*byte)(unsafe.Pointer(&rsa)) |
1553 * Direct access |
1786 * Direct access |
1554 */ |
1787 */ |
1555 //sys Acct(path string) (err error) |
1788 //sys Acct(path string) (err error) |
1556 //sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) |
1789 //sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) |
1557 //sys Adjtimex(buf *Timex) (state int, err error) |
1790 //sys Adjtimex(buf *Timex) (state int, err error) |
1558 //sys Capget(hdr *CapUserHeader, data *CapUserData) (err error) |
1791 //sysnb Capget(hdr *CapUserHeader, data *CapUserData) (err error) |
1559 //sys Capset(hdr *CapUserHeader, data *CapUserData) (err error) |
1792 //sysnb Capset(hdr *CapUserHeader, data *CapUserData) (err error) |
1560 //sys Chdir(path string) (err error) |
1793 //sys Chdir(path string) (err error) |
1561 //sys Chroot(path string) (err error) |
1794 //sys Chroot(path string) (err error) |
1562 //sys ClockGetres(clockid int32, res *Timespec) (err error) |
1795 //sys ClockGetres(clockid int32, res *Timespec) (err error) |
1563 //sys ClockGettime(clockid int32, time *Timespec) (err error) |
1796 //sys ClockGettime(clockid int32, time *Timespec) (err error) |
1564 //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) |
1797 //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) |
1565 //sys Close(fd int) (err error) |
1798 //sys Close(fd int) (err error) |
|
1799 //sys CloseRange(first uint, last uint, flags uint) (err error) |
1566 //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) |
1800 //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) |
1567 //sys DeleteModule(name string, flags int) (err error) |
1801 //sys DeleteModule(name string, flags int) (err error) |
1568 //sys Dup(oldfd int) (fd int, err error) |
1802 //sys Dup(oldfd int) (fd int, err error) |
|
1803 |
|
1804 func Dup2(oldfd, newfd int) error { |
|
1805 // Android O and newer blocks dup2; riscv and arm64 don't implement dup2. |
|
1806 if runtime.GOOS == "android" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "arm64" { |
|
1807 return Dup3(oldfd, newfd, 0) |
|
1808 } |
|
1809 return dup2(oldfd, newfd) |
|
1810 } |
|
1811 |
1569 //sys Dup3(oldfd int, newfd int, flags int) (err error) |
1812 //sys Dup3(oldfd int, newfd int, flags int) (err error) |
1570 //sysnb EpollCreate1(flag int) (fd int, err error) |
1813 //sysnb EpollCreate1(flag int) (fd int, err error) |
1571 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) |
1814 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) |
1572 //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 |
1815 //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 |
1573 //sys Exit(code int) = SYS_EXIT_GROUP |
1816 //sys Exit(code int) = SYS_EXIT_GROUP |
1614 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) |
1857 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) |
1615 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) |
1858 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) |
1616 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) |
1859 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) |
1617 //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) |
1860 //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) |
1618 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT |
1861 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT |
1619 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 |
1862 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 |
1620 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) |
1863 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) |
1621 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 |
1864 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 |
1622 //sys read(fd int, p []byte) (n int, err error) |
1865 //sys read(fd int, p []byte) (n int, err error) |
1623 //sys Removexattr(path string, attr string) (err error) |
1866 //sys Removexattr(path string, attr string) (err error) |
1624 //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) |
1867 //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) |
1625 //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) |
1868 //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) |
1688 //sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) |
1931 //sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) |
1689 //sys Sync() |
1932 //sys Sync() |
1690 //sys Syncfs(fd int) (err error) |
1933 //sys Syncfs(fd int) (err error) |
1691 //sysnb Sysinfo(info *Sysinfo_t) (err error) |
1934 //sysnb Sysinfo(info *Sysinfo_t) (err error) |
1692 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) |
1935 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) |
|
1936 //sysnb TimerfdCreate(clockid int, flags int) (fd int, err error) |
|
1937 //sysnb TimerfdGettime(fd int, currValue *ItimerSpec) (err error) |
|
1938 //sysnb TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error) |
1693 //sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error) |
1939 //sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error) |
1694 //sysnb Times(tms *Tms) (ticks uintptr, err error) |
1940 //sysnb Times(tms *Tms) (ticks uintptr, err error) |
1695 //sysnb Umask(mask int) (oldmask int) |
1941 //sysnb Umask(mask int) (oldmask int) |
1696 //sysnb Uname(buf *Utsname) (err error) |
1942 //sysnb Uname(buf *Utsname) (err error) |
1697 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 |
1943 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 |
1857 } |
2103 } |
1858 |
2104 |
1859 return int(n), nil |
2105 return int(n), nil |
1860 } |
2106 } |
1861 |
2107 |
|
2108 func isGroupMember(gid int) bool { |
|
2109 groups, err := Getgroups() |
|
2110 if err != nil { |
|
2111 return false |
|
2112 } |
|
2113 |
|
2114 for _, g := range groups { |
|
2115 if g == gid { |
|
2116 return true |
|
2117 } |
|
2118 } |
|
2119 return false |
|
2120 } |
|
2121 |
1862 //sys faccessat(dirfd int, path string, mode uint32) (err error) |
2122 //sys faccessat(dirfd int, path string, mode uint32) (err error) |
|
2123 //sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) |
1863 |
2124 |
1864 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { |
2125 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { |
1865 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { |
2126 if flags == 0 { |
1866 return EINVAL |
2127 return faccessat(dirfd, path, mode) |
|
2128 } |
|
2129 |
|
2130 if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM { |
|
2131 return err |
1867 } |
2132 } |
1868 |
2133 |
1869 // The Linux kernel faccessat system call does not take any flags. |
2134 // The Linux kernel faccessat system call does not take any flags. |
1870 // The glibc faccessat implements the flags itself; see |
2135 // The glibc faccessat implements the flags itself; see |
1871 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD |
2136 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD |
1872 // Because people naturally expect syscall.Faccessat to act |
2137 // Because people naturally expect syscall.Faccessat to act |
1873 // like C faccessat, we do the same. |
2138 // like C faccessat, we do the same. |
1874 |
2139 |
1875 if flags == 0 { |
2140 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { |
1876 return faccessat(dirfd, path, mode) |
2141 return EINVAL |
1877 } |
2142 } |
1878 |
2143 |
1879 var st Stat_t |
2144 var st Stat_t |
1880 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil { |
2145 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil { |
1881 return err |
2146 return err |
1928 } |
2193 } |
1929 |
2194 |
1930 return EACCES |
2195 return EACCES |
1931 } |
2196 } |
1932 |
2197 |
1933 //sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT |
2198 //sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT |
1934 //sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT |
2199 //sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT |
1935 |
2200 |
1936 // fileHandle is the argument to nameToHandleAt and openByHandleAt. We |
2201 // fileHandle is the argument to nameToHandleAt and openByHandleAt. We |
1937 // originally tried to generate it via unix/linux/types.go with "type |
2202 // originally tried to generate it via unix/linux/types.go with "type |
1938 // fileHandle C.struct_file_handle" but that generated empty structs |
2203 // fileHandle C.struct_file_handle" but that generated empty structs |
1939 // for mips64 and mips64le. Instead, hard code it for now (it's the |
2204 // for mips64 and mips64le. Instead, hard code it for now (it's the |