From c07fdc87e34d001c1c37819bd0cd991ee4964c8f Mon Sep 17 00:00:00 2001 From: LoveSy Date: Wed, 1 Oct 2025 19:30:15 +0800 Subject: [PATCH] Handle second splice() failure gracefully --- native/src/core/su/pts.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/native/src/core/su/pts.rs b/native/src/core/su/pts.rs index ba79094c3..b0d47450a 100644 --- a/native/src/core/su/pts.rs +++ b/native/src/core/su/pts.rs @@ -10,7 +10,7 @@ use nix::{ }; use std::fs::File; use std::io::{Read, Write}; -use std::mem::MaybeUninit; +use std::mem::{ManuallyDrop, MaybeUninit}; use std::os::fd::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd}; use std::sync::atomic::{AtomicBool, Ordering}; @@ -51,20 +51,24 @@ fn pump_via_copy(mut fd_in: &File, mut fd_out: &File) -> LoggedResult<()> { } fn pump_via_splice(fd_in: &File, fd_out: &File, pipe: &(OwnedFd, OwnedFd)) -> LoggedResult<()> { - if !SHOULD_USE_SPLICE.load(Ordering::Acquire) { + if !SHOULD_USE_SPLICE.load(Ordering::Relaxed) { return pump_via_copy(fd_in, fd_out); } // The pipe capacity is by default 16 pages, let's just use 65536 let Ok(len) = splice(fd_in, &pipe.1, 65536) else { // If splice failed, stop using splice and fallback to userspace copy - SHOULD_USE_SPLICE.store(false, Ordering::Release); + SHOULD_USE_SPLICE.store(false, Ordering::Relaxed); return pump_via_copy(fd_in, fd_out); }; if len == 0 { return Ok(()); } - splice(&pipe.0, fd_out, len)?; + if let Err(_) = splice(&pipe.0, fd_out, len) { + // If splice failed, stop using splice and fallback to userspace copy + SHOULD_USE_SPLICE.store(false, Ordering::Relaxed); + return pump_via_copy(&ManuallyDrop::new(unsafe { File::from_raw_fd(pipe.0.as_raw_fd()) }), fd_out); + } Ok(()) }