mirror of
https://git.meli.delivery/meli/meli
synced 2024-10-30 21:20:34 +00:00
melib/datetime: don't use LC_ category in place of LC_ masks in libc calls
LC_ masks are bit masks, whereas category values are not. Concerns #159 [imap] all mail timestamps are zero/epoch #159 https://git.meli.delivery/meli/meli/issues/159
This commit is contained in:
parent
dd0baa82e9
commit
3697b7d960
@ -41,6 +41,7 @@ use crate::error::{Result, ResultIntoMeliError};
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
pub type UnixTimestamp = u64;
|
pub type UnixTimestamp = u64;
|
||||||
pub const RFC3339_FMT_WITH_TIME: &str = "%Y-%m-%dT%H:%M:%S\0";
|
pub const RFC3339_FMT_WITH_TIME: &str = "%Y-%m-%dT%H:%M:%S\0";
|
||||||
@ -74,14 +75,36 @@ extern "C" {
|
|||||||
fn gettimeofday(tv: *mut libc::timeval, tz: *mut libc::timezone) -> i32;
|
fn gettimeofday(tv: *mut libc::timeval, tz: *mut libc::timezone) -> i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(i32)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
enum LocaleCategoryMask {
|
||||||
|
Time = libc::LC_TIME_MASK,
|
||||||
|
All = libc::LC_ALL_MASK,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(i32)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
enum LocaleCategory {
|
||||||
|
Time = libc::LC_TIME,
|
||||||
|
All = libc::LC_ALL,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "netbsd"))]
|
#[cfg(not(target_os = "netbsd"))]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct Locale {
|
struct Locale {
|
||||||
|
mask: LocaleCategoryMask,
|
||||||
|
category: LocaleCategory,
|
||||||
new_locale: libc::locale_t,
|
new_locale: libc::locale_t,
|
||||||
old_locale: libc::locale_t,
|
old_locale: libc::locale_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "netbsd")]
|
#[cfg(target_os = "netbsd")]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct Locale {
|
struct Locale {
|
||||||
mask: std::os::raw::c_int,
|
mask: LocaleCategoryMask,
|
||||||
|
category: LocaleCategory,
|
||||||
old_locale: *const std::os::raw::c_char,
|
old_locale: *const std::os::raw::c_char,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +117,7 @@ impl Drop for Locale {
|
|||||||
}
|
}
|
||||||
#[cfg(target_os = "netbsd")]
|
#[cfg(target_os = "netbsd")]
|
||||||
unsafe {
|
unsafe {
|
||||||
let _ = libc::setlocale(self.mask, self.old_locale);
|
let _ = libc::setlocale(self.category as c_int, self.old_locale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,11 +126,12 @@ impl Drop for Locale {
|
|||||||
impl Locale {
|
impl Locale {
|
||||||
#[cfg(not(target_os = "netbsd"))]
|
#[cfg(not(target_os = "netbsd"))]
|
||||||
fn new(
|
fn new(
|
||||||
mask: std::os::raw::c_int,
|
mask: LocaleCategoryMask,
|
||||||
|
category: LocaleCategory,
|
||||||
locale: *const std::os::raw::c_char,
|
locale: *const std::os::raw::c_char,
|
||||||
base: libc::locale_t,
|
base: libc::locale_t,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let new_locale = unsafe { libc::newlocale(mask, locale, base) };
|
let new_locale = unsafe { libc::newlocale(mask as c_int, locale, base) };
|
||||||
if new_locale.is_null() {
|
if new_locale.is_null() {
|
||||||
return Err(nix::Error::last().into());
|
return Err(nix::Error::last().into());
|
||||||
}
|
}
|
||||||
@ -117,25 +141,32 @@ impl Locale {
|
|||||||
return Err(nix::Error::last().into());
|
return Err(nix::Error::last().into());
|
||||||
}
|
}
|
||||||
Ok(Locale {
|
Ok(Locale {
|
||||||
|
mask,
|
||||||
|
category,
|
||||||
new_locale,
|
new_locale,
|
||||||
old_locale,
|
old_locale,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "netbsd")]
|
#[cfg(target_os = "netbsd")]
|
||||||
fn new(
|
fn new(
|
||||||
mask: std::os::raw::c_int,
|
mask: LocaleCategoryMask,
|
||||||
|
category: LocaleCategory,
|
||||||
locale: *const std::os::raw::c_char,
|
locale: *const std::os::raw::c_char,
|
||||||
_base: libc::locale_t,
|
_base: libc::locale_t,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let old_locale = unsafe { libc::setlocale(mask, std::ptr::null_mut()) };
|
let old_locale = unsafe { libc::setlocale(category as c_int, std::ptr::null_mut()) };
|
||||||
if old_locale.is_null() {
|
if old_locale.is_null() {
|
||||||
return Err(nix::Error::last().into());
|
return Err(nix::Error::last().into());
|
||||||
}
|
}
|
||||||
let new_locale = unsafe { libc::setlocale(mask, locale) };
|
let new_locale = unsafe { libc::setlocale(category as c_int, locale) };
|
||||||
if new_locale.is_null() {
|
if new_locale.is_null() {
|
||||||
return Err(nix::Error::last().into());
|
return Err(nix::Error::last().into());
|
||||||
}
|
}
|
||||||
Ok(Locale { mask, old_locale })
|
Ok(Locale {
|
||||||
|
mask,
|
||||||
|
category,
|
||||||
|
old_locale,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +197,8 @@ pub fn timestamp_to_string(timestamp: UnixTimestamp, fmt: Option<&str>, posix: b
|
|||||||
let _with_locale: Option<Result<Locale>> = if posix {
|
let _with_locale: Option<Result<Locale>> = if posix {
|
||||||
Some(
|
Some(
|
||||||
Locale::new(
|
Locale::new(
|
||||||
libc::LC_TIME,
|
LocaleCategoryMask::Time,
|
||||||
|
LocaleCategory::Time,
|
||||||
b"C\0".as_ptr() as *const std::os::raw::c_char,
|
b"C\0".as_ptr() as *const std::os::raw::c_char,
|
||||||
std::ptr::null_mut(),
|
std::ptr::null_mut(),
|
||||||
)
|
)
|
||||||
@ -304,7 +336,8 @@ where
|
|||||||
let fmt = unsafe { CStr::from_bytes_with_nul_unchecked(fmt.as_bytes()) };
|
let fmt = unsafe { CStr::from_bytes_with_nul_unchecked(fmt.as_bytes()) };
|
||||||
let ret = {
|
let ret = {
|
||||||
let _with_locale = Locale::new(
|
let _with_locale = Locale::new(
|
||||||
libc::LC_TIME,
|
LocaleCategoryMask::Time,
|
||||||
|
LocaleCategory::Time,
|
||||||
b"C\0".as_ptr() as *const std::os::raw::c_char,
|
b"C\0".as_ptr() as *const std::os::raw::c_char,
|
||||||
std::ptr::null_mut(),
|
std::ptr::null_mut(),
|
||||||
)
|
)
|
||||||
@ -365,7 +398,8 @@ where
|
|||||||
let fmt = unsafe { CStr::from_bytes_with_nul_unchecked(fmt.as_bytes()) };
|
let fmt = unsafe { CStr::from_bytes_with_nul_unchecked(fmt.as_bytes()) };
|
||||||
let ret = {
|
let ret = {
|
||||||
let _with_locale = Locale::new(
|
let _with_locale = Locale::new(
|
||||||
libc::LC_TIME,
|
LocaleCategoryMask::Time,
|
||||||
|
LocaleCategory::Time,
|
||||||
b"C\0".as_ptr() as *const std::os::raw::c_char,
|
b"C\0".as_ptr() as *const std::os::raw::c_char,
|
||||||
std::ptr::null_mut(),
|
std::ptr::null_mut(),
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user