diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4310d47ff..a95f9067dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#582](https://github.com/nix-rust/nix/pull/582)
- Added `nix::unistd::{openat, fstatat, readlink, readlinkat}`
([#551](https://github.com/nix-rust/nix/pull/551))
+- Added `nix::ptr::openpty`
+ ([#456](https://github.com/nix-rust/nix/pull/456))
### Changed
- Marked `sys::mman::{ mmap, munmap, madvise, munlock, msync }` as unsafe.
diff --git a/src/lib.rs b/src/lib.rs
index ecbf139dc6..56ed5c3fa8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -44,6 +44,8 @@ pub mod mount;
#[cfg(target_os = "linux")]
pub mod mqueue;
+pub mod pty;
+
#[cfg(any(target_os = "linux", target_os = "macos"))]
pub mod poll;
diff --git a/src/pty.rs b/src/pty.rs
new file mode 100644
index 0000000000..d07e7684a5
--- /dev/null
+++ b/src/pty.rs
@@ -0,0 +1,52 @@
+use libc;
+
+use {Errno, Result};
+use std::os::unix::io::RawFd;
+
+use sys::termios::Termios;
+
+pub use libc::pid_t as SessionId;
+pub use libc::winsize as Winsize;
+
+pub struct OpenptyResult {
+ pub master: RawFd,
+ pub slave: RawFd,
+}
+
+/// Create a new pseudoterminal, returning the slave and master file descriptors
+/// in `OpenptyResult`
+/// (see [openpty](http://man7.org/linux/man-pages/man3/openpty.3.html)).
+///
+/// If `winsize` is not `None`, the window size of the slave will be set to
+/// 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<'a, 'b, T: Into