32 return Fchownat(AT_FDCWD, path, uid, gid, 0) |
34 return Fchownat(AT_FDCWD, path, uid, gid, 0) |
33 } |
35 } |
34 |
36 |
35 func Creat(path string, mode uint32) (fd int, err error) { |
37 func Creat(path string, mode uint32) (fd int, err error) { |
36 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) |
38 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) |
|
39 } |
|
40 |
|
41 //sys FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) |
|
42 //sys fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) |
|
43 |
|
44 func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error) { |
|
45 if pathname == "" { |
|
46 return fanotifyMark(fd, flags, mask, dirFd, nil) |
|
47 } |
|
48 p, err := BytePtrFromString(pathname) |
|
49 if err != nil { |
|
50 return err |
|
51 } |
|
52 return fanotifyMark(fd, flags, mask, dirFd, p) |
37 } |
53 } |
38 |
54 |
39 //sys fchmodat(dirfd int, path string, mode uint32) (err error) |
55 //sys fchmodat(dirfd int, path string, mode uint32) (err error) |
40 |
56 |
41 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { |
57 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { |
53 //sys ioctl(fd int, req uint, arg uintptr) (err error) |
69 //sys ioctl(fd int, req uint, arg uintptr) (err error) |
54 |
70 |
55 // ioctl itself should not be exposed directly, but additional get/set |
71 // ioctl itself should not be exposed directly, but additional get/set |
56 // functions for specific types are permissible. |
72 // functions for specific types are permissible. |
57 |
73 |
58 // IoctlSetInt performs an ioctl operation which sets an integer value |
74 // IoctlRetInt performs an ioctl operation specified by req on a device |
59 // on fd, using the specified request number. |
75 // associated with opened file descriptor fd, and returns a non-negative |
60 func IoctlSetInt(fd int, req uint, value int) error { |
76 // integer that is returned by the ioctl syscall. |
61 return ioctl(fd, req, uintptr(value)) |
77 func IoctlRetInt(fd int, req uint) (int, error) { |
62 } |
78 ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0) |
63 |
79 if err != 0 { |
64 func ioctlSetWinsize(fd int, req uint, value *Winsize) error { |
80 return 0, err |
65 return ioctl(fd, req, uintptr(unsafe.Pointer(value))) |
81 } |
66 } |
82 return int(ret), nil |
67 |
83 } |
68 func ioctlSetTermios(fd int, req uint, value *Termios) error { |
84 |
69 return ioctl(fd, req, uintptr(unsafe.Pointer(value))) |
85 // IoctlSetPointerInt performs an ioctl operation which sets an |
70 } |
86 // integer value on fd, using the specified request number. The ioctl |
71 |
87 // argument is called with a pointer to the integer value, rather than |
72 // IoctlGetInt performs an ioctl operation which gets an integer value |
88 // passing the integer value directly. |
73 // from fd, using the specified request number. |
89 func IoctlSetPointerInt(fd int, req uint, value int) error { |
74 func IoctlGetInt(fd int, req uint) (int, error) { |
90 v := int32(value) |
75 var value int |
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 |
76 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
102 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
77 return value, err |
103 return value, err |
78 } |
104 } |
79 |
105 |
80 func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { |
106 func IoctlGetRTCTime(fd int) (*RTCTime, error) { |
81 var value Winsize |
107 var value RTCTime |
82 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
108 err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value))) |
83 return &value, err |
|
84 } |
|
85 |
|
86 func IoctlGetTermios(fd int, req uint) (*Termios, error) { |
|
87 var value Termios |
|
88 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
|
89 return &value, err |
109 return &value, err |
90 } |
110 } |
91 |
111 |
92 //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) |
112 //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) |
93 |
113 |
708 sa.raw.Shared_umem_fd = sa.SharedUmemFD |
728 sa.raw.Shared_umem_fd = sa.SharedUmemFD |
709 |
729 |
710 return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil |
730 return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil |
711 } |
731 } |
712 |
732 |
|
733 // This constant mirrors the #define of PX_PROTO_OE in |
|
734 // linux/if_pppox.h. We're defining this by hand here instead of |
|
735 // autogenerating through mkerrors.sh because including |
|
736 // linux/if_pppox.h causes some declaration conflicts with other |
|
737 // includes (linux/if_pppox.h includes linux/in.h, which conflicts |
|
738 // with netinet/in.h). Given that we only need a single zero constant |
|
739 // out of that file, it's cleaner to just define it by hand here. |
|
740 const px_proto_oe = 0 |
|
741 |
|
742 type SockaddrPPPoE struct { |
|
743 SID uint16 |
|
744 Remote []byte |
|
745 Dev string |
|
746 raw RawSockaddrPPPoX |
|
747 } |
|
748 |
|
749 func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { |
|
750 if len(sa.Remote) != 6 { |
|
751 return nil, 0, EINVAL |
|
752 } |
|
753 if len(sa.Dev) > IFNAMSIZ-1 { |
|
754 return nil, 0, EINVAL |
|
755 } |
|
756 |
|
757 *(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX |
|
758 // This next field is in host-endian byte order. We can't use the |
|
759 // same unsafe pointer cast as above, because this value is not |
|
760 // 32-bit aligned and some architectures don't allow unaligned |
|
761 // access. |
|
762 // |
|
763 // However, the value of px_proto_oe is 0, so we can use |
|
764 // encoding/binary helpers to write the bytes without worrying |
|
765 // about the ordering. |
|
766 binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe) |
|
767 // This field is deliberately big-endian, unlike the previous |
|
768 // one. The kernel expects SID to be in network byte order. |
|
769 binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) |
|
770 copy(sa.raw[8:14], sa.Remote) |
|
771 for i := 14; i < 14+IFNAMSIZ; i++ { |
|
772 sa.raw[i] = 0 |
|
773 } |
|
774 copy(sa.raw[14:], sa.Dev) |
|
775 return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil |
|
776 } |
|
777 |
|
778 // SockaddrTIPC implements the Sockaddr interface for AF_TIPC type sockets. |
|
779 // For more information on TIPC, see: http://tipc.sourceforge.net/. |
|
780 type SockaddrTIPC struct { |
|
781 // Scope is the publication scopes when binding service/service range. |
|
782 // Should be set to TIPC_CLUSTER_SCOPE or TIPC_NODE_SCOPE. |
|
783 Scope int |
|
784 |
|
785 // Addr is the type of address used to manipulate a socket. Addr must be |
|
786 // one of: |
|
787 // - *TIPCSocketAddr: "id" variant in the C addr union |
|
788 // - *TIPCServiceRange: "nameseq" variant in the C addr union |
|
789 // - *TIPCServiceName: "name" variant in the C addr union |
|
790 // |
|
791 // If nil, EINVAL will be returned when the structure is used. |
|
792 Addr TIPCAddr |
|
793 |
|
794 raw RawSockaddrTIPC |
|
795 } |
|
796 |
|
797 // TIPCAddr is implemented by types that can be used as an address for |
|
798 // SockaddrTIPC. It is only implemented by *TIPCSocketAddr, *TIPCServiceRange, |
|
799 // and *TIPCServiceName. |
|
800 type TIPCAddr interface { |
|
801 tipcAddrtype() uint8 |
|
802 tipcAddr() [12]byte |
|
803 } |
|
804 |
|
805 func (sa *TIPCSocketAddr) tipcAddr() [12]byte { |
|
806 var out [12]byte |
|
807 copy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:]) |
|
808 return out |
|
809 } |
|
810 |
|
811 func (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR } |
|
812 |
|
813 func (sa *TIPCServiceRange) tipcAddr() [12]byte { |
|
814 var out [12]byte |
|
815 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:]) |
|
816 return out |
|
817 } |
|
818 |
|
819 func (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE } |
|
820 |
|
821 func (sa *TIPCServiceName) tipcAddr() [12]byte { |
|
822 var out [12]byte |
|
823 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:]) |
|
824 return out |
|
825 } |
|
826 |
|
827 func (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR } |
|
828 |
|
829 func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) { |
|
830 if sa.Addr == nil { |
|
831 return nil, 0, EINVAL |
|
832 } |
|
833 |
|
834 sa.raw.Family = AF_TIPC |
|
835 sa.raw.Scope = int8(sa.Scope) |
|
836 sa.raw.Addrtype = sa.Addr.tipcAddrtype() |
|
837 sa.raw.Addr = sa.Addr.tipcAddr() |
|
838 |
|
839 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil |
|
840 } |
|
841 |
713 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { |
842 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { |
714 switch rsa.Addr.Family { |
843 switch rsa.Addr.Family { |
715 case AF_NETLINK: |
844 case AF_NETLINK: |
716 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) |
845 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) |
717 sa := new(SockaddrNetlink) |
846 sa := new(SockaddrNetlink) |
818 Ifindex: pp.Ifindex, |
947 Ifindex: pp.Ifindex, |
819 QueueID: pp.Queue_id, |
948 QueueID: pp.Queue_id, |
820 SharedUmemFD: pp.Shared_umem_fd, |
949 SharedUmemFD: pp.Shared_umem_fd, |
821 } |
950 } |
822 return sa, nil |
951 return sa, nil |
|
952 case AF_PPPOX: |
|
953 pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa)) |
|
954 if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe { |
|
955 return nil, EINVAL |
|
956 } |
|
957 sa := &SockaddrPPPoE{ |
|
958 SID: binary.BigEndian.Uint16(pp[6:8]), |
|
959 Remote: pp[8:14], |
|
960 } |
|
961 for i := 14; i < 14+IFNAMSIZ; i++ { |
|
962 if pp[i] == 0 { |
|
963 sa.Dev = string(pp[14:i]) |
|
964 break |
|
965 } |
|
966 } |
|
967 return sa, nil |
|
968 case AF_TIPC: |
|
969 pp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa)) |
|
970 |
|
971 sa := &SockaddrTIPC{ |
|
972 Scope: int(pp.Scope), |
|
973 } |
|
974 |
|
975 // Determine which union variant is present in pp.Addr by checking |
|
976 // pp.Addrtype. |
|
977 switch pp.Addrtype { |
|
978 case TIPC_SERVICE_RANGE: |
|
979 sa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr)) |
|
980 case TIPC_SERVICE_ADDR: |
|
981 sa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr)) |
|
982 case TIPC_SOCKET_ADDR: |
|
983 sa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr)) |
|
984 default: |
|
985 return nil, EINVAL |
|
986 } |
|
987 |
|
988 return sa, nil |
823 } |
989 } |
824 return nil, EAFNOSUPPORT |
990 return nil, EAFNOSUPPORT |
825 } |
991 } |
826 |
992 |
827 func Accept(fd int) (nfd int, sa Sockaddr, err error) { |
993 func Accept(fd int) (nfd int, sa Sockaddr, err error) { |
903 } |
1069 } |
904 } |
1070 } |
905 return string(buf[:vallen-1]), nil |
1071 return string(buf[:vallen-1]), nil |
906 } |
1072 } |
907 |
1073 |
|
1074 func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) { |
|
1075 var value TpacketStats |
|
1076 vallen := _Socklen(SizeofTpacketStats) |
|
1077 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) |
|
1078 return &value, err |
|
1079 } |
|
1080 |
|
1081 func GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) { |
|
1082 var value TpacketStatsV3 |
|
1083 vallen := _Socklen(SizeofTpacketStatsV3) |
|
1084 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) |
|
1085 return &value, err |
|
1086 } |
|
1087 |
908 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { |
1088 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { |
909 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) |
1089 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) |
|
1090 } |
|
1091 |
|
1092 func SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error { |
|
1093 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) |
|
1094 } |
|
1095 |
|
1096 // SetsockoptSockFprog attaches a classic BPF or an extended BPF program to a |
|
1097 // socket to filter incoming packets. See 'man 7 socket' for usage information. |
|
1098 func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error { |
|
1099 return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog)) |
|
1100 } |
|
1101 |
|
1102 func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error { |
|
1103 var p unsafe.Pointer |
|
1104 if len(filter) > 0 { |
|
1105 p = unsafe.Pointer(&filter[0]) |
|
1106 } |
|
1107 return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter)) |
|
1108 } |
|
1109 |
|
1110 func SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error { |
|
1111 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) |
|
1112 } |
|
1113 |
|
1114 func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error { |
|
1115 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) |
910 } |
1116 } |
911 |
1117 |
912 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) |
1118 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) |
913 |
1119 |
914 // KeyctlInt calls keyctl commands in which each argument is an int. |
1120 // KeyctlInt calls keyctl commands in which each argument is an int. |
1014 // http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html |
1220 // http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html |
1015 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) { |
1221 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) { |
1016 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer) |
1222 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer) |
1017 } |
1223 } |
1018 |
1224 |
|
1225 // KeyctlRestrictKeyring implements the KEYCTL_RESTRICT_KEYRING command. This |
|
1226 // command limits the set of keys that can be linked to the keyring, regardless |
|
1227 // of keyring permissions. The command requires the "setattr" permission. |
|
1228 // |
|
1229 // When called with an empty keyType the command locks the keyring, preventing |
|
1230 // any further keys from being linked to the keyring. |
|
1231 // |
|
1232 // The "asymmetric" keyType defines restrictions requiring key payloads to be |
|
1233 // DER encoded X.509 certificates signed by keys in another keyring. Restrictions |
|
1234 // for "asymmetric" include "builtin_trusted", "builtin_and_secondary_trusted", |
|
1235 // "key_or_keyring:<key>", and "key_or_keyring:<key>:chain". |
|
1236 // |
|
1237 // As of Linux 4.12, only the "asymmetric" keyType defines type-specific |
|
1238 // restrictions. |
|
1239 // |
|
1240 // See the full documentation at: |
|
1241 // http://man7.org/linux/man-pages/man3/keyctl_restrict_keyring.3.html |
|
1242 // http://man7.org/linux/man-pages/man2/keyctl.2.html |
|
1243 func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error { |
|
1244 if keyType == "" { |
|
1245 return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid) |
|
1246 } |
|
1247 return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction) |
|
1248 } |
|
1249 |
|
1250 //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 |
|
1252 |
1019 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
1253 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
1020 var msg Msghdr |
1254 var msg Msghdr |
1021 var rsa RawSockaddrAny |
1255 var rsa RawSockaddrAny |
1022 msg.Name = (*byte)(unsafe.Pointer(&rsa)) |
1256 msg.Name = (*byte)(unsafe.Pointer(&rsa)) |
1023 msg.Namelen = uint32(SizeofSockaddrAny) |
1257 msg.Namelen = uint32(SizeofSockaddrAny) |
1120 // to retrieve arbitrary-length data. |
1354 // to retrieve arbitrary-length data. |
1121 |
1355 |
1122 // The ptrace syscall differs from glibc's ptrace. |
1356 // The ptrace syscall differs from glibc's ptrace. |
1123 // Peeks returns the word in *data, not as the return value. |
1357 // Peeks returns the word in *data, not as the return value. |
1124 |
1358 |
1125 var buf [sizeofPtr]byte |
1359 var buf [SizeofPtr]byte |
1126 |
1360 |
1127 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned |
1361 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned |
1128 // access (PEEKUSER warns that it might), but if we don't |
1362 // access (PEEKUSER warns that it might), but if we don't |
1129 // align our reads, we might straddle an unmapped page |
1363 // align our reads, we might straddle an unmapped page |
1130 // boundary and not get the bytes leading up to the page |
1364 // boundary and not get the bytes leading up to the page |
1131 // boundary. |
1365 // boundary. |
1132 n := 0 |
1366 n := 0 |
1133 if addr%sizeofPtr != 0 { |
1367 if addr%SizeofPtr != 0 { |
1134 err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) |
1368 err = ptrace(req, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) |
1135 if err != nil { |
1369 if err != nil { |
1136 return 0, err |
1370 return 0, err |
1137 } |
1371 } |
1138 n += copy(out, buf[addr%sizeofPtr:]) |
1372 n += copy(out, buf[addr%SizeofPtr:]) |
1139 out = out[n:] |
1373 out = out[n:] |
1140 } |
1374 } |
1141 |
1375 |
1142 // Remainder. |
1376 // Remainder. |
1143 for len(out) > 0 { |
1377 for len(out) > 0 { |
1171 // As for ptracePeek, we need to align our accesses to deal |
1405 // As for ptracePeek, we need to align our accesses to deal |
1172 // with the possibility of straddling an invalid page. |
1406 // with the possibility of straddling an invalid page. |
1173 |
1407 |
1174 // Leading edge. |
1408 // Leading edge. |
1175 n := 0 |
1409 n := 0 |
1176 if addr%sizeofPtr != 0 { |
1410 if addr%SizeofPtr != 0 { |
1177 var buf [sizeofPtr]byte |
1411 var buf [SizeofPtr]byte |
1178 err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) |
1412 err = ptrace(peekReq, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) |
1179 if err != nil { |
1413 if err != nil { |
1180 return 0, err |
1414 return 0, err |
1181 } |
1415 } |
1182 n += copy(buf[addr%sizeofPtr:], data) |
1416 n += copy(buf[addr%SizeofPtr:], data) |
1183 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) |
1417 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) |
1184 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word) |
1418 err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word) |
1185 if err != nil { |
1419 if err != nil { |
1186 return 0, err |
1420 return 0, err |
1187 } |
1421 } |
1188 data = data[n:] |
1422 data = data[n:] |
1189 } |
1423 } |
1190 |
1424 |
1191 // Interior. |
1425 // Interior. |
1192 for len(data) > sizeofPtr { |
1426 for len(data) > SizeofPtr { |
1193 word := *((*uintptr)(unsafe.Pointer(&data[0]))) |
1427 word := *((*uintptr)(unsafe.Pointer(&data[0]))) |
1194 err = ptrace(pokeReq, pid, addr+uintptr(n), word) |
1428 err = ptrace(pokeReq, pid, addr+uintptr(n), word) |
1195 if err != nil { |
1429 if err != nil { |
1196 return n, err |
1430 return n, err |
1197 } |
1431 } |
1198 n += sizeofPtr |
1432 n += SizeofPtr |
1199 data = data[sizeofPtr:] |
1433 data = data[SizeofPtr:] |
1200 } |
1434 } |
1201 |
1435 |
1202 // Trailing edge. |
1436 // Trailing edge. |
1203 if len(data) > 0 { |
1437 if len(data) > 0 { |
1204 var buf [sizeofPtr]byte |
1438 var buf [SizeofPtr]byte |
1205 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) |
1439 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) |
1206 if err != nil { |
1440 if err != nil { |
1207 return n, err |
1441 return n, err |
1208 } |
1442 } |
1209 copy(buf[0:], data) |
1443 copy(buf[0:], data) |
1257 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal)) |
1491 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal)) |
1258 } |
1492 } |
1259 |
1493 |
1260 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } |
1494 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } |
1261 |
1495 |
|
1496 func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) } |
|
1497 |
1262 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } |
1498 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } |
|
1499 |
|
1500 func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) } |
1263 |
1501 |
1264 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } |
1502 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } |
1265 |
1503 |
1266 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) |
1504 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) |
1267 |
1505 |
1268 func Reboot(cmd int) (err error) { |
1506 func Reboot(cmd int) (err error) { |
1269 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") |
1507 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") |
1270 } |
1508 } |
1271 |
1509 |
1272 func ReadDirent(fd int, buf []byte) (n int, err error) { |
1510 func direntIno(buf []byte) (uint64, bool) { |
1273 return Getdents(fd, buf) |
1511 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) |
|
1512 } |
|
1513 |
|
1514 func direntReclen(buf []byte) (uint64, bool) { |
|
1515 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) |
|
1516 } |
|
1517 |
|
1518 func direntNamlen(buf []byte) (uint64, bool) { |
|
1519 reclen, ok := direntReclen(buf) |
|
1520 if !ok { |
|
1521 return 0, false |
|
1522 } |
|
1523 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true |
1274 } |
1524 } |
1275 |
1525 |
1276 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) |
1526 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) |
1277 |
1527 |
1278 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { |
1528 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { |
1296 * Direct access |
1553 * Direct access |
1297 */ |
1554 */ |
1298 //sys Acct(path string) (err error) |
1555 //sys Acct(path string) (err error) |
1299 //sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) |
1556 //sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) |
1300 //sys Adjtimex(buf *Timex) (state int, err error) |
1557 //sys Adjtimex(buf *Timex) (state int, err error) |
|
1558 //sys Capget(hdr *CapUserHeader, data *CapUserData) (err error) |
|
1559 //sys Capset(hdr *CapUserHeader, data *CapUserData) (err error) |
1301 //sys Chdir(path string) (err error) |
1560 //sys Chdir(path string) (err error) |
1302 //sys Chroot(path string) (err error) |
1561 //sys Chroot(path string) (err error) |
1303 //sys ClockGetres(clockid int32, res *Timespec) (err error) |
1562 //sys ClockGetres(clockid int32, res *Timespec) (err error) |
1304 //sys ClockGettime(clockid int32, time *Timespec) (err error) |
1563 //sys ClockGettime(clockid int32, time *Timespec) (err error) |
|
1564 //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) |
1305 //sys Close(fd int) (err error) |
1565 //sys Close(fd int) (err error) |
1306 //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) |
1566 //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) |
1307 //sys Dup(oldfd int) (fd int, err error) |
1568 //sys Dup(oldfd int) (fd int, err error) |
1308 //sys Dup3(oldfd int, newfd int, flags int) (err error) |
1569 //sys Dup3(oldfd int, newfd int, flags int) (err error) |
1309 //sysnb EpollCreate1(flag int) (fd int, err error) |
1570 //sysnb EpollCreate1(flag int) (fd int, err error) |
1310 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) |
1571 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) |
1311 //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 |
1572 //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 |
1312 //sys Exit(code int) = SYS_EXIT_GROUP |
1573 //sys Exit(code int) = SYS_EXIT_GROUP |
1313 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) |
1574 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) |
1314 //sys Fchdir(fd int) (err error) |
1575 //sys Fchdir(fd int) (err error) |
1315 //sys Fchmod(fd int, mode uint32) (err error) |
1576 //sys Fchmod(fd int, mode uint32) (err error) |
1316 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) |
1577 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) |
1317 //sys fcntl(fd int, cmd int, arg int) (val int, err error) |
|
1318 //sys Fdatasync(fd int) (err error) |
1578 //sys Fdatasync(fd int) (err error) |
1319 //sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) |
1579 //sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) |
|
1580 //sys FinitModule(fd int, params string, flags int) (err error) |
1320 //sys Flistxattr(fd int, dest []byte) (sz int, err error) |
1581 //sys Flistxattr(fd int, dest []byte) (sz int, err error) |
1321 //sys Flock(fd int, how int) (err error) |
1582 //sys Flock(fd int, how int) (err error) |
1322 //sys Fremovexattr(fd int, attr string) (err error) |
1583 //sys Fremovexattr(fd int, attr string) (err error) |
1323 //sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) |
1584 //sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) |
1324 //sys Fsync(fd int) (err error) |
1585 //sys Fsync(fd int) (err error) |
1336 //sys Getrandom(buf []byte, flags int) (n int, err error) |
1597 //sys Getrandom(buf []byte, flags int) (n int, err error) |
1337 //sysnb Getrusage(who int, rusage *Rusage) (err error) |
1598 //sysnb Getrusage(who int, rusage *Rusage) (err error) |
1338 //sysnb Getsid(pid int) (sid int, err error) |
1599 //sysnb Getsid(pid int) (sid int, err error) |
1339 //sysnb Gettid() (tid int) |
1600 //sysnb Gettid() (tid int) |
1340 //sys Getxattr(path string, attr string, dest []byte) (sz int, err error) |
1601 //sys Getxattr(path string, attr string, dest []byte) (sz int, err error) |
|
1602 //sys InitModule(moduleImage []byte, params string) (err error) |
1341 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) |
1603 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) |
1342 //sysnb InotifyInit1(flags int) (fd int, err error) |
1604 //sysnb InotifyInit1(flags int) (fd int, err error) |
1343 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) |
1605 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) |
1344 //sysnb Kill(pid int, sig syscall.Signal) (err error) |
1606 //sysnb Kill(pid int, sig syscall.Signal) (err error) |
1345 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG |
1607 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG |
1357 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 |
1619 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 |
1358 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) |
1620 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) |
1359 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 |
1621 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 |
1360 //sys read(fd int, p []byte) (n int, err error) |
1622 //sys read(fd int, p []byte) (n int, err error) |
1361 //sys Removexattr(path string, attr string) (err error) |
1623 //sys Removexattr(path string, attr string) (err error) |
1362 //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) |
|
1363 //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) |
1624 //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) |
1364 //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) |
1625 //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) |
1365 //sys Setdomainname(p []byte) (err error) |
1626 //sys Setdomainname(p []byte) (err error) |
1366 //sys Sethostname(p []byte) (err error) |
1627 //sys Sethostname(p []byte) (err error) |
1367 //sysnb Setpgid(pid int, pgid int) (err error) |
1628 //sysnb Setpgid(pid int, pgid int) (err error) |
1368 //sysnb Setsid() (pid int, err error) |
1629 //sysnb Setsid() (pid int, err error) |
1369 //sysnb Settimeofday(tv *Timeval) (err error) |
1630 //sysnb Settimeofday(tv *Timeval) (err error) |
1370 //sys Setns(fd int, nstype int) (err error) |
1631 //sys Setns(fd int, nstype int) (err error) |
1371 |
1632 |
|
1633 // PrctlRetInt performs a prctl operation specified by option and further |
|
1634 // optional arguments arg2 through arg5 depending on option. It returns a |
|
1635 // non-negative integer that is returned by the prctl syscall. |
|
1636 func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) { |
|
1637 ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) |
|
1638 if err != 0 { |
|
1639 return 0, err |
|
1640 } |
|
1641 return int(ret), nil |
|
1642 } |
|
1643 |
1372 // issue 1435. |
1644 // issue 1435. |
1373 // On linux Setuid and Setgid only affects the current thread, not the process. |
1645 // On linux Setuid and Setgid only affects the current thread, not the process. |
1374 // This does not match what most callers expect so we must return an error |
1646 // This does not match what most callers expect so we must return an error |
1375 // here rather than letting the caller think that the call succeeded. |
1647 // here rather than letting the caller think that the call succeeded. |
1376 |
1648 |
1380 |
1652 |
1381 func Setgid(uid int) (err error) { |
1653 func Setgid(uid int) (err error) { |
1382 return EOPNOTSUPP |
1654 return EOPNOTSUPP |
1383 } |
1655 } |
1384 |
1656 |
|
1657 // SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set. |
|
1658 // setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability. |
|
1659 // If the call fails due to other reasons, current fsgid will be returned. |
|
1660 func SetfsgidRetGid(gid int) (int, error) { |
|
1661 return setfsgid(gid) |
|
1662 } |
|
1663 |
|
1664 // SetfsuidRetUid sets fsuid for current thread and returns previous fsuid set. |
|
1665 // setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability |
|
1666 // If the call fails due to other reasons, current fsuid will be returned. |
|
1667 func SetfsuidRetUid(uid int) (int, error) { |
|
1668 return setfsuid(uid) |
|
1669 } |
|
1670 |
|
1671 func Setfsgid(gid int) error { |
|
1672 _, err := setfsgid(gid) |
|
1673 return err |
|
1674 } |
|
1675 |
|
1676 func Setfsuid(uid int) error { |
|
1677 _, err := setfsuid(uid) |
|
1678 return err |
|
1679 } |
|
1680 |
|
1681 func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) { |
|
1682 return signalfd(fd, sigmask, _C__NSIG/8, flags) |
|
1683 } |
|
1684 |
1385 //sys Setpriority(which int, who int, prio int) (err error) |
1685 //sys Setpriority(which int, who int, prio int) (err error) |
1386 //sys Setxattr(path string, attr string, data []byte, flags int) (err error) |
1686 //sys Setxattr(path string, attr string, data []byte, flags int) (err error) |
|
1687 //sys signalfd(fd int, sigmask *Sigset_t, maskSize uintptr, flags int) (newfd int, err error) = SYS_SIGNALFD4 |
1387 //sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) |
1688 //sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) |
1388 //sys Sync() |
1689 //sys Sync() |
1389 //sys Syncfs(fd int) (err error) |
1690 //sys Syncfs(fd int) (err error) |
1390 //sysnb Sysinfo(info *Sysinfo_t) (err error) |
1691 //sysnb Sysinfo(info *Sysinfo_t) (err error) |
1391 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) |
1692 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) |
1397 //sys Unshare(flags int) (err error) |
1698 //sys Unshare(flags int) (err error) |
1398 //sys write(fd int, p []byte) (n int, err error) |
1699 //sys write(fd int, p []byte) (n int, err error) |
1399 //sys exitThread(code int) (err error) = SYS_EXIT |
1700 //sys exitThread(code int) (err error) = SYS_EXIT |
1400 //sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ |
1701 //sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ |
1401 //sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE |
1702 //sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE |
|
1703 //sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV |
|
1704 //sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV |
|
1705 //sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV |
|
1706 //sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV |
|
1707 //sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2 |
|
1708 //sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2 |
|
1709 |
|
1710 func bytes2iovec(bs [][]byte) []Iovec { |
|
1711 iovecs := make([]Iovec, len(bs)) |
|
1712 for i, b := range bs { |
|
1713 iovecs[i].SetLen(len(b)) |
|
1714 if len(b) > 0 { |
|
1715 iovecs[i].Base = &b[0] |
|
1716 } else { |
|
1717 iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero)) |
|
1718 } |
|
1719 } |
|
1720 return iovecs |
|
1721 } |
|
1722 |
|
1723 // offs2lohi splits offs into its lower and upper unsigned long. On 64-bit |
|
1724 // systems, hi will always be 0. On 32-bit systems, offs will be split in half. |
|
1725 // preadv/pwritev chose this calling convention so they don't need to add a |
|
1726 // padding-register for alignment on ARM. |
|
1727 func offs2lohi(offs int64) (lo, hi uintptr) { |
|
1728 return uintptr(offs), uintptr(uint64(offs) >> SizeofLong) |
|
1729 } |
|
1730 |
|
1731 func Readv(fd int, iovs [][]byte) (n int, err error) { |
|
1732 iovecs := bytes2iovec(iovs) |
|
1733 n, err = readv(fd, iovecs) |
|
1734 readvRacedetect(iovecs, n, err) |
|
1735 return n, err |
|
1736 } |
|
1737 |
|
1738 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { |
|
1739 iovecs := bytes2iovec(iovs) |
|
1740 lo, hi := offs2lohi(offset) |
|
1741 n, err = preadv(fd, iovecs, lo, hi) |
|
1742 readvRacedetect(iovecs, n, err) |
|
1743 return n, err |
|
1744 } |
|
1745 |
|
1746 func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { |
|
1747 iovecs := bytes2iovec(iovs) |
|
1748 lo, hi := offs2lohi(offset) |
|
1749 n, err = preadv2(fd, iovecs, lo, hi, flags) |
|
1750 readvRacedetect(iovecs, n, err) |
|
1751 return n, err |
|
1752 } |
|
1753 |
|
1754 func readvRacedetect(iovecs []Iovec, n int, err error) { |
|
1755 if !raceenabled { |
|
1756 return |
|
1757 } |
|
1758 for i := 0; n > 0 && i < len(iovecs); i++ { |
|
1759 m := int(iovecs[i].Len) |
|
1760 if m > n { |
|
1761 m = n |
|
1762 } |
|
1763 n -= m |
|
1764 if m > 0 { |
|
1765 raceWriteRange(unsafe.Pointer(iovecs[i].Base), m) |
|
1766 } |
|
1767 } |
|
1768 if err == nil { |
|
1769 raceAcquire(unsafe.Pointer(&ioSync)) |
|
1770 } |
|
1771 } |
|
1772 |
|
1773 func Writev(fd int, iovs [][]byte) (n int, err error) { |
|
1774 iovecs := bytes2iovec(iovs) |
|
1775 if raceenabled { |
|
1776 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
|
1777 } |
|
1778 n, err = writev(fd, iovecs) |
|
1779 writevRacedetect(iovecs, n) |
|
1780 return n, err |
|
1781 } |
|
1782 |
|
1783 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { |
|
1784 iovecs := bytes2iovec(iovs) |
|
1785 if raceenabled { |
|
1786 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
|
1787 } |
|
1788 lo, hi := offs2lohi(offset) |
|
1789 n, err = pwritev(fd, iovecs, lo, hi) |
|
1790 writevRacedetect(iovecs, n) |
|
1791 return n, err |
|
1792 } |
|
1793 |
|
1794 func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { |
|
1795 iovecs := bytes2iovec(iovs) |
|
1796 if raceenabled { |
|
1797 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
|
1798 } |
|
1799 lo, hi := offs2lohi(offset) |
|
1800 n, err = pwritev2(fd, iovecs, lo, hi, flags) |
|
1801 writevRacedetect(iovecs, n) |
|
1802 return n, err |
|
1803 } |
|
1804 |
|
1805 func writevRacedetect(iovecs []Iovec, n int) { |
|
1806 if !raceenabled { |
|
1807 return |
|
1808 } |
|
1809 for i := 0; n > 0 && i < len(iovecs); i++ { |
|
1810 m := int(iovecs[i].Len) |
|
1811 if m > n { |
|
1812 m = n |
|
1813 } |
|
1814 n -= m |
|
1815 if m > 0 { |
|
1816 raceReadRange(unsafe.Pointer(iovecs[i].Base), m) |
|
1817 } |
|
1818 } |
|
1819 } |
1402 |
1820 |
1403 // mmap varies by architecture; see syscall_linux_*.go. |
1821 // mmap varies by architecture; see syscall_linux_*.go. |
1404 //sys munmap(addr uintptr, length uintptr) (err error) |
1822 //sys munmap(addr uintptr, length uintptr) (err error) |
1405 |
1823 |
1406 var mapper = &mmapper{ |
1824 var mapper = &mmapper{ |
1513 } |
1928 } |
1514 |
1929 |
1515 return EACCES |
1930 return EACCES |
1516 } |
1931 } |
1517 |
1932 |
|
1933 //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 |
|
1935 |
|
1936 // fileHandle is the argument to nameToHandleAt and openByHandleAt. We |
|
1937 // originally tried to generate it via unix/linux/types.go with "type |
|
1938 // fileHandle C.struct_file_handle" but that generated empty structs |
|
1939 // for mips64 and mips64le. Instead, hard code it for now (it's the |
|
1940 // same everywhere else) until the mips64 generator issue is fixed. |
|
1941 type fileHandle struct { |
|
1942 Bytes uint32 |
|
1943 Type int32 |
|
1944 } |
|
1945 |
|
1946 // FileHandle represents the C struct file_handle used by |
|
1947 // name_to_handle_at (see NameToHandleAt) and open_by_handle_at (see |
|
1948 // OpenByHandleAt). |
|
1949 type FileHandle struct { |
|
1950 *fileHandle |
|
1951 } |
|
1952 |
|
1953 // NewFileHandle constructs a FileHandle. |
|
1954 func NewFileHandle(handleType int32, handle []byte) FileHandle { |
|
1955 const hdrSize = unsafe.Sizeof(fileHandle{}) |
|
1956 buf := make([]byte, hdrSize+uintptr(len(handle))) |
|
1957 copy(buf[hdrSize:], handle) |
|
1958 fh := (*fileHandle)(unsafe.Pointer(&buf[0])) |
|
1959 fh.Type = handleType |
|
1960 fh.Bytes = uint32(len(handle)) |
|
1961 return FileHandle{fh} |
|
1962 } |
|
1963 |
|
1964 func (fh *FileHandle) Size() int { return int(fh.fileHandle.Bytes) } |
|
1965 func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type } |
|
1966 func (fh *FileHandle) Bytes() []byte { |
|
1967 n := fh.Size() |
|
1968 if n == 0 { |
|
1969 return nil |
|
1970 } |
|
1971 return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n] |
|
1972 } |
|
1973 |
|
1974 // NameToHandleAt wraps the name_to_handle_at system call; it obtains |
|
1975 // a handle for a path name. |
|
1976 func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) { |
|
1977 var mid _C_int |
|
1978 // Try first with a small buffer, assuming the handle will |
|
1979 // only be 32 bytes. |
|
1980 size := uint32(32 + unsafe.Sizeof(fileHandle{})) |
|
1981 didResize := false |
|
1982 for { |
|
1983 buf := make([]byte, size) |
|
1984 fh := (*fileHandle)(unsafe.Pointer(&buf[0])) |
|
1985 fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{})) |
|
1986 err = nameToHandleAt(dirfd, path, fh, &mid, flags) |
|
1987 if err == EOVERFLOW { |
|
1988 if didResize { |
|
1989 // We shouldn't need to resize more than once |
|
1990 return |
|
1991 } |
|
1992 didResize = true |
|
1993 size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{})) |
|
1994 continue |
|
1995 } |
|
1996 if err != nil { |
|
1997 return |
|
1998 } |
|
1999 return FileHandle{fh}, int(mid), nil |
|
2000 } |
|
2001 } |
|
2002 |
|
2003 // OpenByHandleAt wraps the open_by_handle_at system call; it opens a |
|
2004 // file via a handle as previously returned by NameToHandleAt. |
|
2005 func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) { |
|
2006 return openByHandleAt(mountFD, handle.fileHandle, flags) |
|
2007 } |
|
2008 |
|
2009 // Klogset wraps the sys_syslog system call; it sets console_loglevel to |
|
2010 // the value specified by arg and passes a dummy pointer to bufp. |
|
2011 func Klogset(typ int, arg int) (err error) { |
|
2012 var p unsafe.Pointer |
|
2013 _, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg)) |
|
2014 if errno != 0 { |
|
2015 return errnoErr(errno) |
|
2016 } |
|
2017 return nil |
|
2018 } |
|
2019 |
1518 /* |
2020 /* |
1519 * Unimplemented |
2021 * Unimplemented |
1520 */ |
2022 */ |
1521 // AfsSyscall |
2023 // AfsSyscall |
1522 // Alarm |
2024 // Alarm |
1523 // ArchPrctl |
2025 // ArchPrctl |
1524 // Brk |
2026 // Brk |
1525 // Capget |
|
1526 // Capset |
|
1527 // ClockNanosleep |
2027 // ClockNanosleep |
1528 // ClockSettime |
2028 // ClockSettime |
1529 // Clone |
2029 // Clone |
1530 // CreateModule |
|
1531 // DeleteModule |
|
1532 // EpollCtlOld |
2030 // EpollCtlOld |
1533 // EpollPwait |
2031 // EpollPwait |
1534 // EpollWaitOld |
2032 // EpollWaitOld |
1535 // Execve |
2033 // Execve |
1536 // Fork |
2034 // Fork |