-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add UTF8LocaleGuard struct and use coarse grained locale setting Missing: - setlocale is not threadsafe, and hance on windows tests fails due to wrong locale beeing restaured Signed-off-by: Jonathas-Conceicao <jonathas.conceicao@ossystems.com.br>
- Loading branch information
Jonathas-Conceicao
committed
Mar 2, 2021
1 parent
a4d0667
commit cda039d
Showing
3 changed files
with
93 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Copyright (C) 2021 O.S. Systems Software LTDA | ||
// | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
|
||
// Change from the C to system locale, allowing libarchive to handle filenames | ||
// in UTF-8. We restrict to change LC_CTYPE only, since libarchive only needs | ||
// the charset set. | ||
// | ||
// See on libarchive Website for a more complete description of the issue: | ||
// | ||
// https://github.com/libarchive/libarchive/issues/587 | ||
// https://github.com/libarchive/libarchive/wiki/Filenames | ||
pub(crate) struct UTF8LocaleGuard { | ||
#[cfg(unix)] | ||
save: libc::locale_t, | ||
|
||
#[cfg(windows)] | ||
save: Option<std::ffi::CString>, | ||
} | ||
|
||
#[cfg(unix)] | ||
impl UTF8LocaleGuard { | ||
pub(crate) fn new() -> Self { | ||
#[cfg(target_os = "linux")] | ||
let locale = b"\0"; | ||
|
||
#[cfg(target_os = "macos")] | ||
let locale = b"UTF-8\0"; | ||
|
||
let utf8_locale = unsafe { | ||
libc::newlocale( | ||
libc::LC_CTYPE_MASK, | ||
locale.as_ptr() as *const libc::c_char, | ||
std::ptr::null_mut(), | ||
) | ||
}; | ||
|
||
let save = unsafe { libc::uselocale(utf8_locale) }; | ||
|
||
Self { save } | ||
} | ||
} | ||
|
||
#[cfg(unix)] | ||
impl Drop for UTF8LocaleGuard { | ||
fn drop(&mut self) { | ||
unsafe { libc::uselocale(self.save) }; | ||
} | ||
} | ||
|
||
#[cfg(windows)] | ||
impl UTF8LocaleGuard { | ||
pub(crate) fn new() -> Self { | ||
let locale = b".UTF-8\0"; | ||
|
||
let save = { | ||
let old_locale = unsafe { libc::setlocale(libc::LC_CTYPE, std::ptr::null()) }; | ||
if old_locale.is_null() { | ||
None | ||
} else { | ||
Some(unsafe { std::ffi::CStr::from_ptr(old_locale) }.to_owned()) | ||
} | ||
}; | ||
|
||
unsafe { | ||
libc::setlocale( | ||
libc::LC_CTYPE, | ||
std::ffi::CStr::from_bytes_with_nul_unchecked(locale).as_ptr(), | ||
) | ||
}; | ||
|
||
Self { save } | ||
} | ||
} | ||
|
||
#[cfg(windows)] | ||
impl Drop for UTF8LocaleGuard { | ||
fn drop(&mut self) { | ||
if let Some(locale) = &self.save { | ||
println!("Restauring to: {}", locale.to_str().unwrap()); | ||
unsafe { libc::setlocale(libc::LC_CTYPE, locale.as_ptr()) }; | ||
} else { | ||
println!("No locale to restaure to"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters