libgo: update to go1.9
[official-gcc.git] / libgo / go / internal / poll / fd_unix.go
blobc40c701f59c69da9b1aef2f656b400b28cb6c10d
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.
5 // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
7 package poll
9 import (
10 "io"
11 "syscall"
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
20 // System file descriptor. Immutable until Close.
21 Sysfd int
23 // I/O poller.
24 pd pollDesc
26 // Writev cache.
27 iovecs *[]syscall.Iovec
29 // Whether this is a streaming descriptor, as opposed to a
30 // packet-based descriptor like a UDP socket. Immutable.
31 IsStream bool
33 // Whether a zero byte read indicates EOF. This is false for a
34 // message based socket connection.
35 ZeroReadIsEOF bool
37 // Whether this is a file rather than a network socket.
38 isFile bool
41 // Init initializes the FD. The Sysfd field should already be set.
42 // This can be called multiple times on a single FD.
43 // The net argument is a network name from the net package (e.g., "tcp"),
44 // or "file".
45 func (fd *FD) Init(net string, pollable bool) error {
46 // We don't actually care about the various network types.
47 if net == "file" {
48 fd.isFile = true
50 if !pollable {
51 return nil
53 return fd.pd.init(fd)
56 // Destroy closes the file descriptor. This is called when there are
57 // no remaining references.
58 func (fd *FD) destroy() error {
59 // Poller may want to unregister fd in readiness notification mechanism,
60 // so this must be executed before CloseFunc.
61 fd.pd.close()
62 err := CloseFunc(fd.Sysfd)
63 fd.Sysfd = -1
64 return err
67 // Close closes the FD. The underlying file descriptor is closed by the
68 // destroy method when there are no remaining references.
69 func (fd *FD) Close() error {
70 if !fd.fdmu.increfAndClose() {
71 return errClosing(fd.isFile)
73 // Unblock any I/O. Once it all unblocks and returns,
74 // so that it cannot be referring to fd.sysfd anymore,
75 // the final decref will close fd.sysfd. This should happen
76 // fairly quickly, since all the I/O is non-blocking, and any
77 // attempts to block in the pollDesc will return errClosing(fd.isFile).
78 fd.pd.evict()
79 // The call to decref will call destroy if there are no other
80 // references.
81 return fd.decref()
84 // Shutdown wraps the shutdown network call.
85 func (fd *FD) Shutdown(how int) error {
86 if err := fd.incref(); err != nil {
87 return err
89 defer fd.decref()
90 return syscall.Shutdown(fd.Sysfd, how)
93 // Darwin and FreeBSD can't read or write 2GB+ files at a time,
94 // even on 64-bit systems.
95 // The same is true of socket implementations on many systems.
96 // See golang.org/issue/7812 and golang.org/issue/16266.
97 // Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned.
98 const maxRW = 1 << 30
100 // Read implements io.Reader.
101 func (fd *FD) Read(p []byte) (int, error) {
102 if err := fd.readLock(); err != nil {
103 return 0, err
105 defer fd.readUnlock()
106 if len(p) == 0 {
107 // If the caller wanted a zero byte read, return immediately
108 // without trying (but after acquiring the readLock).
109 // Otherwise syscall.Read returns 0, nil which looks like
110 // io.EOF.
111 // TODO(bradfitz): make it wait for readability? (Issue 15735)
112 return 0, nil
114 if err := fd.pd.prepareRead(fd.isFile); err != nil {
115 return 0, err
117 if fd.IsStream && len(p) > maxRW {
118 p = p[:maxRW]
120 for {
121 n, err := syscall.Read(fd.Sysfd, p)
122 if err != nil {
123 n = 0
124 if err == syscall.EAGAIN && fd.pd.pollable() {
125 if err = fd.pd.waitRead(fd.isFile); err == nil {
126 continue
130 err = fd.eofError(n, err)
131 return n, err
135 // Pread wraps the pread system call.
136 func (fd *FD) Pread(p []byte, off int64) (int, error) {
137 // Call incref, not readLock, because since pread specifies the
138 // offset it is independent from other reads.
139 // Similarly, using the poller doesn't make sense for pread.
140 if err := fd.incref(); err != nil {
141 return 0, err
143 if fd.IsStream && len(p) > maxRW {
144 p = p[:maxRW]
146 n, err := syscall.Pread(fd.Sysfd, p, off)
147 if err != nil {
148 n = 0
150 fd.decref()
151 err = fd.eofError(n, err)
152 return n, err
155 // ReadFrom wraps the recvfrom network call.
156 func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
157 if err := fd.readLock(); err != nil {
158 return 0, nil, err
160 defer fd.readUnlock()
161 if err := fd.pd.prepareRead(fd.isFile); err != nil {
162 return 0, nil, err
164 for {
165 n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
166 if err != nil {
167 n = 0
168 if err == syscall.EAGAIN && fd.pd.pollable() {
169 if err = fd.pd.waitRead(fd.isFile); err == nil {
170 continue
174 err = fd.eofError(n, err)
175 return n, sa, err
179 // ReadMsg wraps the recvmsg network call.
180 func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
181 if err := fd.readLock(); err != nil {
182 return 0, 0, 0, nil, err
184 defer fd.readUnlock()
185 if err := fd.pd.prepareRead(fd.isFile); err != nil {
186 return 0, 0, 0, nil, err
188 for {
189 n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0)
190 if err != nil {
191 // TODO(dfc) should n and oobn be set to 0
192 if err == syscall.EAGAIN && fd.pd.pollable() {
193 if err = fd.pd.waitRead(fd.isFile); err == nil {
194 continue
198 err = fd.eofError(n, err)
199 return n, oobn, flags, sa, err
203 // Write implements io.Writer.
204 func (fd *FD) Write(p []byte) (int, error) {
205 if err := fd.writeLock(); err != nil {
206 return 0, err
208 defer fd.writeUnlock()
209 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
210 return 0, err
212 var nn int
213 for {
214 max := len(p)
215 if fd.IsStream && max-nn > maxRW {
216 max = nn + maxRW
218 n, err := syscall.Write(fd.Sysfd, p[nn:max])
219 if n > 0 {
220 nn += n
222 if nn == len(p) {
223 return nn, err
225 if err == syscall.EAGAIN && fd.pd.pollable() {
226 if err = fd.pd.waitWrite(fd.isFile); err == nil {
227 continue
230 if err != nil {
231 return nn, err
233 if n == 0 {
234 return nn, io.ErrUnexpectedEOF
239 // Pwrite wraps the pwrite system call.
240 func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
241 // Call incref, not writeLock, because since pwrite specifies the
242 // offset it is independent from other writes.
243 // Similarly, using the poller doesn't make sense for pwrite.
244 if err := fd.incref(); err != nil {
245 return 0, err
247 defer fd.decref()
248 var nn int
249 for {
250 max := len(p)
251 if fd.IsStream && max-nn > maxRW {
252 max = nn + maxRW
254 n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
255 if n > 0 {
256 nn += n
258 if nn == len(p) {
259 return nn, err
261 if err != nil {
262 return nn, err
264 if n == 0 {
265 return nn, io.ErrUnexpectedEOF
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
275 defer fd.writeUnlock()
276 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
277 return 0, err
279 for {
280 err := syscall.Sendto(fd.Sysfd, p, 0, sa)
281 if err == syscall.EAGAIN && fd.pd.pollable() {
282 if err = fd.pd.waitWrite(fd.isFile); err == nil {
283 continue
286 if err != nil {
287 return 0, err
289 return len(p), nil
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
298 defer fd.writeUnlock()
299 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
300 return 0, 0, err
302 for {
303 n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
304 if err == syscall.EAGAIN && fd.pd.pollable() {
305 if err = fd.pd.waitWrite(fd.isFile); err == nil {
306 continue
309 if err != nil {
310 return n, 0, err
312 return n, len(oob), err
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
321 defer fd.readUnlock()
323 if err := fd.pd.prepareRead(fd.isFile); err != nil {
324 return -1, nil, "", err
326 for {
327 s, rsa, errcall, err := accept(fd.Sysfd)
328 if err == nil {
329 return s, rsa, "", err
331 switch err {
332 case syscall.EAGAIN:
333 if fd.pd.pollable() {
334 if err = fd.pd.waitRead(fd.isFile); err == nil {
335 continue
338 case syscall.ECONNABORTED:
339 // This means that a socket on the listen
340 // queue was closed before we Accept()ed it;
341 // it's a silly error, so try again.
342 continue
344 return -1, nil, errcall, err
348 // Seek wraps syscall.Seek.
349 func (fd *FD) Seek(offset int64, whence int) (int64, error) {
350 if err := fd.incref(); err != nil {
351 return 0, err
353 defer fd.decref()
354 return syscall.Seek(fd.Sysfd, offset, whence)
357 // ReadDirent wraps syscall.ReadDirent.
358 // We treat this like an ordinary system call rather than a call
359 // that tries to fill the buffer.
360 func (fd *FD) ReadDirent(buf []byte) (int, error) {
361 if err := fd.incref(); err != nil {
362 return 0, err
364 defer fd.decref()
365 for {
366 n, err := syscall.ReadDirent(fd.Sysfd, buf)
367 if err != nil {
368 n = 0
369 if err == syscall.EAGAIN && fd.pd.pollable() {
370 if err = fd.pd.waitRead(fd.isFile); err == nil {
371 continue
375 // Do not call eofError; caller does not expect to see io.EOF.
376 return n, err
380 // Fchdir wraps syscall.Fchdir.
381 func (fd *FD) Fchdir() error {
382 if err := fd.incref(); err != nil {
383 return err
385 defer fd.decref()
386 return syscall.Fchdir(fd.Sysfd)
389 // Fstat wraps syscall.Fstat
390 func (fd *FD) Fstat(s *syscall.Stat_t) error {
391 if err := fd.incref(); err != nil {
392 return err
394 defer fd.decref()
395 return syscall.Fstat(fd.Sysfd, s)
398 // On Unix variants only, expose the IO event for the net code.
400 // WaitWrite waits until data can be read from fd.
401 func (fd *FD) WaitWrite() error {
402 return fd.pd.waitWrite(fd.isFile)
405 // RawControl invokes the user-defined function f for a non-IO
406 // operation.
407 func (fd *FD) RawControl(f func(uintptr)) error {
408 if err := fd.incref(); err != nil {
409 return err
411 defer fd.decref()
412 f(uintptr(fd.Sysfd))
413 return nil
416 // RawRead invokes the user-defined function f for a read operation.
417 func (fd *FD) RawRead(f func(uintptr) bool) error {
418 if err := fd.readLock(); err != nil {
419 return err
421 defer fd.readUnlock()
422 if err := fd.pd.prepareRead(fd.isFile); err != nil {
423 return err
425 for {
426 if f(uintptr(fd.Sysfd)) {
427 return nil
429 if err := fd.pd.waitRead(fd.isFile); err != nil {
430 return err
435 // RawWrite invokes the user-defined function f for a write operation.
436 func (fd *FD) RawWrite(f func(uintptr) bool) error {
437 if err := fd.writeLock(); err != nil {
438 return err
440 defer fd.writeUnlock()
441 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
442 return err
444 for {
445 if f(uintptr(fd.Sysfd)) {
446 return nil
448 if err := fd.pd.waitWrite(fd.isFile); err != nil {
449 return err