Source file src/internal/poll/fd_unix.go
1
2
3
4
5
6
7 package poll
8
9 import (
10 "io"
11 "runtime"
12 "sync/atomic"
13 "syscall"
14 )
15
16
17
18 type FD struct {
19
20 fdmu fdMutex
21
22
23 Sysfd int
24
25
26 pd pollDesc
27
28
29 iovecs *[]syscall.Iovec
30
31
32 csema uint32
33
34
35 isBlocking uint32
36
37
38
39 IsStream bool
40
41
42
43 ZeroReadIsEOF bool
44
45
46 isFile bool
47 }
48
49
50
51
52
53
54 func (fd *FD) Init(net string, pollable bool) error {
55
56 if net == "file" {
57 fd.isFile = true
58 }
59 if !pollable {
60 fd.isBlocking = 1
61 return nil
62 }
63 err := fd.pd.init(fd)
64 if err != nil {
65
66
67 fd.isBlocking = 1
68 }
69 return err
70 }
71
72
73
74 func (fd *FD) destroy() error {
75
76
77 fd.pd.close()
78 err := CloseFunc(fd.Sysfd)
79 fd.Sysfd = -1
80 runtime_Semrelease(&fd.csema)
81 return err
82 }
83
84
85
86 func (fd *FD) Close() error {
87 if !fd.fdmu.increfAndClose() {
88 return errClosing(fd.isFile)
89 }
90
91
92
93
94
95
96 fd.pd.evict()
97
98
99
100 err := fd.decref()
101
102
103
104
105
106
107
108 if fd.isBlocking == 0 {
109 runtime_Semacquire(&fd.csema)
110 }
111
112 return err
113 }
114
115
116 func (fd *FD) Shutdown(how int) error {
117 if err := fd.incref(); err != nil {
118 return err
119 }
120 defer fd.decref()
121 return syscall.Shutdown(fd.Sysfd, how)
122 }
123
124
125 func (fd *FD) SetBlocking() error {
126 if err := fd.incref(); err != nil {
127 return err
128 }
129 defer fd.decref()
130
131
132
133 atomic.StoreUint32(&fd.isBlocking, 1)
134 return syscall.SetNonblock(fd.Sysfd, false)
135 }
136
137
138
139
140
141
142 const maxRW = 1 << 30
143
144
145 func (fd *FD) Read(p []byte) (int, error) {
146 if err := fd.readLock(); err != nil {
147 return 0, err
148 }
149 defer fd.readUnlock()
150 if len(p) == 0 {
151
152
153
154
155
156 return 0, nil
157 }
158 if err := fd.pd.prepareRead(fd.isFile); err != nil {
159 return 0, err
160 }
161 if fd.IsStream && len(p) > maxRW {
162 p = p[:maxRW]
163 }
164 for {
165 n, err := syscall.Read(fd.Sysfd, p)
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
171 }
172 }
173
174
175
176 if runtime.GOOS == "darwin" && err == syscall.EINTR {
177 continue
178 }
179 }
180 err = fd.eofError(n, err)
181 return n, err
182 }
183 }
184
185
186 func (fd *FD) Pread(p []byte, off int64) (int, error) {
187
188
189
190 if err := fd.incref(); err != nil {
191 return 0, err
192 }
193 if fd.IsStream && len(p) > maxRW {
194 p = p[:maxRW]
195 }
196 n, err := syscall.Pread(fd.Sysfd, p, off)
197 if err != nil {
198 n = 0
199 }
200 fd.decref()
201 err = fd.eofError(n, err)
202 return n, err
203 }
204
205
206 func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
207 if err := fd.readLock(); err != nil {
208 return 0, nil, err
209 }
210 defer fd.readUnlock()
211 if err := fd.pd.prepareRead(fd.isFile); err != nil {
212 return 0, nil, err
213 }
214 for {
215 n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
216 if err != nil {
217 n = 0
218 if err == syscall.EAGAIN && fd.pd.pollable() {
219 if err = fd.pd.waitRead(fd.isFile); err == nil {
220 continue
221 }
222 }
223 }
224 err = fd.eofError(n, err)
225 return n, sa, err
226 }
227 }
228
229
230 func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
231 if err := fd.readLock(); err != nil {
232 return 0, 0, 0, nil, err
233 }
234 defer fd.readUnlock()
235 if err := fd.pd.prepareRead(fd.isFile); err != nil {
236 return 0, 0, 0, nil, err
237 }
238 for {
239 n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0)
240 if err != nil {
241
242 if err == syscall.EAGAIN && fd.pd.pollable() {
243 if err = fd.pd.waitRead(fd.isFile); err == nil {
244 continue
245 }
246 }
247 }
248 err = fd.eofError(n, err)
249 return n, oobn, flags, sa, err
250 }
251 }
252
253
254 func (fd *FD) Write(p []byte) (int, error) {
255 if err := fd.writeLock(); err != nil {
256 return 0, err
257 }
258 defer fd.writeUnlock()
259 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
260 return 0, err
261 }
262 var nn int
263 for {
264 max := len(p)
265 if fd.IsStream && max-nn > maxRW {
266 max = nn + maxRW
267 }
268 n, err := syscall.Write(fd.Sysfd, p[nn:max])
269 if n > 0 {
270 nn += n
271 }
272 if nn == len(p) {
273 return nn, err
274 }
275 if err == syscall.EAGAIN && fd.pd.pollable() {
276 if err = fd.pd.waitWrite(fd.isFile); err == nil {
277 continue
278 }
279 }
280 if err != nil {
281 return nn, err
282 }
283 if n == 0 {
284 return nn, io.ErrUnexpectedEOF
285 }
286 }
287 }
288
289
290 func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
291
292
293
294 if err := fd.incref(); err != nil {
295 return 0, err
296 }
297 defer fd.decref()
298 var nn int
299 for {
300 max := len(p)
301 if fd.IsStream && max-nn > maxRW {
302 max = nn + maxRW
303 }
304 n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
305 if n > 0 {
306 nn += n
307 }
308 if nn == len(p) {
309 return nn, err
310 }
311 if err != nil {
312 return nn, err
313 }
314 if n == 0 {
315 return nn, io.ErrUnexpectedEOF
316 }
317 }
318 }
319
320
321 func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
322 if err := fd.writeLock(); err != nil {
323 return 0, err
324 }
325 defer fd.writeUnlock()
326 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
327 return 0, err
328 }
329 for {
330 err := syscall.Sendto(fd.Sysfd, p, 0, sa)
331 if err == syscall.EAGAIN && fd.pd.pollable() {
332 if err = fd.pd.waitWrite(fd.isFile); err == nil {
333 continue
334 }
335 }
336 if err != nil {
337 return 0, err
338 }
339 return len(p), nil
340 }
341 }
342
343
344 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
345 if err := fd.writeLock(); err != nil {
346 return 0, 0, err
347 }
348 defer fd.writeUnlock()
349 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
350 return 0, 0, err
351 }
352 for {
353 n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
354 if err == syscall.EAGAIN && fd.pd.pollable() {
355 if err = fd.pd.waitWrite(fd.isFile); err == nil {
356 continue
357 }
358 }
359 if err != nil {
360 return n, 0, err
361 }
362 return n, len(oob), err
363 }
364 }
365
366
367 func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
368 if err := fd.readLock(); err != nil {
369 return -1, nil, "", err
370 }
371 defer fd.readUnlock()
372
373 if err := fd.pd.prepareRead(fd.isFile); err != nil {
374 return -1, nil, "", err
375 }
376 for {
377 s, rsa, errcall, err := accept(fd.Sysfd)
378 if err == nil {
379 return s, rsa, "", err
380 }
381 switch err {
382 case syscall.EAGAIN:
383 if fd.pd.pollable() {
384 if err = fd.pd.waitRead(fd.isFile); err == nil {
385 continue
386 }
387 }
388 case syscall.ECONNABORTED:
389
390
391
392 continue
393 }
394 return -1, nil, errcall, err
395 }
396 }
397
398
399 func (fd *FD) Seek(offset int64, whence int) (int64, error) {
400 if err := fd.incref(); err != nil {
401 return 0, err
402 }
403 defer fd.decref()
404 return syscall.Seek(fd.Sysfd, offset, whence)
405 }
406
407
408
409
410 func (fd *FD) ReadDirent(buf []byte) (int, error) {
411 if err := fd.incref(); err != nil {
412 return 0, err
413 }
414 defer fd.decref()
415 for {
416 n, err := syscall.ReadDirent(fd.Sysfd, buf)
417 if err != nil {
418 n = 0
419 if err == syscall.EAGAIN && fd.pd.pollable() {
420 if err = fd.pd.waitRead(fd.isFile); err == nil {
421 continue
422 }
423 }
424 }
425
426 return n, err
427 }
428 }
429
430
431 func (fd *FD) Fchdir() error {
432 if err := fd.incref(); err != nil {
433 return err
434 }
435 defer fd.decref()
436 return syscall.Fchdir(fd.Sysfd)
437 }
438
439
440 func (fd *FD) Fstat(s *syscall.Stat_t) error {
441 if err := fd.incref(); err != nil {
442 return err
443 }
444 defer fd.decref()
445 return syscall.Fstat(fd.Sysfd, s)
446 }
447
448
449
450 var tryDupCloexec = int32(1)
451
452
453 func DupCloseOnExec(fd int) (int, string, error) {
454 if atomic.LoadInt32(&tryDupCloexec) == 1 {
455 r0, e1 := fcntl(fd, syscall.F_DUPFD_CLOEXEC, 0)
456 if e1 == nil {
457 return r0, "", nil
458 }
459 switch e1.(syscall.Errno) {
460 case syscall.EINVAL, syscall.ENOSYS:
461
462
463
464 atomic.StoreInt32(&tryDupCloexec, 0)
465 default:
466 return -1, "fcntl", e1
467 }
468 }
469 return dupCloseOnExecOld(fd)
470 }
471
472
473
474 func dupCloseOnExecOld(fd int) (int, string, error) {
475 syscall.ForkLock.RLock()
476 defer syscall.ForkLock.RUnlock()
477 newfd, err := syscall.Dup(fd)
478 if err != nil {
479 return -1, "dup", err
480 }
481 syscall.CloseOnExec(newfd)
482 return newfd, "", nil
483 }
484
485
486 func (fd *FD) Dup() (int, string, error) {
487 if err := fd.incref(); err != nil {
488 return -1, "", err
489 }
490 defer fd.decref()
491 return DupCloseOnExec(fd.Sysfd)
492 }
493
494
495
496
497 func (fd *FD) WaitWrite() error {
498 return fd.pd.waitWrite(fd.isFile)
499 }
500
501
502 func (fd *FD) WriteOnce(p []byte) (int, error) {
503 if err := fd.writeLock(); err != nil {
504 return 0, err
505 }
506 defer fd.writeUnlock()
507 return syscall.Write(fd.Sysfd, p)
508 }
509
510
511
512 func (fd *FD) RawControl(f func(uintptr)) error {
513 if err := fd.incref(); err != nil {
514 return err
515 }
516 defer fd.decref()
517 f(uintptr(fd.Sysfd))
518 return nil
519 }
520
521
522 func (fd *FD) RawRead(f func(uintptr) bool) error {
523 if err := fd.readLock(); err != nil {
524 return err
525 }
526 defer fd.readUnlock()
527 if err := fd.pd.prepareRead(fd.isFile); err != nil {
528 return err
529 }
530 for {
531 if f(uintptr(fd.Sysfd)) {
532 return nil
533 }
534 if err := fd.pd.waitRead(fd.isFile); err != nil {
535 return err
536 }
537 }
538 }
539
540
541 func (fd *FD) RawWrite(f func(uintptr) bool) error {
542 if err := fd.writeLock(); err != nil {
543 return err
544 }
545 defer fd.writeUnlock()
546 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
547 return err
548 }
549 for {
550 if f(uintptr(fd.Sysfd)) {
551 return nil
552 }
553 if err := fd.pd.waitWrite(fd.isFile); err != nil {
554 return err
555 }
556 }
557 }
558
View as plain text