Upgrade vsock to 0.4.0 am: bb91fc7565 am: 128b22d835 am: 93678c42f8

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/vsock/+/2859505

Change-Id: I72f89f75924cdc3da5940eb4fb84ee5248053af0
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 906003c..00feee6 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "41d1faa752299f665d3ca429bf7a3d2367e7e774"
+    "sha1": "a48080b8fd4ace9d3f455222d0336757acd6d098"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..98e44ee
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,10 @@
+version: 2
+updates:
+  - package-ecosystem: "cargo"
+    directory: "/"
+    schedule:
+      interval: "weekly"
+  - package-ecosystem: "github-actions"
+    directory: "/"
+    schedule:
+      interval: "weekly"
diff --git a/.github/workflows/bvt.yaml b/.github/workflows/bvt.yaml
index 78906ec..4a1b681 100644
--- a/.github/workflows/bvt.yaml
+++ b/.github/workflows/bvt.yaml
@@ -5,7 +5,7 @@
     name: BVT
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v4
     - name: install dependencies
       run: |
         rustup target add x86_64-unknown-linux-musl
diff --git a/.github/workflows/commit-message-check.yaml b/.github/workflows/commit-message-check.yaml
index 4d1c57e..dcdf0ec 100644
--- a/.github/workflows/commit-message-check.yaml
+++ b/.github/workflows/commit-message-check.yaml
@@ -19,12 +19,12 @@
     steps:
     - name: Get PR Commits
       id: 'get-pr-commits'
-      uses: tim-actions/get-pr-commits@v1.0.0
+      uses: tim-actions/get-pr-commits@v1.3.0
       with:
         token: ${{ secrets.GITHUB_TOKEN }}
 
     - name: DCO Check
-      uses: tim-actions/dco@2fd0504dc0d27b33f542867c300c60840c6dcb20
+      uses: tim-actions/dco@v1.1.0
       with:
         commits: ${{ steps.get-pr-commits.outputs.commits }}
 
@@ -36,7 +36,7 @@
 
     - name: Check Subject Line Length
       if: ${{ success() || failure() }}
-      uses: tim-actions/commit-message-checker-with-regex@v0.3.1
+      uses: tim-actions/commit-message-checker-with-regex@v0.3.2
       with:
         commits: ${{ steps.get-pr-commits.outputs.commits }}
         pattern: '^.{0,75}(\n.*)*$'
@@ -45,9 +45,9 @@
 
     - name: Check Body Line Length
       if: ${{ success() || failure() }}
-      uses: tim-actions/commit-message-checker-with-regex@v0.3.1
+      uses: tim-actions/commit-message-checker-with-regex@v0.3.2
       with:
         commits: ${{ steps.get-pr-commits.outputs.commits }}
-        pattern: '^.+(\n.{0,72})*$|^.+\n\s*[^a-zA-Z\s\n]|^.+\n\S+$'
+        pattern: '^.+(\n.{0,72})*$|^.+\n\s*[^a-zA-Z\s\n]|^.+\n\S+$|\nSigned-off-by: dependabot\[bot\]'
         error: 'Body line too long (max 72)'
         post_error: ${{ env.error_msg }}
diff --git a/Android.bp b/Android.bp
index d2f46aa..98cc7d5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,9 +23,9 @@
     host_supported: true,
     crate_name: "vsock",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.3.0",
+    cargo_pkg_version: "0.4.0",
     srcs: ["src/lib.rs"],
