diff --git a/src/uu/mknod/locales/en-US.ftl b/src/uu/mknod/locales/en-US.ftl index 2198bcf382c..15ba5b04ff0 100644 --- a/src/uu/mknod/locales/en-US.ftl +++ b/src/uu/mknod/locales/en-US.ftl @@ -32,3 +32,4 @@ mknod-error-invalid-mode = invalid mode ({ $error }) mknod-error-mode-permission-bits-only = mode must specify only file permission bits mknod-error-missing-device-type = missing device type mknod-error-invalid-device-type = invalid device type { $type } +mknod-error-invalid-device-number = invalid { $kind } device number '{ $value }' diff --git a/src/uu/mknod/locales/fr-FR.ftl b/src/uu/mknod/locales/fr-FR.ftl index c3917aac52c..7f874ea22cd 100644 --- a/src/uu/mknod/locales/fr-FR.ftl +++ b/src/uu/mknod/locales/fr-FR.ftl @@ -32,3 +32,4 @@ mknod-error-invalid-mode = mode invalide ({ $error }) mknod-error-mode-permission-bits-only = le mode ne doit spécifier que les bits de permission de fichier mknod-error-missing-device-type = type de périphérique manquant mknod-error-invalid-device-type = type de périphérique invalide { $type } +mknod-error-invalid-device-number = numéro de périphérique { $kind } invalide '{ $value }' diff --git a/src/uu/mknod/src/mknod.rs b/src/uu/mknod/src/mknod.rs index a4398a03323..f6b46f5c0b8 100644 --- a/src/uu/mknod/src/mknod.rs +++ b/src/uu/mknod/src/mknod.rs @@ -138,6 +138,17 @@ fn mknod(file_name: &str, config: Config) -> i32 { errno } +/// Parses a MAJOR/MINOR device number the way GNU does: a plain `u32`, with +/// any other string -- unparseable or overflowing -- reported the same way. +fn parse_device_number(value: &str, kind: &'static str) -> UResult { + value.parse::().map_err(|_| { + USimpleError::new( + 1, + translate!("mknod-error-invalid-device-number", "kind" => kind, "value" => value.to_owned()), + ) + }) +} + #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let args: Vec = args.collect(); @@ -192,11 +203,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { ))] let context = matches.get_one::(options::CONTEXT).cloned(); - let dev = match ( - file_type, - matches.get_one::(options::MAJOR), - matches.get_one::(options::MINOR), - ) { + let major = matches + .get_one::(options::MAJOR) + .map(|value| parse_device_number(value, "major")) + .transpose()?; + let minor = matches + .get_one::(options::MINOR) + .map(|value| parse_device_number(value, "minor")) + .transpose()?; + + let dev = match (file_type, major, minor) { (FileType::Fifo, None, None) => 0, (FileType::Fifo, _, _) => { return Err(UUsageError::new( @@ -204,7 +220,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { translate!("mknod-error-fifo-no-major-minor"), )); } - (_, Some(&major), Some(&minor)) => makedev(major as _, minor as _) as u64, + (_, Some(major), Some(minor)) => makedev(major as _, minor as _) as u64, _ => { return Err(UUsageError::new( 1, @@ -267,14 +283,12 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::MAJOR) .value_name(options::MAJOR) - .help(translate!("mknod-help-major")) - .value_parser(value_parser!(u32)), + .help(translate!("mknod-help-major")), ) .arg( Arg::new(options::MINOR) .value_name(options::MINOR) - .help(translate!("mknod-help-minor")) - .value_parser(value_parser!(u32)), + .help(translate!("mknod-help-minor")), ) .arg( Arg::new(options::SECURITY_CONTEXT) diff --git a/tests/by-util/test_mknod.rs b/tests/by-util/test_mknod.rs index 49fdbc243f9..db7cda04426 100644 --- a/tests/by-util/test_mknod.rs +++ b/tests/by-util/test_mknod.rs @@ -24,7 +24,7 @@ fn test_mknod_overflow_major_minor() { .arg("1") .fails_with_code(1) .no_stdout() - .stderr_contains("invalid value '4294967296'"); //clap generated message, thats fine. + .stderr_is("mknod: invalid major device number '4294967296'\n"); } #[test] @@ -115,14 +115,14 @@ fn test_mknod_character_device_requires_major_and_minor() { .arg("1") .arg("c") .fails() - .stderr_contains("invalid value 'c'"); + .stderr_is("mknod: invalid minor device number 'c'\n"); new_ucmd!() .arg("test_file") .arg("c") .arg("c") .arg("1") .fails() - .stderr_contains("invalid value 'c'"); + .stderr_is("mknod: invalid major device number 'c'\n"); } #[test]