-
Notifications
You must be signed in to change notification settings - Fork 681
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 openpty #456
Add openpty #456
Conversation
So it's only failing on aarch64, because apparently some iotctl used in |
I think our preference would be to work with libc upstream to fix aarch64. Or are you saying that openpty isn't supported at all on aarch64? |
I'm not sure; the test run is failing with |
I think you may have hit https://lists.gnu.org/archive/html/qemu-devel/2016-07/msg04286.html. |
@posborne do you know offhand the version of qemu that's in your docker image? |
Unfortunately, no. The base image I built stuff off of at the time was 15.10. |
I think it's 0.10.50? I have no idea how Docker works, but I think I managed to pull the Docker image and start a container, and from inside a shell in that container:
|
@cactorium that's the android emulator version. Moreover the concerning failure is the one on Looking inside
It may need a bump to 2.7 or 2.8. |
Yeah, we can certainly bump. I would really like to move the CI to something like https://github.com/japaric/trust |
/cc @japaric |
@posborne I could take a stab at getting |
@berkowski That would be awesome. |
@cactorium Can you rebase this so we can give it a run through now that we're testing code on more platforms? |
Can do! |
@cactorium Sorry I didn't notice this the first time, but it looks like this should really be one commit, as you have a few smaller fixing commits. Can you squash this down into one? That would help me review it. I'm also curious how this will end up interacting with #527. @cactorium Can you take a look at that issue, it kind of exploded into talking about how best to deal with the @berkowski If you have time can you take a look over this as well? This is probably of interest to you. |
Err I think I messed up the commit history on this PR a lot, I guess pulling would've been a better choice than an actual rebase. Would you guys have any advice on cleaning up the commit history? I'll look at the other PR in a bit |
Then you can squash them with |
src/pty.rs
Outdated
let mut master: libc::c_int = -1; | ||
let c_termios = match &termios { | ||
&Some(ref termios) => termios as *const Termios, | ||
&None => 0 as *const Termios, |
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.
I think ptr::null()
would be more appropriate
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.
Fixed
src/pty.rs
Outdated
}; | ||
let c_winsize = match &winsize { | ||
&Some(ref ws) => ws as *const Winsize, | ||
&None => 0 as *const Winsize, |
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.
Again, I think ptr::null()
would be more appropriate
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.
Fixed
src/pty.rs
Outdated
libc::openpty( | ||
&mut master as *mut libc::c_int, | ||
&mut slave as *mut libc::c_int, | ||
0 as *mut libc::c_char, |
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.
Again I think ptr::null()
would be more appropriate
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.
Fixed
test/test_pty.rs
Outdated
|
||
#[test] | ||
fn test_openpty() { | ||
// TODO: figure out the right termios settings to pass in here |
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.
Is this a TODO you intend to fix as part of this PR? If we're testing this I think it'd be nice if we could test the case where a termios
and winsize
struct is passed in. Especially if we change the function declaration as I mentioned earlier.
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.
Any advice on what flags to play with? The only ones I can think of messing with don't do much other than turn CR on/off
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.
It doesn't really matter what flags you set so long as the function gets tested with None
and Some(_)
types really. If the CR thing works, go ahead and add a test that tests that.
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.
After looking into it, there's not really a nice way to initialize a Termios object in a platform-agnostic manner until it implements Default
, so I'd argue for pushing that fix later in a separate PR
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.
Could you file a ticket against libc
about this then? I'd actually prefer if we could resolve that before merging this if it's relatively easy.
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.
Default
should always set the fields to valid values, it kind of defeats the point if it doesn't. For the termios struct I'm pretty certain for the termios
struct that all zeros is valid.
But for your tests, just create a termios struct out of uninitialized memory and use the various methods available to set the struct to your desired values. Does that work?
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.
So I ended up using tcgetattr
to populate the Termios
. Apparently this breaks on OS X because they don't support tcgetattr
?
Edit: Either that or it's failing when trying to initialize a pty without carriage returns, it's hard to tell from the logs
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.
Yeah, tcgetattr(stdin)
is failing on OS X, added two print!() statements around that call and only the first one shows up in the log. Two obvious options are to either disable the test on OS X or switch back to just using (None, None)
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.
You can only use tcgetattr
on ttys, which I don't think stdin is, which explains why it fails on mac. What I would recommend is calling tcgetattr
on one of the pttys you create and then use that to open one with that termios. So you'd do both of these in the same test. I'd make that a separate test than the one you already have that is testing reading & writing from a master/slave pair.
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.
Huh, I'm pretty sure it is on Linux-based platforms at least. From my understanding, the terminal emulator spawns a pty, gives the slave (or master? one of them) to the shell program, and draws stuff to the screen based on what it receives on its end. Anyways, that fix did it, both tests passing on all important test cases
src/pty.rs
Outdated
/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's | ||
/// terminal settings of the slave will be set to the values in `termios`. | ||
#[inline] | ||
pub fn openpty(winsize: Option<Winsize>, termios: Option<Termios>) -> Result<OpenptyResult> { |
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.
First, can't both of be borrows?
Second, we should be able to use a slightly different function declaration to give us better ergonomics when using a real struct for either of the arguments, something like:
pub fn openpty<T: Into<Option<&Winsize>>, U: Into<Option<&Termios>>>(winsize: T, termios: U) -> ... {
So now you can use .into()
to convert the options to the struct representations and the caller doesn't need to wrap their struct reference in a Some
. I don't know if the syntax above is exactly correct, but I think it should be. The gtk-rs project did this quite successfully for all their string types and it's nice (here is an example).
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.
Fixed
60d4319
to
b6ed40d
Compare
@cactorium Can you please also add an entry to the CHANGELOG? |
c59e711
to
4909877
Compare
test/test_pty.rs
Outdated
#[test] | ||
fn test_openpty() { | ||
let pty = openpty(None, None).unwrap(); | ||
assert!(pty.master > 0); // must be valid file descriptors |
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.
Please capitalize the "m" in "must" and move this comment to the above line if you want to keep it, though I don't see this comment as very useful. Maybe just remove these trailing comments from the code.
Can you add another test using a valid winsize argument? I can't easily figure out what that struct is, but it'd be nice to have verification that that works as well. |
Well, that sets the size of the terminal window, and there's AFAIK really no nice way to test for it that doesn't involve |
☔ The latest upstream changes (presumably ba5c837) made this pull request unmergeable. Please resolve the merge conflicts. |
@cactorium Can you rebase this now that #556 just merged? |
Done |
src/pty.rs
Outdated
use sys::termios::Termios; | ||
use {Errno, Result, Error, fcntl}; | ||
|
||
pub struct OpenptyResult { |
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 needs a doccomment since it's a public type.
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.
Done
src/pty.rs
Outdated
c_winsize as *mut Winsize) | ||
}; | ||
|
||
let _ = try!(Errno::result(ret)); |
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.
Can't this just be Errno::result(ret)?;
instead? Can you explain what this line is doing for me?
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.
Fixed! I forgot about the new ?
operator, which is why I used a try!
instead
test/test.rs
Outdated
@@ -13,6 +13,7 @@ mod sys; | |||
mod test_fcntl; | |||
mod test_net; | |||
mod test_nix_path; | |||
mod test_pty; |
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.
Yeah, we should really alphabetize this list.
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.
Done
test/test_pty.rs
Outdated
assert!(pty.master > 0); | ||
assert!(pty.slave > 0); | ||
|
||
// writing to one should be readable on the other one |
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.
Can you capitalize the first word in your line comments? Please do that to all of them as well.
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.
Fixed
assert_eq!(len, echoed_string2.len()); | ||
assert_eq!(&buf[0..len], echoed_string2.as_bytes()); | ||
|
||
close(pty.master).unwrap(); |
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.
Don't you normally want to close the slave first? Is there anywhere that suggest that closing the master will close the slave as well at the OS-level?
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.
I'm not sure; the best documentation I could find seemed to imply either way was okay (although nothing implies that closing either end will close the other one):
If fildes refers to the master side of a pseudo-terminal, and this is the last close, a SIGHUP signal shall be sent to the controlling process, if any, for which the slave side of the pseudo-terminal is the controlling terminal. It is unspecified whether closing the master side of the pseudo-terminal flushes all queued input and output.
If fildes refers to the slave side of a STREAMS-based pseudo-terminal, a zero-length message may be sent to the master.
Sorry for taking so long to push changes, it's been a busy few weeks |
54c46ff
to
66cd9af
Compare
Didn't notice the build fail, it's fixed now |
Looks good. Now just blocking on #590. |
@cactorium Can you rebase this on HEAD now that our new testing framework has merged? This is RTM after it passes those tests. |
Done |
@asomers Can you check into why your FreeBSD buildbot isn't running? |
Isn't that just disabled? It's got that DISABLE_TESTS=1 flag on all the recent builds I looked at: https://travis-ci.org/nix-rust/nix/builds |
It's not run through Travis CI. We have a separate build server that runs tests on FreeBSD. @asomers runs it. |
Buildbot saw the most recent change, yet did not decide to do a build. I'll dig deeper after I get home tonight. |
I couldn't find anything obviously wrong with the BuildBot server. I've written to the mailing list for help. but in the meantime, I suggest we don't hold up PRs waiting for it to complete. Let's go ahead and merge anything compiles for i686-unknown-freebsd, which is done through Travis. |
bors r+ |
Build succeeded |
Lemme know if anything needs to be fixed