-    edition: "2018",
+    edition: "2021",
     rustlibs: [
         "liblibc",
         "libnix",
diff --git a/Cargo.toml b/Cargo.toml
index 7cde53a..75a6ca9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,9 +10,9 @@
 # See Cargo.toml.orig for the original contents.
 
 [package]
-edition = "2018"
+edition = "2021"
 name = "vsock"
-version = "0.3.0"
+version = "0.4.0"
 authors = [
     "fsyncd",
     "rust-vsock",
@@ -25,10 +25,14 @@
 repository = "https://github.com/rust-vsock/vsock-rs"
 
 [dependencies.libc]
-version = "0.2.126"
+version = "0.2.150"
 
 [dependencies.nix]
-version = "0.24.2"
+version = "0.27.1"
+features = [
+    "ioctl",
+    "socket",
+]
 
 [dev-dependencies.rand]
 version = "0.8.3"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 6b098e9..255d7f1 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,18 +1,18 @@
 [package]
 name = "vsock"
-version = "0.3.0"
+version = "0.4.0"
 authors = ["fsyncd", "rust-vsock"]
 description = "Virtio socket support for Rust"
 repository = "https://github.com/rust-vsock/vsock-rs"
 homepage = "https://github.com/rust-vsock/vsock-rs"
 readme = "README.md"
 license = "Apache-2.0"
-edition = "2018"
+edition = "2021"
 exclude = ["test_fixture"]
 
 [dependencies]
-libc = "0.2.126"
-nix = "0.24.2"
+libc = "0.2.150"
+nix = { version = "0.27.1", features = ["ioctl", "socket"] }
 
 [dev-dependencies]
 rand = "0.8.3"
diff --git a/METADATA b/METADATA
index 218588e..ef6ec77 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/vsock
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
+
 name: "vsock"
 description: "Virtio socket support for Rust"
 third_party {
@@ -7,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/vsock/vsock-0.3.0.crate"
+    value: "https://static.crates.io/crates/vsock/vsock-0.4.0.crate"
   }
-  version: "0.3.0"
+  version: "0.4.0"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2022
-    month: 10
-    day: 6
+    year: 2023
+    month: 12
+    day: 5
   }
 }
diff --git a/README.md b/README.md
index e25c4b0..6f37ae5 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # vsock-rs
 
 Virtio socket support for Rust. Implements VsockListener and VsockStream
-which are analogous to the `std::net::TcpListener` and `std::net::TcpStream` types. 
+which are analogous to the `std::net::TcpListener` and `std::net::TcpStream` types.
 
 ## Usage
 
@@ -11,7 +11,7 @@
 
 ### Prerequisites
 
-You will need a recent qemu-system-x86_64 build in your path.
+You will need a recent `qemu-system-x86_64` build in your path.
 
 ### Host
 
@@ -21,7 +21,7 @@
 make kmod
 ```
 
-Start the test vm, you can shutdown the vm with the keyboard shortcut ```Ctrl+A``` and then ```x```:
+Start the test vm, you can shutdown the vm with the keyboard shortcut `Ctrl+A` and then `x`:
 
 ```
 make vm
