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