github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/internal/poll/fd_unix.go (about) 1 // Copyright 2017 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 poll 8 9 import ( 10 "io" 11 "syscall" 12 ) 13 14 // FD is a file descriptor. The net and os packages use this type as a 15 // field of a larger type representing a network connection or OS file. 16 type FD struct { 17 // Lock sysfd and serialize access to Read and Write methods. 18 fdmu fdMutex 19 20 // System file descriptor. Immutable until Close. 21 Sysfd int 22 23 // I/O poller. 24 pd pollDesc 25 26 // Writev cache. 27 iovecs *[]syscall.Iovec 28 29 // Semaphore signaled when file is closed. 30 csema uint32 31 32 // Whether this is a streaming descriptor, as opposed to a 33 // packet-based descriptor like a UDP socket. Immutable. 34 IsStream bool 35 36 // Whether a zero byte read indicates EOF. This is false for a 37 // message based socket connection. 38 ZeroReadIsEOF bool 39 40 // Whether this is a file rather than a network socket. 41 isFile bool 42 } 43 44 // Init initializes the FD. The Sysfd field should already be set. 45 // This can be called multiple times on a single FD. 46 // The net argument is a network name from the net package (e.g., "tcp"), 47 // or "file". 48 // Set pollable to true if fd should be managed by runtime netpoll. 49 func (fd *FD) Init(net string, pollable bool) error { 50 // We don't actually care about the various network types. 51 if net == "file" { 52 fd.isFile = true 53 } 54 if !pollable { 55 return nil 56 } 57 return fd.pd.init(fd) 58 } 59 60 // Destroy closes the file descriptor. This is called when there are 61 // no remaining references. 62 func (fd *FD) destroy() error { 63 // Poller may want to unregister fd in readiness notification mechanism, 64 // so this must be executed before CloseFunc. 65 fd.pd.close() 66 err := CloseFunc(fd.Sysfd) 67 fd.Sysfd = -1 68 runtime_Semrelease(&fd.csema) 69 return err 70 } 71 72 // Close closes the FD. The underlying file descriptor is closed by the 73 // destroy method when there are no remaining references. 74 func (fd *FD) Close() error { 75 if !fd.fdmu.increfAndClose() { 76 return errClosing(fd.isFile) 77 } 78 // Unblock any I/O. Once it all unblocks and returns, 79 // so that it cannot be referring to fd.sysfd anymore, 80 // the final decref will close fd.sysfd. This should happen 81 // fairly quickly, since all the I/O is non-blocking, and any 82 // attempts to block in the pollDesc will return errClosing(fd.isFile). 83 fd.pd.evict() 84 // The call to decref will call destroy if there are no other 85 // references. 86 err := fd.decref() 87 // Wait until the descriptor is closed. If this was the only 88 // reference, it is already closed. 89 runtime_Semacquire(&fd.csema) 90 return err 91 } 92 93 // Shutdown wraps the shutdown network call. 94 func (fd *FD) Shutdown(how int) error { 95 if err := fd.incref(); err != nil { 96 return err 97 } 98 defer fd.decref() 99 return syscall.Shutdown(fd.Sysfd, how) 100 } 101 102 // Darwin and FreeBSD can't read or write 2GB+ files at a time, 103 // even on 64-bit systems. 104 // The same is true of socket implementations on many systems. 105 // See golang.org/issue/7812 and golang.org/issue/16266. 106 // Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned. 107 const maxRW = 1 << 30 108 109 // Read implements io.Reader. 110 func (fd *FD) Read(p []byte) (int, error) { 111 if err := fd.readLock(); err != nil { 112 return 0, err 113 } 114 defer fd.readUnlock() 115 if len(p) == 0 { 116 // If the caller wanted a zero byte read, return immediately 117 // without trying (but after acquiring the readLock). 118 // Otherwise syscall.Read returns 0, nil which looks like 119 // io.EOF. 120 // TODO(bradfitz): make it wait for readability? (Issue 15735) 121 return 0, nil 122 } 123 if err := fd.pd.prepareRead(fd.isFile); err != nil { 124 return 0, err 125 } 126 if fd.IsStream && len(p) > maxRW { 127 p = p[:maxRW] 128 } 129 for { 130 n, err := syscall.Read(fd.Sysfd, p) 131 if err != nil { 132 n = 0 133 if err == syscall.EAGAIN && fd.pd.pollable() { 134 if err = fd.pd.waitRead(fd.isFile); err == nil { 135 continue 136 } 137 } 138 } 139 err = fd.eofError(n, err) 140 return n, err 141 } 142 } 143 144 // Pread wraps the pread system call. 145 func (fd *FD) Pread(p []byte, off int64) (int, error) { 146 // Call incref, not readLock, because since pread specifies the 147 // offset it is independent from other reads. 148 // Similarly, using the poller doesn't make sense for pread. 149 if err := fd.incref(); err != nil { 150 return 0, err 151 } 152 if fd.IsStream && len(p) > maxRW { 153 p = p[:maxRW] 154 } 155 n, err := syscall.Pread(fd.Sysfd, p, off) 156 if err != nil { 157 n = 0 158 } 159 fd.decref() 160 err = fd.eofError(n, err) 161 return n, err 162 } 163 164 // ReadFrom wraps the recvfrom network call. 165 func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) { 166 if err := fd.readLock(); err != nil { 167 return 0, nil, err 168 } 169 defer fd.readUnlock() 170 if err := fd.pd.prepareRead(fd.isFile); err != nil { 171 return 0, nil, err 172 } 173 for { 174 n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0) 175 if err != nil { 176 n = 0 177 if err == syscall.EAGAIN && fd.pd.pollable() { 178 if err = fd.pd.waitRead(fd.isFile); err == nil { 179 continue 180 } 181 } 182 } 183 err = fd.eofError(n, err) 184 return n, sa, err 185 } 186 } 187 188 // ReadMsg wraps the recvmsg network call. 189 func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) { 190 if err := fd.readLock(); err != nil { 191 return 0, 0, 0, nil, err 192 } 193 defer fd.readUnlock() 194 if err := fd.pd.prepareRead(fd.isFile); err != nil { 195 return 0, 0, 0, nil, err 196 } 197 for { 198 n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0) 199 if err != nil { 200 // TODO(dfc) should n and oobn be set to 0 201 if err == syscall.EAGAIN && fd.pd.pollable() { 202 if err = fd.pd.waitRead(fd.isFile); err == nil { 203 continue 204 } 205 } 206 } 207 err = fd.eofError(n, err) 208 return n, oobn, flags, sa, err 209 } 210 } 211 212 // Write implements io.Writer. 213 func (fd *FD) Write(p []byte) (int, error) { 214 if err := fd.writeLock(); err != nil { 215 return 0, err 216 } 217 defer fd.writeUnlock() 218 if err := fd.pd.prepareWrite(fd.isFile); err != nil { 219 return 0, err 220 } 221 var nn int 222 for { 223 max := len(p) 224 if fd.IsStream && max-nn > maxRW { 225 max = nn + maxRW 226 } 227 n, err := syscall.Write(fd.Sysfd, p[nn:max]) 228 if n > 0 { 229 nn += n 230 } 231 if nn == len(p) { 232 return nn, err 233 } 234 if err == syscall.EAGAIN && fd.pd.pollable() { 235 if err = fd.pd.waitWrite(fd.isFile); err == nil { 236 continue 237 } 238 } 239 if err != nil { 240 return nn, err 241 } 242 if n == 0 { 243 return nn, io.ErrUnexpectedEOF 244 } 245 } 246 } 247 248 // Pwrite wraps the pwrite system call. 249 func (fd *FD) Pwrite(p []byte, off int64) (int, error) { 250 // Call incref, not writeLock, because since pwrite specifies the 251 // offset it is independent from other writes. 252 // Similarly, using the poller doesn't make sense for pwrite. 253 if err := fd.incref(); err != nil { 254 return 0, err 255 } 256 defer fd.decref() 257 var nn int 258 for { 259 max := len(p) 260 if fd.IsStream && max-nn > maxRW { 261 max = nn + maxRW 262 } 263 n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn)) 264 if n > 0 { 265 nn += n 266 } 267 if nn == len(p) { 268 return nn, err 269 } 270 if err != nil { 271 return nn, err 272 } 273 if n == 0 { 274 return nn, io.ErrUnexpectedEOF 275 } 276 } 277 } 278 279 // WriteTo wraps the sendto network call. 280 func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) { 281 if err := fd.writeLock(); err != nil { 282 return 0, err 283 } 284 defer fd.writeUnlock() 285 if err := fd.pd.prepareWrite(fd.isFile); err != nil { 286 return 0, err 287 } 288 for { 289 err := syscall.Sendto(fd.Sysfd, p, 0, sa) 290 if err == syscall.EAGAIN && fd.pd.pollable() { 291 if err = fd.pd.waitWrite(fd.isFile); err == nil { 292 continue 293 } 294 } 295 if err != nil { 296 return 0, err 297 } 298 return len(p), nil 299 } 300 } 301 302 // WriteMsg wraps the sendmsg network call. 303 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) { 304 if err := fd.writeLock(); err != nil { 305 return 0, 0, err 306 } 307 defer fd.writeUnlock() 308 if err := fd.pd.prepareWrite(fd.isFile); err != nil { 309 return 0, 0, err 310 } 311 for { 312 n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0) 313 if err == syscall.EAGAIN && fd.pd.pollable() { 314 if err = fd.pd.waitWrite(fd.isFile); err == nil { 315 continue 316 } 317 } 318 if err != nil { 319 return n, 0, err 320 } 321 return n, len(oob), err 322 } 323 } 324 325 // Accept wraps the accept network call. 326 func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) { 327 if err := fd.readLock(); err != nil { 328 return -1, nil, "", err 329 } 330 defer fd.readUnlock() 331 332 if err := fd.pd.prepareRead(fd.isFile); err != nil { 333 return -1, nil, "", err 334 } 335 for { 336 s, rsa, errcall, err := accept(fd.Sysfd) 337 if err == nil { 338 return s, rsa, "", err 339 } 340 switch err { 341 case syscall.EAGAIN: 342 if fd.pd.pollable() { 343 if err = fd.pd.waitRead(fd.isFile); err == nil { 344 continue 345 } 346 } 347 case syscall.ECONNABORTED: 348 // This means that a socket on the listen 349 // queue was closed before we Accept()ed it; 350 // it's a silly error, so try again. 351 continue 352 } 353 return -1, nil, errcall, err 354 } 355 } 356 357 // Seek wraps syscall.Seek. 358 func (fd *FD) Seek(offset int64, whence int) (int64, error) { 359 if err := fd.incref(); err != nil { 360 return 0, err 361 } 362 defer fd.decref() 363 return syscall.Seek(fd.Sysfd, offset, whence) 364 } 365 366 // ReadDirent wraps syscall.ReadDirent. 367 // We treat this like an ordinary system call rather than a call 368 // that tries to fill the buffer. 369 func (fd *FD) ReadDirent(buf []byte) (int, error) { 370 if err := fd.incref(); err != nil { 371 return 0, err 372 } 373 defer fd.decref() 374 for { 375 n, err := syscall.ReadDirent(fd.Sysfd, buf) 376 if err != nil { 377 n = 0 378 if err == syscall.EAGAIN && fd.pd.pollable() { 379 if err = fd.pd.waitRead(fd.isFile); err == nil { 380 continue 381 } 382 } 383 } 384 // Do not call eofError; caller does not expect to see io.EOF. 385 return n, err 386 } 387 } 388 389 // Fchdir wraps syscall.Fchdir. 390 func (fd *FD) Fchdir() error { 391 if err := fd.incref(); err != nil { 392 return err 393 } 394 defer fd.decref() 395 return syscall.Fchdir(fd.Sysfd) 396 } 397 398 // Fstat wraps syscall.Fstat 399 func (fd *FD) Fstat(s *syscall.Stat_t) error { 400 if err := fd.incref(); err != nil { 401 return err 402 } 403 defer fd.decref() 404 return syscall.Fstat(fd.Sysfd, s) 405 } 406 407 // On Unix variants only, expose the IO event for the net code. 408 409 // WaitWrite waits until data can be read from fd. 410 func (fd *FD) WaitWrite() error { 411 return fd.pd.waitWrite(fd.isFile) 412 } 413 414 // WriteOnce is for testing only. It makes a single write call. 415 func (fd *FD) WriteOnce(p []byte) (int, error) { 416 if err := fd.writeLock(); err != nil { 417 return 0, err 418 } 419 defer fd.writeUnlock() 420 return syscall.Write(fd.Sysfd, p) 421 } 422 423 // RawControl invokes the user-defined function f for a non-IO 424 // operation. 425 func (fd *FD) RawControl(f func(uintptr)) error { 426 if err := fd.incref(); err != nil { 427 return err 428 } 429 defer fd.decref() 430 f(uintptr(fd.Sysfd)) 431 return nil 432 } 433 434 // RawRead invokes the user-defined function f for a read operation. 435 func (fd *FD) RawRead(f func(uintptr) bool) error { 436 if err := fd.readLock(); err != nil { 437 return err 438 } 439 defer fd.readUnlock() 440 if err := fd.pd.prepareRead(fd.isFile); err != nil { 441 return err 442 } 443 for { 444 if f(uintptr(fd.Sysfd)) { 445 return nil 446 } 447 if err := fd.pd.waitRead(fd.isFile); err != nil { 448 return err 449 } 450 } 451 } 452 453 // RawWrite invokes the user-defined function f for a write operation. 454 func (fd *FD) RawWrite(f func(uintptr) bool) error { 455 if err := fd.writeLock(); err != nil { 456 return err 457 } 458 defer fd.writeUnlock() 459 if err := fd.pd.prepareWrite(fd.isFile); err != nil { 460 return err 461 } 462 for { 463 if f(uintptr(fd.Sysfd)) { 464 return nil 465 } 466 if err := fd.pd.waitWrite(fd.isFile); err != nil { 467 return err 468 } 469 } 470 }