diff --git a/.cirrus.yml b/.cirrus.yml
index 522bdafcdb..fc564e65aa 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -9,7 +9,7 @@ env:
   RUSTFLAGS: -D warnings
   RUSTDOCFLAGS: -D warnings
   TOOL: cargo
-  MSRV: 1.65.0
+  MSRV: 1.69.0
   ZFLAGS:
 
 # Tests that don't require executing the build binaries
@@ -146,7 +146,7 @@ task:
   matrix:
     - name: Linux aarch64
       arm_container:
-        image: rust:1.65.0
+        image: rust:1.69.0
         cpu: 1
       depends_on:
         - FreeBSD 14 amd64 & i686
@@ -160,13 +160,13 @@ task:
         TARGET: aarch64-unknown-linux-gnu
     - name: Linux x86_64
       container:
-        image: rust:1.65.0
+        image: rust:1.69.0
         cpu: 1
       env:
         TARGET: x86_64-unknown-linux-gnu
     - name: Linux x86_64 musl
       container:
-        image: rust:1.65.0
+        image: rust:1.69.0
         cpu: 1
       depends_on:
         - FreeBSD 14 amd64 & i686
@@ -199,7 +199,7 @@ task:
 # Tasks for cross-compiling, but no testing
 task:
   container:
-    image: rust:1.65.0
+    image: rust:1.69.0
     cpu: 1
   depends_on:
     - FreeBSD 14 amd64 & i686
@@ -235,7 +235,7 @@ task:
         TARGET: arm-unknown-linux-musleabi
     - name: Fuchsia x86_64
       env:
-        TARGET: x86_64-fuchsia
+        TARGET: x86_64-unknown-fuchsia
     - name: Illumos
       env:
         TARGET: x86_64-unknown-illumos
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d21cad4b8..2406958e0f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,9 @@ This project adheres to [Semantic Versioning](https://semver.org/).
 
 ### Changed
 
+- The MSRV is now 1.69
+  ([#2144](https://github.com/nix-rust/nix/pull/2144))
+
 - The following APIs now take an implementation of `AsFd` rather than a
   `RawFd`:
 
diff --git a/README.md b/README.md
index 452d65466e..157b8da120 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,7 @@ The following targets are supported by `nix`:
 
 ## Minimum Supported Rust Version (MSRV)
 
-nix is supported on Rust 1.65 and higher.  Its MSRV will not be
+nix is supported on Rust 1.69 and higher.  Its MSRV will not be
 changed in the future without bumping the major or minor version.
 
 ## Contributing
diff --git a/src/mount/bsd.rs b/src/mount/bsd.rs
index 3076304cab..bc28b49b71 100644
--- a/src/mount/bsd.rs
+++ b/src/mount/bsd.rs
@@ -396,13 +396,10 @@ impl<'a> Nmount<'a> {
         match Errno::result(res) {
             Ok(_) => Ok(()),
             Err(error) => {
-                let errmsg = match errmsg.iter().position(|&x| x == 0) {
-                    None => None,
-                    Some(0) => None,
-                    Some(n) => {
-                        let sl = &errmsg[0..n + 1];
-                        Some(CStr::from_bytes_with_nul(sl).unwrap())
-                    }
+                let errmsg = if errmsg[0] == 0 {
+                    None
+                } else {
+                    CStr::from_bytes_until_nul(&errmsg[..]).ok()
                 };
                 Err(NmountError::new(error, errmsg))
             }
diff --git a/src/sys/prctl.rs b/src/sys/prctl.rs
index 995382cb0c..a48065a66b 100644
--- a/src/sys/prctl.rs
+++ b/src/sys/prctl.rs
@@ -151,10 +151,11 @@ pub fn get_name() -> Result<CString> {
 
     let res = unsafe { libc::prctl(libc::PR_GET_NAME, &buf, 0, 0, 0) };
 
-    let len = buf.iter().position(|&c| c == 0).unwrap_or(buf.len());
-    let name = CStr::from_bytes_with_nul(&buf[..=len]).map_err(|_| Errno::EINVAL)?;
-
-    Errno::result(res).map(|_| name.to_owned())
+    Errno::result(res).and_then(|_| {
+        CStr::from_bytes_until_nul(&buf)
+            .map(CStr::to_owned)
+            .map_err(|_| Errno::EINVAL)
+    })
 }
 
 /// Sets the timer slack value for the calling thread. Timer slack is used by the kernel to group
diff --git a/src/unistd.rs b/src/unistd.rs
index 2eb23fa95c..700a4af3ba 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -28,14 +28,11 @@ use libc::{
     uid_t, PATH_MAX,
 };
 use std::convert::Infallible;
-use std::ffi::{CStr, OsString};
 #[cfg(not(target_os = "redox"))]
-use std::ffi::{CString, OsStr};
-#[cfg(not(target_os = "redox"))]
-use std::os::unix::ffi::OsStrExt;
-use std::os::unix::ffi::OsStringExt;
-use std::os::unix::io::RawFd;
-use std::os::unix::io::{AsFd, AsRawFd, OwnedFd};
+use std::ffi::CString;
+use std::ffi::{CStr, OsStr, OsString};
+use std::os::unix::ffi::{OsStrExt, OsStringExt};
+use std::os::unix::io::{AsFd, AsRawFd, OwnedFd, RawFd};
 use std::path::PathBuf;
 use std::{fmt, mem, ptr};
 
@@ -3928,9 +3925,9 @@ pub fn ttyname<F: AsFd>(fd: F) -> Result<PathBuf> {
         return Err(Errno::from_i32(ret));
     }
 
-    let nul = buf.iter().position(|c| *c == b'\0').unwrap();
-    buf.truncate(nul);
-    Ok(OsString::from_vec(buf).into())
+    CStr::from_bytes_until_nul(&buf[..])
+        .map(|s| OsStr::from_bytes(s.to_bytes()).into())
+        .map_err(|_| Errno::EINVAL)
 }
 }