[rust][sockets] Change half close to set peer disposition

This seems to have been the intent from the docstring. The local socket
can control whether it writes to the socket or not, but this is needed
to prevent the peer from writing back.

Change-Id: If8dbe93002763188bc44fec62bf669e64e35eaa7
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/683925
Reviewed-by: Abdulla Kamar <abdulla@google.com>
Commit-Queue: David Hastings <dahastin@google.com>
diff --git a/src/connectivity/bluetooth/profiles/bt-hfp-audio-gateway/src/peer/service_level_connection.rs b/src/connectivity/bluetooth/profiles/bt-hfp-audio-gateway/src/peer/service_level_connection.rs
index c920f46..b4ed606 100644
--- a/src/connectivity/bluetooth/profiles/bt-hfp-audio-gateway/src/peer/service_level_connection.rs
+++ b/src/connectivity/bluetooth/profiles/bt-hfp-audio-gateway/src/peer/service_level_connection.rs
@@ -1284,10 +1284,10 @@
 
     #[fuchsia::test(allow_stalls = false)]
     async fn read_error_result_is_propagated_to_stream() {
-        // Close the local end of the channel so that local reads and remote writes
+        // Close the remote end of the channel so that local reads and remote writes
         // fail.
         let (local, remote) = Channel::create();
-        assert!(remote.as_ref().half_close().is_ok());
+        assert!(local.as_ref().half_close().is_ok());
         let mut connection = DataController::new(local);
 
         // Remote writing to us should fail.
@@ -1299,10 +1299,10 @@
 
     #[fuchsia::test(allow_stalls = false)]
     async fn write_error_result_is_propagated_to_stream() {
-        // Close the remote end of the channel so that remote reads and local writes
+        // Close the local end of the channel so that remote reads and local writes
         // fail.
-        let (local, _remote) = Channel::create();
-        assert!(local.as_ref().half_close().is_ok());
+        let (local, remote) = Channel::create();
+        assert!(remote.as_ref().half_close().is_ok());
         let mut connection = DataController::new(local);
 
         // Queue some data to be sent to the remote.
diff --git a/src/connectivity/bluetooth/profiles/bt-hfp-audio-gateway/src/peer/task.rs b/src/connectivity/bluetooth/profiles/bt-hfp-audio-gateway/src/peer/task.rs
index 6451bdf..3eb42b4 100644
--- a/src/connectivity/bluetooth/profiles/bt-hfp-audio-gateway/src/peer/task.rs
+++ b/src/connectivity/bluetooth/profiles/bt-hfp-audio-gateway/src/peer/task.rs
@@ -880,6 +880,7 @@
         at_commands::{self as at, SerDe},
         bt_rfcomm::{profile::build_rfcomm_protocol, ServerChannel},
         core::task::Poll,
+        fidl::AsHandleRef,
         fidl_fuchsia_bluetooth_bredr::{ProfileMarker, ProfileRequestStream, ScoErrorCode},
         fidl_fuchsia_bluetooth_hfp::{
             CallDirection, CallRequest, CallRequestStream, CallState, NextCall, PeerHandlerMarker,
@@ -1214,8 +1215,16 @@
         let run_fut = peer.run(receiver);
         pin_mut!(run_fut);
 
-        // Produces an error when polling the ServiceLevelConnection stream.
-        assert!(remote.as_ref().half_close().is_ok());
+        // Produces an error when polling the ServiceLevelConnection stream by disabling write
+        // on the remote socket and read on the local socket.
+        let status = unsafe {
+            zx::sys::zx_socket_set_disposition(
+                remote.as_ref().raw_handle(),
+                zx::sys::ZX_SOCKET_DISPOSITION_WRITE_DISABLED,
+                0,
+            )
+        };
+        zx::Status::ok(status).unwrap();
 
         // Error on the SLC connection will result in the completion of the peer task.
         let result = exec.run_until_stalled(&mut run_fut);
diff --git a/src/lib/fuchsia-component/src/client.rs b/src/lib/fuchsia-component/src/client.rs
index cc91cdd..2759602 100644
--- a/src/lib/fuchsia-component/src/client.rs
+++ b/src/lib/fuchsia-component/src/client.rs
@@ -781,7 +781,7 @@
             Stdio::MakePipe => {
                 let (local, remote) = Socket::create(SocketOpts::STREAM)?;
                 // local end is read-only
-                local.half_close()?;
+                remote.half_close()?;
 
                 let local = fasync::Socket::from_socket(local)?;
                 let remote = FileDescriptor {
diff --git a/src/lib/zircon/rust/src/socket.rs b/src/lib/zircon/rust/src/socket.rs
index 0f95508..7169425 100644
--- a/src/lib/zircon/rust/src/socket.rs
+++ b/src/lib/zircon/rust/src/socket.rs
@@ -173,8 +173,8 @@
         let status = unsafe {
             sys::zx_socket_set_disposition(
                 self.raw_handle(),
-                sys::ZX_SOCKET_DISPOSITION_WRITE_DISABLED,
                 0,
+                sys::ZX_SOCKET_DISPOSITION_WRITE_DISABLED,
             )
         };
         ok(status)
@@ -230,15 +230,15 @@
         // Try reading when there is nothing to read.
         assert_eq!(s2.read(&mut read_vec), Err(Status::SHOULD_WAIT));
 
-        // Disable writes on one end of the socket.
+        // Disable writes from the socket peer.
         assert!(s1.half_close().is_ok());
-        assert_eq!(s2.read(&mut read_vec), Err(Status::BAD_STATE));
-        assert_eq!(s1.write(b"fail"), Err(Status::BAD_STATE));
+        assert_eq!(s2.write(b"fail"), Err(Status::BAD_STATE));
+        assert_eq!(s1.read(&mut read_vec), Err(Status::BAD_STATE));
 
-        // Writing in the other direction should still work.
-        assert_eq!(s1.read(&mut read_vec), Err(Status::SHOULD_WAIT));
-        assert_eq!(s2.write(b"back").unwrap(), 4);
-        assert_eq!(s1.read(&mut read_vec).unwrap(), 4);
+        // Writing to the peer should still work.
+        assert_eq!(s2.read(&mut read_vec), Err(Status::SHOULD_WAIT));
+        assert_eq!(s1.write(b"back").unwrap(), 4);
+        assert_eq!(s2.read(&mut read_vec).unwrap(), 4);
         assert_eq!(&read_vec[0..4], b"back");
     }
 
diff --git a/third_party/tcpdump/tests/src/lib.rs b/third_party/tcpdump/tests/src/lib.rs
index 9b05fe1..f491d24 100644
--- a/third_party/tcpdump/tests/src/lib.rs
+++ b/third_party/tcpdump/tests/src/lib.rs
@@ -84,8 +84,8 @@
         zx::Socket::create(zx::SocketOpts::STREAM).expect("create stderr socket");
 
     // The reader-ends should not write.
-    let () = stdout_reader.half_close().expect("stdout_reader.half_close");
-    let () = stderr_reader.half_close().expect("stderr_reader.half_close");
+    let () = stdout_writer.half_close().expect("stdout_reader.half_close");
+    let () = stdout_writer.half_close().expect("stderr_reader.half_close");
 
     let path = CString::new(BINARY_PATH).expect("cstring path");
     let path = path.as_c_str();