mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
wsl2: wsl no longer differs in output
refactor `is_wsl` to `is_wsl_1` and `is_wsl_2` On my tests with wsl2 ubuntu2004 all tests pass without special cases I moved wsl detection into uucore so that it can be shared instead of duplicated I moved `parse_mode` into uucode as it seemed to fit there better and anyway requires libc feature
This commit is contained in:
parent
cc4f32d87a
commit
b1fcb621a8
11 changed files with 84 additions and 84 deletions
|
@ -7,8 +7,6 @@
|
|||
|
||||
// spell-checker:ignore (ToDO) parsemode makedev sysmacros makenod newmode perror IFBLK IFCHR IFIFO
|
||||
|
||||
mod parsemode;
|
||||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
|
@ -98,7 +96,7 @@ for details about the options it supports.",
|
|||
let mut last_umask: mode_t = 0;
|
||||
let mut newmode: mode_t = MODE_RW_UGO;
|
||||
if matches.opt_present("mode") {
|
||||
match parsemode::parse_mode(matches.opt_str("mode")) {
|
||||
match uucore::mode::parse_mode(matches.opt_str("mode")) {
|
||||
Ok(parsed) => {
|
||||
if parsed > 0o777 {
|
||||
show_info!("mode must specify only file permission bits");
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
// spell-checker:ignore (ToDO) fperm
|
||||
|
||||
use libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR};
|
||||
|
||||
use uucore::mode;
|
||||
|
||||
pub fn parse_mode(mode: Option<String>) -> Result<mode_t, String> {
|
||||
let fperm = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
if let Some(mode) = mode {
|
||||
let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
let result = if mode.contains(arr) {
|
||||
mode::parse_numeric(fperm as u32, mode.as_str())
|
||||
} else {
|
||||
mode::parse_symbolic(fperm as u32, mode.as_str(), true)
|
||||
};
|
||||
result.map(|mode| mode as mode_t)
|
||||
} else {
|
||||
Ok(fperm)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
/// Test if the program is running under WSL
|
||||
// ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
|
||||
// ToDO: test on WSL2 which likely doesn't need special handling; plan change to `is_wsl_1()` if WSL2 is less needy
|
||||
pub fn is_wsl() -> bool {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
if let Ok(b) = std::fs::read("/proc/sys/kernel/osrelease") {
|
||||
if let Ok(s) = std::str::from_utf8(&b) {
|
||||
let a = s.to_ascii_lowercase();
|
||||
return a.contains("microsoft") || a.contains("wsl");
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn symbolic_modes() {
|
||||
assert_eq!(super::parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
|
||||
assert_eq!(
|
||||
super::parse_mode(Some("+x".to_owned())).unwrap(),
|
||||
if !is_wsl() { 0o777 } else { 0o776 }
|
||||
);
|
||||
assert_eq!(super::parse_mode(Some("a-w".to_owned())).unwrap(), 0o444);
|
||||
assert_eq!(super::parse_mode(Some("g-r".to_owned())).unwrap(), 0o626);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn numeric_modes() {
|
||||
assert_eq!(super::parse_mode(Some("644".to_owned())).unwrap(), 0o644);
|
||||
assert_eq!(super::parse_mode(Some("+100".to_owned())).unwrap(), 0o766);
|
||||
assert_eq!(super::parse_mode(Some("-4".to_owned())).unwrap(), 0o662);
|
||||
assert_eq!(super::parse_mode(None).unwrap(), 0o666);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
// spell-checker:ignore (vars) fperm srwx
|
||||
|
||||
use libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR};
|
||||
|
||||
pub fn parse_numeric(fperm: u32, mut mode: &str) -> Result<u32, String> {
|
||||
let (op, pos) = parse_op(mode, Some('='))?;
|
||||
mode = mode[pos..].trim().trim_start_matches('0');
|
||||
|
@ -129,3 +131,41 @@ fn parse_change(mode: &str, fperm: u32, considering_dir: bool) -> (u32, usize) {
|
|||
}
|
||||
(srwx, pos)
|
||||
}
|
||||
|
||||
pub fn parse_mode(mode: Option<String>) -> Result<mode_t, String> {
|
||||
let fperm = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
if let Some(mode) = mode {
|
||||
let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
let result = if mode.contains(arr) {
|
||||
parse_numeric(fperm as u32, mode.as_str())
|
||||
} else {
|
||||
parse_symbolic(fperm as u32, mode.as_str(), true)
|
||||
};
|
||||
result.map(|mode| mode as mode_t)
|
||||
} else {
|
||||
Ok(fperm)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
#[test]
|
||||
fn symbolic_modes() {
|
||||
assert_eq!(super::parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
|
||||
assert_eq!(
|
||||
super::parse_mode(Some("+x".to_owned())).unwrap(),
|
||||
if !crate::os::is_wsl_1() { 0o777 } else { 0o776 }
|
||||
);
|
||||
assert_eq!(super::parse_mode(Some("a-w".to_owned())).unwrap(), 0o444);
|
||||
assert_eq!(super::parse_mode(Some("g-r".to_owned())).unwrap(), 0o626);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn numeric_modes() {
|
||||
assert_eq!(super::parse_mode(Some("644".to_owned())).unwrap(), 0o644);
|
||||
assert_eq!(super::parse_mode(Some("+100".to_owned())).unwrap(), 0o766);
|
||||
assert_eq!(super::parse_mode(Some("-4".to_owned())).unwrap(), 0o662);
|
||||
assert_eq!(super::parse_mode(None).unwrap(), 0o666);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ mod mods; // core cross-platform modules
|
|||
|
||||
// * cross-platform modules
|
||||
pub use crate::mods::coreopts;
|
||||
pub use crate::mods::os;
|
||||
pub use crate::mods::panic;
|
||||
pub use crate::mods::ranges;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// mods ~ cross-platforms modules (core/bundler file)
|
||||
|
||||
pub mod coreopts;
|
||||
pub mod os;
|
||||
pub mod panic;
|
||||
pub mod ranges;
|
||||
|
|
30
src/uucore/src/lib/mods/os.rs
Normal file
30
src/uucore/src/lib/mods/os.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
/// Test if the program is running under WSL
|
||||
// ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
|
||||
pub fn is_wsl_1() -> bool {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
if is_wsl_2() {
|
||||
return false;
|
||||
}
|
||||
if let Ok(b) = std::fs::read("/proc/sys/kernel/osrelease") {
|
||||
if let Ok(s) = std::str::from_utf8(&b) {
|
||||
let a = s.to_ascii_lowercase();
|
||||
return a.contains("microsoft") || a.contains("wsl");
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn is_wsl_2() -> bool {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
if let Ok(b) = std::fs::read("/proc/sys/kernel/osrelease") {
|
||||
if let Ok(s) = std::str::from_utf8(&b) {
|
||||
let a = s.to_ascii_lowercase();
|
||||
return a.contains("wsl2");
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
use crate::common::util::*;
|
||||
use rust_users::*;
|
||||
use uucore;
|
||||
|
||||
#[test]
|
||||
fn test_invalid_option() {
|
||||
|
@ -104,7 +105,7 @@ fn test_reference() {
|
|||
// skip for root or MS-WSL
|
||||
// * MS-WSL is bugged (as of 2019-12-25), allowing non-root accounts su-level privileges for `chgrp`
|
||||
// * for MS-WSL, succeeds and stdout == 'group of /etc retained as root'
|
||||
if !(get_effective_gid() == 0 || is_wsl()) {
|
||||
if !(get_effective_gid() == 0 || uucore::os::is_wsl_1()) {
|
||||
new_ucmd!()
|
||||
.arg("-v")
|
||||
.arg("--reference=/etc/passwd")
|
||||
|
|
|
@ -4,6 +4,7 @@ use self::regex::Regex;
|
|||
use crate::common::util::*;
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
use rust_users::*;
|
||||
use uucore;
|
||||
|
||||
#[test]
|
||||
fn test_date_email() {
|
||||
|
@ -159,7 +160,7 @@ fn test_date_set_invalid() {
|
|||
#[test]
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
fn test_date_set_permissions_error() {
|
||||
if !(get_effective_uid() == 0 || is_wsl()) {
|
||||
if !(get_effective_uid() == 0 || uucore::os::is_wsl_1()) {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--set").arg("2020-03-11 21:45:00+08:00").fails();
|
||||
let result = result.no_stdout();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::common::util::*;
|
||||
use uucore;
|
||||
|
||||
const SUB_DIR: &str = "subdir/deeper";
|
||||
const SUB_DIR_LINKS: &str = "subdir/links";
|
||||
|
@ -52,7 +53,7 @@ fn _du_basics_subdir(s: String) {
|
|||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
fn _du_basics_subdir(s: String) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
if !uucore::os::is_wsl_1() {
|
||||
assert_eq!(s, "8\tsubdir/deeper\n");
|
||||
} else {
|
||||
assert_eq!(s, "0\tsubdir/deeper\n");
|
||||
|
@ -96,7 +97,7 @@ fn _du_soft_link(s: String) {
|
|||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
fn _du_soft_link(s: String) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
if !uucore::os::is_wsl_1() {
|
||||
assert_eq!(s, "16\tsubdir/links\n");
|
||||
} else {
|
||||
assert_eq!(s, "8\tsubdir/links\n");
|
||||
|
@ -128,7 +129,7 @@ fn _du_hard_link(s: String) {
|
|||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
fn _du_hard_link(s: String) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
if !uucore::os::is_wsl_1() {
|
||||
assert_eq!(s, "16\tsubdir/links\n");
|
||||
} else {
|
||||
assert_eq!(s, "8\tsubdir/links\n");
|
||||
|
@ -156,7 +157,7 @@ fn _du_d_flag(s: String) {
|
|||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
fn _du_d_flag(s: String) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
if !uucore::os::is_wsl_1() {
|
||||
assert_eq!(s, "28\t./subdir\n36\t./\n");
|
||||
} else {
|
||||
assert_eq!(s, "8\t./subdir\n8\t./\n");
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::common::util::*;
|
||||
use std::env;
|
||||
use uucore;
|
||||
|
||||
#[test]
|
||||
fn test_normal() {
|
||||
|
@ -13,7 +14,7 @@ fn test_normal() {
|
|||
for (key, value) in env::vars() {
|
||||
println!("{}: {}", key, value);
|
||||
}
|
||||
if (is_ci() || is_wsl()) && result.stderr.contains("error: no login name") {
|
||||
if (is_ci() || uucore::os::is_wsl_1()) && result.stderr.contains("error: no login name") {
|
||||
// ToDO: investigate WSL failure
|
||||
// In the CI, some server are failing to return logname.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
|
|
|
@ -40,22 +40,6 @@ pub fn is_ci() -> bool {
|
|||
.eq_ignore_ascii_case("true")
|
||||
}
|
||||
|
||||
/// Test if the program is running under WSL
|
||||
// ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
|
||||
// ToDO: test on WSL2 which likely doesn't need special handling; plan change to `is_wsl_1()` if WSL2 is less needy
|
||||
pub fn is_wsl() -> bool {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
if let Ok(b) = std::fs::read("/proc/sys/kernel/osrelease") {
|
||||
if let Ok(s) = std::str::from_utf8(&b) {
|
||||
let a = s.to_ascii_lowercase();
|
||||
return a.contains("microsoft") || a.contains("wsl");
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Read a test scenario fixture, returning its bytes
|
||||
fn read_scenario_fixture<S: AsRef<OsStr>>(tmpd: &Option<Rc<TempDir>>, file_rel_path: S) -> Vec<u8> {
|
||||
let tmpdir_path = tmpd.as_ref().unwrap().as_ref().path();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue