34 return Fchownat(AT_FDCWD, path, uid, gid, 0) |
34 return Fchownat(AT_FDCWD, path, uid, gid, 0) |
35 } |
35 } |
36 |
36 |
37 func Creat(path string, mode uint32) (fd int, err error) { |
37 func Creat(path string, mode uint32) (fd int, err error) { |
38 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) |
38 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) |
|
39 } |
|
40 |
|
41 func EpollCreate(size int) (fd int, err error) { |
|
42 if size <= 0 { |
|
43 return -1, EINVAL |
|
44 } |
|
45 return EpollCreate1(0) |
39 } |
46 } |
40 |
47 |
41 //sys FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) |
48 //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) |
49 //sys fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) |
43 |
50 |
64 return EOPNOTSUPP |
71 return EOPNOTSUPP |
65 } |
72 } |
66 return fchmodat(dirfd, path, mode) |
73 return fchmodat(dirfd, path, mode) |
67 } |
74 } |
68 |
75 |
69 //sys ioctl(fd int, req uint, arg uintptr) (err error) |
76 func InotifyInit() (fd int, err error) { |
70 |
77 return InotifyInit1(0) |
71 // ioctl itself should not be exposed directly, but additional get/set |
78 } |
72 // functions for specific types are permissible. |
79 |
73 // These are defined in ioctl.go and ioctl_linux.go. |
80 //sys ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL |
|
81 //sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL |
|
82 |
|
83 // ioctl itself should not be exposed directly, but additional get/set functions |
|
84 // for specific types are permissible. These are defined in ioctl.go and |
|
85 // ioctl_linux.go. |
|
86 // |
|
87 // The third argument to ioctl is often a pointer but sometimes an integer. |
|
88 // Callers should use ioctlPtr when the third argument is a pointer and ioctl |
|
89 // when the third argument is an integer. |
|
90 // |
|
91 // TODO: some existing code incorrectly uses ioctl when it should use ioctlPtr. |
74 |
92 |
75 //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) |
93 //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) |
76 |
94 |
77 func Link(oldpath string, newpath string) (err error) { |
95 func Link(oldpath string, newpath string) (err error) { |
78 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0) |
96 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0) |
98 |
116 |
99 //sys openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) |
117 //sys openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) |
100 |
118 |
101 func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) { |
119 func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) { |
102 return openat2(dirfd, path, how, SizeofOpenHow) |
120 return openat2(dirfd, path, how, SizeofOpenHow) |
|
121 } |
|
122 |
|
123 func Pipe(p []int) error { |
|
124 return Pipe2(p, 0) |
|
125 } |
|
126 |
|
127 //sysnb pipe2(p *[2]_C_int, flags int) (err error) |
|
128 |
|
129 func Pipe2(p []int, flags int) error { |
|
130 if len(p) != 2 { |
|
131 return EINVAL |
|
132 } |
|
133 var pp [2]_C_int |
|
134 err := pipe2(&pp, flags) |
|
135 if err == nil { |
|
136 p[0] = int(pp[0]) |
|
137 p[1] = int(pp[1]) |
|
138 } |
|
139 return err |
103 } |
140 } |
104 |
141 |
105 //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) |
142 //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) |
106 |
143 |
107 func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { |
144 func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { |
108 if len(fds) == 0 { |
145 if len(fds) == 0 { |
109 return ppoll(nil, 0, timeout, sigmask) |
146 return ppoll(nil, 0, timeout, sigmask) |
110 } |
147 } |
111 return ppoll(&fds[0], len(fds), timeout, sigmask) |
148 return ppoll(&fds[0], len(fds), timeout, sigmask) |
|
149 } |
|
150 |
|
151 func Poll(fds []PollFd, timeout int) (n int, err error) { |
|
152 var ts *Timespec |
|
153 if timeout >= 0 { |
|
154 ts = new(Timespec) |
|
155 *ts = NsecToTimespec(int64(timeout) * 1e6) |
|
156 } |
|
157 return Ppoll(fds, ts, nil) |
112 } |
158 } |
113 |
159 |
114 //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) |
160 //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) |
115 |
161 |
116 func Readlink(path string, buf []byte) (n int, err error) { |
162 func Readlink(path string, buf []byte) (n int, err error) { |
159 } |
205 } |
160 |
206 |
161 //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) |
207 //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) |
162 |
208 |
163 func UtimesNano(path string, ts []Timespec) error { |
209 func UtimesNano(path string, ts []Timespec) error { |
164 if ts == nil { |
210 return UtimesNanoAt(AT_FDCWD, path, ts, 0) |
165 err := utimensat(AT_FDCWD, path, nil, 0) |
|
166 if err != ENOSYS { |
|
167 return err |
|
168 } |
|
169 return utimes(path, nil) |
|
170 } |
|
171 if len(ts) != 2 { |
|
172 return EINVAL |
|
173 } |
|
174 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) |
|
175 if err != ENOSYS { |
|
176 return err |
|
177 } |
|
178 // If the utimensat syscall isn't available (utimensat was added to Linux |
|
179 // in 2.6.22, Released, 8 July 2007) then fall back to utimes |
|
180 var tv [2]Timeval |
|
181 for i := 0; i < 2; i++ { |
|
182 tv[i] = NsecToTimeval(TimespecToNsec(ts[i])) |
|
183 } |
|
184 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) |
|
185 } |
211 } |
186 |
212 |
187 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { |
213 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { |
188 if ts == nil { |
214 if ts == nil { |
189 return utimensat(dirfd, path, nil, flags) |
215 return utimensat(dirfd, path, nil, flags) |
481 // SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets |
510 // SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets |
482 // using the RFCOMM protocol. |
511 // using the RFCOMM protocol. |
483 // |
512 // |
484 // Server example: |
513 // Server example: |
485 // |
514 // |
486 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) |
515 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) |
487 // _ = unix.Bind(fd, &unix.SockaddrRFCOMM{ |
516 // _ = unix.Bind(fd, &unix.SockaddrRFCOMM{ |
488 // Channel: 1, |
517 // Channel: 1, |
489 // Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00 |
518 // Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00 |
490 // }) |
519 // }) |
491 // _ = Listen(fd, 1) |
520 // _ = Listen(fd, 1) |
492 // nfd, sa, _ := Accept(fd) |
521 // nfd, sa, _ := Accept(fd) |
493 // fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd) |
522 // fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd) |
494 // Read(nfd, buf) |
523 // Read(nfd, buf) |
495 // |
524 // |
496 // Client example: |
525 // Client example: |
497 // |
526 // |
498 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) |
527 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) |
499 // _ = Connect(fd, &SockaddrRFCOMM{ |
528 // _ = Connect(fd, &SockaddrRFCOMM{ |
500 // Channel: 1, |
529 // Channel: 1, |
501 // Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11 |
530 // Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11 |
502 // }) |
531 // }) |
503 // Write(fd, []byte(`hello`)) |
532 // Write(fd, []byte(`hello`)) |
504 type SockaddrRFCOMM struct { |
533 type SockaddrRFCOMM struct { |
505 // Addr represents a bluetooth address, byte ordering is little-endian. |
534 // Addr represents a bluetooth address, byte ordering is little-endian. |
506 Addr [6]uint8 |
535 Addr [6]uint8 |
507 |
536 |
508 // Channel is a designated bluetooth channel, only 1-30 are available for use. |
537 // Channel is a designated bluetooth channel, only 1-30 are available for use. |
525 // zero values for CAN_RAW and CAN_BCM sockets as they have no meaning. |
554 // zero values for CAN_RAW and CAN_BCM sockets as they have no meaning. |
526 // |
555 // |
527 // The SockaddrCAN struct must be bound to the socket file descriptor |
556 // The SockaddrCAN struct must be bound to the socket file descriptor |
528 // using Bind before the CAN socket can be used. |
557 // using Bind before the CAN socket can be used. |
529 // |
558 // |
530 // // Read one raw CAN frame |
559 // // Read one raw CAN frame |
531 // fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW) |
560 // fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW) |
532 // addr := &SockaddrCAN{Ifindex: index} |
561 // addr := &SockaddrCAN{Ifindex: index} |
533 // Bind(fd, addr) |
562 // Bind(fd, addr) |
534 // frame := make([]byte, 16) |
563 // frame := make([]byte, 16) |
535 // Read(fd, frame) |
564 // Read(fd, frame) |
536 // |
565 // |
537 // The full SocketCAN documentation can be found in the linux kernel |
566 // The full SocketCAN documentation can be found in the linux kernel |
538 // archives at: https://www.kernel.org/doc/Documentation/networking/can.txt |
567 // archives at: https://www.kernel.org/doc/Documentation/networking/can.txt |
539 type SockaddrCAN struct { |
568 type SockaddrCAN struct { |
540 Ifindex int |
569 Ifindex int |
601 // back as hash output or ciphertext. |
630 // back as hash output or ciphertext. |
602 // |
631 // |
603 // Here is an example of using an AF_ALG socket with SHA1 hashing. |
632 // Here is an example of using an AF_ALG socket with SHA1 hashing. |
604 // The initial socket setup process is as follows: |
633 // The initial socket setup process is as follows: |
605 // |
634 // |
606 // // Open a socket to perform SHA1 hashing. |
635 // // Open a socket to perform SHA1 hashing. |
607 // fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0) |
636 // fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0) |
608 // addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"} |
637 // addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"} |
609 // unix.Bind(fd, addr) |
638 // unix.Bind(fd, addr) |
610 // // Note: unix.Accept does not work at this time; must invoke accept() |
639 // // Note: unix.Accept does not work at this time; must invoke accept() |
611 // // manually using unix.Syscall. |
640 // // manually using unix.Syscall. |
612 // hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0) |
641 // hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0) |
613 // |
642 // |
614 // Once a file descriptor has been returned from Accept, it may be used to |
643 // Once a file descriptor has been returned from Accept, it may be used to |
615 // perform SHA1 hashing. The descriptor is not safe for concurrent use, but |
644 // perform SHA1 hashing. The descriptor is not safe for concurrent use, but |
616 // may be re-used repeatedly with subsequent Write and Read operations. |
645 // may be re-used repeatedly with subsequent Write and Read operations. |
617 // |
646 // |
618 // When hashing a small byte slice or string, a single Write and Read may |
647 // When hashing a small byte slice or string, a single Write and Read may |
619 // be used: |
648 // be used: |
620 // |
649 // |
621 // // Assume hashfd is already configured using the setup process. |
650 // // Assume hashfd is already configured using the setup process. |
622 // hash := os.NewFile(hashfd, "sha1") |
651 // hash := os.NewFile(hashfd, "sha1") |
623 // // Hash an input string and read the results. Each Write discards |
652 // // Hash an input string and read the results. Each Write discards |
624 // // previous hash state. Read always reads the current state. |
653 // // previous hash state. Read always reads the current state. |
625 // b := make([]byte, 20) |
654 // b := make([]byte, 20) |
626 // for i := 0; i < 2; i++ { |
655 // for i := 0; i < 2; i++ { |
627 // io.WriteString(hash, "Hello, world.") |
656 // io.WriteString(hash, "Hello, world.") |
628 // hash.Read(b) |
657 // hash.Read(b) |
629 // fmt.Println(hex.EncodeToString(b)) |
658 // fmt.Println(hex.EncodeToString(b)) |
630 // } |
659 // } |
631 // // Output: |
660 // // Output: |
632 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 |
661 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 |
633 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 |
662 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 |
634 // |
663 // |
635 // For hashing larger byte slices, or byte streams such as those read from |
664 // For hashing larger byte slices, or byte streams such as those read from |
636 // a file or socket, use Sendto with MSG_MORE to instruct the kernel to update |
665 // a file or socket, use Sendto with MSG_MORE to instruct the kernel to update |
637 // the hash digest instead of creating a new one for a given chunk and finalizing it. |
666 // the hash digest instead of creating a new one for a given chunk and finalizing it. |
638 // |
667 // |
639 // // Assume hashfd and addr are already configured using the setup process. |
668 // // Assume hashfd and addr are already configured using the setup process. |
640 // hash := os.NewFile(hashfd, "sha1") |
669 // hash := os.NewFile(hashfd, "sha1") |
641 // // Hash the contents of a file. |
670 // // Hash the contents of a file. |
642 // f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz") |
671 // f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz") |
643 // b := make([]byte, 4096) |
672 // b := make([]byte, 4096) |
644 // for { |
673 // for { |
645 // n, err := f.Read(b) |
674 // n, err := f.Read(b) |
646 // if err == io.EOF { |
675 // if err == io.EOF { |
647 // break |
676 // break |
648 // } |
677 // } |
649 // unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr) |
678 // unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr) |
650 // } |
679 // } |
651 // hash.Read(b) |
680 // hash.Read(b) |
652 // fmt.Println(hex.EncodeToString(b)) |
681 // fmt.Println(hex.EncodeToString(b)) |
653 // // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5 |
682 // // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5 |
654 // |
683 // |
655 // For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html. |
684 // For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html. |
656 type SockaddrALG struct { |
685 type SockaddrALG struct { |
657 Type string |
686 Type string |
658 Name string |
687 Name string |
830 |
859 |
831 func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) { |
860 func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) { |
832 if sa.Addr == nil { |
861 if sa.Addr == nil { |
833 return nil, 0, EINVAL |
862 return nil, 0, EINVAL |
834 } |
863 } |
835 |
|
836 sa.raw.Family = AF_TIPC |
864 sa.raw.Family = AF_TIPC |
837 sa.raw.Scope = int8(sa.Scope) |
865 sa.raw.Scope = int8(sa.Scope) |
838 sa.raw.Addrtype = sa.Addr.tipcAddrtype() |
866 sa.raw.Addrtype = sa.Addr.tipcAddrtype() |
839 sa.raw.Addr = sa.Addr.tipcAddr() |
867 sa.raw.Addr = sa.Addr.tipcAddr() |
840 |
|
841 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil |
868 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil |
842 } |
869 } |
843 |
870 |
844 // SockaddrL2TPIP implements the Sockaddr interface for IPPROTO_L2TP/AF_INET sockets. |
871 // SockaddrL2TPIP implements the Sockaddr interface for IPPROTO_L2TP/AF_INET sockets. |
845 type SockaddrL2TPIP struct { |
872 type SockaddrL2TPIP struct { |
1033 case IPPROTO_L2TP: |
1050 case IPPROTO_L2TP: |
1034 pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa)) |
1051 pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa)) |
1035 sa := new(SockaddrL2TPIP6) |
1052 sa := new(SockaddrL2TPIP6) |
1036 sa.ConnId = pp.Conn_id |
1053 sa.ConnId = pp.Conn_id |
1037 sa.ZoneId = pp.Scope_id |
1054 sa.ZoneId = pp.Scope_id |
1038 for i := 0; i < len(sa.Addr); i++ { |
1055 sa.Addr = pp.Addr |
1039 sa.Addr[i] = pp.Addr[i] |
|
1040 } |
|
1041 return sa, nil |
1056 return sa, nil |
1042 default: |
1057 default: |
1043 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) |
1058 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) |
1044 sa := new(SockaddrInet6) |
1059 sa := new(SockaddrInet6) |
1045 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) |
1060 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) |
1046 sa.Port = int(p[0])<<8 + int(p[1]) |
1061 sa.Port = int(p[0])<<8 + int(p[1]) |
1047 sa.ZoneId = pp.Scope_id |
1062 sa.ZoneId = pp.Scope_id |
1048 for i := 0; i < len(sa.Addr); i++ { |
1063 sa.Addr = pp.Addr |
1049 sa.Addr[i] = pp.Addr[i] |
|
1050 } |
|
1051 return sa, nil |
1064 return sa, nil |
1052 } |
1065 } |
1053 |
1066 |
1054 case AF_VSOCK: |
1067 case AF_VSOCK: |
1055 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) |
1068 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) |
1344 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) |
1353 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) |
1345 } |
1354 } |
1346 |
1355 |
1347 func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error { |
1356 func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error { |
1348 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) |
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))) |
1349 } |
1365 } |
1350 |
1366 |
1351 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) |
1367 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) |
1352 |
1368 |
1353 // KeyctlInt calls keyctl commands in which each argument is an int. |
1369 // KeyctlInt calls keyctl commands in which each argument is an int. |
1481 } |
1497 } |
1482 |
1498 |
1483 //sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL |
1499 //sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL |
1484 //sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL |
1500 //sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL |
1485 |
1501 |
1486 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
1502 func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { |
1487 var msg Msghdr |
1503 var msg Msghdr |
1488 var rsa RawSockaddrAny |
1504 msg.Name = (*byte)(unsafe.Pointer(rsa)) |
1489 msg.Name = (*byte)(unsafe.Pointer(&rsa)) |
|
1490 msg.Namelen = uint32(SizeofSockaddrAny) |
1505 msg.Namelen = uint32(SizeofSockaddrAny) |
1491 var iov Iovec |
|
1492 if len(p) > 0 { |
|
1493 iov.Base = &p[0] |
|
1494 iov.SetLen(len(p)) |
|
1495 } |
|
1496 var dummy byte |
1506 var dummy byte |
1497 if len(oob) > 0 { |
1507 if len(oob) > 0 { |
1498 if len(p) == 0 { |
1508 if emptyIovecs(iov) { |
1499 var sockType int |
1509 var sockType int |
1500 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) |
1510 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) |
1501 if err != nil { |
1511 if err != nil { |
1502 return |
1512 return |
1503 } |
1513 } |
1504 // receive at least one normal byte |
1514 // receive at least one normal byte |
1505 if sockType != SOCK_DGRAM { |
1515 if sockType != SOCK_DGRAM { |
1506 iov.Base = &dummy |
1516 var iova [1]Iovec |
1507 iov.SetLen(1) |
1517 iova[0].Base = &dummy |
|
1518 iova[0].SetLen(1) |
|
1519 iov = iova[:] |
1508 } |
1520 } |
1509 } |
1521 } |
1510 msg.Control = &oob[0] |
1522 msg.Control = &oob[0] |
1511 msg.SetControllen(len(oob)) |
1523 msg.SetControllen(len(oob)) |
1512 } |
1524 } |
1513 msg.Iov = &iov |
1525 if len(iov) > 0 { |
1514 msg.Iovlen = 1 |
1526 msg.Iov = &iov[0] |
|
1527 msg.SetIovlen(len(iov)) |
|
1528 } |
1515 if n, err = recvmsg(fd, &msg, flags); err != nil { |
1529 if n, err = recvmsg(fd, &msg, flags); err != nil { |
1516 return |
1530 return |
1517 } |
1531 } |
1518 oobn = int(msg.Controllen) |
1532 oobn = int(msg.Controllen) |
1519 recvflags = int(msg.Flags) |
1533 recvflags = int(msg.Flags) |
1520 // source address is only specified if the socket is unconnected |
|
1521 if rsa.Addr.Family != AF_UNSPEC { |
|
1522 from, err = anyToSockaddr(fd, &rsa) |
|
1523 } |
|
1524 return |
1534 return |
1525 } |
1535 } |
1526 |
1536 |
1527 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { |
1537 func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { |
1528 _, err = SendmsgN(fd, p, oob, to, flags) |
|
1529 return |
|
1530 } |
|
1531 |
|
1532 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { |
|
1533 var ptr unsafe.Pointer |
|
1534 var salen _Socklen |
|
1535 if to != nil { |
|
1536 var err error |
|
1537 ptr, salen, err = to.sockaddr() |
|
1538 if err != nil { |
|
1539 return 0, err |
|
1540 } |
|
1541 } |
|
1542 var msg Msghdr |
1538 var msg Msghdr |
1543 msg.Name = (*byte)(ptr) |
1539 msg.Name = (*byte)(ptr) |
1544 msg.Namelen = uint32(salen) |
1540 msg.Namelen = uint32(salen) |
1545 var iov Iovec |
|
1546 if len(p) > 0 { |
|
1547 iov.Base = &p[0] |
|
1548 iov.SetLen(len(p)) |
|
1549 } |
|
1550 var dummy byte |
1541 var dummy byte |
|
1542 var empty bool |
1551 if len(oob) > 0 { |
1543 if len(oob) > 0 { |
1552 if len(p) == 0 { |
1544 empty = emptyIovecs(iov) |
|
1545 if empty { |
1553 var sockType int |
1546 var sockType int |
1554 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) |
1547 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) |
1555 if err != nil { |
1548 if err != nil { |
1556 return 0, err |
1549 return 0, err |
1557 } |
1550 } |
1558 // send at least one normal byte |
1551 // send at least one normal byte |
1559 if sockType != SOCK_DGRAM { |
1552 if sockType != SOCK_DGRAM { |
1560 iov.Base = &dummy |
1553 var iova [1]Iovec |
1561 iov.SetLen(1) |
1554 iova[0].Base = &dummy |
|
1555 iova[0].SetLen(1) |
1562 } |
1556 } |
1563 } |
1557 } |
1564 msg.Control = &oob[0] |
1558 msg.Control = &oob[0] |
1565 msg.SetControllen(len(oob)) |
1559 msg.SetControllen(len(oob)) |
1566 } |
1560 } |
1567 msg.Iov = &iov |
1561 if len(iov) > 0 { |
1568 msg.Iovlen = 1 |
1562 msg.Iov = &iov[0] |
|
1563 msg.SetIovlen(len(iov)) |
|
1564 } |
1569 if n, err = sendmsg(fd, &msg, flags); err != nil { |
1565 if n, err = sendmsg(fd, &msg, flags); err != nil { |
1570 return 0, err |
1566 return 0, err |
1571 } |
1567 } |
1572 if len(oob) > 0 && len(p) == 0 { |
1568 if len(oob) > 0 && empty { |
1573 n = 0 |
1569 n = 0 |
1574 } |
1570 } |
1575 return n, nil |
1571 return n, nil |
1576 } |
1572 } |
1577 |
1573 |
1767 datap, err := BytePtrFromString(data) |
1763 datap, err := BytePtrFromString(data) |
1768 if err != nil { |
1764 if err != nil { |
1769 return err |
1765 return err |
1770 } |
1766 } |
1771 return mount(source, target, fstype, flags, datap) |
1767 return mount(source, target, fstype, flags, datap) |
|
1768 } |
|
1769 |
|
1770 //sys mountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr, size uintptr) (err error) = SYS_MOUNT_SETATTR |
|
1771 |
|
1772 // MountSetattr is a wrapper for mount_setattr(2). |
|
1773 // https://man7.org/linux/man-pages/man2/mount_setattr.2.html |
|
1774 // |
|
1775 // Requires kernel >= 5.12. |
|
1776 func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error { |
|
1777 return mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr)) |
1772 } |
1778 } |
1773 |
1779 |
1774 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { |
1780 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { |
1775 if raceenabled { |
1781 if raceenabled { |
1776 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
1782 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
1800 //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) |
1806 //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) |
1801 //sys DeleteModule(name string, flags int) (err error) |
1807 //sys DeleteModule(name string, flags int) (err error) |
1802 //sys Dup(oldfd int) (fd int, err error) |
1808 //sys Dup(oldfd int) (fd int, err error) |
1803 |
1809 |
1804 func Dup2(oldfd, newfd int) error { |
1810 func Dup2(oldfd, newfd int) error { |
1805 // Android O and newer blocks dup2; riscv and arm64 don't implement dup2. |
1811 return Dup3(oldfd, newfd, 0) |
1806 if runtime.GOOS == "android" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "arm64" { |
|
1807 return Dup3(oldfd, newfd, 0) |
|
1808 } |
|
1809 return dup2(oldfd, newfd) |
|
1810 } |
1812 } |
1811 |
1813 |
1812 //sys Dup3(oldfd int, newfd int, flags int) (err error) |
1814 //sys Dup3(oldfd int, newfd int, flags int) (err error) |
1813 //sysnb EpollCreate1(flag int) (fd int, err error) |
1815 //sysnb EpollCreate1(flag int) (fd int, err error) |
1814 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) |
1816 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) |
1824 //sys Flistxattr(fd int, dest []byte) (sz int, err error) |
1826 //sys Flistxattr(fd int, dest []byte) (sz int, err error) |
1825 //sys Flock(fd int, how int) (err error) |
1827 //sys Flock(fd int, how int) (err error) |
1826 //sys Fremovexattr(fd int, attr string) (err error) |
1828 //sys Fremovexattr(fd int, attr string) (err error) |
1827 //sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) |
1829 //sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) |
1828 //sys Fsync(fd int) (err error) |
1830 //sys Fsync(fd int) (err error) |
|
1831 //sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) |
|
1832 //sys Fsopen(fsName string, flags int) (fd int, err error) |
|
1833 //sys Fspick(dirfd int, pathName string, flags int) (fd int, err error) |
1829 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 |
1834 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 |
1830 //sysnb Getpgid(pid int) (pgid int, err error) |
1835 //sysnb Getpgid(pid int) (pgid int, err error) |
1831 |
1836 |
1832 func Getpgrp() (pid int) { |
1837 func Getpgrp() (pid int) { |
1833 pid, _ = Getpgid(0) |
1838 pid, _ = Getpgid(0) |
1854 //sys Lremovexattr(path string, attr string) (err error) |
1859 //sys Lremovexattr(path string, attr string) (err error) |
1855 //sys Lsetxattr(path string, attr string, data []byte, flags int) (err error) |
1860 //sys Lsetxattr(path string, attr string, data []byte, flags int) (err error) |
1856 //sys MemfdCreate(name string, flags int) (fd int, err error) |
1861 //sys MemfdCreate(name string, flags int) (fd int, err error) |
1857 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) |
1862 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) |
1858 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) |
1863 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) |
|
1864 //sys MoveMount(fromDirfd int, fromPathName string, toDirfd int, toPathName string, flags int) (err error) |
1859 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) |
1865 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) |
|
1866 //sys OpenTree(dfd int, fileName string, flags uint) (r int, err error) |
1860 //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) |
1867 //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) |
1861 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT |
1868 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT |
1862 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 |
1869 //sysnb Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 |
1863 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) |
1870 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) |
1864 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 |
1871 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 |
1865 //sys read(fd int, p []byte) (n int, err error) |
1872 //sys read(fd int, p []byte) (n int, err error) |
1866 //sys Removexattr(path string, attr string) (err error) |
1873 //sys Removexattr(path string, attr string) (err error) |
1867 //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) |
1874 //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) |
2292 } |
2299 } |
2293 |
2300 |
2294 //sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV |
2301 //sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV |
2295 //sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV |
2302 //sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV |
2296 |
2303 |
|
2304 //sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN |
|
2305 //sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD |
|
2306 //sys PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) = SYS_PIDFD_SEND_SIGNAL |
|
2307 |
|
2308 //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) |
|
2309 //sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) |
|
2310 //sys shmdt(addr uintptr) (err error) |
|
2311 //sys shmget(key int, size int, flag int) (id int, err error) |
|
2312 |
|
2313 //sys getitimer(which int, currValue *Itimerval) (err error) |
|
2314 //sys setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error) |
|
2315 |
|
2316 // MakeItimerval creates an Itimerval from interval and value durations. |
|
2317 func MakeItimerval(interval, value time.Duration) Itimerval { |
|
2318 return Itimerval{ |
|
2319 Interval: NsecToTimeval(interval.Nanoseconds()), |
|
2320 Value: NsecToTimeval(value.Nanoseconds()), |
|
2321 } |
|
2322 } |
|
2323 |
|
2324 // A value which may be passed to the which parameter for Getitimer and |
|
2325 // Setitimer. |
|
2326 type ItimerWhich int |
|
2327 |
|
2328 // Possible which values for Getitimer and Setitimer. |
|
2329 const ( |
|
2330 ItimerReal ItimerWhich = ITIMER_REAL |
|
2331 ItimerVirtual ItimerWhich = ITIMER_VIRTUAL |
|
2332 ItimerProf ItimerWhich = ITIMER_PROF |
|
2333 ) |
|
2334 |
|
2335 // Getitimer wraps getitimer(2) to return the current value of the timer |
|
2336 // specified by which. |
|
2337 func Getitimer(which ItimerWhich) (Itimerval, error) { |
|
2338 var it Itimerval |
|
2339 if err := getitimer(int(which), &it); err != nil { |
|
2340 return Itimerval{}, err |
|
2341 } |
|
2342 |
|
2343 return it, nil |
|
2344 } |
|
2345 |
|
2346 // Setitimer wraps setitimer(2) to arm or disarm the timer specified by which. |
|
2347 // It returns the previous value of the timer. |
|
2348 // |
|
2349 // If the Itimerval argument is the zero value, the timer will be disarmed. |
|
2350 func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) { |
|
2351 var prev Itimerval |
|
2352 if err := setitimer(int(which), &it, &prev); err != nil { |
|
2353 return Itimerval{}, err |
|
2354 } |
|
2355 |
|
2356 return prev, nil |
|
2357 } |
|
2358 |
2297 /* |
2359 /* |
2298 * Unimplemented |
2360 * Unimplemented |
2299 */ |
2361 */ |
2300 // AfsSyscall |
2362 // AfsSyscall |
2301 // Alarm |
|
2302 // ArchPrctl |
2363 // ArchPrctl |
2303 // Brk |
2364 // Brk |
2304 // ClockNanosleep |
2365 // ClockNanosleep |
2305 // ClockSettime |
2366 // ClockSettime |
2306 // Clone |
2367 // Clone |