@@ -434,43 +434,40 @@ func (fd *FD) Read(buf []byte) (int, error) {
434
434
return 0 , err
435
435
}
436
436
defer fd .readUnlock ()
437
+ if fd .isFile {
438
+ fd .l .Lock ()
439
+ defer fd .l .Unlock ()
440
+ }
437
441
438
442
if len (buf ) > maxRW {
439
443
buf = buf [:maxRW ]
440
444
}
441
445
442
446
var n int
443
447
var err error
444
- if fd .isFile {
445
- fd .l .Lock ()
446
- defer fd .l .Unlock ()
447
- switch fd .kind {
448
- case kindConsole :
449
- n , err = fd .readConsole (buf )
450
- default :
451
- o := & fd .rop
452
- o .InitBuf (buf )
453
- n , err = execIO (o , func (o * operation ) error {
454
- return syscall .ReadFile (o .fd .Sysfd , unsafe .Slice (o .buf .Buf , o .buf .Len ), & o .qty , o .overlapped ())
455
- })
456
- fd .addOffset (n )
457
- if fd .kind == kindPipe && err != nil {
458
- switch err {
459
- case syscall .ERROR_BROKEN_PIPE :
460
- // Returned by pipes when the other end is closed.
461
- err = nil
462
- case syscall .ERROR_OPERATION_ABORTED :
463
- // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
464
- // If the fd is a pipe and the Read was interrupted by CancelIoEx,
465
- // we assume it is interrupted by Close.
466
- err = ErrFileClosing
467
- }
448
+ switch fd .kind {
449
+ case kindConsole :
450
+ n , err = fd .readConsole (buf )
451
+ case kindFile , kindPipe :
452
+ o := & fd .rop
453
+ o .InitBuf (buf )
454
+ n , err = execIO (o , func (o * operation ) error {
455
+ return syscall .ReadFile (o .fd .Sysfd , unsafe .Slice (o .buf .Buf , o .buf .Len ), & o .qty , o .overlapped ())
456
+ })
457
+ fd .addOffset (n )
458
+ if fd .kind == kindPipe && err != nil {
459
+ switch err {
460
+ case syscall .ERROR_BROKEN_PIPE :
461
+ // Returned by pipes when the other end is closed.
462
+ err = nil
463
+ case syscall .ERROR_OPERATION_ABORTED :
464
+ // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
465
+ // If the fd is a pipe and the Read was interrupted by CancelIoEx,
466
+ // we assume it is interrupted by Close.
467
+ err = ErrFileClosing
468
468
}
469
469
}
470
- if err != nil {
471
- n = 0
472
- }
473
- } else {
470
+ case kindNet :
474
471
o := & fd .rop
475
472
o .InitBuf (buf )
476
473
n , err = execIO (o , func (o * operation ) error {
@@ -701,36 +698,32 @@ func (fd *FD) Write(buf []byte) (int, error) {
701
698
defer fd .l .Unlock ()
702
699
}
703
700
704
- ntotal := 0
705
- for len ( buf ) > 0 {
706
- b := buf
707
- if len ( b ) > maxRW {
708
- b = b [: maxRW ]
701
+ var ntotal int
702
+ for {
703
+ max := len ( buf )
704
+ if max - ntotal > maxRW {
705
+ max = ntotal + maxRW
709
706
}
707
+ b := buf [ntotal :max ]
710
708
var n int
711
709
var err error
712
- if fd .isFile {
713
- switch fd .kind {
714
- case kindConsole :
715
- n , err = fd .writeConsole (b )
716
- default :
717
- o := & fd .wop
718
- o .InitBuf (b )
719
- n , err = execIO (o , func (o * operation ) error {
720
- return syscall .WriteFile (o .fd .Sysfd , unsafe .Slice (o .buf .Buf , o .buf .Len ), & o .qty , o .overlapped ())
721
- })
722
- fd .addOffset (n )
723
- if fd .kind == kindPipe && err == syscall .ERROR_OPERATION_ABORTED {
724
- // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
725
- // If the fd is a pipe and the Write was interrupted by CancelIoEx,
726
- // we assume it is interrupted by Close.
727
- err = ErrFileClosing
728
- }
729
- }
730
- if err != nil {
731
- n = 0
710
+ switch fd .kind {
711
+ case kindConsole :
712
+ n , err = fd .writeConsole (b )
713
+ case kindPipe , kindFile :
714
+ o := & fd .wop
715
+ o .InitBuf (b )
716
+ n , err = execIO (o , func (o * operation ) error {
717
+ return syscall .WriteFile (o .fd .Sysfd , unsafe .Slice (o .buf .Buf , o .buf .Len ), & o .qty , o .overlapped ())
718
+ })
719
+ fd .addOffset (n )
720
+ if fd .kind == kindPipe && err == syscall .ERROR_OPERATION_ABORTED {
721
+ // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
722
+ // If the fd is a pipe and the Write was interrupted by CancelIoEx,
723
+ // we assume it is interrupted by Close.
724
+ err = ErrFileClosing
732
725
}
733
- } else {
726
+ case kindNet :
734
727
if race .Enabled {
735
728
race .ReleaseMerge (unsafe .Pointer (& ioSync ))
736
729
}
@@ -741,12 +734,13 @@ func (fd *FD) Write(buf []byte) (int, error) {
741
734
})
742
735
}
743
736
ntotal += n
744
- if err != nil {
737
+ if ntotal == len ( buf ) || err != nil {
745
738
return ntotal , err
746
739
}
747
- buf = buf [n :]
740
+ if n == 0 {
741
+ return ntotal , io .ErrUnexpectedEOF
742
+ }
748
743
}
749
- return ntotal , nil
750
744
}
751
745
752
746
// writeConsole writes len(b) bytes to the console File.
@@ -814,26 +808,29 @@ func (fd *FD) Pwrite(buf []byte, off int64) (int, error) {
814
808
defer syscall .Seek (fd .Sysfd , curoffset , io .SeekStart )
815
809
defer fd .setOffset (curoffset )
816
810
817
- ntotal := 0
818
- for len ( buf ) > 0 {
819
- b := buf
820
- if len ( b ) > maxRW {
821
- b = b [: maxRW ]
811
+ var ntotal int
812
+ for {
813
+ max := len ( buf )
814
+ if max - ntotal > maxRW {
815
+ max = ntotal + maxRW
822
816
}
817
+ b := buf [ntotal :max ]
823
818
o := & fd .wop
824
819
o .InitBuf (b )
825
- fd .setOffset (off )
820
+ fd .setOffset (off + int64 ( ntotal ) )
826
821
n , err := execIO (o , func (o * operation ) error {
827
822
return syscall .WriteFile (o .fd .Sysfd , unsafe .Slice (o .buf .Buf , o .buf .Len ), & o .qty , & o .o )
828
823
})
829
- ntotal += int (n )
830
- if err != nil {
824
+ if n > 0 {
825
+ ntotal += n
826
+ }
827
+ if ntotal == len (buf ) || err != nil {
831
828
return ntotal , err
832
829
}
833
- buf = buf [n :]
834
- off += int64 (n )
830
+ if n == 0 {
831
+ return ntotal , io .ErrUnexpectedEOF
832
+ }
835
833
}
836
- return ntotal , nil
837
834
}
838
835
839
836
// Writev emulates the Unix writev system call.
0 commit comments