-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Add a method to set the controlling tty of child processes (unix). #28982
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nikomatsakis (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. The way Github handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
I do not think calling |
@nagisa what would you propose should happen? I think there are four options:
Only the first and last seem reasonable to me; I chose the last because you will always want to set |
tty sets session_leader to true and if it is unset by the time spawn is
|
Expanding on my point above: It is not really unrealistic for |
…which will be set to be the controlling terminal.
Thanks for the PR @withoutboats! I think m feelings by this point are that there's enough various niche things you can do post-fork, pre-exec that there's no way we're going to bind all of them. I would prefer to have at this point a unix-specific "run this closure after the fork" function rather than continue to pile on various functions here and there. There's already a bunch of related desires to have this sort of functionality, and it should make building this sort of function quite easy on crates.io as an extension trait! |
@nagisa I understand wanting to be able to undo any setting on the @alexcrichton Being able to run a closure after the fork is definitely the solution to everyone's problem. Literally none of the functionality in I also don't think that setting controlling terminal is niche, though: its a fundamental part of job control just like creating a new session. Passing in termios flags and window size parameters (which Merging these two conversation streams, I'd actually say that creating a new session and setting the ctty for that session are deeply coupled behaviors. Currently the API lets you create a new session, but only one without a controlling terminal. I think the actual best API here is for (I've incidentally removed a misleading comment from the docs, though it seems out of place that the API docs for session_leader gives instructions on how to create a daemon in the first place.) |
@withoutboats Ah yeah I agree that most of the extension trait on unix may not be necessary, but that doesn't mean we should remove all the methods! It's definitely nice for us to handle some of the most common use cases (like this if it turns out to be that way) in the standard library itself. The purpose of the escape hatch "run this closure" would just be to provide any ability to do this externally so this sort of functionality could grow outside first. I also think old issues about safety and such don't necessarily matter so much, this may need to be |
Oh no, I dind't mean to suggest that other methods be deprecated. Obviously having to pass a closure to the child to run after the fork is not very convenient and shouldn't be the only way to set up the child. I do think that it doesn't make a lot of sense to support I'll look into opening a separate PR with a run-after-fork closure. I think the closure would be an |
That plus I believe it may want to be |
cc rust-lang/rfcs#1359, an RFC I've now opened on adding the ability to run an after-fork closure |
@withoutboats you may be interested in tty-rs ;) |
I'm gonna close this due to inactivity in favor of rust-lang/rfcs#1359 for now, but we can always reopen/resubmit depending on the outcome over there! |
On UNIX, processes may have a controlling terminal. Currently, there is no way to set the controlling terminal of a child process using the
std::process::Command
API. I am working on a library which abstracts over the tty subsystem; this method is needed to create a Rustic equivalent to fork_pty(3).The proposed API works like this:
Command::tty()
sets session_leader to true, regardless of whether or not session_leader() has been called. It prevents future calls to session_leader from having any impact.Command::tty()
does not automatically cause the controlling terminal to be set as the stdio handles of the child process. To do that, one needs to call the appropriate methods withStdio::from_raw_fd(fd)
or the like. I made this decision to make the API more flexible (e.g. if you want to run a process that needs to have a controlling terminal set for some reason, but you don't want to communicate with it over that tty pair).Command::spawn()
, in the child process, after setting the process to be the leader of a new session, if an fd has been set to be the ctty for the child, this change is performed using the TIOCSCTTY ioctl.I think this code is correct, but I feel a bit out of my depth with regard to a few things. In particular: is TIOCSCTTY supported, with the same ioctl number, on all relevant platforms? is closing the file descriptor in the child process the correct behavior in the context of Rust's RAII?