PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/libgo/go/net/fd_unix.go

https://gitlab.com/sortix/gcc
Go | 518 lines | 412 code | 42 blank | 64 comment | 174 complexity | 27d4a7d7809b9c327355d5d91345190a MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  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 := syscall.Connect(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 http://golang.org/issue/6828.
  78. if runtime.GOOS == "solaris" {
  79. return nil
  80. }
  81. fallthrough
  82. default:
  83. return 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 := syscall.GetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
  105. if err != nil {
  106. return 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 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 closesocket.
  120. fd.pd.Close()
  121. closesocket(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. fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict
  170. if !fd.fdmu.IncrefAndClose() {
  171. fd.pd.Unlock()
  172. return errClosing
  173. }
  174. // Unblock any I/O. Once it all unblocks and returns,
  175. // so that it cannot be referring to fd.sysfd anymore,
  176. // the final decref will close fd.sysfd. This should happen
  177. // fairly quickly, since all the I/O is non-blocking, and any
  178. // attempts to block in the pollDesc will return errClosing.
  179. doWakeup := fd.pd.Evict()
  180. fd.pd.Unlock()
  181. fd.decref()
  182. if doWakeup {
  183. fd.pd.Wakeup()
  184. }
  185. return nil
  186. }
  187. func (fd *netFD) shutdown(how int) error {
  188. if err := fd.incref(); err != nil {
  189. return err
  190. }
  191. defer fd.decref()
  192. err := syscall.Shutdown(fd.sysfd, how)
  193. if err != nil {
  194. return &OpError{"shutdown", fd.net, fd.laddr, err}
  195. }
  196. return nil
  197. }
  198. func (fd *netFD) closeRead() error {
  199. return fd.shutdown(syscall.SHUT_RD)
  200. }
  201. func (fd *netFD) closeWrite() error {
  202. return fd.shutdown(syscall.SHUT_WR)
  203. }
  204. func (fd *netFD) Read(p []byte) (n int, err error) {
  205. if err := fd.readLock(); err != nil {
  206. return 0, err
  207. }
  208. defer fd.readUnlock()
  209. if err := fd.pd.PrepareRead(); err != nil {
  210. return 0, &OpError{"read", fd.net, fd.raddr, err}
  211. }
  212. for {
  213. n, err = syscall.Read(int(fd.sysfd), p)
  214. if err != nil {
  215. n = 0
  216. if err == syscall.EAGAIN {
  217. if err = fd.pd.WaitRead(); err == nil {
  218. continue
  219. }
  220. }
  221. }
  222. err = chkReadErr(n, err, fd)
  223. break
  224. }
  225. if err != nil && err != io.EOF {
  226. err = &OpError{"read", fd.net, fd.raddr, err}
  227. }
  228. return
  229. }
  230. func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
  231. if err := fd.readLock(); err != nil {
  232. return 0, nil, err
  233. }
  234. defer fd.readUnlock()
  235. if err := fd.pd.PrepareRead(); err != nil {
  236. return 0, nil, &OpError{"read", fd.net, fd.laddr, err}
  237. }
  238. for {
  239. n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0)
  240. if err != nil {
  241. n = 0
  242. if err == syscall.EAGAIN {
  243. if err = fd.pd.WaitRead(); err == nil {
  244. continue
  245. }
  246. }
  247. }
  248. err = chkReadErr(n, err, fd)
  249. break
  250. }
  251. if err != nil && err != io.EOF {
  252. err = &OpError{"read", fd.net, fd.laddr, err}
  253. }
  254. return
  255. }
  256. func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
  257. if err := fd.readLock(); err != nil {
  258. return 0, 0, 0, nil, err
  259. }
  260. defer fd.readUnlock()
  261. if err := fd.pd.PrepareRead(); err != nil {
  262. return 0, 0, 0, nil, &OpError{"read", fd.net, fd.laddr, err}
  263. }
  264. for {
  265. n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0)
  266. if err != nil {
  267. // TODO(dfc) should n and oobn be set to 0
  268. if err == syscall.EAGAIN {
  269. if err = fd.pd.WaitRead(); err == nil {
  270. continue
  271. }
  272. }
  273. }
  274. err = chkReadErr(n, err, fd)
  275. break
  276. }
  277. if err != nil && err != io.EOF {
  278. err = &OpError{"read", fd.net, fd.laddr, err}
  279. }
  280. return
  281. }
  282. func chkReadErr(n int, err error, fd *netFD) error {
  283. if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM && fd.sotype != syscall.SOCK_RAW {
  284. return io.EOF
  285. }
  286. return err
  287. }
  288. func (fd *netFD) Write(p []byte) (nn int, err error) {
  289. if err := fd.writeLock(); err != nil {
  290. return 0, err
  291. }
  292. defer fd.writeUnlock()
  293. if err := fd.pd.PrepareWrite(); err != nil {
  294. return 0, &OpError{"write", fd.net, fd.raddr, err}
  295. }
  296. for {
  297. var n int
  298. n, err = syscall.Write(int(fd.sysfd), p[nn:])
  299. if n > 0 {
  300. nn += n
  301. }
  302. if nn == len(p) {
  303. break
  304. }
  305. if err == syscall.EAGAIN {
  306. if err = fd.pd.WaitWrite(); err == nil {
  307. continue
  308. }
  309. }
  310. if err != nil {
  311. n = 0
  312. break
  313. }
  314. if n == 0 {
  315. err = io.ErrUnexpectedEOF
  316. break
  317. }
  318. }
  319. if err != nil {
  320. err = &OpError{"write", fd.net, fd.raddr, err}
  321. }
  322. return nn, err
  323. }
  324. func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
  325. if err := fd.writeLock(); err != nil {
  326. return 0, err
  327. }
  328. defer fd.writeUnlock()
  329. if err := fd.pd.PrepareWrite(); err != nil {
  330. return 0, &OpError{"write", fd.net, fd.raddr, err}
  331. }
  332. for {
  333. err = syscall.Sendto(fd.sysfd, p, 0, sa)
  334. if err == syscall.EAGAIN {
  335. if err = fd.pd.WaitWrite(); err == nil {
  336. continue
  337. }
  338. }
  339. break
  340. }
  341. if err == nil {
  342. n = len(p)
  343. } else {
  344. err = &OpError{"write", fd.net, fd.raddr, err}
  345. }
  346. return
  347. }
  348. func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
  349. if err := fd.writeLock(); err != nil {
  350. return 0, 0, err
  351. }
  352. defer fd.writeUnlock()
  353. if err := fd.pd.PrepareWrite(); err != nil {
  354. return 0, 0, &OpError{"write", fd.net, fd.raddr, err}
  355. }
  356. for {
  357. n, err = syscall.SendmsgN(fd.sysfd, p, oob, sa, 0)
  358. if err == syscall.EAGAIN {
  359. if err = fd.pd.WaitWrite(); err == nil {
  360. continue
  361. }
  362. }
  363. break
  364. }
  365. if err == nil {
  366. oobn = len(oob)
  367. } else {
  368. err = &OpError{"write", fd.net, fd.raddr, err}
  369. }
  370. return
  371. }
  372. func (fd *netFD) accept() (netfd *netFD, err error) {
  373. if err := fd.readLock(); err != nil {
  374. return nil, err
  375. }
  376. defer fd.readUnlock()
  377. var s int
  378. var rsa syscall.Sockaddr
  379. if err = fd.pd.PrepareRead(); err != nil {
  380. return nil, &OpError{"accept", fd.net, fd.laddr, err}
  381. }
  382. for {
  383. s, rsa, err = accept(fd.sysfd)
  384. if err != nil {
  385. if err == syscall.EAGAIN {
  386. if err = fd.pd.WaitRead(); err == nil {
  387. continue
  388. }
  389. } else if err == syscall.ECONNABORTED {
  390. // This means that a socket on the listen queue was closed
  391. // before we Accept()ed it; it's a silly error, so try again.
  392. continue
  393. }
  394. return nil, &OpError{"accept", fd.net, fd.laddr, err}
  395. }
  396. break
  397. }
  398. if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil {
  399. closesocket(s)
  400. return nil, err
  401. }
  402. if err = netfd.init(); err != nil {
  403. fd.Close()
  404. return nil, err
  405. }
  406. lsa, _ := syscall.Getsockname(netfd.sysfd)
  407. netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
  408. return netfd, nil
  409. }
  410. // tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used.
  411. // If the kernel doesn't support it, this is set to 0.
  412. var tryDupCloexec = int32(1)
  413. func dupCloseOnExec(fd int) (newfd int, err error) {
  414. if atomic.LoadInt32(&tryDupCloexec) == 1 && syscall.F_DUPFD_CLOEXEC != 0 {
  415. r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
  416. if runtime.GOOS == "darwin" && e1 == syscall.EBADF {
  417. // On OS X 10.6 and below (but we only support
  418. // >= 10.6), F_DUPFD_CLOEXEC is unsupported
  419. // and fcntl there falls back (undocumented)
  420. // to doing an ioctl instead, returning EBADF
  421. // in this case because fd is not of the
  422. // expected device fd type. Treat it as
  423. // EINVAL instead, so we fall back to the
  424. // normal dup path.
  425. // TODO: only do this on 10.6 if we can detect 10.6
  426. // cheaply.
  427. e1 = syscall.EINVAL
  428. }
  429. switch e1 {
  430. case 0:
  431. return int(r0), nil
  432. case syscall.EINVAL:
  433. // Old kernel. Fall back to the portable way
  434. // from now on.
  435. atomic.StoreInt32(&tryDupCloexec, 0)
  436. default:
  437. return -1, e1
  438. }
  439. }
  440. return dupCloseOnExecOld(fd)
  441. }
  442. // dupCloseOnExecUnixOld is the traditional way to dup an fd and
  443. // set its O_CLOEXEC bit, using two system calls.
  444. func dupCloseOnExecOld(fd int) (newfd int, err error) {
  445. syscall.ForkLock.RLock()
  446. defer syscall.ForkLock.RUnlock()
  447. newfd, err = syscall.Dup(fd)
  448. if err != nil {
  449. return -1, err
  450. }
  451. syscall.CloseOnExec(newfd)
  452. return
  453. }
  454. func (fd *netFD) dup() (f *os.File, err error) {
  455. ns, err := dupCloseOnExec(fd.sysfd)
  456. if err != nil {
  457. return nil, &OpError{"dup", fd.net, fd.laddr, err}
  458. }
  459. // We want blocking mode for the new fd, hence the double negative.
  460. // This also puts the old fd into blocking mode, meaning that
  461. // I/O will block the thread instead of letting us use the epoll server.
  462. // Everything will still work, just with more threads.
  463. if err = syscall.SetNonblock(ns, false); err != nil {
  464. return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
  465. }
  466. return os.NewFile(uintptr(ns), fd.name()), nil
  467. }
  468. func closesocket(s int) error {
  469. return syscall.Close(s)
  470. }
  471. func skipRawSocketTests() (skip bool, skipmsg string, err error) {
  472. if os.Getuid() != 0 {
  473. return true, "skipping test; must be root", nil
  474. }
  475. return false, "", nil
  476. }