@@ -112,65 +112,84 @@ addToLibrary({
112112 }
113113 return newFlags ;
114114 } ,
115-
115+ getattr ( func , node ) {
116+ var stat = NODEFS . tryFSOperation ( func ) ;
117+ if ( NODEFS . isWindows ) {
118+ // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake
119+ // them with default blksize of 4096.
120+ // See http://support.microsoft.com/kb/140365
121+ if ( ! stat . blksize ) {
122+ stat . blksize = 4096 ;
123+ }
124+ if ( ! stat . blocks ) {
125+ stat . blocks = ( stat . size + stat . blksize - 1 ) / stat . blksize | 0 ;
126+ }
127+ // Windows does not report the 'x' permission bit, so propagate read
128+ // bits to execute bits.
129+ stat . mode |= ( stat . mode & { { { cDefs . S_IRUGO } } } ) >> 2 ;
130+ }
131+ return {
132+ dev : stat . dev ,
133+ ino : node . id ,
134+ mode : stat . mode ,
135+ nlink : stat . nlink ,
136+ uid : stat . uid ,
137+ gid : stat . gid ,
138+ rdev : stat . rdev ,
139+ size : stat . size ,
140+ atime : stat . atime ,
141+ mtime : stat . mtime ,
142+ ctime : stat . ctime ,
143+ blksize : stat . blksize ,
144+ blocks : stat . blocks
145+ } ;
146+ } ,
147+ // Common code for both node and stream setattr
148+ // For node getatrr:
149+ // - arg is a native path
150+ // - chmod, utimes, truncate are fs.chmodSync, fs.utimesSync, fs.truncateSync
151+ // For stream getatrr:
152+ // - arg is a native file descriptor
153+ // - chmod, utimes, truncate are fs.fchmodSync, fs.futimesSync, fs.ftruncateSync
154+ setattr ( arg , node , attr , chmod , utimes , truncate , stat ) {
155+ NODEFS . tryFSOperation ( ( ) => {
156+ if ( attr . mode !== undefined ) {
157+ var mode = attr . mode ;
158+ if ( NODEFS . isWindows ) {
159+ // Windows only supports S_IREAD / S_IWRITE (S_IRUSR / S_IWUSR)
160+ // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/chmod-wchmod
161+ mode &= { { { cDefs . S_IRUSR | cDefs . S_IWUSR } } } ;
162+ }
163+ chmod ( arg , mode ) ;
164+ // update the common node structure mode as well
165+ node. mode = attr . mode ;
166+ }
167+ if ( typeof ( attr . atime ?? attr . mtime ) === "number" ) {
168+ // Unfortunately, we have to stat the current value if we don't want
169+ // to change it. On top of that, since the times don't round trip
170+ // this will only keep the value nearly unchanged not exactly
171+ // unchanged. See:
172+ // https://github.com/nodejs/node/issues/56492
173+ var atime = new Date ( attr . atime ?? stat ( arg ) . atime ) ;
174+ var mtime = new Date ( attr . mtime ?? stat ( arg ) . mtime ) ;
175+ utimes ( arg , atime , mtime ) ;
176+ }
177+ if ( attr . size !== undefined ) {
178+ truncate ( arg , attr . size ) ;
179+ }
180+ } ) ;
181+ } ,
116182 node_ops : {
117183 getattr ( node ) {
118184 var path = NODEFS . realPath ( node ) ;
119- var stat ;
120- NODEFS . tryFSOperation ( ( ) => stat = fs . lstatSync ( path ) ) ;
121- if ( NODEFS . isWindows ) {
122- // Windows does not report the 'x' permission bit, so propagate read
123- // bits to execute bits.
124- stat. mode |= ( stat . mode & { { { cDefs . S_IRUGO } } } ) >> 2 ;
125- }
126- return {
127- dev : stat . dev ,
128- ino : node . id ,
129- mode : stat . mode ,
130- nlink : stat . nlink ,
131- uid : stat . uid ,
132- gid : stat . gid ,
133- rdev : stat . rdev ,
134- size : stat . size ,
135- atime : stat . atime ,
136- mtime : stat . mtime ,
137- ctime : stat . ctime ,
138- blksize : stat . blksize ,
139- blocks : stat . blocks
140- } ;
185+ return NODEFS . getattr ( ( ) => fs . lstatSync ( path ) , node ) ;
141186 } ,
142187 setattr ( node , attr ) {
143188 var path = NODEFS . realPath ( node ) ;
144- NODEFS . tryFSOperation ( ( ) => {
145- if ( attr . mode !== undefined ) {
146- if ( attr . dontFollow ) {
147- throw new FS . ErrnoError ( { { { cDefs . ENOSYS } } } ) ;
148- }
149- var mode = attr . mode ;
150- if ( NODEFS . isWindows ) {
151- // Windows only supports S_IREAD / S_IWRITE (S_IRUSR / S_IWUSR)
152- // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/chmod-wchmod
153- mode &= { { { cDefs . S_IRUSR | cDefs . S_IWUSR } } } ;
154- }
155- fs . chmodSync ( path , mode ) ;
156- // update the common node structure mode as well
157- node. mode = attr . mode ;
158- }
159- if ( typeof ( attr . atime ?? attr . mtime ) = == "number ") {
160- // Unfortunately, we have to stat the current value if we don't want
161- // to change it. On top of that, since the times don't round trip
162- // this will only keep the value nearly unchanged not exactly
163- // unchanged. See:
164- // https://github.com/nodejs/node/issues/56492
165- var stat = ( ) => fs . lstatSync ( NODEFS . realPath ( node ) ) ;
166- var atime = new Date ( attr . atime ?? stat ( ) . atime ) ;
167- var mtime = new Date ( attr . mtime ?? stat ( ) . mtime ) ;
168- fs . utimesSync ( path , atime , mtime ) ;
169- }
170- if ( attr . size !== undefined ) {
171- fs . truncateSync ( path , attr. size ) ;
172- }
173- } ) ;
189+ if ( attr . mode != null && attr . dontFollow ) {
190+ throw new FS . ErrnoError ( { { { cDefs . ENOSYS } } } ) ;
191+ }
192+ NODEFS . setattr ( path , node , attr , fs . chmodSync , fs . utimesSync , fs . truncateSync , fs . lstatSync ) ;
174193 } ,
175194 lookup ( parent , name ) {
176195 var path = PATH . join2 ( NODEFS . realPath ( parent ) , name ) ;
@@ -228,18 +247,22 @@ addToLibrary({
228247 }
229248 } ,
230249 stream_ops : {
250+ getattr ( stream ) {
251+ return NODEFS . getattr ( ( ) => fs . fstatSync ( stream . nfd ) , stream . node ) ;
252+ } ,
253+ setattr ( stream , attr ) {
254+ NODEFS . setattr ( stream . nfd , stream . node , attr , fs . fchmodSync , fs . futimesSync , fs . ftruncateSync , fs . fstatSync ) ;
255+ } ,
231256 open ( stream ) {
232257 var path = NODEFS . realPath ( stream . node ) ;
233258 NODEFS . tryFSOperation ( ( ) => {
234- if ( FS . isFile ( stream . node . mode ) ) {
235- stream . shared . refcount = 1 ;
236- stream . nfd = fs . openSync ( path , NODEFS . flagsForNode ( stream . flags ) ) ;
237- }
259+ stream . shared . refcount = 1 ;
260+ stream . nfd = fs . openSync ( path , NODEFS . flagsForNode ( stream . flags ) ) ;
238261 } ) ;
239262 } ,
240263 close ( stream ) {
241264 NODEFS . tryFSOperation ( ( ) => {
242- if ( FS . isFile ( stream . node . mode ) && stream . nfd && -- stream . shared . refcount === 0 ) {
265+ if ( stream . nfd && -- stream . shared . refcount === 0 ) {
243266 fs . closeSync ( stream . nfd ) ;
244267 }
245268 } ) ;
0 commit comments