Nix ptsname_r() Shim

Build Status

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.

```rust extern crate nix; use nix::fcntl::ORDWR; use nix::pty::{posixopenpt, ptsname_r};

fn main() { let masterfd = posixopenpt(ORDWR).unwrap(); let slavename = ptsnamer(&masterfd).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.

```rust extern crate nix; use nix::fcntl::ORDWR; // Remove use of Nix's ptsnamer use nix::pty::posix_openpt;

// Add this crate and use its ptsnamer extern crate nixptsnamershim; use nixptsnamershim::ptsnamer;

fn main() { let masterfd = posixopenpt(ORDWR).unwrap(); let slavename = ptsnamer(&masterfd).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:

License

Licensed under either of

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.