Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions fuzz/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/uu/date/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ jiff = { workspace = true, features = [
] }
parse_datetime = { workspace = true }
regex = { workspace = true }
thiserror = { workspace = true }
uucore = { workspace = true, features = ["parser", "i18n-datetime"] }

[target.'cfg(unix)'.dependencies]
libc = { workspace = true }
nix = { workspace = true, features = ["time"] }

[target.'cfg(windows)'.dependencies]
Expand Down
2 changes: 1 addition & 1 deletion src/uu/date/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ date-error-setting-date-not-supported-macos = setting the date is not supported
date-error-setting-date-not-supported-redox = setting the date is not supported by Redox
date-error-cannot-set-date = cannot set date
date-error-extra-operand = extra operand '{$operand}'
date-error-write = write error: {$error}
date-error-stdout = standard output: {$error}
date-error-format-missing-plus = the argument {$arg} lacks a leading '+';
when using an option to specify date(s), any non-option
argument must be a format string beginning with '+'
4 changes: 2 additions & 2 deletions src/uu/date/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ date-error-setting-date-not-supported-macos = la définition de la date n'est pa
date-error-setting-date-not-supported-redox = la définition de la date n'est pas prise en charge par Redox
date-error-cannot-set-date = impossible de définir la date
date-error-extra-operand = opérande supplémentaire '{$operand}'
date-error-write = erreur d'écriture: {$error}
date-error-stdout = sortie standard: {$error}
date-error-format-missing-plus = l'argument {$arg} ne commence pas par un signe '+';
lorsqu'une option est utilisée pour spécifier une ou plusieurs dates, tout argument autre
lorsqu'une option est utilisée pour spécifier une ou plusieurs dates, tout argument autre
qu'une option doit être une chaîne de format commençant par un signe '+'.
16 changes: 12 additions & 4 deletions src/uu/date/src/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

// spell-checker:ignore strtime ; (format) DATEFILE MMDDhhmm ; (vars) datetime datetimes getres AWST ACST AEST foobarbaz

mod error;
mod format_modifiers;
mod locale;

Expand All @@ -30,6 +31,8 @@ use windows_sys::Win32::{Foundation::SYSTEMTIME, System::SystemInformation::SetS

use uucore::parser::shortcut_value_parser::ShortcutValueParser;

use crate::error::{Error, StdoutError};

// Options
const DATE: &str = "date";
const HOURS: &str = "hours";
Expand Down Expand Up @@ -283,6 +286,11 @@ fn parse_military_timezone_with_offset(s: &str) -> Option<(i32, DayDelta)> {
#[uucore::main]
#[allow(clippy::cognitive_complexity)]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
#[cfg(unix)]
if uucore::signals::stdout_was_closed() {
return Err(Error::from(StdoutError::BadFd).into());
}

let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;

let date_source = if let Some(date_os) = matches.get_one::<std::ffi::OsString>(OPT_DATE) {
Expand Down Expand Up @@ -562,9 +570,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
&config,
skip_localization,
) {
Ok(s) => writeln!(stdout, "{s}").map_err(|e| {
USimpleError::new(1, translate!("date-error-write", "error" => e))
})?,
Ok(s) => {
writeln!(stdout, "{s}").map_err(|e| Error::from(StdoutError::Io(e)))?;
}
Err(e) => {
let _ = stdout.flush();
return Err(USimpleError::new(
Expand All @@ -586,7 +594,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {

stdout
.flush()
.map_err(|e| USimpleError::new(1, translate!("date-error-write", "error" => e)))?;
.map_err(|e| Error::from(StdoutError::Io(e)))?;
Ok(())
}

Expand Down
39 changes: 39 additions & 0 deletions src/uu/date/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This file is part of the uutils coreutils package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use std::io;

use thiserror::Error;
use uucore::error::{UError, strip_errno};
use uucore::translate;

#[derive(Debug, Error)]
pub(crate) enum Error {
#[error("{}", translate!("date-error-stdout", "error" => .0))]
Stdout(StdoutError),
}

impl From<StdoutError> for Error {
fn from(error: StdoutError) -> Self {
Self::Stdout(error)
}
}

impl UError for Error {
fn code(&self) -> i32 {
EXIT_ERR
}
}

#[derive(Debug, Error)]
pub(crate) enum StdoutError {
#[cfg(unix)]
#[error("{}", strip_errno(&io::Error::from_raw_os_error(libc::EBADF)))]
BadFd,
#[error("{}", strip_errno(.0))]
Io(#[from] io::Error),
}

static EXIT_ERR: i32 = 1;
4 changes: 2 additions & 2 deletions tests/by-util/test_date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2229,14 +2229,14 @@ fn test_percent_percent_not_replaced() {

#[test]
#[cfg(target_os = "linux")]
fn test_date_write_error_dev_full() {
fn test_date_stdout_error_dev_full() {
use std::fs::OpenOptions;
let dev_full = OpenOptions::new().write(true).open("/dev/full").unwrap();
new_ucmd!()
.arg("+%s")
.set_stdout(dev_full)
.fails()
.stderr_contains("write error");
.stderr_contains("standard output");
}

// Tests for GNU test leap-1: leap year overflow in date arithmetic
Expand Down
Loading