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.

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