-
Notifications
You must be signed in to change notification settings - Fork 42
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 IO safety in unix.rs
#101
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use std::{env, process::Command}; | ||
|
||
use jobserver::{Client, FromEnvErrorKind}; | ||
|
||
fn main() { | ||
match env::args().skip(1).next().unwrap_or_default().as_str() { | ||
"" => { | ||
let me = env::current_exe().unwrap(); | ||
let mut cmd = Command::new(me); | ||
let client = Client::new(1).unwrap(); | ||
client.configure(&mut cmd); | ||
drop(client); | ||
assert!(cmd.arg("from_env").status().unwrap().success()); | ||
} | ||
"from_env" => { | ||
let me = env::current_exe().unwrap(); | ||
let mut cmd = Command::new(me); | ||
let client = unsafe { | ||
match Client::from_env_ext(true).client { | ||
// Its ok for a dropped jobservers path to no longer exist (e.g. on Windows). | ||
Err(e) if matches!(e.kind(), FromEnvErrorKind::CannotOpenPath) => return, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMHO it's kind of a bad behavior that it has different behavior on different platform. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately having the same behaviour would be difficult:
The only possibility that comes to mind would be if on Windows the parent process lets the child process inherit a copy of the semaphore handle; this would mean that the semaphore would stick around for as long as that process was running. The difficult bit is ensuring only the desired processes inherit the handle and making sure the handle isn't closed before the command is spawned. This would require stdlib support, possibly involving There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ChrisDenton, one more case to start supporting this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am happy to collaborate would @beetrees on this to stop processes from inheriting handles. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check out rust-lang/rust#115501. |
||
res => res.unwrap(), | ||
} | ||
}; | ||
client.configure(&mut cmd); | ||
drop(client); | ||
assert!(cmd.arg("use_it").status().unwrap().success()); | ||
} | ||
"use_it" => { | ||
let client = unsafe { | ||
match Client::from_env_ext(true).client { | ||
// See above. | ||
Err(e) if matches!(e.kind(), FromEnvErrorKind::CannotOpenPath) => return, | ||
res => res.unwrap(), | ||
} | ||
}; | ||
client.acquire().unwrap(); | ||
} | ||
_ => unreachable!(), | ||
} | ||
} |
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 is awesome, now it would always work once
Client::configure
is called