Uh oh!
There was an error while loading. Please reload this page.
Add File::try_clone - #31069
Conversation
reem
commented
Jan 21, 2016
Looks great; looking forward to removing my much more fragile platform specific code. |
alexcrichton
commented
Jan 21, 2016
This seems reasonable to me, although I will cc @rust-lang/libs and tag with it to make sure we're all good with the insta-stablilization. |
oli-obk
commented
Jan 21, 2016
I know this can't cause memory unsafety, but isn't it very unexpected to be able to modify a file from two threads simultaneously (without additional synchronization, writing to the file will be very amusing at best) |
alexcrichton
commented
Jan 21, 2016
sfackler
commented
Jan 21, 2016
@oli-obk I hate to be the bearer of unexpected news, but that is already the case: @alexcrichton I implemented this at @reem's request, so he'd be able to better speak to the use cases. |
oli-obk
commented
Jan 21, 2016
Ugh, ugly. Still, there you are at least bound to an instance. So what's the difference between |
sfackler
commented
Jan 21, 2016
It's pretty annoying to access the impls for |
reem
commented
Jan 22, 2016
Hmm, I actually could get by in my case with an EDIT: For clarity, the case is moving from one enum variant which contains a File to another enum variant which should contain the same File with an |
oli-obk
commented
Jan 22, 2016
I don't know how powerful impl specialization would be, but could it create a special impl for |
retep998
commented
Jan 22, 2016
@oli-obk That seems overly complicated and would be a lot of complexity when simply duplicating a file handle can be done now fairly easily with just a single public method. |
oli-obk
commented
Jan 22, 2016
I'm aware of that. But it's much clearer that Since the borrowing semantics of |
retep998
commented
Jan 22, 2016
Even if you duplicate a |
oli-obk
commented
Jan 22, 2016
Yes, but shared ownership is represented through
It's probably not important anyway. We can always get true ownership back through a newtype that doesn't give access to the internal value. Still a sad deviation, but one that's already happened, now we gotta live with it. |
alexcrichton
commented
Jan 22, 2016
@oli-obk I at least would consider us to not perform that sort of specialization or optimization in the future. There are some use cases where you want an entirely separate handle and/or file descriptor to pass to a library which it itself calls |
bluss
commented
Jan 22, 2016
insta-stabilizing seems wrong (why is this PR special)? If any time is right for it, it's this week though; it will still need 11 weeks to reach the stable release. |
sfackler
commented
Jan 22, 2016
Fair enough, I'm fine with landing it unstable. I'll update it tonight. |
sfackler
commented
Jan 26, 2016
Updated to be unstable. |
aturon
commented
Jan 27, 2016
I'm fine with this functionality, under the rubric of exposing cross-platform IO APIs that apply to our various IO objects (part of the vision of IO reform). The name isn't great, though. If you succeed here, you haven't really cloned, you've created a new alias. (And we also avoid |
alexcrichton
commented
Jan 27, 2016
@aturon note, however, that we have already stabilized |
BurntSushi
commented
Jan 27, 2016
@aturon To bikeshed a bit more, |
aturon
commented
Jan 27, 2016
Yeah, I thought about that, though I'd argue it's mildly more obvious what's going on in those cases. D'oh! I'm surprised that got through, though I imagine I signed off on it at some point :-) Given the |
sfackler
commented
Jan 27, 2016
Agreed that |
alexcrichton
commented
Feb 4, 2016
The libs team discussed this during triage today and the conclusion was to merge (mirrors existing APIs, seems like good functionality to have). @sfackler could you open a tracking issue and update the pointer here? Other than that r=me |
sfackler
commented
Feb 4, 2016
@bors r=alexcrichton |
bors
commented
Feb 4, 2016
📌 Commit a414b61 has been approved by |
bors
commented
Feb 4, 2016
⌛ Testing commit a414b61 with merge 7b9d6d3... |
I have it set as stable right now under the rationale that it's extending an existing, stable API to another type in the "obvious" way. r? @alexcrichton cc @reem
bors
commented
Feb 4, 2016
| pub fn duplicate(&self) -> io::Result<File> { | ||
| Ok(File { | ||
| handle: try!(self.handle.duplicate(0, true, c::DUPLICATE_SAME_ACCESS)), |
There was a problem hiding this comment.
Asking 3.5 years after the fact: Does anyone know why we set inheritable = true here? I've run into a bug (because duct was abusing File::try_clone somewhat) where pipes get inherited by processes that aren't supposed to inherit them, when spawning happens on multiple threads at once. Normally the CREATE_PROCESS_LOCK prevents this, but this line here creates inheritable handles outside of that lock. duct is going to work around this by making all the appropriate system calls explicitly. But this inheritable flag might be cause some programs in the wild to keep files open longer than they should (even without a multi-threaded race condition like mine), and on Windows in particular that could cause bugs by making them un-deletable.
File handles shouldn't be inheritable in general. `std::process::Command` takes care of making them inheritable when child processes are spawned, and the `CREATE_PROCESS_LOCK` protects against races in that section on Windows. But `File::try_clone` has been creating inheritable file descriptors outside of that lock, which could be leaking into other child processes unintentionally. See also rust-lang#31069 (comment).
…ichton make File::try_clone produce non-inheritable handles on Windows ~**NOT READY FOR REVIEW.** This PR is currently mainly to trigger CI so that I can see what happens. (Is there a better way to trigger CI?) I don't know whether this change makes sense yet.~ (Edit: @Mark-Simulacrum clarified that CI doesn't currently run on Windows.) --- File handles shouldn't be inheritable in general. `std::process::Command` takes care of making them inheritable when child processes are spawned, and the `CREATE_PROCESS_LOCK` protects against races in that section on Windows. But `File::try_clone` has been creating inheritable file descriptors outside of that lock, which could be leaking into other child processes unintentionally. See also rust-lang#31069 (comment).
…ichton make File::try_clone produce non-inheritable handles on Windows ~**NOT READY FOR REVIEW.** This PR is currently mainly to trigger CI so that I can see what happens. (Is there a better way to trigger CI?) I don't know whether this change makes sense yet.~ (Edit: @Mark-Simulacrum clarified that CI doesn't currently run on Windows.) --- File handles shouldn't be inheritable in general. `std::process::Command` takes care of making them inheritable when child processes are spawned, and the `CREATE_PROCESS_LOCK` protects against races in that section on Windows. But `File::try_clone` has been creating inheritable file descriptors outside of that lock, which could be leaking into other child processes unintentionally. See also rust-lang#31069 (comment).
I have it set as stable right now under the rationale that it's extending an existing, stable API to another type in the "obvious" way.
r? @alexcrichton
cc @reem