1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

install: implement stripping symbol table (#2047)

This commit is contained in:
Sivachandran 2021-04-10 15:23:29 +05:30 committed by GitHub
parent 698924a20a
commit ee070028e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 126 additions and 8 deletions

View file

@ -23,9 +23,11 @@ use std::fs;
use std::fs::File;
use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::result::Result;
const DEFAULT_MODE: u32 = 0o755;
const DEFAULT_STRIP_PROGRAM: &str = "strip";
#[allow(dead_code)]
pub struct Behavior {
@ -37,6 +39,8 @@ pub struct Behavior {
verbose: bool,
preserve_timestamps: bool,
compare: bool,
strip: bool,
strip_program: String,
}
#[derive(Clone, Eq, PartialEq)]
@ -164,17 +168,15 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.help("apply access/modification times of SOURCE files to corresponding destination files")
)
.arg(
// TODO implement flag
Arg::with_name(OPT_STRIP)
.short("s")
.long(OPT_STRIP)
.help("(unimplemented) strip symbol tables")
.help("strip symbol tables (no action Windows)")
)
.arg(
// TODO implement flag
Arg::with_name(OPT_STRIP_PROGRAM)
.long(OPT_STRIP_PROGRAM)
.help("(unimplemented) program used to strip binaries")
.help("program used to strip binaries (no action Windows)")
.value_name("PROGRAM")
)
.arg(
@ -266,10 +268,6 @@ fn check_unimplemented<'a>(matches: &ArgMatches) -> Result<(), &'a str> {
Err("-b")
} else if matches.is_present(OPT_CREATED) {
Err("-D")
} else if matches.is_present(OPT_STRIP) {
Err("--strip, -s")
} else if matches.is_present(OPT_STRIP_PROGRAM) {
Err("--strip-program")
} else if matches.is_present(OPT_SUFFIX) {
Err("--suffix, -S")
} else if matches.is_present(OPT_TARGET_DIRECTORY) {
@ -339,6 +337,12 @@ fn behavior(matches: &ArgMatches) -> Result<Behavior, i32> {
verbose: matches.is_present(OPT_VERBOSE),
preserve_timestamps: matches.is_present(OPT_PRESERVE_TIMESTAMPS),
compare: matches.is_present(OPT_COMPARE),
strip: matches.is_present(OPT_STRIP),
strip_program: String::from(
matches
.value_of(OPT_STRIP_PROGRAM)
.unwrap_or(DEFAULT_STRIP_PROGRAM),
),
})
}
@ -521,6 +525,21 @@ fn copy(from: &PathBuf, to: &PathBuf, b: &Behavior) -> Result<(), ()> {
return Err(());
}
if b.strip && cfg!(not(windows)) {
match Command::new(&b.strip_program).arg(to).output() {
Ok(o) => {
if !o.status.success() {
crash!(
1,
"strip program failed: {}",
String::from_utf8(o.stderr).unwrap_or_default()
);
}
}
Err(e) => crash!(1, "strip program execution failed: {}", e),
}
}
if mode::chmod(&to, b.mode()).is_err() {
return Err(());
}

View file

@ -2,6 +2,8 @@ use crate::common::util::*;
use filetime::FileTime;
use rust_users::*;
use std::os::unix::fs::PermissionsExt;
#[cfg(not(windows))]
use std::process::Command;
#[cfg(target_os = "linux")]
use std::thread::sleep;
@ -566,3 +568,97 @@ fn test_install_copy_then_compare_file_with_extra_mode() {
assert!(after_install_sticky != after_install_sticky_again);
}
const STRIP_TARGET_FILE: &str = "helloworld_installed";
const SYMBOL_DUMP_PROGRAM: &str = "objdump";
const STRIP_SOURCE_FILE_SYMBOL: &str = "main";
fn strip_source_file() -> &'static str {
if cfg!(target_os = "macos") {
"helloworld_macos"
} else {
"helloworld_linux"
}
}
#[test]
#[cfg(not(windows))]
fn test_install_and_strip() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
scene
.ucmd()
.arg("-s")
.arg(strip_source_file())
.arg(STRIP_TARGET_FILE)
.succeeds()
.no_stderr();
let output = Command::new(SYMBOL_DUMP_PROGRAM)
.arg("-t")
.arg(at.plus(STRIP_TARGET_FILE))
.output()
.unwrap();
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(!stdout.contains(STRIP_SOURCE_FILE_SYMBOL));
}
#[test]
#[cfg(not(windows))]
fn test_install_and_strip_with_program() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
scene
.ucmd()
.arg("-s")
.arg("--strip-program")
.arg("/usr/bin/strip")
.arg(strip_source_file())
.arg(STRIP_TARGET_FILE)
.succeeds()
.no_stderr();
let output = Command::new(SYMBOL_DUMP_PROGRAM)
.arg("-t")
.arg(at.plus(STRIP_TARGET_FILE))
.output()
.unwrap();
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(!stdout.contains(STRIP_SOURCE_FILE_SYMBOL));
}
#[test]
#[cfg(not(windows))]
fn test_install_and_strip_with_invalid_program() {
let scene = TestScenario::new(util_name!());
let stderr = scene
.ucmd()
.arg("-s")
.arg("--strip-program")
.arg("/bin/date")
.arg(strip_source_file())
.arg(STRIP_TARGET_FILE)
.fails()
.stderr;
assert!(stderr.contains("strip program failed"));
}
#[test]
#[cfg(not(windows))]
fn test_install_and_strip_with_non_existent_program() {
let scene = TestScenario::new(util_name!());
let stderr = scene
.ucmd()
.arg("-s")
.arg("--strip-program")
.arg("/usr/bin/non_existent_program")
.arg(strip_source_file())
.arg(STRIP_TARGET_FILE)
.fails()
.stderr;
assert!(stderr.contains("No such file or directory"));
}

3
tests/fixtures/install/helloworld.rs vendored Normal file
View file

@ -0,0 +1,3 @@
fn main() {
println!("Hello World!");
}

BIN
tests/fixtures/install/helloworld_linux vendored Executable file

Binary file not shown.

BIN
tests/fixtures/install/helloworld_macos vendored Executable file

Binary file not shown.