@@ -85,6 +85,7 @@ const {
8585const { FSReqCallback } = binding ;
8686const { toPathIfFileURL } = require ( 'internal/url' ) ;
8787const internalUtil = require ( 'internal/util' ) ;
88+ const { isCustomIterable } = require ( 'internal/streams/utils' ) ;
8889const {
8990 constants : {
9091 kIoMaxLength,
@@ -828,12 +829,12 @@ function write(fd, buffer, offset, length, position, callback) {
828829 } else {
829830 position = length ;
830831 }
831- length = 'utf8' ;
832+ length = length || 'utf8' ;
832833 }
833834
834835 const str = String ( buffer ) ;
835836 validateEncoding ( str , length ) ;
836- callback = maybeCallback ( position ) ;
837+ callback = maybeCallback ( callback || position ) ;
837838
838839 const req = new FSReqCallback ( ) ;
839840 req . oncomplete = wrapper ;
@@ -2039,7 +2040,8 @@ function lutimesSync(path, atime, mtime) {
20392040 handleErrorFromBinding ( ctx ) ;
20402041}
20412042
2042- function writeAll ( fd , isUserFd , buffer , offset , length , signal , callback ) {
2043+ function writeAll (
2044+ fd , isUserFd , buffer , offset , length , signal , encoding , callback ) {
20432045 if ( signal ?. aborted ) {
20442046 const abortError = new AbortError ( ) ;
20452047 if ( isUserFd ) {
@@ -2051,7 +2053,29 @@ function writeAll(fd, isUserFd, buffer, offset, length, signal, callback) {
20512053 }
20522054 return ;
20532055 }
2054- // write(fd, buffer, offset, length, position, callback)
2056+ if ( isCustomIterable ( buffer ) ) {
2057+ ( async ( ) => {
2058+ for await ( const buf of buffer ) {
2059+ fs . write (
2060+ fd , buf , undefined ,
2061+ isArrayBufferView ( buf ) ? buf . byteLength : encoding ,
2062+ null , ( writeErr , _ ) => {
2063+ if ( writeErr ) {
2064+ if ( isUserFd ) {
2065+ callback ( writeErr ) ;
2066+ } else {
2067+ fs . close ( fd , ( err ) => {
2068+ callback ( aggregateTwoErrors ( err , writeErr ) ) ;
2069+ } ) ;
2070+ }
2071+ }
2072+ }
2073+ ) ;
2074+ }
2075+ fs . close ( fd , callback ) ;
2076+ } ) ( ) ;
2077+ return ;
2078+ }
20552079 fs . write ( fd , buffer , offset , length , null , ( writeErr , written ) => {
20562080 if ( writeErr ) {
20572081 if ( isUserFd ) {
@@ -2070,7 +2094,8 @@ function writeAll(fd, isUserFd, buffer, offset, length, signal, callback) {
20702094 } else {
20712095 offset += written ;
20722096 length -= written ;
2073- writeAll ( fd , isUserFd , buffer , offset , length , signal , callback ) ;
2097+ writeAll (
2098+ fd , isUserFd , buffer , offset , length , signal , encoding , callback ) ;
20742099 }
20752100 } ) ;
20762101}
@@ -2093,15 +2118,16 @@ function writeFile(path, data, options, callback) {
20932118 options = getOptions ( options , { encoding : 'utf8' , mode : 0o666 , flag : 'w' } ) ;
20942119 const flag = options . flag || 'w' ;
20952120
2096- if ( ! isArrayBufferView ( data ) ) {
2121+ if ( ! isArrayBufferView ( data ) && ! isCustomIterable ( data ) ) {
20972122 validateStringAfterArrayBufferView ( data , 'data' ) ;
20982123 data = Buffer . from ( String ( data ) , options . encoding || 'utf8' ) ;
20992124 }
21002125
21012126 if ( isFd ( path ) ) {
21022127 const isUserFd = true ;
21032128 const signal = options . signal ;
2104- writeAll ( path , isUserFd , data , 0 , data . byteLength , signal , callback ) ;
2129+ writeAll ( path , isUserFd , data ,
2130+ 0 , data . byteLength , signal , options . encoding , callback ) ;
21052131 return ;
21062132 }
21072133
@@ -2114,7 +2140,8 @@ function writeFile(path, data, options, callback) {
21142140 } else {
21152141 const isUserFd = false ;
21162142 const signal = options . signal ;
2117- writeAll ( fd , isUserFd , data , 0 , data . byteLength , signal , callback ) ;
2143+ writeAll ( fd , isUserFd , data ,
2144+ 0 , data . byteLength , signal , options . encoding , callback ) ;
21182145 }
21192146 } ) ;
21202147}
0 commit comments