Replace localtime_r with a 64-bit-time_t wrapper

Part of #10634
This commit is contained in:
Johannes Altmanninger 2024-08-07 09:54:41 +02:00
parent 70357c4f6e
commit 3a9b4149da
4 changed files with 22 additions and 14 deletions

View file

@ -16,7 +16,7 @@
//! 5. The chaos_mode boolean can be set to true to do things like lower buffer sizes which can //! 5. The chaos_mode boolean can be set to true to do things like lower buffer sizes which can
//! trigger race conditions. This is useful for testing. //! trigger race conditions. This is useful for testing.
use crate::{common::cstr2wcstring, env::EnvVar, wcstringutil::trim}; use crate::{common::cstr2wcstring, env::EnvVar, libc::localtime64_r, wcstringutil::trim};
use std::{ use std::{
borrow::Cow, borrow::Cow,
collections::{BTreeMap, HashMap, HashSet, VecDeque}, collections::{BTreeMap, HashMap, HashSet, VecDeque},
@ -1409,10 +1409,8 @@ fn format_history_record(
) -> WString { ) -> WString {
let mut result = WString::new(); let mut result = WString::new();
let seconds = time_to_seconds(item.timestamp()); let seconds = time_to_seconds(item.timestamp());
let seconds = seconds as libc::time_t;
let mut timestamp: libc::tm = unsafe { std::mem::zeroed() };
if let Some(show_time_format) = show_time_format.and_then(|s| CString::new(s).ok()) { if let Some(show_time_format) = show_time_format.and_then(|s| CString::new(s).ok()) {
if !unsafe { libc::localtime_r(&seconds, &mut timestamp).is_null() } { if let Some(timestamp) = localtime64_r(seconds) {
const max_tstamp_length: usize = 100; const max_tstamp_length: usize = 100;
let mut timestamp_str = [0_u8; max_tstamp_length]; let mut timestamp_str = [0_u8; max_tstamp_length];
// The libc crate fails to declare strftime on BSD. // The libc crate fails to declare strftime on BSD.

View file

@ -9,6 +9,7 @@
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
@ -213,3 +214,8 @@ bool C_fstatat64(int dirfd, const char* file, int flag, uint64_t* st_dev, uint64
*st_mode = buf.st_mode; *st_mode = buf.st_mode;
return true; return true;
} }
bool C_localtime64_r(int64_t timep, struct tm* result) {
time_t timep_ = timep;
return localtime_r(&timep_, result);
}

View file

@ -112,3 +112,14 @@ extern "C" {
st_mode: *mut libc::mode_t, st_mode: *mut libc::mode_t,
) -> bool; ) -> bool;
} }
pub(crate) fn localtime64_r(timep: i64) -> Option<libc::tm> {
let mut timestamp = unsafe { std::mem::zeroed() };
if !unsafe { C_localtime64_r(timep, &mut timestamp) } {
return None;
}
Some(timestamp)
}
extern "C" {
fn C_localtime64_r(timep: i64, result: *mut libc::tm) -> bool;
}

View file

@ -1,4 +1,5 @@
use crate::env::{EnvMode, EnvStack, EnvVar, EnvVarFlags, Environment}; use crate::env::{EnvMode, EnvStack, EnvVar, EnvVarFlags, Environment};
use crate::libc::localtime64_r;
use crate::tests::prelude::*; use crate::tests::prelude::*;
use crate::wchar::prelude::*; use crate::wchar::prelude::*;
use crate::wutil::wgetcwd; use crate::wutil::wgetcwd;
@ -63,16 +64,8 @@ fn return_timezone_hour(tstamp: SystemTime, timezone: &wstr) -> libc::c_int {
let _var = vars.get(L!("TZ")); let _var = vars.get(L!("TZ"));
let tstamp: libc::time_t = tstamp let tstamp = tstamp.duration_since(UNIX_EPOCH).unwrap().as_secs();
.duration_since(UNIX_EPOCH) localtime64_r(tstamp.try_into().unwrap()).unwrap().tm_hour
.unwrap()
.as_secs()
.try_into()
.unwrap();
let mut local_time: libc::tm = unsafe { std::mem::zeroed() };
unsafe { libc::localtime_r(&tstamp, &mut local_time) };
local_time.tm_hour
} }
/// Verify that setting TZ calls tzset() in the current shell process. /// Verify that setting TZ calls tzset() in the current shell process.