From dd3abcfe267872adfcec975e18f53a5ca4bc54c7 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 25 Jul 2023 13:26:25 +0200 Subject: [PATCH 1/7] Fix Clippy warnings --- src/event/source.rs | 6 +++--- src/interest.rs | 2 +- src/io_source.rs | 6 +++--- src/net/tcp/stream.rs | 20 ++++++++++---------- src/net/uds/stream.rs | 20 ++++++++++---------- src/sys/unix/pipe.rs | 20 ++++++++++---------- src/sys/unix/selector/kqueue.rs | 2 +- src/sys/unix/uds/mod.rs | 4 ++-- src/waker.rs | 2 +- tests/interest.rs | 2 +- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/event/source.rs b/src/event/source.rs index f38268ab6..ae595420c 100644 --- a/src/event/source.rs +++ b/src/event/source.rs @@ -121,7 +121,7 @@ where token: Token, interests: Interest, ) -> io::Result<()> { - (&mut **self).register(registry, token, interests) + (**self).register(registry, token, interests) } fn reregister( @@ -130,10 +130,10 @@ where token: Token, interests: Interest, ) -> io::Result<()> { - (&mut **self).reregister(registry, token, interests) + (**self).reregister(registry, token, interests) } fn deregister(&mut self, registry: &Registry) -> io::Result<()> { - (&mut **self).deregister(registry) + (**self).deregister(registry) } } diff --git a/src/interest.rs b/src/interest.rs index ee5158ab5..59b330a3f 100644 --- a/src/interest.rs +++ b/src/interest.rs @@ -163,7 +163,7 @@ impl fmt::Debug for Interest { one = true } } - #[cfg(any(target_os = "freebsd"))] + #[cfg(target_os = "freebsd")] { if self.is_lio() { if one { diff --git a/src/io_source.rs b/src/io_source.rs index 6939c0d03..27f505d14 100644 --- a/src/io_source.rs +++ b/src/io_source.rs @@ -230,7 +230,7 @@ impl SelectorId { /// Associate an I/O source with `registry`, returning an error if its /// already registered. fn associate(&self, registry: &Registry) -> io::Result<()> { - let registry_id = poll::selector(®istry).id(); + let registry_id = poll::selector(registry).id(); let previous_id = self.id.swap(registry_id, Ordering::AcqRel); if previous_id == Self::UNASSOCIATED { @@ -247,7 +247,7 @@ impl SelectorId { /// error if its registered with a different `Registry` or not registered at /// all. fn check_association(&self, registry: &Registry) -> io::Result<()> { - let registry_id = poll::selector(®istry).id(); + let registry_id = poll::selector(registry).id(); let id = self.id.load(Ordering::Acquire); if id == registry_id { @@ -268,7 +268,7 @@ impl SelectorId { /// Remove a previously made association from `registry`, returns an error /// if it was not previously associated with `registry`. fn remove_association(&self, registry: &Registry) -> io::Result<()> { - let registry_id = poll::selector(®istry).id(); + let registry_id = poll::selector(registry).id(); let previous_id = self.id.swap(Self::UNASSOCIATED, Ordering::AcqRel); if previous_id == registry_id { diff --git a/src/net/tcp/stream.rs b/src/net/tcp/stream.rs index cdbd46a48..48d18884e 100644 --- a/src/net/tcp/stream.rs +++ b/src/net/tcp/stream.rs @@ -174,49 +174,49 @@ impl TcpStream { impl Read for TcpStream { fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.inner.do_io(|inner| (&*inner).read(buf)) + self.inner.do_io(|mut inner| inner.read(buf)) } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.inner.do_io(|inner| (&*inner).read_vectored(bufs)) + self.inner.do_io(|mut inner| inner.read_vectored(bufs)) } } impl<'a> Read for &'a TcpStream { fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.inner.do_io(|inner| (&*inner).read(buf)) + self.inner.do_io(|mut inner| inner.read(buf)) } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.inner.do_io(|inner| (&*inner).read_vectored(bufs)) + self.inner.do_io(|mut inner| inner.read_vectored(bufs)) } } impl Write for TcpStream { fn write(&mut self, buf: &[u8]) -> io::Result { - self.inner.do_io(|inner| (&*inner).write(buf)) + self.inner.do_io(|mut inner| inner.write(buf)) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - self.inner.do_io(|inner| (&*inner).write_vectored(bufs)) + self.inner.do_io(|mut inner| inner.write_vectored(bufs)) } fn flush(&mut self) -> io::Result<()> { - self.inner.do_io(|inner| (&*inner).flush()) + self.inner.do_io(|mut inner| inner.flush()) } } impl<'a> Write for &'a TcpStream { fn write(&mut self, buf: &[u8]) -> io::Result { - self.inner.do_io(|inner| (&*inner).write(buf)) + self.inner.do_io(|mut inner| inner.write(buf)) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - self.inner.do_io(|inner| (&*inner).write_vectored(bufs)) + self.inner.do_io(|mut inner| inner.write_vectored(bufs)) } fn flush(&mut self) -> io::Result<()> { - self.inner.do_io(|inner| (&*inner).flush()) + self.inner.do_io(|mut inner| inner.flush()) } } diff --git a/src/net/uds/stream.rs b/src/net/uds/stream.rs index f21d9e7ba..7715612a3 100644 --- a/src/net/uds/stream.rs +++ b/src/net/uds/stream.rs @@ -73,49 +73,49 @@ impl UnixStream { impl Read for UnixStream { fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.inner.do_io(|inner| (&*inner).read(buf)) + self.inner.do_io(|mut inner| inner.read(buf)) } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.inner.do_io(|inner| (&*inner).read_vectored(bufs)) + self.inner.do_io(|mut inner| inner.read_vectored(bufs)) } } impl<'a> Read for &'a UnixStream { fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.inner.do_io(|inner| (&*inner).read(buf)) + self.inner.do_io(|mut inner| inner.read(buf)) } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.inner.do_io(|inner| (&*inner).read_vectored(bufs)) + self.inner.do_io(|mut inner| inner.read_vectored(bufs)) } } impl Write for UnixStream { fn write(&mut self, buf: &[u8]) -> io::Result { - self.inner.do_io(|inner| (&*inner).write(buf)) + self.inner.do_io(|mut inner| inner.write(buf)) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - self.inner.do_io(|inner| (&*inner).write_vectored(bufs)) + self.inner.do_io(|mut inner| inner.write_vectored(bufs)) } fn flush(&mut self) -> io::Result<()> { - self.inner.do_io(|inner| (&*inner).flush()) + self.inner.do_io(|mut inner| inner.flush()) } } impl<'a> Write for &'a UnixStream { fn write(&mut self, buf: &[u8]) -> io::Result { - self.inner.do_io(|inner| (&*inner).write(buf)) + self.inner.do_io(|mut inner| inner.write(buf)) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - self.inner.do_io(|inner| (&*inner).write_vectored(bufs)) + self.inner.do_io(|mut inner| inner.write_vectored(bufs)) } fn flush(&mut self) -> io::Result<()> { - self.inner.do_io(|inner| (&*inner).flush()) + self.inner.do_io(|mut inner| inner.flush()) } } diff --git a/src/sys/unix/pipe.rs b/src/sys/unix/pipe.rs index ccf5252d5..3c43c89b6 100644 --- a/src/sys/unix/pipe.rs +++ b/src/sys/unix/pipe.rs @@ -244,29 +244,29 @@ impl event::Source for Sender { impl Write for Sender { fn write(&mut self, buf: &[u8]) -> io::Result { - self.inner.do_io(|sender| (&*sender).write(buf)) + self.inner.do_io(|mut inner| inner.write(buf)) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - self.inner.do_io(|sender| (&*sender).write_vectored(bufs)) + self.inner.do_io(|mut inner| inner.write_vectored(bufs)) } fn flush(&mut self) -> io::Result<()> { - self.inner.do_io(|sender| (&*sender).flush()) + self.inner.do_io(|mut inner| inner.flush()) } } impl Write for &Sender { fn write(&mut self, buf: &[u8]) -> io::Result { - self.inner.do_io(|sender| (&*sender).write(buf)) + self.inner.do_io(|mut inner| inner.write(buf)) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - self.inner.do_io(|sender| (&*sender).write_vectored(bufs)) + self.inner.do_io(|mut inner| inner.write_vectored(bufs)) } fn flush(&mut self) -> io::Result<()> { - self.inner.do_io(|sender| (&*sender).flush()) + self.inner.do_io(|mut inner| inner.flush()) } } @@ -341,21 +341,21 @@ impl event::Source for Receiver { impl Read for Receiver { fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.inner.do_io(|sender| (&*sender).read(buf)) + self.inner.do_io(|mut inner| inner.read(buf)) } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.inner.do_io(|sender| (&*sender).read_vectored(bufs)) + self.inner.do_io(|mut inner| inner.read_vectored(bufs)) } } impl Read for &Receiver { fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.inner.do_io(|sender| (&*sender).read(buf)) + self.inner.do_io(|mut inner| inner.read(buf)) } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.inner.do_io(|sender| (&*sender).read_vectored(bufs)) + self.inner.do_io(|mut inner| inner.read_vectored(bufs)) } } diff --git a/src/sys/unix/selector/kqueue.rs b/src/sys/unix/selector/kqueue.rs index b36a5375e..b7a01a51c 100644 --- a/src/sys/unix/selector/kqueue.rs +++ b/src/sys/unix/selector/kqueue.rs @@ -285,7 +285,7 @@ fn kevent_register( Err(err) } }) - .and_then(|()| check_errors(&changes, ignored_errors)) + .and_then(|()| check_errors(changes, ignored_errors)) } /// Check all events for possible errors, it returns the first error found. diff --git a/src/sys/unix/uds/mod.rs b/src/sys/unix/uds/mod.rs index 3ec829f0c..bfce4563b 100644 --- a/src/sys/unix/uds/mod.rs +++ b/src/sys/unix/uds/mod.rs @@ -40,7 +40,7 @@ cfg_os_poll! { sockaddr.sun_family = libc::AF_UNIX as libc::sa_family_t; let bytes = path.as_os_str().as_bytes(); - match (bytes.get(0), bytes.len().cmp(&sockaddr.sun_path.len())) { + match (bytes.first(), bytes.len().cmp(&sockaddr.sun_path.len())) { // Abstract paths don't need a null terminator (Some(&0), Ordering::Greater) => { return Err(io::Error::new( @@ -64,7 +64,7 @@ cfg_os_poll! { let offset = path_offset(&sockaddr); let mut socklen = offset + bytes.len(); - match bytes.get(0) { + match bytes.first() { // The struct has already been zeroes so the null byte for pathname // addresses is already there. Some(&0) | None => {} diff --git a/src/waker.rs b/src/waker.rs index bc73029d3..e3b27ba6d 100644 --- a/src/waker.rs +++ b/src/waker.rs @@ -84,7 +84,7 @@ impl Waker { pub fn new(registry: &Registry, token: Token) -> io::Result { #[cfg(debug_assertions)] registry.register_waker(); - sys::Waker::new(poll::selector(®istry), token).map(|inner| Waker { inner }) + sys::Waker::new(poll::selector(registry), token).map(|inner| Waker { inner }) } /// Wake up the [`Poll`] associated with this `Waker`. diff --git a/tests/interest.rs b/tests/interest.rs index 1d77964ad..1eb27ceb1 100644 --- a/tests/interest.rs +++ b/tests/interest.rs @@ -34,7 +34,7 @@ fn fmt_debug() { { assert_eq!(format!("{:?}", Interest::AIO), "AIO"); } - #[cfg(any(target_os = "freebsd"))] + #[cfg(target_os = "freebsd")] { assert_eq!(format!("{:?}", Interest::LIO), "LIO"); } From 0b130cc10cbcd7b2e22cc38c59b2d59dadbc70b0 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 25 Jul 2023 15:11:15 +0200 Subject: [PATCH 2/7] Update to FreeBSD 12.4 in CI Matching what we use to test v0.8. --- .cirrus.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 3c359c074..a90b9dd36 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,5 +1,5 @@ freebsd_instance: - image: freebsd-12-2-release-amd64 + image: freebsd-12-4-release-amd64 env: RUST_BACKTRACE: full @@ -7,8 +7,7 @@ env: task: name: FreeBSD setup_script: - - pkg install -y curl - - curl https://sh.rustup.rs -sSf --output rustup.sh + - fetch https://sh.rustup.rs -o rustup.sh - sh rustup.sh -y --profile minimal cargo_cache: folder: $HOME/.cargo/registry From dc9f71df1d8436cbef86e32138eba22806cb42ba Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 25 Jul 2023 15:13:01 +0200 Subject: [PATCH 3/7] Add GitHub Actions based CI to v0.7 This matches v0.8 CI. --- .github/workflows/ci.yml | 144 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..fe50a343d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,144 @@ +name: CI +on: + push: + branches: [ "master", "v0.7.x" ] + pull_request: + branches: [ "master", "v0.7.x" ] +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: full + CI: true + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + Test: + runs-on: ${{ matrix.os }} + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + os: ["ubuntu-latest", "macos-latest", "windows-latest"] + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@stable + - name: Install Cargo-hack + run: cargo install --debug cargo-hack + - name: Check all features + run: cargo hack check --feature-powerset + - name: Tests + run: cargo test --all-features + - name: Tests release build + run: cargo test --release --all-features + MinimalVersions: + runs-on: ${{ matrix.os }} + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + os: ["ubuntu-latest", "macos-latest", "windows-latest"] + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@nightly + - name: Install minimal verions + run: cargo update -Zminimal-versions + - name: Tests + run: cargo test --all-features + MSRV: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master + with: + # NOTE: When updating also update Clippy flags, some are disabled due to + # MSRV. + toolchain: 1.46.0 + - name: Check + # We only run check allowing us to use newer features in tests. + # We enable all features except for the `log` feature as since log v0.4.19 + # it requires a MSRV later then rustc 1.46. + run: cargo check --no-default-features --features os-poll,os-ext,net + Nightly: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@nightly + - name: Tests + run: cargo test --all-features + Clippy: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - name: Clippy + # NOTE: `clippy::uninlined-format-args` is enabled due to MSRV. + run: cargo clippy --all-targets --all-features -- -D warnings -A clippy::cognitive-complexity -A clippy::uninlined-format-args + Docs: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@stable + - name: Check docs + run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features + Rustfmt: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: Check formatting + # FIXME: for some reason this doesn't actually check all files. + # So instead we run `rustfmt` directly on each file. + #cargo fmt --all -- --check + run: find src tests examples -type f -iname "*.rs" | xargs rustfmt --check + CheckTargets: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - name: Install all targets + run: make install_targets + - name: Install Cargo-hack + run: cargo install --debug cargo-hack + - name: Check all targets + run: make check_all_targets + Sanitizer: + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + sanitizer: [address, leak, memory, thread] + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@nightly + - name: Add rust source + run: rustup component add rust-src + - name: Run tests with sanitizer + run: make test_sanitizer SAN=${{ matrix.sanitizer }} + # Single job required to merge the pr. + Passed: + runs-on: ubuntu-latest + needs: + - Test + - MinimalVersions + - MSRV + - Nightly + - Clippy + - Docs + - Rustfmt + - CheckTargets + steps: + - run: exit 0 From 87d71a2a02d6cdf7622b9cb7872748c2a77ef08c Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 25 Jul 2023 15:18:19 +0200 Subject: [PATCH 4/7] Silence dead_code lint for TcpKeepalive For various combination of the feature we can sometimes end up with TcpKeepalive's fields not being used. Since we know that they are used with other features the simplest solution is to just ignore the list for now. --- src/net/tcp/socket.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/net/tcp/socket.rs b/src/net/tcp/socket.rs index 69fbacf68..c831c38ec 100644 --- a/src/net/tcp/socket.rs +++ b/src/net/tcp/socket.rs @@ -24,6 +24,7 @@ pub struct TcpSocket { /// Configures a socket's TCP keepalive parameters. #[derive(Debug, Default, Clone)] +#[allow(dead_code)] pub struct TcpKeepalive { pub(crate) time: Option, #[cfg(any( From 7bc6eda849829ea0288e183a466a03dd870cc4cb Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 25 Jul 2023 20:33:19 +0200 Subject: [PATCH 5/7] Remove Sanitizer from v0.7 CI Never added it to the Makefile. --- .github/workflows/ci.yml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe50a343d..ab328e13c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,7 +78,7 @@ jobs: components: clippy - name: Clippy # NOTE: `clippy::uninlined-format-args` is enabled due to MSRV. - run: cargo clippy --all-targets --all-features -- -D warnings -A clippy::cognitive-complexity -A clippy::uninlined-format-args + run: cargo clippy --all-features -- -D warnings -A clippy::cognitive-complexity -A clippy::uninlined-format-args Docs: runs-on: ubuntu-latest timeout-minutes: 10 @@ -114,20 +114,6 @@ jobs: run: cargo install --debug cargo-hack - name: Check all targets run: make check_all_targets - Sanitizer: - runs-on: ubuntu-latest - timeout-minutes: 10 - strategy: - fail-fast: false - matrix: - sanitizer: [address, leak, memory, thread] - steps: - - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@nightly - - name: Add rust source - run: rustup component add rust-src - - name: Run tests with sanitizer - run: make test_sanitizer SAN=${{ matrix.sanitizer }} # Single job required to merge the pr. Passed: runs-on: ubuntu-latest From 1e25feb0156eff19157ec64a15e1c23516341365 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 25 Jul 2023 20:33:43 +0200 Subject: [PATCH 6/7] Remove unused raw_socket from SockState --- src/sys/windows/selector.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sys/windows/selector.rs b/src/sys/windows/selector.rs index 572a9a905..5d8ca642f 100644 --- a/src/sys/windows/selector.rs +++ b/src/sys/windows/selector.rs @@ -29,6 +29,7 @@ use winapi::um::minwinbase::OVERLAPPED; #[derive(Debug)] struct AfdGroup { + #[allow(dead_code)] // Not always used depending on the feature set enabled. cp: Arc, afd_group: Mutex>>, } @@ -36,8 +37,8 @@ struct AfdGroup { impl AfdGroup { pub fn new(cp: Arc) -> AfdGroup { AfdGroup { - afd_group: Mutex::new(Vec::new()), cp, + afd_group: Mutex::new(Vec::new()), } } @@ -93,7 +94,6 @@ pub struct SockState { poll_info: AfdPollInfo, afd: Arc, - raw_socket: RawSocket, base_socket: RawSocket, user_evts: u32, @@ -107,7 +107,7 @@ pub struct SockState { // last raw os error error: Option, - pinned: PhantomPinned, + _pinned: PhantomPinned, } impl SockState { @@ -263,7 +263,6 @@ cfg_io_source! { iosb: IoStatusBlock::zeroed(), poll_info: AfdPollInfo::zeroed(), afd, - raw_socket, base_socket: get_base_socket(raw_socket)?, user_evts: 0, pending_evts: 0, @@ -271,7 +270,7 @@ cfg_io_source! { poll_status: SockPollStatus::Idle, delete_pending: false, error: None, - pinned: PhantomPinned, + _pinned: PhantomPinned, }) } From 39213c45a317b78ebaaf31277e37dad448a25aef Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 25 Jul 2023 20:42:48 +0200 Subject: [PATCH 7/7] Run rustfmt on everything Some files are not picked up by running cargo fmt, but find src tests examples -type f -iname "*.rs" | xargs rustfmt does the trick. --- src/net/mod.rs | 2 +- src/net/tcp/mod.rs | 2 +- src/sys/unix/tcp.rs | 30 ++--- src/sys/unix/uds/listener.rs | 9 +- src/sys/windows/net.rs | 8 +- src/sys/windows/tcp.rs | 246 +++++++++++++++++++---------------- 6 files changed, 155 insertions(+), 142 deletions(-) diff --git a/src/net/mod.rs b/src/net/mod.rs index 4df701d45..6ea5c6d77 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -8,7 +8,7 @@ //! [portability guidelines]: ../struct.Poll.html#portability mod tcp; -pub use self::tcp::{TcpListener, TcpSocket, TcpStream, TcpKeepalive}; +pub use self::tcp::{TcpKeepalive, TcpListener, TcpSocket, TcpStream}; mod udp; pub use self::udp::UdpSocket; diff --git a/src/net/tcp/mod.rs b/src/net/tcp/mod.rs index 4e47aeed0..7658bdfc4 100644 --- a/src/net/tcp/mod.rs +++ b/src/net/tcp/mod.rs @@ -2,7 +2,7 @@ mod listener; pub use self::listener::TcpListener; mod socket; -pub use self::socket::{TcpSocket, TcpKeepalive}; +pub use self::socket::{TcpKeepalive, TcpSocket}; mod stream; pub use self::stream::TcpStream; diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs index 59642c610..73b3b30a0 100644 --- a/src/sys/unix/tcp.rs +++ b/src/sys/unix/tcp.rs @@ -6,8 +6,8 @@ use std::net::{self, SocketAddr}; use std::os::unix::io::{AsRawFd, FromRawFd}; use std::time::Duration; -use crate::sys::unix::net::{new_socket, socket_addr, to_socket_addr}; use crate::net::TcpKeepalive; +use crate::sys::unix::net::{new_socket, socket_addr, to_socket_addr}; #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "haiku"))] use libc::SO_KEEPALIVE as KEEPALIVE_TIME; @@ -41,12 +41,8 @@ pub(crate) fn connect(socket: TcpSocket, addr: SocketAddr) -> io::Result { - Err(err) - } - _ => { - Ok(unsafe { net::TcpStream::from_raw_fd(socket) }) - } + Err(err) if err.raw_os_error() != Some(libc::EINPROGRESS) => Err(err), + _ => Ok(unsafe { net::TcpStream::from_raw_fd(socket) }), } } @@ -151,7 +147,7 @@ pub(crate) fn set_linger(socket: TcpSocket, dur: Option) -> io::Result } pub(crate) fn get_linger(socket: TcpSocket) -> io::Result> { - let mut val: libc::linger = unsafe { std::mem::zeroed() }; + let mut val: libc::linger = unsafe { std::mem::zeroed() }; let mut len = mem::size_of::() as libc::socklen_t; syscall!(getsockopt( @@ -268,13 +264,12 @@ pub(crate) fn set_keepalive_params(socket: TcpSocket, keepalive: TcpKeepalive) - if let Some(dur) = keepalive.interval { set_keepalive_interval(socket, dur)?; } - + if let Some(retries) = keepalive.retries { set_keepalive_retries(socket, retries)?; } } - Ok(()) } @@ -456,12 +451,9 @@ pub fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, Socket // OSes inherit the non-blocking flag from the listener, so we just have to // set `CLOEXEC`. #[cfg(any( - all( - target_arch = "x86", - target_os = "android" - ), - target_os = "ios", - target_os = "macos", + all(target_arch = "x86", target_os = "android"), + target_os = "ios", + target_os = "macos", target_os = "solaris" ))] let stream = { @@ -473,11 +465,11 @@ pub fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, Socket .map(|socket| unsafe { net::TcpStream::from_raw_fd(socket) }) .and_then(|s| { syscall!(fcntl(s.as_raw_fd(), libc::F_SETFD, libc::FD_CLOEXEC))?; - + // See https://github.com/tokio-rs/mio/issues/1450 - #[cfg(all(target_arch = "x86",target_os = "android"))] + #[cfg(all(target_arch = "x86", target_os = "android"))] syscall!(fcntl(s.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK))?; - + Ok(s) }) }?; diff --git a/src/sys/unix/uds/listener.rs b/src/sys/unix/uds/listener.rs index 547ff5705..84a9591b5 100644 --- a/src/sys/unix/uds/listener.rs +++ b/src/sys/unix/uds/listener.rs @@ -66,10 +66,7 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So target_os = "macos", target_os = "netbsd", target_os = "solaris", - all( - target_arch = "x86", - target_os = "android" - ) + all(target_arch = "x86", target_os = "android") ))] let socket = syscall!(accept( listener.as_raw_fd(), @@ -83,9 +80,9 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC))?; // See https://github.com/tokio-rs/mio/issues/1450 - #[cfg(all(target_arch = "x86",target_os = "android"))] + #[cfg(all(target_arch = "x86", target_os = "android"))] syscall!(fcntl(socket, libc::F_SETFL, libc::O_NONBLOCK))?; - + Ok(s) }); diff --git a/src/sys/windows/net.rs b/src/sys/windows/net.rs index 2de98fa70..db1896f19 100644 --- a/src/sys/windows/net.rs +++ b/src/sys/windows/net.rs @@ -4,10 +4,10 @@ use std::net::SocketAddr; use std::sync::Once; use winapi::ctypes::c_int; -use winapi::shared::inaddr::{in_addr_S_un, IN_ADDR}; use winapi::shared::in6addr::{in6_addr_u, IN6_ADDR}; -use winapi::shared::ws2def::{AF_INET, AF_INET6, ADDRESS_FAMILY, SOCKADDR, SOCKADDR_IN}; -use winapi::shared::ws2ipdef::{SOCKADDR_IN6_LH, SOCKADDR_IN6_LH_u}; +use winapi::shared::inaddr::{in_addr_S_un, IN_ADDR}; +use winapi::shared::ws2def::{ADDRESS_FAMILY, AF_INET, AF_INET6, SOCKADDR, SOCKADDR_IN}; +use winapi::shared::ws2ipdef::{SOCKADDR_IN6_LH_u, SOCKADDR_IN6_LH}; use winapi::um::winsock2::{ioctlsocket, socket, FIONBIO, INVALID_SOCKET, SOCKET}; /// Initialise the network stack for Windows. @@ -80,7 +80,7 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, c_int) { let sockaddr = SocketAddrCRepr { v4: sockaddr_in }; (sockaddr, mem::size_of::() as c_int) - }, + } SocketAddr::V6(ref addr) => { let sin6_addr = unsafe { let mut u = mem::zeroed::(); diff --git a/src/sys/windows/tcp.rs b/src/sys/windows/tcp.rs index 6757b4476..da6258346 100644 --- a/src/sys/windows/tcp.rs +++ b/src/sys/windows/tcp.rs @@ -1,25 +1,26 @@ -use std::io; use std::convert::TryInto; +use std::io; use std::mem::size_of; use std::net::{self, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; -use std::time::Duration; -use std::ptr; use std::os::windows::io::FromRawSocket; use std::os::windows::raw::SOCKET as StdSocket; // winapi uses usize, stdlib uses u32/u64. +use std::ptr; +use std::time::Duration; -use winapi::ctypes::{c_char, c_int, c_ushort, c_ulong}; -use winapi::shared::ws2def::{SOCKADDR_STORAGE, AF_INET, AF_INET6, SOCKADDR_IN}; -use winapi::shared::ws2ipdef::SOCKADDR_IN6_LH; +use winapi::ctypes::{c_char, c_int, c_ulong, c_ushort}; use winapi::shared::mstcpip; +use winapi::shared::ws2def::{AF_INET, AF_INET6, SOCKADDR_IN, SOCKADDR_STORAGE}; +use winapi::shared::ws2ipdef::SOCKADDR_IN6_LH; -use winapi::shared::minwindef::{BOOL, TRUE, FALSE, DWORD, LPVOID, LPDWORD}; +use winapi::shared::minwindef::{BOOL, DWORD, FALSE, LPDWORD, LPVOID, TRUE}; use winapi::um::winsock2::{ - self, closesocket, linger, setsockopt, getsockopt, getsockname, PF_INET, PF_INET6, SOCKET, SOCKET_ERROR, - SOCK_STREAM, SOL_SOCKET, SO_LINGER, SO_REUSEADDR, SO_RCVBUF, SO_SNDBUF, SO_KEEPALIVE, WSAIoctl, LPWSAOVERLAPPED, + self, closesocket, getsockname, getsockopt, linger, setsockopt, WSAIoctl, LPWSAOVERLAPPED, + PF_INET, PF_INET6, SOCKET, SOCKET_ERROR, SOCK_STREAM, SOL_SOCKET, SO_KEEPALIVE, SO_LINGER, + SO_RCVBUF, SO_REUSEADDR, SO_SNDBUF, }; -use crate::sys::windows::net::{init, new_socket, socket_addr}; use crate::net::TcpKeepalive; +use crate::sys::windows::net::{init, new_socket, socket_addr}; pub(crate) type TcpSocket = SOCKET; @@ -57,18 +58,14 @@ pub(crate) fn connect(socket: TcpSocket, addr: SocketAddr) -> io::Result { - Err(err) - } - _ => { - Ok(unsafe { net::TcpStream::from_raw_socket(socket as StdSocket) }) - } + Err(err) if err.kind() != io::ErrorKind::WouldBlock => Err(err), + _ => Ok(unsafe { net::TcpStream::from_raw_socket(socket as StdSocket) }), } } pub(crate) fn listen(socket: TcpSocket, backlog: u32) -> io::Result { - use winsock2::listen; use std::convert::TryInto; + use winsock2::listen; let backlog = backlog.try_into().unwrap_or(i32::max_value()); syscall!(listen(socket, backlog), PartialEq::eq, SOCKET_ERROR)?; @@ -82,13 +79,15 @@ pub(crate) fn close(socket: TcpSocket) { pub(crate) fn set_reuseaddr(socket: TcpSocket, reuseaddr: bool) -> io::Result<()> { let val: BOOL = if reuseaddr { TRUE } else { FALSE }; - match unsafe { setsockopt( - socket, - SOL_SOCKET, - SO_REUSEADDR, - &val as *const _ as *const c_char, - size_of::() as c_int, - ) } { + match unsafe { + setsockopt( + socket, + SOL_SOCKET, + SO_REUSEADDR, + &val as *const _ as *const c_char, + size_of::() as c_int, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => Ok(()), } @@ -98,13 +97,15 @@ pub(crate) fn get_reuseaddr(socket: TcpSocket) -> io::Result { let mut optval: c_char = 0; let mut optlen = size_of::() as c_int; - match unsafe { getsockopt( - socket, - SOL_SOCKET, - SO_REUSEADDR, - &mut optval as *mut _ as *mut _, - &mut optlen, - ) } { + match unsafe { + getsockopt( + socket, + SOL_SOCKET, + SO_REUSEADDR, + &mut optval as *mut _ as *mut _, + &mut optlen, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => Ok(optval != 0), } @@ -114,31 +115,34 @@ pub(crate) fn get_localaddr(socket: TcpSocket) -> io::Result { let mut storage: SOCKADDR_STORAGE = unsafe { std::mem::zeroed() }; let mut length = std::mem::size_of_val(&storage) as c_int; - match unsafe { getsockname( - socket, - &mut storage as *mut _ as *mut _, - &mut length - ) } { + match unsafe { getsockname(socket, &mut storage as *mut _ as *mut _, &mut length) } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => { if storage.ss_family as c_int == AF_INET { // Safety: if the ss_family field is AF_INET then storage must be a sockaddr_in. let addr: &SOCKADDR_IN = unsafe { &*(&storage as *const _ as *const SOCKADDR_IN) }; let ip_bytes = unsafe { addr.sin_addr.S_un.S_un_b() }; - let ip = Ipv4Addr::from([ip_bytes.s_b1, ip_bytes.s_b2, ip_bytes.s_b3, ip_bytes.s_b4]); + let ip = + Ipv4Addr::from([ip_bytes.s_b1, ip_bytes.s_b2, ip_bytes.s_b3, ip_bytes.s_b4]); let port = u16::from_be(addr.sin_port); Ok(SocketAddr::V4(SocketAddrV4::new(ip, port))) } else if storage.ss_family as c_int == AF_INET6 { // Safety: if the ss_family field is AF_INET6 then storage must be a sockaddr_in6. - let addr: &SOCKADDR_IN6_LH = unsafe { &*(&storage as *const _ as *const SOCKADDR_IN6_LH) }; + let addr: &SOCKADDR_IN6_LH = + unsafe { &*(&storage as *const _ as *const SOCKADDR_IN6_LH) }; let ip = Ipv6Addr::from(*unsafe { addr.sin6_addr.u.Byte() }); let port = u16::from_be(addr.sin6_port); let scope_id = unsafe { *addr.u.sin6_scope_id() }; - Ok(SocketAddr::V6(SocketAddrV6::new(ip, port, addr.sin6_flowinfo, scope_id))) + Ok(SocketAddr::V6(SocketAddrV6::new( + ip, + port, + addr.sin6_flowinfo, + scope_id, + ))) } else { Err(std::io::ErrorKind::InvalidInput.into()) } - }, + } } } @@ -148,13 +152,15 @@ pub(crate) fn set_linger(socket: TcpSocket, dur: Option) -> io::Result l_linger: dur.map(|dur| dur.as_secs() as c_ushort).unwrap_or_default(), }; - match unsafe { setsockopt( - socket, - SOL_SOCKET, - SO_LINGER, - &val as *const _ as *const c_char, - size_of::() as c_int, - ) } { + match unsafe { + setsockopt( + socket, + SOL_SOCKET, + SO_LINGER, + &val as *const _ as *const c_char, + size_of::() as c_int, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => Ok(()), } @@ -164,13 +170,15 @@ pub(crate) fn get_linger(socket: TcpSocket) -> io::Result> { let mut val: linger = unsafe { std::mem::zeroed() }; let mut len = size_of::() as c_int; - match unsafe { getsockopt( - socket, - SOL_SOCKET, - SO_LINGER, - &mut val as *mut _ as *mut _, - &mut len, - ) } { + match unsafe { + getsockopt( + socket, + SOL_SOCKET, + SO_LINGER, + &mut val as *mut _ as *mut _, + &mut len, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => { if val.l_onoff == 0 { @@ -178,20 +186,21 @@ pub(crate) fn get_linger(socket: TcpSocket) -> io::Result> { } else { Ok(Some(Duration::from_secs(val.l_linger as u64))) } - }, + } } } - pub(crate) fn set_recv_buffer_size(socket: TcpSocket, size: u32) -> io::Result<()> { let size = size.try_into().ok().unwrap_or_else(i32::max_value); - match unsafe { setsockopt( - socket, - SOL_SOCKET, - SO_RCVBUF, - &size as *const _ as *const c_char, - size_of::() as c_int - ) } { + match unsafe { + setsockopt( + socket, + SOL_SOCKET, + SO_RCVBUF, + &size as *const _ as *const c_char, + size_of::() as c_int, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => Ok(()), } @@ -200,13 +209,15 @@ pub(crate) fn set_recv_buffer_size(socket: TcpSocket, size: u32) -> io::Result<( pub(crate) fn get_recv_buffer_size(socket: TcpSocket) -> io::Result { let mut optval: c_int = 0; let mut optlen = size_of::() as c_int; - match unsafe { getsockopt( - socket, - SOL_SOCKET, - SO_RCVBUF, - &mut optval as *mut _ as *mut _, - &mut optlen as *mut _, - ) } { + match unsafe { + getsockopt( + socket, + SOL_SOCKET, + SO_RCVBUF, + &mut optval as *mut _ as *mut _, + &mut optlen as *mut _, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => Ok(optval as u32), } @@ -214,13 +225,15 @@ pub(crate) fn get_recv_buffer_size(socket: TcpSocket) -> io::Result { pub(crate) fn set_send_buffer_size(socket: TcpSocket, size: u32) -> io::Result<()> { let size = size.try_into().ok().unwrap_or_else(i32::max_value); - match unsafe { setsockopt( - socket, - SOL_SOCKET, - SO_SNDBUF, - &size as *const _ as *const c_char, - size_of::() as c_int - ) } { + match unsafe { + setsockopt( + socket, + SOL_SOCKET, + SO_SNDBUF, + &size as *const _ as *const c_char, + size_of::() as c_int, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => Ok(()), } @@ -229,13 +242,15 @@ pub(crate) fn set_send_buffer_size(socket: TcpSocket, size: u32) -> io::Result<( pub(crate) fn get_send_buffer_size(socket: TcpSocket) -> io::Result { let mut optval: c_int = 0; let mut optlen = size_of::() as c_int; - match unsafe { getsockopt( - socket, - SOL_SOCKET, - SO_SNDBUF, - &mut optval as *mut _ as *mut _, - &mut optlen as *mut _, - ) } { + match unsafe { + getsockopt( + socket, + SOL_SOCKET, + SO_SNDBUF, + &mut optval as *mut _ as *mut _, + &mut optlen as *mut _, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => Ok(optval as u32), } @@ -243,13 +258,15 @@ pub(crate) fn get_send_buffer_size(socket: TcpSocket) -> io::Result { pub(crate) fn set_keepalive(socket: TcpSocket, keepalive: bool) -> io::Result<()> { let val: BOOL = if keepalive { TRUE } else { FALSE }; - match unsafe { setsockopt( - socket, - SOL_SOCKET, - SO_KEEPALIVE, - &val as *const _ as *const c_char, - size_of::() as c_int - ) } { + match unsafe { + setsockopt( + socket, + SOL_SOCKET, + SO_KEEPALIVE, + &val as *const _ as *const c_char, + size_of::() as c_int, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => Ok(()), } @@ -259,13 +276,15 @@ pub(crate) fn get_keepalive(socket: TcpSocket) -> io::Result { let mut optval: c_char = 0; let mut optlen = size_of::() as c_int; - match unsafe { getsockopt( - socket, - SOL_SOCKET, - SO_KEEPALIVE, - &mut optval as *mut _ as *mut _, - &mut optlen, - ) } { + match unsafe { + getsockopt( + socket, + SOL_SOCKET, + SO_KEEPALIVE, + &mut optval as *mut _ as *mut _, + &mut optlen, + ) + } { SOCKET_ERROR => Err(io::Error::last_os_error()), _ => Ok(optval != FALSE as c_char), } @@ -274,7 +293,10 @@ pub(crate) fn get_keepalive(socket: TcpSocket) -> io::Result { pub(crate) fn set_keepalive_params(socket: TcpSocket, keepalive: TcpKeepalive) -> io::Result<()> { /// Windows configures keepalive time/interval in a u32 of milliseconds. fn dur_to_ulong_ms(dur: Duration) -> c_ulong { - dur.as_millis().try_into().ok().unwrap_or_else(u32::max_value) + dur.as_millis() + .try_into() + .ok() + .unwrap_or_else(u32::max_value) } // If any of the fields on the `tcp_keepalive` struct were not provided by @@ -302,19 +324,21 @@ pub(crate) fn set_keepalive_params(socket: TcpSocket, keepalive: TcpKeepalive) - }; let mut out = 0; - match unsafe { WSAIoctl( - socket, - mstcpip::SIO_KEEPALIVE_VALS, - &mut keepalive as *mut _ as LPVOID, - size_of::() as DWORD, - ptr::null_mut() as LPVOID, - 0 as DWORD, - &mut out as *mut _ as LPDWORD, - 0 as LPWSAOVERLAPPED, - None, - ) } { + match unsafe { + WSAIoctl( + socket, + mstcpip::SIO_KEEPALIVE_VALS, + &mut keepalive as *mut _ as LPVOID, + size_of::() as DWORD, + ptr::null_mut() as LPVOID, + 0 as DWORD, + &mut out as *mut _ as LPDWORD, + 0 as LPWSAOVERLAPPED, + None, + ) + } { 0 => Ok(()), - _ => Err(io::Error::last_os_error()) + _ => Err(io::Error::last_os_error()), } }