You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

297 lines
6.8 KiB

  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build darwin dragonfly freebsd linux netbsd openbsd solaris
  5. package unix
  6. import (
  7. "runtime"
  8. "sync"
  9. "syscall"
  10. "unsafe"
  11. )
  12. var (
  13. Stdin = 0
  14. Stdout = 1
  15. Stderr = 2
  16. )
  17. const (
  18. darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8
  19. dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8
  20. netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
  21. )
  22. // Do the interface allocations only once for common
  23. // Errno values.
  24. var (
  25. errEAGAIN error = syscall.EAGAIN
  26. errEINVAL error = syscall.EINVAL
  27. errENOENT error = syscall.ENOENT
  28. )
  29. // errnoErr returns common boxed Errno values, to prevent
  30. // allocations at runtime.
  31. func errnoErr(e syscall.Errno) error {
  32. switch e {
  33. case 0:
  34. return nil
  35. case EAGAIN:
  36. return errEAGAIN
  37. case EINVAL:
  38. return errEINVAL
  39. case ENOENT:
  40. return errENOENT
  41. }
  42. return e
  43. }
  44. func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
  45. func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
  46. func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
  47. func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
  48. // Mmap manager, for use by operating system-specific implementations.
  49. type mmapper struct {
  50. sync.Mutex
  51. active map[*byte][]byte // active mappings; key is last byte in mapping
  52. mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
  53. munmap func(addr uintptr, length uintptr) error
  54. }
  55. func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  56. if length <= 0 {
  57. return nil, EINVAL
  58. }
  59. // Map the requested memory.
  60. addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
  61. if errno != nil {
  62. return nil, errno
  63. }
  64. // Slice memory layout
  65. var sl = struct {
  66. addr uintptr
  67. len int
  68. cap int
  69. }{addr, length, length}
  70. // Use unsafe to turn sl into a []byte.
  71. b := *(*[]byte)(unsafe.Pointer(&sl))
  72. // Register mapping in m and return it.
  73. p := &b[cap(b)-1]
  74. m.Lock()
  75. defer m.Unlock()
  76. m.active[p] = b
  77. return b, nil
  78. }
  79. func (m *mmapper) Munmap(data []byte) (err error) {
  80. if len(data) == 0 || len(data) != cap(data) {
  81. return EINVAL
  82. }
  83. // Find the base of the mapping.
  84. p := &data[cap(data)-1]
  85. m.Lock()
  86. defer m.Unlock()
  87. b := m.active[p]
  88. if b == nil || &b[0] != &data[0] {
  89. return EINVAL
  90. }
  91. // Unmap the memory and update m.
  92. if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
  93. return errno
  94. }
  95. delete(m.active, p)
  96. return nil
  97. }
  98. func Read(fd int, p []byte) (n int, err error) {
  99. n, err = read(fd, p)
  100. if raceenabled {
  101. if n > 0 {
  102. raceWriteRange(unsafe.Pointer(&p[0]), n)
  103. }
  104. if err == nil {
  105. raceAcquire(unsafe.Pointer(&ioSync))
  106. }
  107. }
  108. return
  109. }
  110. func Write(fd int, p []byte) (n int, err error) {
  111. if raceenabled {
  112. raceReleaseMerge(unsafe.Pointer(&ioSync))
  113. }
  114. n, err = write(fd, p)
  115. if raceenabled && n > 0 {
  116. raceReadRange(unsafe.Pointer(&p[0]), n)
  117. }
  118. return
  119. }
  120. // For testing: clients can set this flag to force
  121. // creation of IPv6 sockets to return EAFNOSUPPORT.
  122. var SocketDisableIPv6 bool
  123. type Sockaddr interface {
  124. sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
  125. }
  126. type SockaddrInet4 struct {
  127. Port int
  128. Addr [4]byte
  129. raw RawSockaddrInet4
  130. }
  131. type SockaddrInet6 struct {
  132. Port int
  133. ZoneId uint32
  134. Addr [16]byte
  135. raw RawSockaddrInet6
  136. }
  137. type SockaddrUnix struct {
  138. Name string
  139. raw RawSockaddrUnix
  140. }
  141. func Bind(fd int, sa Sockaddr) (err error) {
  142. ptr, n, err := sa.sockaddr()
  143. if err != nil {
  144. return err
  145. }
  146. return bind(fd, ptr, n)
  147. }
  148. func Connect(fd int, sa Sockaddr) (err error) {
  149. ptr, n, err := sa.sockaddr()
  150. if err != nil {
  151. return err
  152. }
  153. return connect(fd, ptr, n)
  154. }
  155. func Getpeername(fd int) (sa Sockaddr, err error) {
  156. var rsa RawSockaddrAny
  157. var len _Socklen = SizeofSockaddrAny
  158. if err = getpeername(fd, &rsa, &len); err != nil {
  159. return
  160. }
  161. return anyToSockaddr(&rsa)
  162. }
  163. func GetsockoptInt(fd, level, opt int) (value int, err error) {
  164. var n int32
  165. vallen := _Socklen(4)
  166. err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  167. return int(n), err
  168. }
  169. func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
  170. var rsa RawSockaddrAny
  171. var len _Socklen = SizeofSockaddrAny
  172. if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
  173. return
  174. }
  175. if rsa.Addr.Family != AF_UNSPEC {
  176. from, err = anyToSockaddr(&rsa)
  177. }
  178. return
  179. }
  180. func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
  181. ptr, n, err := to.sockaddr()
  182. if err != nil {
  183. return err
  184. }
  185. return sendto(fd, p, flags, ptr, n)
  186. }
  187. func SetsockoptByte(fd, level, opt int, value byte) (err error) {
  188. return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
  189. }
  190. func SetsockoptInt(fd, level, opt int, value int) (err error) {
  191. var n = int32(value)
  192. return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
  193. }
  194. func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
  195. return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
  196. }
  197. func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
  198. return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
  199. }
  200. func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
  201. return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
  202. }
  203. func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
  204. return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
  205. }
  206. func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
  207. return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
  208. }
  209. func SetsockoptString(fd, level, opt int, s string) (err error) {
  210. return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s)))
  211. }
  212. func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
  213. return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
  214. }
  215. func Socket(domain, typ, proto int) (fd int, err error) {
  216. if domain == AF_INET6 && SocketDisableIPv6 {
  217. return -1, EAFNOSUPPORT
  218. }
  219. fd, err = socket(domain, typ, proto)
  220. return
  221. }
  222. func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
  223. var fdx [2]int32
  224. err = socketpair(domain, typ, proto, &fdx)
  225. if err == nil {
  226. fd[0] = int(fdx[0])
  227. fd[1] = int(fdx[1])
  228. }
  229. return
  230. }
  231. func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
  232. if raceenabled {
  233. raceReleaseMerge(unsafe.Pointer(&ioSync))
  234. }
  235. return sendfile(outfd, infd, offset, count)
  236. }
  237. var ioSync int64
  238. func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
  239. func SetNonblock(fd int, nonblocking bool) (err error) {
  240. flag, err := fcntl(fd, F_GETFL, 0)
  241. if err != nil {
  242. return err
  243. }
  244. if nonblocking {
  245. flag |= O_NONBLOCK
  246. } else {
  247. flag &= ^O_NONBLOCK
  248. }
  249. _, err = fcntl(fd, F_SETFL, flag)
  250. return err
  251. }