github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/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 // Whether this is a streaming descriptor, as opposed to a 30 // packet-based descriptor like a UDP socket. Immutable. 31 IsStream bool 32 33 // Whether a zero byte read indicates EOF. This is false for a 34 // message based socket connection. 35 ZeroReadIsEOF bool 36 } 37 38 // Init initializes the FD. The Sysfd field should already be set. 39 // This can be called multiple times on a single FD. 40 func (fd *FD) Init() error { 41 return fd.pd.init(fd) 42 } 43 44 // Destroy closes the file descriptor. This is called when there are 45 // no remaining references. 46 func (fd *FD) destroy() error { 47 // Poller may want to unregister fd in readiness notification mechanism, 48 // so this must be executed before CloseFunc. 49 fd.pd.close() 50 err := CloseFunc(fd.Sysfd) 51 fd.Sysfd = -1 52 return err 53 } 54 55 // Close closes the FD. The underlying file descriptor is closed by the 56 // destroy method when there are no remaining references. 57 func (fd *FD) Close() error { 58 if !fd.fdmu.increfAndClose() { 59 return ErrClosing 60 } 61 // Unblock any I/O. Once it all unblocks and returns, 62 // so that it cannot be referring to fd.sysfd anymore, 63 // the final decref will close fd.sysfd. This should happen 64 // fairly quickly, since all the I/O is non-blocking, and any 65 // attempts to block in the pollDesc will return ErrClosing. 66 fd.pd.evict() 67 // The call to decref will call destroy if there are no other 68 // references. 69 return fd.decref() 70 } 71 72 // Shutdown wraps the shutdown network call. 73 func (fd *FD) Shutdown(how int) error { 74 if err := fd.incref(); err != nil { 75 return err 76 } 77 defer fd.decref() 78 return syscall.Shutdown(fd.Sysfd, how) 79 } 80 81 // Darwin and FreeBSD can't read or write 2GB+ files at a time, 82 // even on 64-bit systems. 83 // The same is true of socket implementations on many systems. 84 // See golang.org/issue/7812 and golang.org/issue/16266. 85 // Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned. 86 const maxRW = 1 << 30 87 88 // Read implements io.Reader. 89 func (fd *FD) Read(p []byte) (int, error) { 90 if err := fd.readLock(); err != nil { 91 return 0, err 92 } 93 defer fd.readUnlock() 94 if len(p) == 0 { 95 // If the caller wanted a zero byte read, return immediately 96 // without trying (but after acquiring the readLock). 97 // Otherwise syscall.Read returns 0, nil which looks like 98 // io.EOF. 99 // TODO(bradfitz): make it wait for readability? (Issue 15735) 100 return 0, nil 101 } 102 if err := fd.pd.prepareRead(); err != nil { 103 return 0, err 104 } 105 if fd.IsStream && len(p) > maxRW { 106 p = p[:maxRW] 107 } 108 for { 109 n, err := syscall.Read(fd.Sysfd, p) 110 if err != nil { 111 n = 0 112 if err == syscall.EAGAIN { 113 if err = fd.pd.waitRead(); err == nil { 114 continue 115 } 116 } 117 } 118 err = fd.eofError(n, err) 119 return n, err 120 } 121 } 122 123 // Pread wraps the pread system call. 124 func (fd *FD) Pread(p []byte, off int64) (int, error) { 125 if err := fd.readLock(); err != nil { 126 return 0, err 127 } 128 defer fd.readUnlock() 129 if err := fd.pd.prepareRead(); err != nil { 130 return 0, err 131 } 132 if fd.IsStream && len(p) > maxRW { 133 p = p[:maxRW] 134 } 135 for { 136 n, err := syscall.Pread(fd.Sysfd, p, off) 137 if err != nil { 138 n = 0 139 if err == syscall.EAGAIN { 140 if err = fd.pd.waitRead(); err == nil { 141 continue 142 } 143 } 144 } 145 err = fd.eofError(n, err) 146 return n, err 147 } 148 } 149 150 // ReadFrom wraps the recvfrom network call. 151 func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) { 152 if err := fd.readLock(); err != nil { 153 return 0, nil, err 154 } 155 defer fd.readUnlock() 156 if err := fd.pd.prepareRead(); err != nil { 157 return 0, nil, err 158 } 159 for { 160 n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0) 161 if err != nil { 162 n = 0 163 if err == syscall.EAGAIN { 164 if err = fd.pd.waitRead(); err == nil { 165 continue 166 } 167 } 168 } 169 err = fd.eofError(n, err) 170 return n, sa, err 171 } 172 } 173 174 // ReadMsg wraps the recvmsg network call. 175 func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) { 176 if err := fd.readLock(); err != nil { 177 return 0, 0, 0, nil, err 178 } 179 defer fd.readUnlock() 180 if err := fd.pd.prepareRead(); err != nil { 181 return 0, 0, 0, nil, err 182 } 183 for { 184 n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0) 185 if err != nil { 186 // TODO(dfc) should n and oobn be set to 0 187 if err == syscall.EAGAIN { 188 if err = fd.pd.waitRead(); err == nil { 189 continue 190 } 191 } 192 } 193 err = fd.eofError(n, err) 194 return n, oobn, flags, sa, err 195 } 196 } 197 198 // Write implements io.Writer. 199 func (fd *FD) Write(p []byte) (int, error) { 200 if err := fd.writeLock(); err != nil { 201 return 0, err 202 } 203 defer fd.writeUnlock() 204 if err := fd.pd.prepareWrite(); err != nil { 205 return 0, err 206 } 207 var nn int 208 for { 209 max := len(p) 210 if fd.IsStream && max-nn > maxRW { 211 max = nn + maxRW 212 } 213 n, err := syscall.Write(fd.Sysfd, p[nn:max]) 214 if n > 0 { 215 nn += n 216 } 217 if nn == len(p) { 218 return nn, err 219 } 220 if err == syscall.EAGAIN { 221 if err = fd.pd.waitWrite(); err == nil { 222 continue 223 } 224 } 225 if err != nil { 226 return nn, err 227 } 228 if n == 0 { 229 return nn, io.ErrUnexpectedEOF 230 } 231 } 232 } 233 234 // Pwrite wraps the pwrite system call. 235 func (fd *FD) Pwrite(p []byte, off int64) (int, error) { 236 if err := fd.writeLock(); err != nil { 237 return 0, err 238 } 239 defer fd.writeUnlock() 240 if err := fd.pd.prepareWrite(); err != nil { 241 return 0, err 242 } 243 var nn int 244 for { 245 max := len(p) 246 if fd.IsStream && max-nn > maxRW { 247 max = nn + maxRW 248 } 249 n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn)) 250 if n > 0 { 251 nn += n 252 } 253 if nn == len(p) { 254 return nn, err 255 } 256 if err == syscall.EAGAIN { 257 if err = fd.pd.waitWrite(); err == nil { 258 continue 259 } 260 } 261 if err != nil { 262 return nn, err 263 } 264 if n == 0 { 265 return nn, io.ErrUnexpectedEOF 266 } 267 } 268 } 269 270 // WriteTo wraps the sendto network call. 271 func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) { 272 if err := fd.writeLock(); err != nil { 273 return 0, err 274 } 275 defer fd.writeUnlock() 276 if err := fd.pd.prepareWrite(); err != nil { 277 return 0, err 278 } 279 for { 280 err := syscall.Sendto(fd.Sysfd, p, 0, sa) 281 if err == syscall.EAGAIN { 282 if err = fd.pd.waitWrite(); err == nil { 283 continue 284 } 285 } 286 if err != nil { 287 return 0, err 288 } 289 return len(p), nil 290 } 291 } 292 293 // WriteMsg wraps the sendmsg network call. 294 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) { 295 if err := fd.writeLock(); err != nil { 296 return 0, 0, err 297 } 298 defer fd.writeUnlock() 299 if err := fd.pd.prepareWrite(); err != nil { 300 return 0, 0, err 301 } 302 for { 303 n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0) 304 if err == syscall.EAGAIN { 305 if err = fd.pd.waitWrite(); err == nil { 306 continue 307 } 308 } 309 if err != nil { 310 return n, 0, err 311 } 312 return n, len(oob), err 313 } 314 } 315 316 // Accept wraps the accept network call. 317 func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) { 318 if err := fd.readLock(); err != nil { 319 return -1, nil, "", err 320 } 321 defer fd.readUnlock() 322 323 if err := fd.pd.prepareRead(); err != nil { 324 return -1, nil, "", err 325 } 326 for { 327 s, rsa, errcall, err := accept(fd.Sysfd) 328 if err == nil { 329 return s, rsa, "", err 330 } 331 switch err { 332 case syscall.EAGAIN: 333 if err = fd.pd.waitRead(); err == nil { 334 continue 335 } 336 case syscall.ECONNABORTED: 337 // This means that a socket on the listen 338 // queue was closed before we Accept()ed it; 339 // it's a silly error, so try again. 340 continue 341 } 342 return -1, nil, errcall, err 343 } 344 } 345 346 // Seek wraps syscall.Seek. 347 func (fd *FD) Seek(offset int64, whence int) (int64, error) { 348 if err := fd.incref(); err != nil { 349 return 0, err 350 } 351 defer fd.decref() 352 return syscall.Seek(fd.Sysfd, offset, whence) 353 } 354 355 // ReadDirent wraps syscall.ReadDirent. 356 // We treat this like an ordinary system call rather than a call 357 // that tries to fill the buffer. 358 func (fd *FD) ReadDirent(buf []byte) (int, error) { 359 if err := fd.incref(); err != nil { 360 return 0, err 361 } 362 defer fd.decref() 363 for { 364 n, err := syscall.ReadDirent(fd.Sysfd, buf) 365 if err != nil { 366 n = 0 367 if err == syscall.EAGAIN { 368 if err = fd.pd.waitRead(); err == nil { 369 continue 370 } 371 } 372 } 373 // Do not call eofError; caller does not expect to see io.EOF. 374 return n, err 375 } 376 } 377 378 // Fchdir wraps syscall.Fchdir. 379 func (fd *FD) Fchdir() error { 380 if err := fd.incref(); err != nil { 381 return err 382 } 383 defer fd.decref() 384 return syscall.Fchdir(fd.Sysfd) 385 } 386 387 // Fstat wraps syscall.Fstat 388 func (fd *FD) Fstat(s *syscall.Stat_t) error { 389 if err := fd.incref(); err != nil { 390 return err 391 } 392 defer fd.decref() 393 return syscall.Fstat(fd.Sysfd, s) 394 } 395 396 // On Unix variants only, expose the IO event for the net code. 397 398 // WaitWrite waits until data can be read from fd. 399 func (fd *FD) WaitWrite() error { 400 return fd.pd.waitWrite() 401 }