-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Fix utime() syscall #16460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
@@ -32,20 +33,35 @@ void test() { | |||
// will fail | |||
struct utimbuf t = {1000000000, 1000000000}; | |||
|
|||
utime("writeable", &t); | |||
errno = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm .. if this line is needed.. how was the test passing before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no clue ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know any JS at all. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are completely right! I got a bit confused with var and let :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm % comments
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 == 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: #16458
Signed-off-by: Christian Heimes christian@python.org