PageRenderTime 57ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/gofrontend/libgo/go/net/fd_unix.go

http://github.com/axw/llgo
Go | 506 lines | 397 code | 40 blank | 69 comment | 148 complexity | de59827147974a22a544c2f08f4a78a3 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  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 nacl netbsd openbsd solaris
  5. package net
  6. import (
  7. "io"
  8. "os"
  9. "runtime"
  10. "sync/atomic"
  11. "syscall"
  12. "time"
  13. )
  14. // Network file descriptor.
  15. type netFD struct {
  16. // locking/lifetime of sysfd + serialize access to Read and Write methods
  17. fdmu fdMutex
  18. // immutable until Close
  19. sysfd int
  20. family int
  21. sotype int
  22. isConnected bool
  23. net string
  24. laddr Addr
  25. raddr Addr
  26. // wait server
  27. pd pollDesc
  28. }
  29. func sysInit() {
  30. }
  31. func dial(network string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
  32. return dialer(deadline)
  33. }
  34. func newFD(sysfd, family, sotype int, net string) (*netFD, error) {
  35. return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, nil
  36. }
  37. func (fd *netFD) init() error {
  38. if err := fd.pd.Init(fd); err != nil {
  39. return err
  40. }
  41. return nil
  42. }
  43. func (fd *netFD) setAddr(laddr, raddr Addr) {
  44. fd.laddr = laddr
  45. fd.raddr = raddr
  46. runtime.SetFinalizer(fd, (*netFD).Close)
  47. }
  48. func (fd *netFD) name() string {
  49. var ls, rs string
  50. if fd.laddr != nil {
  51. ls = fd.laddr.String()
  52. }
  53. if fd.raddr != nil {
  54. rs = fd.raddr.String()
  55. }
  56. return fd.net + ":" + ls + "->" + rs
  57. }
  58. func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
  59. // Do not need to call fd.writeLock here,
  60. // because fd is not yet accessible to user,
  61. // so no concurrent operations are possible.
  62. switch err := connectFunc(fd.sysfd, ra); err {
  63. case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
  64. case nil, syscall.EISCONN:
  65. if !deadline.IsZero() && deadline.Before(time.Now()) {
  66. return errTimeout
  67. }
  68. if err := fd.init(); err != nil {
  69. return err
  70. }
  71. return nil
  72. case syscall.EINVAL:
  73. // On Solaris we can see EINVAL if the socket has
  74. // already been accepted and closed by the server.
  75. // Treat this as a successful connection--writes to
  76. // the socket will see EOF. For details and a test
  77. // case in C see https://golang.org/issue/6828.
  78. if runtime.GOOS == "solaris" {
  79. return nil
  80. }
  81. fallthrough
  82. default:
  83. return os.NewSyscallError("connect", err)
  84. }
  85. if err := fd.init(); err != nil {
  86. return err
  87. }
  88. if !deadline.IsZero() {
  89. fd.setWriteDeadline(deadline)
  90. defer fd.setWriteDeadline(noDeadline)
  91. }
  92. for {
  93. // Performing multiple connect system calls on a
  94. // non-blocking socket under Unix variants does not
  95. // necessarily result in earlier errors being
  96. // returned. Instead, once runtime-integrated network
  97. // poller tells us that the socket is ready, get the
  98. // SO_ERROR socket option to see if the connection
  99. // succeeded or failed. See issue 7474 for further
  100. // details.
  101. if err := fd.pd.WaitWrite(); err != nil {
  102. return err
  103. }
  104. nerr, err := getsockoptIntFunc(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
  105. if err != nil {
  106. return os.NewSyscallError("getsockopt", err)
  107. }
  108. switch err := syscall.Errno(nerr); err {
  109. case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
  110. case syscall.Errno(0), syscall.EISCONN:
  111. return nil
  112. default:
  113. return os.NewSyscallError("getsockopt", err)
  114. }
  115. }
  116. }
  117. func (fd *netFD) destroy() {
  118. // Poller may want to unregister fd in readiness notification mechanism,
  119. // so this must be executed before closeFunc.
  120. fd.pd.Close()
  121. closeFunc(fd.sysfd)
  122. fd.sysfd = -1
  123. runtime.SetFinalizer(fd, nil)
  124. }
  125. // Add a reference to this fd.
  126. // Returns an error if the fd cannot be used.
  127. func (fd *netFD) incref() error {
  128. if !fd.fdmu.Incref() {
  129. return errClosing
  130. }
  131. return nil
  132. }
  133. // Remove a reference to this FD and close if we've been asked to do so
  134. // (and there are no references left).
  135. func (fd *netFD) decref() {
  136. if fd.fdmu.Decref() {
  137. fd.destroy()
  138. }
  139. }
  140. // Add a reference to this fd and lock for reading.
  141. // Returns an error if the fd cannot be used.
  142. func (fd *netFD) readLock() error {
  143. if !fd.fdmu.RWLock(true) {
  144. return errClosing
  145. }
  146. return nil
  147. }
  148. // Unlock for reading and remove a reference to this FD.
  149. func (fd *netFD) readUnlock() {
  150. if fd.fdmu.RWUnlock(true) {
  151. fd.destroy()
  152. }
  153. }
  154. // Add a reference to this fd and lock for writing.
  155. // Returns an error if the fd cannot be used.
  156. func (fd *netFD) writeLock() error {
  157. if !fd.fdmu.RWLock(false) {
  158. return errClosing
  159. }
  160. return nil
  161. }
  162. // Unlock for writing and remove a reference to this FD.
  163. func (fd *netFD) writeUnlock() {
  164. if fd.fdmu.RWUnlock(false) {
  165. fd.destroy()
  166. }
  167. }
  168. func (fd *netFD) Close() error {
  169. if !fd.fdmu.IncrefAndClose() {
  170. return errClosing
  171. }
  172. // Unblock any I/O. Once it all unblocks and returns,
  173. // so that it cannot be referring to fd.sysfd anymore,
  174. // the final decref will close fd.sysfd. This should happen
  175. // fairly quickly, since all the I/O is non-blocking, and any
  176. // attempts to block in the pollDesc will return errClosing.
  177. fd.pd.Evict()
  178. fd.decref()
  179. return nil
  180. }
  181. func (fd *netFD) shutdown(how int) error {
  182. if err := fd.incref(); err != nil {
  183. return err
  184. }
  185. defer fd.decref()
  186. return os.NewSyscallError("shutdown", syscall.Shutdown(fd.sysfd, how))
  187. }
  188. func (fd *netFD) closeRead() error {
  189. return fd.shutdown(syscall.SHUT_RD)
  190. }
  191. func (fd *netFD) closeWrite() error {
  192. return fd.shutdown(syscall.SHUT_WR)
  193. }
  194. func (fd *netFD) Read(p []byte) (n int, err error) {
  195. if err := fd.readLock(); err != nil {
  196. return 0, err
  197. }
  198. defer fd.readUnlock()
  199. if err := fd.pd.PrepareRead(); err != nil {
  200. return 0, err
  201. }
  202. for {
  203. n, err = syscall.Read(fd.sysfd, p)
  204. if err != nil {
  205. n = 0
  206. if err == syscall.EAGAIN {
  207. if err = fd.pd.WaitRead(); err == nil {
  208. continue
  209. }
  210. }
  211. }
  212. err = fd.eofError(n, err)
  213. break
  214. }
  215. if _, ok := err.(syscall.Errno); ok {
  216. err = os.NewSyscallError("read", err)
  217. }
  218. return
  219. }
  220. func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
  221. if err := fd.readLock(); err != nil {
  222. return 0, nil, err
  223. }
  224. defer fd.readUnlock()
  225. if err := fd.pd.PrepareRead(); err != nil {
  226. return 0, nil, err
  227. }
  228. for {
  229. n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0)
  230. if err != nil {
  231. n = 0
  232. if err == syscall.EAGAIN {
  233. if err = fd.pd.WaitRead(); err == nil {
  234. continue
  235. }
  236. }
  237. }
  238. err = fd.eofError(n, err)
  239. break
  240. }
  241. if _, ok := err.(syscall.Errno); ok {
  242. err = os.NewSyscallError("recvfrom", err)
  243. }
  244. return
  245. }
  246. func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
  247. if err := fd.readLock(); err != nil {
  248. return 0, 0, 0, nil, err
  249. }
  250. defer fd.readUnlock()
  251. if err := fd.pd.PrepareRead(); err != nil {
  252. return 0, 0, 0, nil, err
  253. }
  254. for {
  255. n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0)
  256. if err != nil {
  257. // TODO(dfc) should n and oobn be set to 0
  258. if err == syscall.EAGAIN {
  259. if err = fd.pd.WaitRead(); err == nil {
  260. continue
  261. }
  262. }
  263. }
  264. err = fd.eofError(n, err)
  265. break
  266. }
  267. if _, ok := err.(syscall.Errno); ok {
  268. err = os.NewSyscallError("recvmsg", err)
  269. }
  270. return
  271. }
  272. func (fd *netFD) Write(p []byte) (nn int, err error) {
  273. if err := fd.writeLock(); err != nil {
  274. return 0, err
  275. }
  276. defer fd.writeUnlock()
  277. if err := fd.pd.PrepareWrite(); err != nil {
  278. return 0, err
  279. }
  280. for {
  281. var n int
  282. n, err = syscall.Write(fd.sysfd, p[nn:])
  283. if n > 0 {
  284. nn += n
  285. }
  286. if nn == len(p) {
  287. break
  288. }
  289. if err == syscall.EAGAIN {
  290. if err = fd.pd.WaitWrite(); err == nil {
  291. continue
  292. }
  293. }
  294. if err != nil {
  295. break
  296. }
  297. if n == 0 {
  298. err = io.ErrUnexpectedEOF
  299. break
  300. }
  301. }
  302. if _, ok := err.(syscall.Errno); ok {
  303. err = os.NewSyscallError("write", err)
  304. }
  305. return nn, err
  306. }
  307. func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
  308. if err := fd.writeLock(); err != nil {
  309. return 0, err
  310. }
  311. defer fd.writeUnlock()
  312. if err := fd.pd.PrepareWrite(); err != nil {
  313. return 0, err
  314. }
  315. for {
  316. err = syscall.Sendto(fd.sysfd, p, 0, sa)
  317. if err == syscall.EAGAIN {
  318. if err = fd.pd.WaitWrite(); err == nil {
  319. continue
  320. }
  321. }
  322. break
  323. }
  324. if err == nil {
  325. n = len(p)
  326. }
  327. if _, ok := err.(syscall.Errno); ok {
  328. err = os.NewSyscallError("sendto", err)
  329. }
  330. return
  331. }
  332. func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
  333. if err := fd.writeLock(); err != nil {
  334. return 0, 0, err
  335. }
  336. defer fd.writeUnlock()
  337. if err := fd.pd.PrepareWrite(); err != nil {
  338. return 0, 0, err
  339. }
  340. for {
  341. n, err = syscall.SendmsgN(fd.sysfd, p, oob, sa, 0)
  342. if err == syscall.EAGAIN {
  343. if err = fd.pd.WaitWrite(); err == nil {
  344. continue
  345. }
  346. }
  347. break
  348. }
  349. if err == nil {
  350. oobn = len(oob)
  351. }
  352. if _, ok := err.(syscall.Errno); ok {
  353. err = os.NewSyscallError("sendmsg", err)
  354. }
  355. return
  356. }
  357. func (fd *netFD) accept() (netfd *netFD, err error) {
  358. if err := fd.readLock(); err != nil {
  359. return nil, err
  360. }
  361. defer fd.readUnlock()
  362. var s int
  363. var rsa syscall.Sockaddr
  364. if err = fd.pd.PrepareRead(); err != nil {
  365. return nil, err
  366. }
  367. for {
  368. s, rsa, err = accept(fd.sysfd)
  369. if err != nil {
  370. nerr, ok := err.(*os.SyscallError)
  371. if !ok {
  372. return nil, err
  373. }
  374. switch nerr.Err {
  375. case syscall.EAGAIN:
  376. if err = fd.pd.WaitRead(); err == nil {
  377. continue
  378. }
  379. case syscall.ECONNABORTED:
  380. // This means that a socket on the
  381. // listen queue was closed before we
  382. // Accept()ed it; it's a silly error,
  383. // so try again.
  384. continue
  385. }
  386. return nil, err
  387. }
  388. break
  389. }
  390. if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil {
  391. closeFunc(s)
  392. return nil, err
  393. }
  394. if err = netfd.init(); err != nil {
  395. fd.Close()
  396. return nil, err
  397. }
  398. lsa, _ := syscall.Getsockname(netfd.sysfd)
  399. netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
  400. return netfd, nil
  401. }
  402. // Use a helper function to call fcntl. This is defined in C in
  403. // libgo/runtime.
  404. //extern __go_fcntl_uintptr
  405. func fcntl(uintptr, uintptr, uintptr) (uintptr, uintptr)
  406. // tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used.
  407. // If the kernel doesn't support it, this is set to 0.
  408. var tryDupCloexec = int32(1)
  409. func dupCloseOnExec(fd int) (newfd int, err error) {
  410. if atomic.LoadInt32(&tryDupCloexec) == 1 && syscall.F_DUPFD_CLOEXEC != 0 {
  411. syscall.Entersyscall()
  412. r0, errno := fcntl(uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
  413. syscall.Exitsyscall()
  414. e1 := syscall.Errno(errno)
  415. if runtime.GOOS == "darwin" && e1 == syscall.EBADF {
  416. // On OS X 10.6 and below (but we only support
  417. // >= 10.6), F_DUPFD_CLOEXEC is unsupported
  418. // and fcntl there falls back (undocumented)
  419. // to doing an ioctl instead, returning EBADF
  420. // in this case because fd is not of the
  421. // expected device fd type. Treat it as
  422. // EINVAL instead, so we fall back to the
  423. // normal dup path.
  424. // TODO: only do this on 10.6 if we can detect 10.6
  425. // cheaply.
  426. e1 = syscall.EINVAL
  427. }
  428. switch e1 {
  429. case 0:
  430. return int(r0), nil
  431. case syscall.EINVAL:
  432. // Old kernel. Fall back to the portable way
  433. // from now on.
  434. atomic.StoreInt32(&tryDupCloexec, 0)
  435. default:
  436. return -1, os.NewSyscallError("fcntl", e1)
  437. }
  438. }
  439. return dupCloseOnExecOld(fd)
  440. }
  441. // dupCloseOnExecUnixOld is the traditional way to dup an fd and
  442. // set its O_CLOEXEC bit, using two system calls.
  443. func dupCloseOnExecOld(fd int) (newfd int, err error) {
  444. syscall.ForkLock.RLock()
  445. defer syscall.ForkLock.RUnlock()
  446. newfd, err = syscall.Dup(fd)
  447. if err != nil {
  448. return -1, os.NewSyscallError("dup", err)
  449. }
  450. syscall.CloseOnExec(newfd)
  451. return
  452. }
  453. func (fd *netFD) dup() (f *os.File, err error) {
  454. ns, err := dupCloseOnExec(fd.sysfd)
  455. if err != nil {
  456. return nil, err
  457. }
  458. // We want blocking mode for the new fd, hence the double negative.
  459. // This also puts the old fd into blocking mode, meaning that
  460. // I/O will block the thread instead of letting us use the epoll server.
  461. // Everything will still work, just with more threads.
  462. if err = syscall.SetNonblock(ns, false); err != nil {
  463. return nil, os.NewSyscallError("setnonblock", err)
  464. }
  465. return os.NewFile(uintptr(ns), fd.name()), nil
  466. }