Skip to content
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

Provide and emulate ptsname_r on macOS and iOS by using the TIOCPTYGNAME syscall. #742

Closed

Conversation

nelsonjchen
Copy link
Contributor

This provides a thread-safe alternative to ptsname() and compatibility for existing projects using ptsname_r() on macOS.

So, I'm not sure if this belongs in nix. Would this fall under the "but to unify what can" aspect?

@Susurrus
Copy link
Contributor

@nelsonjchen This isn't something that's currently done in nix as far as I know, emulating functionality, and I'm not certain where I stand on this quite yet. But one thing that would help would be hearing what your specific use case is for this? Given that this functionality isn't provided by mac directly, and that mac also supports posix_openpt I'm not certain how much of a use there is for this and whether nix should bear the support costs of providing it.

…AME syscall.

This provides a thread-safe alternative to ptsname() and compatibility
for existing projects using ptsname_r() on macOS.
@nelsonjchen
Copy link
Contributor Author

nelsonjchen commented Aug 23, 2017

@Susurrus

I'm not sure how the availability of posix_openpt support on the Mac relates here. It's great it is but it does not provide ptsname functionality and I'm using it but I think the addition of a thread-safe ptsname or just a straight ptsname_r that's thread safe would be a great help to anyone wanting to doing work with master and slave terminals in macOS and to keep the nix API feeling Rusty.

My use case is that I would like to write a Rust application that simulates a device on the other end of a serial port in macOS and Linux. If I want to use the "UI" of this simulated device, I would need to know what the corresponding slave terminal device is and would need some form of ptsname functionality to be able to point whatever at the slave terminal device aka. emulated serial port. I would like this application to have minimal to no change between the two OSes. I greatly prefer to use thread-safe APIs wherever possible as surprising things can will happen when a non-thread-safe API is used if I was offered a choice. On macOS, I can only use ptsname from nix which is not thread safe and not ptsname_r which is thread safe.

With ptsname, I guess I could implement my own static mutex lock around ptsname to get past that issue. But, should there even be these kinds of concerns or workarounds about memory access when using Rust outside of unsafe? Runtime error and panic stuff with Rc's and Cells are one thing but memory concurrency issues are another. The Rust developers and community go on and on about "fearless concurrency" and using ptsname as-is in nix sure makes me fear even though it's outside of unsafe. Mentioning that it's not thread safe in the comment doesn't feel like a very Rusty API or approach and I think nix falls a tad bit short there. Use of ptsname in nix just doesn't feel safe nor Rusty to me.

I too have some doubts about this PR and I couldn't find any precedent so I figure it might be good to just use this issue to set some precedent for nix and to refer others to this approach or a possible externalized functionality filler crate if it doesn't get in.

I think I'm at least the third person using Rust to want a simple ptsname_r-like functionality on macOS that behaves much like the one on Linux.

As cited in the code, this is derived from two other examples of this kind of code out there:

  • This guy, who came up with most of this approach, was using it for what I'm assuming is something work related at some large hosting provider. I'm not sure what purpose he was exactly using it for but he had a need for ptsname_r functionality. He's not using nix, but I can see that he cfg gates his similar nix-like wrappers to the OS. I'm guessing that he also wants to maintain a similar API between Linux and macOS. This version was the basis for the following reference.

  • My other reference is doing a pexpect clone. To do a pexpect clone, he has to open the slave terminal by its name which he had to find through ptsname_r and then assign them to the correct descriptors before calling exec in the child. Unlike the first reference, he uses nix, but polyfills in pretty much this implementation of ptsname_r for macOS where nix/macOS falls short. Like me, and the previous example, he also fills in the gap with a similar API for macOS that emulates the Linux version.

@asomers
Copy link
Member

asomers commented Aug 23, 2017

My feeling is that this wrapper is outside of the scope of nix. However, you raise an interesting point. Since mutable global variables are always considered unsafe by Rust, nix's ptsname function should also be unsafe. We can't simply add a mutex in nix's ptsname wrapper, because a Rust program could access both nix::ptsname and libc::ptsname directly.

nelsonjchen added a commit to nelsonjchen/nix that referenced this pull request Aug 24, 2017
On some platforms, `ptsname()` mutates global variables and mutating
global variables is always considered `unsafe` by Rust.

Reference:

nix-rust#742 (comment)
nelsonjchen added a commit to nelsonjchen/nix that referenced this pull request Aug 24, 2017
On some platforms, `ptsname()` mutates global variables and mutating
global variables is always considered `unsafe` by Rust.

Reference:

nix-rust#742 (comment)
nelsonjchen added a commit to nelsonjchen/nix that referenced this pull request Aug 24, 2017
On some platforms, `ptsname()` mutates global variables and mutating
global variables is always considered `unsafe` by Rust.

Reference:

nix-rust#742 (comment)
nelsonjchen added a commit to nelsonjchen/nix that referenced this pull request Aug 24, 2017
On all platforms, `ptsname()` mutates global variables and mutating
global variables is always considered `unsafe` by Rust.

Reference:

nix-rust#742 (comment)
nelsonjchen added a commit to nelsonjchen/nix that referenced this pull request Aug 24, 2017
`ptsname()` mutates global variables and mutating global variables is
always considered `unsafe` by Rust.

Reference:

nix-rust#742 (comment)
nelsonjchen added a commit to nelsonjchen/nix that referenced this pull request Aug 24, 2017
`ptsname()` mutates global variables and mutating global variables is
always considered `unsafe` by Rust.

Reference:

nix-rust#742 (comment)
bors bot added a commit that referenced this pull request Aug 25, 2017
744: Mark and document pty::ptsname() as unsafe r=asomers a=nelsonjchen

On some platforms, `ptsname()` mutates global variables and mutating
global variables is always considered `unsafe` by Rust.

Reference:

#742 (comment)
@Susurrus
Copy link
Contributor

I'm also in agreement that ptsname_r shouldn't be emulated by nix. This is in line with our stance that syscalls shouldn't be supported by nix directly. I'm closing in this in favor of an external library covering this use case.

@Susurrus Susurrus closed this Aug 25, 2017
asomers pushed a commit to asomers/nix that referenced this pull request Sep 3, 2017
`ptsname()` mutates global variables and mutating global variables is
always considered `unsafe` by Rust.

Reference:

nix-rust#742 (comment)
@nelsonjchen
Copy link
Contributor Author

I've since moved this into its own external library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants