4 releases
Uses old Rust 2015
0.2.0 | Sep 22, 2018 |
---|---|
0.1.3 | Oct 16, 2017 |
0.1.2 | Oct 4, 2017 |
0.1.1 | Oct 4, 2017 |
#713 in Unix APIs
11KB
78 lines
Nix ptsname_r()
Shim
Using this shim's ptsname_r()
over Nix's ptsname_r()
on Linux will make your application portable to macOS with regards to ptsname_r()
. The ptsname_r()
exposed by this crate will simply reference Nix's original ptsname_r()
on Linux and use its shim on macOS. The signature of the function is identical and the behavior is identical.
Usage
Here's an example of how to convert and use this shim for an existing program using ptsname_r
from Nix.
Before
Using Nix's ptsname_r()
, which is not available on macOS.
extern crate nix;
use nix::fcntl::O_RDWR;
use nix::pty::{posix_openpt, ptsname_r};
fn main() {
let master_fd = posix_openpt(O_RDWR).unwrap();
let slave_name = ptsname_r(&master_fd).unwrap();
println!("Slave Name was: {}", slave_name);
}
After
Using Nix ptsname_r()
Shim's ptsname_r()
, which makes equivalent functionality available on macOS but falls back to Nix's ptsname_r()
on other platforms.
extern crate nix;
use nix::fcntl::O_RDWR;
// Remove use of Nix's ptsname_r
use nix::pty::posix_openpt;
// Add this crate and use its ptsname_r
extern crate nix_ptsname_r_shim;
use nix_ptsname_r_shim::ptsname_r;
fn main() {
let master_fd = posix_openpt(O_RDWR).unwrap();
let slave_name = ptsname_r(&master_fd).unwrap();
println!("Slave Name was: {}", slave_name);
}
Background
In POSIX, ptsname()
is used on a file descriptor created by posix_openpt
to get the name of the slave psuedoterminal.
Unfortunately, ptsname()
modifies global variables in order to return a pointer to the modified variables with the name of the slave in it. In Rust's Nix, this is interpreted as unsafe. It is also not thread-safe and can cause issues during signal handling amongst other issues. Thus, the implementation in Nix is marked as unsafe
.
In response, at least on the Linux platform, there is a function called ptsname_r()
which is a re-entrant and safer version of ptsname()
as it writes to a buffer the caller provides. In Nix, it allocates a buffer and wraps it into an owned String
to make it safe.
Unfortunately, macOS/Darwin does not include the ptsname_r()
function. Alternatively, you are to use the TIOCPTYGNAME
syscall with the master file descriptor and a buffer pointer as the argument. It's almost like ptsname_r()
but it's different nevertheless.
It was determined that it was not in the scope of Nix to include shims such as this for platforms that do in fact have the functionality but the underlying calls are different.. Emulated functionality should be moved to an outside crate.
It's out of scope, but a shim like this is desired, as can be demonstrated with the following two examples who have implemented similar shims:
-
This example is the first I've found with this approach. The author was using it for what I'm assuming is something work related at some large hosting provider. I'm not sure what purpose the author was exactly using it for but the author had a need for
ptsname_r
functionality. The author was not usingnix
, but I can see that the authorcfg
gates their similarnix
-like wrappers to the OS. I'm guessing that the author also wants to maintain a similar API between Linux and macOS. This version might have been the basis for the following reference. -
My other example is doing a pexpect clone. To do a pexpect clone, the author 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, the author usesnix
, but polyfills in pretty much this implementation ofptsname_r
for macOS wherenix
/macOS falls short. Like me, and the previous example, the author also fills in the gap with a similar API for macOS that emulates the Linux version.
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Dependencies
~1.5MB
~36K SLoC