summaryrefslogtreecommitdiff
path: root/test/test.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-12-08 16:10:25 +0000
committerGitHub <noreply@github.com>2022-12-08 16:10:25 +0000
commita2356abe578dc822dbaf4386fbc17a63385ba0f8 (patch)
tree24d6303c4083960790f6fe03323fd595498e4755 /test/test.rs
parent7f18847f4d59390698c62e2fd5a609cef2439673 (diff)
parent8f52bc97c96922f61140948eacabf966712d105e (diff)
downloadnix-a2356abe578dc822dbaf4386fbc17a63385ba0f8.zip
Merge #1921
1921: feat: I/O safety for 'sys/termios' & 'pty' r=asomers a=SteveLauC #### What this PR does: 1. Adds I/O safety for modules `sys/termios` and `pty` ------ #### Known Problems: 1. [Double free issue on `PtyMaster`](https://github.com/nix-rust/nix/issues/659) I have changed the `RawFd` in `PtyMaster` to `OwnedFd` in this PR, with this change, the double-free issue still exists, see this test code snippet (From [this comment](https://github.com/nix-rust/nix/issues/659#issuecomment-315544022)) ```rust use std::io::prelude::*; use std::os::unix::io::AsRawFd; fn main() { let mut f = { let m = nix::pty::posix_openpt(nix::fcntl::OFlag::O_RDWR).unwrap(); // get fd 3 nix::unistd::close(m.as_raw_fd()).unwrap(); // close fd 3 std::fs::File::create("foo").unwrap() // get fd 3 again }; // m goes out of scope, `drop(OwnedFd)`, fd 3 closed f.write("whatever".as_bytes()).unwrap(); // EBADF } ``` I have tested this code with `nix 0.26.1`, and I am still getting `EBADF`, which means the current impl does not prevent this problem either. ```shell $ cat Cargo.toml | grep nix nix = "0.26.1" $ cargo r -q thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 9, kind: Uncategorized, message: "Bad file descriptor" }', src/main.rs:10:36 ``` If we still wanna the drop of `PtyMaster` panic when the internal `fd` is invalid as we did in #677, then we have to revert the changes to use `RawFd` and manually impl `Drop`. 2. Some trait implementations for some types are removed * `struct OpenptyResult`: 1. PartialEq 2. Eq 3. Hash 4. Clone * `struct ForkptyResult`: 1. Clone * `struct PtyMaster`: 1. PartialEq 2. Eq 3. Hash In the previous implementation, these trait impls are `#[derive()]`ed, due to the type change to `OwnedFd`, we can no longer derive them. Should we manually implement them? I kinda think we should at least impl `PartialEq` and `Eq` for `OpenptyResult` and `PtyMaster`. ----- #### Some Clarifications that may help code review 1. For the basic `fd`-related syscall like `read(2)`, `write(2)` and `fcntl(2)` , I am still using the old `RawFd` interfaces, as they will be covered in other PRs. 2. Two helper functions 1. `write_all()` in `test/sys/test_termios.rs`: ```rust /// Helper function analogous to `std::io::Write::write_all`, but for `RawFd`s fn write_all(f: RawFd, buf: &[u8]) { /// Helper function analogous to `std::io::Write::write_all`, but for `Fd`s fn write_all<Fd: AsFd>(f: &Fd, buf: &[u8]) { let mut len = 0; while len < buf.len() { len += write(f, &buf[len..]).unwrap(); len += write(f.as_fd().as_raw_fd(), &buf[len..]).unwrap(); } } ``` 2. `read_exact()` in `test/test.rs`: ```rust /// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s fn read_exact(f: RawFd, buf: &mut [u8]) { /// Helper function analogous to `std::io::Read::read_exact`, but for `Fd`s fn read_exact<Fd: AsFd>(f: &Fd, buf: &mut [u8]) { let mut len = 0; while len < buf.len() { // get_mut would be better than split_at_mut, but it requires nightly let (_, remaining) = buf.split_at_mut(len); len += read(f, remaining).unwrap(); len += read(f.as_fd().as_raw_fd(), remaining).unwrap(); } } ``` I have added I/O safety for them, but it actually does not matter whether they use `Fd: AsFd` or `RawFd`. So feel free to ask me to discard these changes if you guys don't like it. Co-authored-by: Steve Lau <stevelauc@outlook.com>
Diffstat (limited to 'test/test.rs')
-rw-r--r--test/test.rs8
1 files changed, 4 insertions, 4 deletions
diff --git a/test/test.rs b/test/test.rs
index 6b42aad9..b139ec3a 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -66,16 +66,16 @@ mod test_unistd;
use nix::unistd::{chdir, getcwd, read};
use parking_lot::{Mutex, RwLock, RwLockWriteGuard};
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
use std::path::PathBuf;
-/// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s
-fn read_exact(f: RawFd, buf: &mut [u8]) {
+/// Helper function analogous to `std::io::Read::read_exact`, but for `Fd`s
+fn read_exact<Fd: AsFd>(f: &Fd, buf: &mut [u8]) {
let mut len = 0;
while len < buf.len() {
// get_mut would be better than split_at_mut, but it requires nightly
let (_, remaining) = buf.split_at_mut(len);
- len += read(f, remaining).unwrap();
+ len += read(f.as_fd().as_raw_fd(), remaining).unwrap();
}
}