github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/net/fd_unix.go (about) 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 "context" 11 "io" 12 "os" 13 "runtime" 14 "sync/atomic" 15 "syscall" 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 isStream bool 28 isConnected bool 29 net string 30 laddr Addr 31 raddr Addr 32 33 // writev cache. 34 iovecs *[]syscall.Iovec 35 36 // wait server 37 pd pollDesc 38 } 39 40 func sysInit() { 41 } 42 43 func newFD(sysfd, family, sotype int, net string) (*netFD, error) { 44 return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net, isStream: sotype == syscall.SOCK_STREAM}, 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(ctx context.Context, la, ra syscall.Sockaddr) (ret 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 := connectFunc(fd.sysfd, ra); err { 76 case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR: 77 case nil, syscall.EISCONN: 78 select { 79 case <-ctx.Done(): 80 return mapErr(ctx.Err()) 81 default: 82 } 83 if err := fd.init(); err != nil { 84 return err 85 } 86 return nil 87 case syscall.EINVAL: 88 // On Solaris we can see EINVAL if the socket has 89 // already been accepted and closed by the server. 90 // Treat this as a successful connection--writes to 91 // the socket will see EOF. For details and a test 92 // case in C see https://golang.org/issue/6828. 93 if runtime.GOOS == "solaris" { 94 return nil 95 } 96 fallthrough 97 default: 98 return os.NewSyscallError("connect", err) 99 } 100 if err := fd.init(); err != nil { 101 return err 102 } 103 if deadline, _ := ctx.Deadline(); !deadline.IsZero() { 104 fd.setWriteDeadline(deadline) 105 defer fd.setWriteDeadline(noDeadline) 106 } 107 108 // Start the "interrupter" goroutine, if this context might be canceled. 109 // (The background context cannot) 110 // 111 // The interrupter goroutine waits for the context to be done and 112 // interrupts the dial (by altering the fd's write deadline, which 113 // wakes up waitWrite). 114 if ctx != context.Background() { 115 // Wait for the interrupter goroutine to exit before returning 116 // from connect. 117 done := make(chan struct{}) 118 interruptRes := make(chan error) 119 defer func() { 120 close(done) 121 if ctxErr := <-interruptRes; ctxErr != nil && ret == nil { 122 // The interrupter goroutine called setWriteDeadline, 123 // but the connect code below had returned from 124 // waitWrite already and did a successful connect (ret 125 // == nil). Because we've now poisoned the connection 126 // by making it unwritable, don't return a successful 127 // dial. This was issue 16523. 128 ret = ctxErr 129 fd.Close() // prevent a leak 130 } 131 }() 132 go func() { 133 select { 134 case <-ctx.Done(): 135 // Force the runtime's poller to immediately give up 136 // waiting for writability, unblocking waitWrite 137 // below. 138 fd.setWriteDeadline(aLongTimeAgo) 139 testHookCanceledDial() 140 interruptRes <- ctx.Err() 141 case <-done: 142 interruptRes <- nil 143 } 144 }() 145 } 146 147 for { 148 // Performing multiple connect system calls on a 149 // non-blocking socket under Unix variants does not 150 // necessarily result in earlier errors being 151 // returned. Instead, once runtime-integrated network 152 // poller tells us that the socket is ready, get the 153 // SO_ERROR socket option to see if the connection 154 // succeeded or failed. See issue 7474 for further 155 // details. 156 if err := fd.pd.waitWrite(); err != nil { 157 select { 158 case <-ctx.Done(): 159 return mapErr(ctx.Err()) 160 default: 161 } 162 return err 163 } 164 nerr, err := getsockoptIntFunc(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR) 165 if err != nil { 166 return os.NewSyscallError("getsockopt", err) 167 } 168 switch err := syscall.Errno(nerr); err { 169 case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR: 170 case syscall.Errno(0), syscall.EISCONN: 171 if runtime.GOOS != "darwin" { 172 return nil 173 } 174 // See golang.org/issue/14548. 175 // On Darwin, multiple connect system calls on 176 // a non-blocking socket never harm SO_ERROR. 177 switch err := connectFunc(fd.sysfd, ra); err { 178 case nil, syscall.EISCONN: 179 return nil 180 } 181 default: 182 return os.NewSyscallError("getsockopt", err) 183 } 184 } 185 } 186 187 func (fd *netFD) destroy() { 188 // Poller may want to unregister fd in readiness notification mechanism, 189 // so this must be executed before closeFunc. 190 fd.pd.close() 191 closeFunc(fd.sysfd) 192 fd.sysfd = -1 193 runtime.SetFinalizer(fd, nil) 194 } 195 196 func (fd *netFD) Close() error { 197 if !fd.fdmu.increfAndClose() { 198 return errClosing 199 } 200 // Unblock any I/O. Once it all unblocks and returns, 201 // so that it cannot be referring to fd.sysfd anymore, 202 // the final decref will close fd.sysfd. This should happen 203 // fairly quickly, since all the I/O is non-blocking, and any 204 // attempts to block in the pollDesc will return errClosing. 205 fd.pd.evict() 206 fd.decref() 207 return nil 208 } 209 210 func (fd *netFD) shutdown(how int) error { 211 if err := fd.incref(); err != nil { 212 return err 213 } 214 defer fd.decref() 215 return os.NewSyscallError("shutdown", syscall.Shutdown(fd.sysfd, how)) 216 } 217 218 func (fd *netFD) closeRead() error { 219 return fd.shutdown(syscall.SHUT_RD) 220 } 221 222 func (fd *netFD) closeWrite() error { 223 return fd.shutdown(syscall.SHUT_WR) 224 } 225 226 func (fd *netFD) Read(p []byte) (n int, err error) { 227 if err := fd.readLock(); err != nil { 228 return 0, err 229 } 230 defer fd.readUnlock() 231 if len(p) == 0 { 232 // If the caller wanted a zero byte read, return immediately 233 // without trying. (But after acquiring the readLock.) Otherwise 234 // syscall.Read returns 0, nil and eofError turns that into 235 // io.EOF. 236 // TODO(bradfitz): make it wait for readability? (Issue 15735) 237 return 0, nil 238 } 239 if err := fd.pd.prepareRead(); err != nil { 240 return 0, err 241 } 242 if fd.isStream && len(p) > 1<<30 { 243 p = p[:1<<30] 244 } 245 for { 246 n, err = syscall.Read(fd.sysfd, p) 247 if err != nil { 248 n = 0 249 if err == syscall.EAGAIN { 250 if err = fd.pd.waitRead(); err == nil { 251 continue 252 } 253 } 254 } 255 err = fd.eofError(n, err) 256 break 257 } 258 if _, ok := err.(syscall.Errno); ok { 259 err = os.NewSyscallError("read", err) 260 } 261 return 262 } 263 264 func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { 265 if err := fd.readLock(); err != nil { 266 return 0, nil, err 267 } 268 defer fd.readUnlock() 269 if err := fd.pd.prepareRead(); err != nil { 270 return 0, nil, err 271 } 272 for { 273 n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0) 274 if err != nil { 275 n = 0 276 if err == syscall.EAGAIN { 277 if err = fd.pd.waitRead(); err == nil { 278 continue 279 } 280 } 281 } 282 err = fd.eofError(n, err) 283 break 284 } 285 if _, ok := err.(syscall.Errno); ok { 286 err = os.NewSyscallError("recvfrom", err) 287 } 288 return 289 } 290 291 func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) { 292 if err := fd.readLock(); err != nil { 293 return 0, 0, 0, nil, err 294 } 295 defer fd.readUnlock() 296 if err := fd.pd.prepareRead(); err != nil { 297 return 0, 0, 0, nil, err 298 } 299 for { 300 n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0) 301 if err != nil { 302 // TODO(dfc) should n and oobn be set to 0 303 if err == syscall.EAGAIN { 304 if err = fd.pd.waitRead(); err == nil { 305 continue 306 } 307 } 308 } 309 err = fd.eofError(n, err) 310 break 311 } 312 if _, ok := err.(syscall.Errno); ok { 313 err = os.NewSyscallError("recvmsg", err) 314 } 315 return 316 } 317 318 func (fd *netFD) Write(p []byte) (nn int, err error) { 319 if err := fd.writeLock(); err != nil { 320 return 0, err 321 } 322 defer fd.writeUnlock() 323 if err := fd.pd.prepareWrite(); err != nil { 324 return 0, err 325 } 326 for { 327 var n int 328 max := len(p) 329 if fd.isStream && max-nn > 1<<30 { 330 max = nn + 1<<30 331 } 332 n, err = syscall.Write(fd.sysfd, p[nn:max]) 333 if n > 0 { 334 nn += n 335 } 336 if nn == len(p) { 337 break 338 } 339 if err == syscall.EAGAIN { 340 if err = fd.pd.waitWrite(); err == nil { 341 continue 342 } 343 } 344 if err != nil { 345 break 346 } 347 if n == 0 { 348 err = io.ErrUnexpectedEOF 349 break 350 } 351 } 352 if _, ok := err.(syscall.Errno); ok { 353 err = os.NewSyscallError("write", err) 354 } 355 return nn, err 356 } 357 358 func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) { 359 if err := fd.writeLock(); err != nil { 360 return 0, err 361 } 362 defer fd.writeUnlock() 363 if err := fd.pd.prepareWrite(); err != nil { 364 return 0, err 365 } 366 for { 367 err = syscall.Sendto(fd.sysfd, p, 0, sa) 368 if err == syscall.EAGAIN { 369 if err = fd.pd.waitWrite(); err == nil { 370 continue 371 } 372 } 373 break 374 } 375 if err == nil { 376 n = len(p) 377 } 378 if _, ok := err.(syscall.Errno); ok { 379 err = os.NewSyscallError("sendto", err) 380 } 381 return 382 } 383 384 func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) { 385 if err := fd.writeLock(); err != nil { 386 return 0, 0, err 387 } 388 defer fd.writeUnlock() 389 if err := fd.pd.prepareWrite(); err != nil { 390 return 0, 0, err 391 } 392 for { 393 n, err = syscall.SendmsgN(fd.sysfd, p, oob, sa, 0) 394 if err == syscall.EAGAIN { 395 if err = fd.pd.waitWrite(); err == nil { 396 continue 397 } 398 } 399 break 400 } 401 if err == nil { 402 oobn = len(oob) 403 } 404 if _, ok := err.(syscall.Errno); ok { 405 err = os.NewSyscallError("sendmsg", err) 406 } 407 return 408 } 409 410 func (fd *netFD) accept() (netfd *netFD, err error) { 411 if err := fd.readLock(); err != nil { 412 return nil, err 413 } 414 defer fd.readUnlock() 415 416 var s int 417 var rsa syscall.Sockaddr 418 if err = fd.pd.prepareRead(); err != nil { 419 return nil, err 420 } 421 for { 422 s, rsa, err = accept(fd.sysfd) 423 if err != nil { 424 nerr, ok := err.(*os.SyscallError) 425 if !ok { 426 return nil, err 427 } 428 switch nerr.Err { 429 case syscall.EAGAIN: 430 if err = fd.pd.waitRead(); err == nil { 431 continue 432 } 433 case syscall.ECONNABORTED: 434 // This means that a socket on the 435 // listen queue was closed before we 436 // Accept()ed it; it's a silly error, 437 // so try again. 438 continue 439 } 440 return nil, err 441 } 442 break 443 } 444 445 if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil { 446 closeFunc(s) 447 return nil, err 448 } 449 if err = netfd.init(); err != nil { 450 fd.Close() 451 return nil, err 452 } 453 lsa, _ := syscall.Getsockname(netfd.sysfd) 454 netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa)) 455 return netfd, nil 456 } 457 458 // tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used. 459 // If the kernel doesn't support it, this is set to 0. 460 var tryDupCloexec = int32(1) 461 462 func dupCloseOnExec(fd int) (newfd int, err error) { 463 if atomic.LoadInt32(&tryDupCloexec) == 1 { 464 r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0) 465 if runtime.GOOS == "darwin" && e1 == syscall.EBADF { 466 // On OS X 10.6 and below (but we only support 467 // >= 10.6), F_DUPFD_CLOEXEC is unsupported 468 // and fcntl there falls back (undocumented) 469 // to doing an ioctl instead, returning EBADF 470 // in this case because fd is not of the 471 // expected device fd type. Treat it as 472 // EINVAL instead, so we fall back to the 473 // normal dup path. 474 // TODO: only do this on 10.6 if we can detect 10.6 475 // cheaply. 476 e1 = syscall.EINVAL 477 } 478 switch e1 { 479 case 0: 480 return int(r0), nil 481 case syscall.EINVAL: 482 // Old kernel. Fall back to the portable way 483 // from now on. 484 atomic.StoreInt32(&tryDupCloexec, 0) 485 default: 486 return -1, os.NewSyscallError("fcntl", e1) 487 } 488 } 489 return dupCloseOnExecOld(fd) 490 } 491 492 // dupCloseOnExecUnixOld is the traditional way to dup an fd and 493 // set its O_CLOEXEC bit, using two system calls. 494 func dupCloseOnExecOld(fd int) (newfd int, err error) { 495 syscall.ForkLock.RLock() 496 defer syscall.ForkLock.RUnlock() 497 newfd, err = syscall.Dup(fd) 498 if err != nil { 499 return -1, os.NewSyscallError("dup", err) 500 } 501 syscall.CloseOnExec(newfd) 502 return 503 } 504 505 func (fd *netFD) dup() (f *os.File, err error) { 506 ns, err := dupCloseOnExec(fd.sysfd) 507 if err != nil { 508 return nil, err 509 } 510 511 // We want blocking mode for the new fd, hence the double negative. 512 // This also puts the old fd into blocking mode, meaning that 513 // I/O will block the thread instead of letting us use the epoll server. 514 // Everything will still work, just with more threads. 515 if err = syscall.SetNonblock(ns, false); err != nil { 516 return nil, os.NewSyscallError("setnonblock", err) 517 } 518 519 return os.NewFile(uintptr(ns), fd.name()), nil 520 }