Fix utime() syscall - #16460
Conversation
Fix off by factor 1000: ``FS.utime()`` expects mtime and atime in seconds. ``times == NULL`` is now correctly handled. ``utimes(path, NULL)`` updates atime and mtime to current time. https://nodejs.org/api/fs.html#fsutimespath-atime-mtime-callback Fixes: emscripten-core#16458 Signed-off-by: Christian Heimes <christian@python.org>
sbc100
left a comment
There was a problem hiding this comment.
Thanks!
I'm curious to see if any tests fail.. if they don't it means we lack coverage.
I compiled The test file now resets errno, checks return values, and tests for |
| struct utimbuf t = {1000000000, 1000000000}; | ||
|
|
||
| utime("writeable", &t); | ||
| errno = 0; |
There was a problem hiding this comment.
Hmm .. if this line is needed.. how was the test passing before?
There was a problem hiding this comment.
What test are you running that fails if you remove this line?
./tests/runner core2.test_utime works fine for on HEAD.
There was a problem hiding this comment.
I executed the test manually with $ emcc -s NODERAWFS -o test_utime.js test_utime.c && node test_utime.js. The test failed with error message RuntimeError: Aborted(Assertion failed: !errno, at: test_utime.c,37,test). My guess is that some function earlier left errno != 0.
From man errno(3):
The value in errno is significant only when the return value of the call indicated an error (i.e., -1 from most system calls; -1 or NULL from most library functions); a function that succeeds is allowed to change errno. The value of errno is never set to zero by any system call or library function.
In other words, if you want to use errno for error checking, then you have to reset errno to 0 before a function call and check it immediately after the function call.
There was a problem hiding this comment.
Yes, I'm only confused about how that test was passing before.
It sounds like the tests passes because its not run with NODERAWFS today? i.e. ./tests/runner core2.test_utime does not set NODERAWFS. Perhaps we should annotate that test with also_with_noderawfs
| var mtime = (seconds*1000) + (nanoseconds/(1000*1000)); | ||
| if (!times) { | ||
| var atime = Date.now()/1000; | ||
| var mtime = atime; |
There was a problem hiding this comment.
Seems a little odd to declare var mtime and var atime in both branches of the if/else. Maybe just declare them in one? (I'm not a JS expert but IIRC you just need one var decl for a give variable it it will be hoisted to function level).
There was a problem hiding this comment.
I don't know any JS at all. :)
There was a problem hiding this comment.
mtime and atime should be declared on level up (var mtime, atime;).
Otherwise the FS.utime(path, atime, mtime) will not be able to access the variables on the scope.
There was a problem hiding this comment.
Is that true? I thought var declaration were hoisted to the function level in JS. This seems to work just fine:
function foo() {
if (0) {
var bar = 10;
} else {
bar = 7;
}
console.error(bar);
}
It looks odd but its saves a few bytes in code size.
There was a problem hiding this comment.
You are completely right! I got a bit confused with var and let :P
|
Tests are failing. The noderawfs layer defines the utime function as
Perhaps the values must be adjusted in the noderawfs layer instead? |
|
Tests are no passing. I had to implement the same fix in wasmfs layer. |
sbc100
left a comment
There was a problem hiding this comment.
lgtm! We can try to figure out why the missing errno = 0 was ok in the past but not any more as a followup.
| mSeconds = aSeconds; | ||
| } else { | ||
| aSeconds = times[0].tv_sec; | ||
| mSeconds = times[1].tv_sec; |
There was a problem hiding this comment.
I'm curious how / why this was needed? Do we run test_utime under WASMFS? Or did you try running manually with this flag?
There was a problem hiding this comment.
This was needed to implement utime(path, NULL) for wasmfs. The PR fixes utime(path, times) on noderawfs and implements utime(path, NULL) for all fs layers.
test_utime was failing on test_core.wasmfs, https://app.circleci.com/pipelines/github/emscripten-core/emscripten/19754/workflows/57871d6d-c5f8-4f0c-83ae-2566038f9724/jobs/513149
There was a problem hiding this comment.
At thanks.. i had forgotten that we can run the whole of the core tests suite in wasmfs mode
Fix off by factor 1000:
FS.utime()expects mtime and atime in seconds.times == NULLis now correctly handled.utimes(path, NULL)updates atime and mtime to current time.
https://nodejs.org/api/fs.html#fsutimespath-atime-mtime-callback
Fixes: #16458
Signed-off-by: Christian Heimes christian@python.org