@@ -33,4 +33,4 @@
 
 ```
 make check
-```
\ No newline at end of file
+```
diff --git a/src/lib.rs b/src/lib.rs
index e482e9f..99439f8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -28,19 +28,21 @@
         sockopt::{ReceiveTimeout, SendTimeout, SocketError},
         AddressFamily, GetSockOpt, MsgFlags, SetSockOpt, SockFlag, SockType,
     },
-    unistd::close,
 };
-use std::fs::File;
-use std::io::{Error, ErrorKind, Read, Result, Write};
-use std::mem::{self, size_of};
+use std::mem::size_of;
 use std::net::Shutdown;
 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
 use std::time::Duration;
+use std::{fs::File, os::fd::OwnedFd};
+use std::{
+    io::{Error, ErrorKind, Read, Result, Write},
+    os::fd::{AsFd, BorrowedFd},
+};
 
 pub use libc::{VMADDR_CID_ANY, VMADDR_CID_HOST, VMADDR_CID_HYPERVISOR, VMADDR_CID_LOCAL};
 pub use nix::sys::socket::{SockaddrLike, VsockAddr};
 
-fn new_socket() -> Result<RawFd> {
+fn new_socket() -> Result<OwnedFd> {
     Ok(socket(
         AddressFamily::Vsock,
         SockType::Stream,
@@ -64,9 +66,9 @@
 }
 
 /// A virtio socket server, listening for connections.
-#[derive(Debug, Clone)]
+#[derive(Debug)]
 pub struct VsockListener {
-    socket: RawFd,
+    socket: OwnedFd,
 }
 
 impl VsockListener {
@@ -81,10 +83,10 @@
 
         let socket = new_socket()?;
 
-        bind(socket, addr)?;
+        bind(socket.as_raw_fd(), addr)?;
 
         // rust stdlib uses a 128 connection backlog
-        listen(socket, 128)?;
+        listen(&socket, 128)?;
 
         Ok(Self { socket })
     }
@@ -96,12 +98,14 @@
 
     /// The local socket address of the listener.
     pub fn local_addr(&self) -> Result<VsockAddr> {
-        Ok(getsockname(self.socket)?)
+        Ok(getsockname(self.socket.as_raw_fd())?)
     }
 
     /// Create a new independently owned handle to the underlying socket.
     pub fn try_clone(&self) -> Result<Self> {
-        Ok(self.clone())
+        Ok(Self {
+            socket: self.socket.try_clone()?,
+        })
     }
 
     /// Accept a new incoming connection from this listener.
@@ -116,7 +120,7 @@
         let mut vsock_addr_len = size_of::<sockaddr_vm>() as socklen_t;
         let socket = unsafe {
             accept4(
-                self.socket,
+                self.socket.as_raw_fd(),
                 &mut vsock_addr as *mut _ as *mut sockaddr,
                 &mut vsock_addr_len,
                 SOCK_CLOEXEC,
@@ -139,7 +143,7 @@
 
     /// Retrieve the latest error associated with the underlying socket.
     pub fn take_error(&self) -> Result<Option<Error>> {
-        let error = SocketError.get(self.socket)?;
+        let error = SocketError.get(&self.socket)?;
         Ok(if error == 0 {
             None
         } else {
@@ -150,7 +154,7 @@
     /// Move this stream in and out of nonblocking mode.
     pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()> {
         let mut nonblocking: i32 = if nonblocking { 1 } else { 0 };
-        if unsafe { ioctl(self.socket, FIONBIO, &mut nonblocking) } < 0 {
+        if unsafe { ioctl(self.socket.as_raw_fd(), FIONBIO, &mut nonblocking) } < 0 {
             Err(Error::last_os_error())
         } else {
             Ok(())
@@ -160,34 +164,34 @@
 
 impl AsRawFd for VsockListener {
     fn as_raw_fd(&self) -> RawFd {
-        self.socket
+        self.socket.as_raw_fd()
+    }
+}
+
+impl AsFd for VsockListener {
+    fn as_fd(&self) -> BorrowedFd {
+        self.socket.as_fd()
     }
 }
 
 impl FromRawFd for VsockListener {
     unsafe fn from_raw_fd(socket: RawFd) -> Self {
-        Self { socket }
+        Self {
+            socket: OwnedFd::from_raw_fd(socket),
+        }
     }
 }
 
 impl IntoRawFd for VsockListener {
     fn into_raw_fd(self) -> RawFd {
-        let fd = self.socket;
-        mem::forget(self);
-        fd
-    }
-}
-
-impl Drop for VsockListener {
-    fn drop(&mut self) {
-        let _ = close(self.socket);
+        self.socket.into_raw_fd()
     }
 }
 
 /// A virtio stream between a local and a remote socket.
-#[derive(Debug, Clone)]
+#[derive(Debug)]
 pub struct VsockStream {
-    socket: RawFd,
+    socket: OwnedFd,
 }
 
 impl VsockStream {
@@ -200,9 +204,9 @@
             ));
         }
 
-        let sock = new_socket()?;
-        connect(sock, addr)?;
-        Ok(unsafe { Self::from_raw_fd(sock) })
+        let socket = new_socket()?;
+        connect(socket.as_raw_fd(), addr)?;
+        Ok(Self { socket })
     }
 
     /// Open a connection to a remote host with specified cid and port.
@@ -212,12 +216,12 @@
 
     /// Virtio socket address of the remote peer associated with this connection.
     pub fn peer_addr(&self) -> Result<VsockAddr> {
-        Ok(getpeername(self.socket)?)
+        Ok(getpeername(self.socket.as_raw_fd())?)
     }
 
     /// Virtio socket address of the local address associated with this connection.
     pub fn local_addr(&self) -> Result<VsockAddr> {
-        Ok(getsockname(self.socket)?)
+        Ok(getsockname(self.socket.as_raw_fd())?)
     }
 
     /// Shutdown the read, write, or both halves of this connection.
@@ -227,29 +231,31 @@
             Shutdown::Read => socket::Shutdown::Read,
             Shutdown::Both => socket::Shutdown::Both,
         };
-        Ok(shutdown(self.socket, how)?)
+        Ok(shutdown(self.socket.as_raw_fd(), how)?)
     }
 
     /// Create a new independently owned handle to the underlying socket.
     pub fn try_clone(&self) -> Result<Self> {
-        Ok(self.clone())
+        Ok(Self {
+            socket: self.socket.try_clone()?,
+        })
     }
 
     /// Set the timeout on read operations.
     pub fn set_read_timeout(&self, dur: Option<Duration>) -> Result<()> {
         let timeout = Self::timeval_from_duration(dur)?.into();
-        Ok(SendTimeout.set(self.socket, &timeout)?)
+        Ok(ReceiveTimeout.set(&self.socket, &timeout)?)
     }
 
     /// Set the timeout on write operations.
     pub fn set_write_timeout(&self, dur: Option<Duration>) -> Result<()> {
         let timeout = Self::timeval_from_duration(dur)?.into();
-        Ok(ReceiveTimeout.set(self.socket, &timeout)?)
+        Ok(SendTimeout.set(&self.socket, &timeout)?)
     }
 
     /// Retrieve the latest error associated with the underlying socket.
     pub fn take_error(&self) -> Result<Option<Error>> {
-        let error = SocketError.get(self.socket)?;
+        let error = SocketError.get(&self.socket)?;
         Ok(if error == 0 {
             None
         } else {
@@ -260,7 +266,7 @@
     /// Move this stream in and out of nonblocking mode.
     pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()> {
         let mut nonblocking: i32 = if nonblocking { 1 } else { 0 };
-        if unsafe { ioctl(self.socket, FIONBIO, &mut nonblocking) } < 0 {
+        if unsafe { ioctl(self.socket.as_raw_fd(), FIONBIO, &mut nonblocking) } < 0 {
             Err(Error::last_os_error())
         } else {
             Ok(())
@@ -319,13 +325,13 @@
 
 impl Read for &VsockStream {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
-        Ok(recv(self.socket, buf, MsgFlags::empty())?)
+        Ok(recv(self.socket.as_raw_fd(), buf, MsgFlags::empty())?)
     }
 }
 
 impl Write for &VsockStream {
     fn write(&mut self, buf: &[u8]) -> Result<usize> {
-        Ok(send(self.socket, buf, MsgFlags::MSG_NOSIGNAL)?)
+        Ok(send(self.socket.as_raw_fd(), buf, MsgFlags::MSG_NOSIGNAL)?)
     }
 
     fn flush(&mut self) -> Result<()> {
@@ -335,27 +341,27 @@
 
 impl AsRawFd for VsockStream {
     fn as_raw_fd(&self) -> RawFd {
-        self.socket
+        self.socket.as_raw_fd()
+    }
+}
+
+impl AsFd for VsockStream {
+    fn as_fd(&self) -> BorrowedFd {
+        self.socket.as_fd()
     }
 }
 
 impl FromRawFd for VsockStream {
     unsafe fn from_raw_fd(socket: RawFd) -> Self {
-        Self { socket }
+        Self {
+            socket: OwnedFd::from_raw_fd(socket),
+        }
     }
 }
 
 impl IntoRawFd for VsockStream {
     fn into_raw_fd(self) -> RawFd {
-        let fd = self.socket;
-        mem::forget(self);
-        fd
-    }
-}
-
-impl Drop for VsockStream {
-    fn drop(&mut self) {
-        let _ = close(self.socket);
+        self.socket.into_raw_fd()
     }
 }