1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-01 13:37:48 +00:00

Merge pull request #2330 from miDeb/cp/close-fd

cp: close file descriptors after cow on linux
This commit is contained in:
Sylvestre Ledru 2021-06-03 07:54:34 +02:00 committed by GitHub
commit 5de623cfab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 64 additions and 9 deletions

View file

@ -1,4 +1,4 @@
// spell-checker:ignore (flags) reflink (fs) tmpfs
// spell-checker:ignore (flags) reflink (fs) tmpfs (linux) rlimit Rlim NOFILE
use crate::common::util::*;
#[cfg(not(windows))]
@ -14,6 +14,8 @@ use std::os::windows::fs::symlink_file;
#[cfg(target_os = "linux")]
use filetime::FileTime;
#[cfg(target_os = "linux")]
use rlimit::Resource;
#[cfg(not(windows))]
use std::env;
#[cfg(target_os = "linux")]
@ -1276,3 +1278,15 @@ fn test_cp_reflink_insufficient_permission() {
.fails()
.stderr_only("cp: 'unreadable' -> 'existing_file.txt': Permission denied (os error 13)");
}
#[cfg(target_os = "linux")]
#[test]
fn test_closes_file_descriptors() {
new_ucmd!()
.arg("-r")
.arg("--reflink=auto")
.arg("dir_with_10_files/")
.arg("dir_with_10_files_new/")
.with_limit(Resource::NOFILE, 9, 9)
.succeeds();
}

View file

@ -1,5 +1,10 @@
//spell-checker: ignore (linux) rlimit prlimit Rlim
#![allow(dead_code)]
use pretty_assertions::assert_eq;
#[cfg(target_os = "linux")]
use rlimit::{prlimit, rlim};
use std::env;
#[cfg(not(windows))]
use std::ffi::CString;
@ -724,6 +729,8 @@ pub struct UCommand {
stdout: Option<Stdio>,
stderr: Option<Stdio>,
bytes_into_stdin: Option<Vec<u8>>,
#[cfg(target_os = "linux")]
limits: Vec<(rlimit::Resource, rlim, rlim)>,
}
impl UCommand {
@ -758,6 +765,8 @@ impl UCommand {
stdin: None,
stdout: None,
stderr: None,
#[cfg(target_os = "linux")]
limits: vec![],
}
}
@ -855,6 +864,17 @@ impl UCommand {
self
}
#[cfg(target_os = "linux")]
pub fn with_limit(
&mut self,
resource: rlimit::Resource,
soft_limit: rlim,
hard_limit: rlim,
) -> &mut Self {
self.limits.push((resource, soft_limit, hard_limit));
self
}
/// Spawns the command, feeds the stdin if any, and returns the
/// child process immediately.
pub fn run_no_wait(&mut self) -> Child {
@ -871,6 +891,17 @@ impl UCommand {
.spawn()
.unwrap();
#[cfg(target_os = "linux")]
for &(resource, soft_limit, hard_limit) in &self.limits {
prlimit(
child.id() as i32,
resource,
Some((soft_limit, hard_limit)),
None,
)
.unwrap();
}
if let Some(ref input) = self.bytes_into_stdin {
let write_result = child
.stdin

0
tests/fixtures/cp/dir_with_10_files/0 vendored Normal file
View file

0
tests/fixtures/cp/dir_with_10_files/1 vendored Normal file
View file

0
tests/fixtures/cp/dir_with_10_files/2 vendored Normal file
View file

0
tests/fixtures/cp/dir_with_10_files/3 vendored Normal file
View file

0
tests/fixtures/cp/dir_with_10_files/4 vendored Normal file
View file

0
tests/fixtures/cp/dir_with_10_files/5 vendored Normal file
View file

0
tests/fixtures/cp/dir_with_10_files/6 vendored Normal file
View file

0
tests/fixtures/cp/dir_with_10_files/7 vendored Normal file
View file

0
tests/fixtures/cp/dir_with_10_files/8 vendored Normal file
View file

0
tests/fixtures/cp/dir_with_10_files/9 vendored Normal file
View file