FileStream.st
changeset 25357 cec6ca6e3af4
parent 25318 bc5c4223ece2
child 25367 e117c14e2800
--- a/FileStream.st	Sun Apr 05 00:21:49 2020 +0200
+++ b/FileStream.st	Wed Apr 15 20:18:14 2020 +0200
@@ -940,9 +940,11 @@
      If nuberOfBytesOrNil is nil, copy until the end of myself.
      Redefined to use operating system features to do a fast copy."
 
-    |pos n nWritten fromFd toFd|
+    |pos nToWrite nWritten fromFd toFd|
 
+    nToWrite := numberOfBytesOrNil.
     outStream isExternalStream ifTrue:[
+        "/ try optimized system call
         fromFd := self fileHandle.
         fromFd isNil ifTrue:[
             self errorNotOpen.
@@ -955,10 +957,8 @@
         ].    
 
         pos := self position.
-        numberOfBytesOrNil isNil ifTrue:[
-            n := self size - pos.
-        ] ifFalse:[
-            n := numberOfBytesOrNil.
+        nToWrite isNil ifTrue:[
+            nToWrite := self fileSize - pos.
         ].
         
         "sendfile() in Linux does not support any combination of file/pipe/socket fds.
@@ -969,15 +969,22 @@
                         copyFromFd:fromFd
                         toFd:toFd
                         startIndex:pos
-                        count:n.
+                        count:nToWrite.
         nWritten > 0 ifTrue:[
             self position:pos+nWritten.
-            ^ n
+            nWritten == nToWrite ifTrue:[
+                "we are finished, all has been written"
+                ^ nToWrite
+            ].
+            "some data has not been written. 
+             Maybe an error occured. We will get the error whe we #copy the rest below"
+            nToWrite := nToWrite - nWritten.
+            ^ nWritten + (super copy:nToWrite into:outStream bufferSize:bufferSize).
         ].
     ].
 
     "fall back..."
-    ^ super copy:numberOfBytesOrNil into:outStream bufferSize:bufferSize.
+    ^ super copy:nToWrite into:outStream bufferSize:bufferSize.
 
     "
      |in out|
@@ -985,19 +992,23 @@
      in := 'Make.proto' asFilename readStream.
      in copyToEndInto:Stdout.
      in close.
+    "
 
+    "
      |in out|
 
      in := 'Make.proto' asFilename readStream.
      out := '/tmp/test' asFilename writeStream.
      in copyToEndInto:out.
+     self assert:(in fileSize == out fileSize).
      in close. out close.
+
      '/tmp/test' asFilename contents.
     "
 
     "Created: / 13-03-2019 / 16:27:04 / Stefan Vogel"
     "Modified (format): / 25-05-2019 / 16:47:53 / Claus Gittinger"
-    "Modified (comment): / 04-03-2020 / 15:09:52 / Stefan Vogel"
+    "Modified (format): / 15-04-2020 / 16:56:48 / Stefan Vogel"
 !
 
 syncFileSystem