LibCore: Consistently treat file descriptors as handles on Windows #3166
+157
−95
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR replaces #2946. It is a prerequisite for LibIPC.
Before porting LibIPC we used CRT file descriptors for files/directories/sockets and file mapping handle (cast to int) for AnonymousBuffer.
When porting LibIPC it became apparent that System::dup and System::close need to be able to work with all types of objects mentioned above.
To address this problem I created #2946 which took a safe route: it allowed to coexist CRT fds and handles by using sign bit to distinguish between them.
Also I realized that CRT fds are better not be used for sockets.
I was already on edge about #2946 when I wrote it. The solution seemed a bit too convoluted for the problem it tried to solve.
These two thing pushed me over the edge:
fd < 0
should be changed tofd == -1
. Seems like not much, but it is one more thing to remember.The problem with CRT fds is that they are fake fds, they only work for some objects (files, folders) and certain circumstances (they cannot be inherited like handles).
So in the end they are too cumbersome to work with in our case.
So I decided to bite the bullet and consistently treat file descriptors as handles on Windows. Now, if you see an fd somewhere in the code outside of SystemWindows.cpp, it is always simply holds a handle on Windows.
Note: Windows handle is not an actual pointer, so it can safely be cast to int.
I was afraid that it will uglify SystemWindows.cpp, but this implementation turned out to be even shorter (by 40 lines). I am very pleased with the result.
There are only 3 places left in SystemWindows.cpp that use CRT fds: open, fstat and mmap. mmap requires fd, and with open/fstat I just wanted to use existing functions instead of implementing them manually using WIN32 APIs.
I use
dup
in these functions as advised here because there is no way of closing fd without closing underlying handle and handles that are associated with fds should not be closed withCloseHandle
(link).I renamed all fd arguments in SystemWindows.cpp to
handle
to distinguish them from CRT fds used in those 3 functions.