RESOLVED FIXED 225362
Port Filesystem::fileMetadata() & Filesystem::getFileModificationTime() to std::filesystem
https://bugs.webkit.org/show_bug.cgi?id=225362
Summary Port Filesystem::fileMetadata() & Filesystem::getFileModificationTime() to st...
Chris Dumez
Reported 2021-05-04 10:48:34 PDT
Port Filesystem::getFileModificationTime() to std::filesystem.
Attachments
Patch (6.47 KB, patch)
2021-05-04 10:49 PDT, Chris Dumez
no flags
Patch (6.49 KB, patch)
2021-05-04 10:55 PDT, Chris Dumez
no flags
Patch (6.62 KB, patch)
2021-05-04 11:57 PDT, Chris Dumez
no flags
Patch (6.71 KB, patch)
2021-05-04 12:04 PDT, Chris Dumez
no flags
Patch (6.92 KB, patch)
2021-05-04 13:29 PDT, Chris Dumez
no flags
Patch (27.23 KB, patch)
2021-05-04 16:58 PDT, Chris Dumez
no flags
Patch (23.22 KB, patch)
2021-05-04 18:41 PDT, Chris Dumez
no flags
Patch (27.58 KB, patch)
2021-05-04 20:53 PDT, Chris Dumez
no flags
Patch (27.89 KB, patch)
2021-05-05 09:11 PDT, Chris Dumez
ews-feeder: commit-queue-
Patch (28.20 KB, patch)
2021-05-05 09:25 PDT, Chris Dumez
no flags
Patch (28.14 KB, patch)
2021-05-05 09:36 PDT, Chris Dumez
no flags
Patch (29.88 KB, patch)
2021-05-05 10:56 PDT, Chris Dumez
no flags
Patch (29.99 KB, patch)
2021-05-06 11:56 PDT, Chris Dumez
no flags
Patch (31.14 KB, patch)
2021-05-06 16:44 PDT, Chris Dumez
no flags
Chris Dumez
Comment 1 2021-05-04 10:49:49 PDT
Chris Dumez
Comment 2 2021-05-04 10:55:21 PDT
Chris Dumez
Comment 3 2021-05-04 11:52:27 PDT
Comment on attachment 427687 [details] Patch Looks like the new test is failing for the GTK port. Will try and figure it out.
Chris Dumez
Comment 4 2021-05-04 11:57:53 PDT
Chris Dumez
Comment 5 2021-05-04 12:04:48 PDT
Chris Dumez
Comment 6 2021-05-04 13:00:31 PDT
Test is still failing in GTK: ../../Tools/TestWebKitAPI/Tests/WTF/FileSystem.cpp:560 Expected: (newModificationTime->secondsSinceEpoch().value()) > (timeBeforeModification.secondsSinceEpoch().value()), actual: -4.81751e+09 vs 1.62016e+09 Look like I am getting a negative modification time :/
Chris Dumez
Comment 7 2021-05-04 13:29:53 PDT
Chris Dumez
Comment 8 2021-05-04 16:58:35 PDT
Darin Adler
Comment 9 2021-05-04 17:16:15 PDT
Comment on attachment 427694 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=427694&action=review > Source/WTF/wtf/FileSystem.cpp:633 > + auto modificationTimeAsTimeT = std::chrono::system_clock::to_time_t(std::chrono::time_point_cast<std::chrono::system_clock::duration>(modificationTime - decltype(modificationTime)::clock::now() + std::chrono::system_clock::now())); There must be a way that doesn’t depend on two subsequent calls to now! I looked here https://stackoverflow.com/questions/61030383/how-to-convert-stdfilesystemfile-time-type-to-time-t Didn’t find something better.
Chris Dumez
Comment 10 2021-05-04 17:27:34 PDT
(In reply to Darin Adler from comment #9) > Comment on attachment 427694 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=427694&action=review > > > Source/WTF/wtf/FileSystem.cpp:633 > > + auto modificationTimeAsTimeT = std::chrono::system_clock::to_time_t(std::chrono::time_point_cast<std::chrono::system_clock::duration>(modificationTime - decltype(modificationTime)::clock::now() + std::chrono::system_clock::now())); > > There must be a way that doesn’t depend on two subsequent calls to now! > > I looked here > https://stackoverflow.com/questions/61030383/how-to-convert- > stdfilesystemfile-time-type-to-time-t > > Didn’t find something better. I did some research and apparently there is no good way with C++17. This is the best I could find so I did this and added a FIXME comment for when we switch to C++20 (which has a better way).
Darin Adler
Comment 11 2021-05-04 17:45:44 PDT
Comment on attachment 427712 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=427712&action=review > Source/WTF/wtf/FileSystem.h:120 > -WTF_EXPORT_PRIVATE Optional<FileMetadata> fileMetadata(const String& path); > -WTF_EXPORT_PRIVATE Optional<FileMetadata> fileMetadataFollowingSymlinks(const String& path); > +WTF_EXPORT_PRIVATE Optional<FileMetadata> fileMetadata(const String& path, ShouldFollowSymbolicLinks = ShouldFollowSymbolicLinks::No); Is this an improvement?
Chris Dumez
Comment 12 2021-05-04 18:00:36 PDT
(In reply to Darin Adler from comment #11) > Comment on attachment 427712 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=427712&action=review > > > Source/WTF/wtf/FileSystem.h:120 > > -WTF_EXPORT_PRIVATE Optional<FileMetadata> fileMetadata(const String& path); > > -WTF_EXPORT_PRIVATE Optional<FileMetadata> fileMetadataFollowingSymlinks(const String& path); > > +WTF_EXPORT_PRIVATE Optional<FileMetadata> fileMetadata(const String& path, ShouldFollowSymbolicLinks = ShouldFollowSymbolicLinks::No); > > Is this an improvement? I think so. We already have the ShouldFollowSymbolicLinks enum and use it for other FileSystem functions. I don't see why fileMetadata() needs a separate function for this. I hesitated making the parameter mandatory though. You seem to disagree?
Darin Adler
Comment 13 2021-05-04 18:12:47 PDT
(In reply to Chris Dumez from comment #12) > You seem to disagree? I generally prefer named functions to parameters that set policy for a function, except in cases where the combinatorial explosion makes them impractical, or when it’s more common to pass an argument through from one level to the next, rather than pass a constant. Just seems less wordy and more human. I think I inherited that preference from Cocoa naming style.
Chris Dumez
Comment 14 2021-05-04 18:22:55 PDT
(In reply to Darin Adler from comment #13) > (In reply to Chris Dumez from comment #12) > > You seem to disagree? > > I generally prefer named functions to parameters that set policy for a > function, except in cases where the combinatorial explosion makes them > impractical, or when it’s more common to pass an argument through from one > level to the next, rather than pass a constant. > > Just seems less wordy and more human. > > I think I inherited that preference from Cocoa naming style. Ok. I will revert this part of my change since it seems a little controversial. I do think that we should make our FileSystem API consistent eventually though, in one direction or another (I have a slight preference for the parameter but I won't fight you on this).
Darin Adler
Comment 15 2021-05-04 18:31:07 PDT
(In reply to Chris Dumez from comment #14) > I do think that we should make our FileSystem API consistent > eventually though, in one direction or another (I have a slight preference > for the parameter but I won't fight you on this). I agree. And my preference is also slight!
Darin Adler
Comment 16 2021-05-04 18:31:52 PDT
Another strength of having a separate named function is that it’s easier to find out if it’s used or not.
Chris Dumez
Comment 17 2021-05-04 18:41:32 PDT
Chris Dumez
Comment 18 2021-05-04 20:53:22 PDT
Chris Dumez
Comment 19 2021-05-05 09:11:40 PDT
Chris Dumez
Comment 20 2021-05-05 09:14:22 PDT
(In reply to Chris Dumez from comment #10) > (In reply to Darin Adler from comment #9) > > Comment on attachment 427694 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=427694&action=review > > > > > Source/WTF/wtf/FileSystem.cpp:633 > > > + auto modificationTimeAsTimeT = std::chrono::system_clock::to_time_t(std::chrono::time_point_cast<std::chrono::system_clock::duration>(modificationTime - decltype(modificationTime)::clock::now() + std::chrono::system_clock::now())); > > > > There must be a way that doesn’t depend on two subsequent calls to now! > > > > I looked here > > https://stackoverflow.com/questions/61030383/how-to-convert- > > stdfilesystemfile-time-type-to-time-t > > > > Didn’t find something better. > > I did some research and apparently there is no good way with C++17. This is > the best I could find so I did this and added a FIXME comment for when we > switch to C++20 (which has a better way). In this latest iteration, I use SFINAE to use std::filesystem::file_time_type::clock::to_time_t() whenever available (It is available on my machine but according to [1] is not available in MSVC and GCC 9). [1] https://en.cppreference.com/w/cpp/filesystem/file_time_type
Chris Dumez
Comment 21 2021-05-05 09:15:06 PDT
(In reply to Chris Dumez from comment #20) > (In reply to Chris Dumez from comment #10) > > (In reply to Darin Adler from comment #9) > > > Comment on attachment 427694 [details] > > > Patch > > > > > > View in context: > > > https://bugs.webkit.org/attachment.cgi?id=427694&action=review > > > > > > > Source/WTF/wtf/FileSystem.cpp:633 > > > > + auto modificationTimeAsTimeT = std::chrono::system_clock::to_time_t(std::chrono::time_point_cast<std::chrono::system_clock::duration>(modificationTime - decltype(modificationTime)::clock::now() + std::chrono::system_clock::now())); > > > > > > There must be a way that doesn’t depend on two subsequent calls to now! > > > > > > I looked here > > > https://stackoverflow.com/questions/61030383/how-to-convert- > > > stdfilesystemfile-time-type-to-time-t > > > > > > Didn’t find something better. > > > > I did some research and apparently there is no good way with C++17. This is > > the best I could find so I did this and added a FIXME comment for when we > > switch to C++20 (which has a better way). > > In this latest iteration, I use SFINAE to use > std::filesystem::file_time_type::clock::to_time_t() whenever available (It > is available on my machine but according to [1] is not available in MSVC and > GCC 9). > > [1] https://en.cppreference.com/w/cpp/filesystem/file_time_type But of course, it doesn't build on GTK :face-palm:
Chris Dumez
Comment 22 2021-05-05 09:25:51 PDT
Chris Dumez
Comment 23 2021-05-05 09:36:15 PDT
Darin Adler
Comment 24 2021-05-05 10:03:57 PDT
Comment on attachment 427774 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=427774&action=review > Source/WTF/wtf/FileSystem.cpp:671 > + if (shouldFollowSymbolicLinks == ShouldFollowSymbolicLinks::Yes && std::filesystem::is_symlink(fsPath, ec)) { > + fsPath = std::filesystem::read_symlink(fsPath, ec); > + if (ec) > + return WTF::nullopt; > + } This follows one level of symbolic link. To "follow" a symbolic ink I think we may need to do this in a loop, likely with a limit of some sort to deal with cycles.
Chris Dumez
Comment 25 2021-05-05 10:07:42 PDT
(In reply to Darin Adler from comment #24) > Comment on attachment 427774 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=427774&action=review > > > Source/WTF/wtf/FileSystem.cpp:671 > > + if (shouldFollowSymbolicLinks == ShouldFollowSymbolicLinks::Yes && std::filesystem::is_symlink(fsPath, ec)) { > > + fsPath = std::filesystem::read_symlink(fsPath, ec); > > + if (ec) > > + return WTF::nullopt; > > + } > > This follows one level of symbolic link. To "follow" a symbolic ink I think > we may need to do this in a loop, likely with a limit of some sort to deal > with cycles. Interesting. I did not realize this was a thing. I'll write a test and tweak the code accordingly.
Chris Dumez
Comment 26 2021-05-05 10:56:58 PDT
Chris Dumez
Comment 27 2021-05-06 10:31:03 PDT
Anybody willing to review this? I have addressed all the feedback so far.
Darin Adler
Comment 28 2021-05-06 11:02:41 PDT
Comment on attachment 427781 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=427781&action=review > Source/WTF/wtf/FileSystem.cpp:130 > + std::time_t timeT = toTimeT(fileTime); > + return WallTime::fromRawSeconds(timeT); Don’t think we need the local variable. > Source/WTF/wtf/FileSystem.cpp:133 > +static std::filesystem::path resolveSymlinks(std::filesystem::path path, std::error_code ec) I think we intend that ec is an in/out argument, but here it’s only being passed in. I would expect tests to fail because of this, since failure would not be propagated to the caller. > Source/WTF/wtf/FileSystem.cpp:136 > + static const unsigned maxSymlinkDepth = MAXSYMLINKS; constexpr > Source/WTF/wtf/FileSystem.cpp:138 > + static const unsigned maxSymlinkDepth = 40; constexpr
Darin Adler
Comment 29 2021-05-06 11:04:17 PDT
Started reviewing yesterday and spotted one significant mistake that makes me worry about the thoroughness of our testing. Don’t have time to finish reviewing right now, but sent you my comment in progress that include that mistake. I applaud the goal of making this more elegant and less platform-specific, but I am worried about making a lot of changes here with room for error, without extensive testing, and without obvious compelling, concrete benefit that would cause us to take the risk. That’s why I am not super-fast to review, since I feel we need to be cautious.
Chris Dumez
Comment 30 2021-05-06 11:24:03 PDT
(In reply to Darin Adler from comment #29) > Started reviewing yesterday and spotted one significant mistake that makes > me worry about the thoroughness of our testing. Don’t have time to finish > reviewing right now, but sent you my comment in progress that include that > mistake. > > I applaud the goal of making this more elegant and less platform-specific, > but I am worried about making a lot of changes here with room for error, > without extensive testing, and without obvious compelling, concrete benefit > that would cause us to take the risk. That’s why I am not super-fast to > review, since I feel we need to be cautious. I understand. I would just like to point out that we had almost no testing for our FileSystem API and my patches do bring in API tests. Clearly my tests were not enough since you've spotted mistakes but I have added tests for every mistake you spotted.
Chris Dumez
Comment 31 2021-05-06 11:39:58 PDT
(In reply to Darin Adler from comment #28) > Comment on attachment 427781 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=427781&action=review > > > Source/WTF/wtf/FileSystem.cpp:130 > > + std::time_t timeT = toTimeT(fileTime); > > + return WallTime::fromRawSeconds(timeT); > > Don’t think we need the local variable. Will fix. > > > Source/WTF/wtf/FileSystem.cpp:133 > > +static std::filesystem::path resolveSymlinks(std::filesystem::path path, std::error_code ec) > > I think we intend that ec is an in/out argument, but here it’s only being > passed in. I would expect tests to fail because of this, since failure would > not be propagated to the caller. The function also returns a default-constructed path when failing so the caller (even though it didn't have the right error_code) would still fail later on. > > > Source/WTF/wtf/FileSystem.cpp:136 > > + static const unsigned maxSymlinkDepth = MAXSYMLINKS; > > constexpr > > > Source/WTF/wtf/FileSystem.cpp:138 > > + static const unsigned maxSymlinkDepth = 40; > > constexpr Will fix.
Darin Adler
Comment 32 2021-05-06 11:46:43 PDT
Yes, really happy about the new tests you are adding! If someone else doesn’t review, I will eventually get to it.
Chris Dumez
Comment 33 2021-05-06 11:56:20 PDT
Darin Adler
Comment 34 2021-05-06 16:23:53 PDT
Comment on attachment 427916 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=427916&action=review > LayoutTests/ChangeLog:8 > + Stop testing the size of a directory in the data transfer API as the result is implementation-specific. I understand that this test wasn’t a good way to test the value of size. But is it right to just stop testing it at all? How can we best make sure it keeps working properly?
Chris Dumez
Comment 35 2021-05-06 16:27:32 PDT
(In reply to Darin Adler from comment #34) > Comment on attachment 427916 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=427916&action=review > > > LayoutTests/ChangeLog:8 > > + Stop testing the size of a directory in the data transfer API as the result is implementation-specific. > > I understand that this test wasn’t a good way to test the value of size. But > is it right to just stop testing it at all? How can we best make sure it > keeps working properly? Maybe I can just add 0 to the list of allowed values then.
Chris Dumez
Comment 36 2021-05-06 16:44:44 PDT
EWS
Comment 37 2021-05-06 21:09:31 PDT
Found 1 new test failure: http/tests/media/clearkey/collect-webkit-media-session.html
EWS
Comment 38 2021-05-06 22:00:47 PDT
Committed r277158 (237444@main): <https://commits.webkit.org/237444@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 427958 [details].
Radar WebKit Bug Importer
Comment 39 2021-05-06 22:01:16 PDT
Note You need to log in before you can comment on or make changes to this bug.