diff options
Diffstat (limited to 'library/std/src/sys/unix')
| -rw-r--r-- | library/std/src/sys/unix/fd.rs | 11 | ||||
| -rw-r--r-- | library/std/src/sys/unix/fs.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys/unix/net.rs | 22 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_common.rs | 33 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_common/tests.rs | 24 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_unix.rs | 4 |
6 files changed, 90 insertions, 10 deletions
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 30812dabb4e..dbaa3c33e2e 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -4,7 +4,7 @@ mod tests; use crate::cmp; -use crate::io::{self, IoSlice, IoSliceMut, Read, ReadBuf}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read}; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::sys::cvt; use crate::sys_common::{AsInner, FromInner, IntoInner}; @@ -131,20 +131,19 @@ impl FileDesc { } } - pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> { + pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> { let ret = cvt(unsafe { libc::read( self.as_raw_fd(), - buf.unfilled_mut().as_mut_ptr() as *mut libc::c_void, - cmp::min(buf.remaining(), READ_LIMIT), + cursor.as_mut().as_mut_ptr() as *mut libc::c_void, + cmp::min(cursor.capacity(), READ_LIMIT), ) })?; // Safety: `ret` bytes were written to the initialized portion of the buffer unsafe { - buf.assume_init(ret as usize); + cursor.advance(ret as usize); } - buf.add_filled(ret as usize); Ok(()) } diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index f38d2fd3d70..cc347e3586a 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -2,7 +2,7 @@ use crate::os::unix::prelude::*; use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; -use crate::io::{self, Error, IoSlice, IoSliceMut, ReadBuf, SeekFrom}; +use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; use crate::mem; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd}; use crate::path::{Path, PathBuf}; @@ -1037,8 +1037,8 @@ impl File { self.0.read_at(buf, offset) } - pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> { - self.0.read_buf(buf) + pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf(cursor) } pub fn write(&self, buf: &[u8]) -> io::Result<usize> { diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index 462a45b01ab..b84bf8f9264 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -393,6 +393,17 @@ impl Socket { } #[cfg(any(target_os = "android", target_os = "linux",))] + pub fn set_quickack(&self, quickack: bool) -> io::Result<()> { + setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int) + } + + #[cfg(any(target_os = "android", target_os = "linux",))] + pub fn quickack(&self) -> io::Result<bool> { + let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)?; + Ok(raw != 0) + } + + #[cfg(any(target_os = "android", target_os = "linux",))] pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int) } @@ -427,6 +438,17 @@ impl Socket { self.0.set_nonblocking(nonblocking) } + #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + #[cfg(target_os = "linux")] + let option = libc::SO_MARK; + #[cfg(target_os = "freebsd")] + let option = libc::SO_USER_COOKIE; + #[cfg(target_os = "openbsd")] + let option = libc::SO_RTABLE; + setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int) + } + pub fn take_error(&self) -> io::Result<Option<io::Error>> { let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index 6985f1d7830..2834ee0ace8 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -92,6 +92,7 @@ pub struct Command { argv: Argv, env: CommandEnv, + program_kind: ProgramKind, cwd: Option<CString>, uid: Option<uid_t>, gid: Option<gid_t>, @@ -148,15 +149,40 @@ pub enum Stdio { Fd(FileDesc), } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum ProgramKind { + /// A program that would be looked up on the PATH (e.g. `ls`) + PathLookup, + /// A relative path (e.g. `my-dir/foo`, `../foo`, `./foo`) + Relative, + /// An absolute path. + Absolute, +} + +impl ProgramKind { + fn new(program: &OsStr) -> Self { + if program.bytes().starts_with(b"/") { + Self::Absolute + } else if program.bytes().contains(&b'/') { + // If the program has more than one component in it, it is a relative path. + Self::Relative + } else { + Self::PathLookup + } + } +} + impl Command { #[cfg(not(target_os = "linux"))] pub fn new(program: &OsStr) -> Command { let mut saw_nul = false; + let program_kind = ProgramKind::new(program.as_ref()); let program = os2c(program, &mut saw_nul); Command { argv: Argv(vec![program.as_ptr(), ptr::null()]), args: vec![program.clone()], program, + program_kind, env: Default::default(), cwd: None, uid: None, @@ -174,11 +200,13 @@ impl Command { #[cfg(target_os = "linux")] pub fn new(program: &OsStr) -> Command { let mut saw_nul = false; + let program_kind = ProgramKind::new(program.as_ref()); let program = os2c(program, &mut saw_nul); Command { argv: Argv(vec![program.as_ptr(), ptr::null()]), args: vec![program.clone()], program, + program_kind, env: Default::default(), cwd: None, uid: None, @@ -254,6 +282,11 @@ impl Command { OsStr::from_bytes(self.program.as_bytes()) } + #[allow(dead_code)] + pub fn get_program_kind(&self) -> ProgramKind { + self.program_kind + } + pub fn get_args(&self) -> CommandArgs<'_> { let mut iter = self.args.iter(); iter.next(); diff --git a/library/std/src/sys/unix/process/process_common/tests.rs b/library/std/src/sys/unix/process/process_common/tests.rs index 1956b3692a7..d176b3401c0 100644 --- a/library/std/src/sys/unix/process/process_common/tests.rs +++ b/library/std/src/sys/unix/process/process_common/tests.rs @@ -122,3 +122,27 @@ fn test_process_group_no_posix_spawn() { t!(cat.wait()); } } + +#[test] +fn test_program_kind() { + let vectors = &[ + ("foo", ProgramKind::PathLookup), + ("foo.out", ProgramKind::PathLookup), + ("./foo", ProgramKind::Relative), + ("../foo", ProgramKind::Relative), + ("dir/foo", ProgramKind::Relative), + // Note that paths on Unix can't contain / in them, so this is actually the directory "fo\\" + // followed by the file "o". + ("fo\\/o", ProgramKind::Relative), + ("/foo", ProgramKind::Absolute), + ("/dir/../foo", ProgramKind::Absolute), + ]; + + for (program, expected_kind) in vectors { + assert_eq!( + ProgramKind::new(program.as_ref()), + *expected_kind, + "actual != expected program kind for input {program}", + ); + } +} diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 75bb92437fd..26ae6281771 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -453,7 +453,9 @@ impl Command { // successfully launch the program, but erroneously return // ENOENT when used with posix_spawn_file_actions_addchdir_np // which was introduced in macOS 10.15. - return Ok(None); + if self.get_program_kind() == ProgramKind::Relative { + return Ok(None); + } } match posix_spawn_file_actions_addchdir_np.get() { Some(f) => Some((f, cwd)), |
