Skip to content

Commit b7ee733

Browse files
authored
Merge branch 'main' into mac-debug
2 parents b30cd30 + 2d718f2 commit b7ee733

File tree

21 files changed

+518
-64
lines changed

21 files changed

+518
-64
lines changed

.github/workflows/GnuTests.yml

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: GnuTests
22

33
# spell-checker:ignore (abbrev/names) CodeCov gnulib GnuTests Swatinem
44
# spell-checker:ignore (jargon) submodules devel
5-
# spell-checker:ignore (libs/utils) autopoint chksum dpkg getenforce getlimits gperf lcov libexpect limactl pyinotify setenforce shopt texinfo valgrind libattr libcap taiki-e
5+
# spell-checker:ignore (libs/utils) autopoint chksum dpkg getenforce getlimits gperf lcov libexpect limactl pyinotify setenforce shopt texinfo valgrind libattr libcap taiki-e zstd cpio
66
# spell-checker:ignore (options) Ccodegen Coverflow Cpanic Zpanic
77
# spell-checker:ignore (people) Dawid Dziurla * dawidd dtolnay
88
# spell-checker:ignore (vars) FILESET SUBDIRS XPASS
@@ -31,6 +31,7 @@ env:
3131
TEST_STTY_FULL_SUMMARY_FILE: 'gnu-stty-full-result.json'
3232
TEST_SELINUX_FULL_SUMMARY_FILE: 'selinux-gnu-full-result.json'
3333
TEST_SELINUX_ROOT_FULL_SUMMARY_FILE: 'selinux-root-gnu-full-result.json'
34+
TEST_SMACK_FULL_SUMMARY_FILE: 'smack-gnu-full-result.json'
3435

3536
jobs:
3637
native:
@@ -318,8 +319,52 @@ jobs:
318319
gnu/tests-selinux/*.log
319320
gnu/tests-selinux/*/*.log.gz
320321
322+
smack:
323+
name: Run GNU tests (SMACK)
324+
runs-on: ubuntu-24.04
325+
steps:
326+
- name: Checkout code (uutils)
327+
uses: actions/checkout@v6
328+
with:
329+
path: 'uutils'
330+
persist-credentials: false
331+
- uses: dtolnay/rust-toolchain@master
332+
with:
333+
toolchain: stable
334+
components: rustfmt
335+
- uses: Swatinem/rust-cache@v2
336+
with:
337+
workspaces: "./uutils -> target"
338+
- name: Checkout code (GNU coreutils)
339+
run: (mkdir -p gnu && cd gnu && bash ../uutils/util/fetch-gnu.sh)
340+
- name: Install dependencies
341+
run: |
342+
sudo apt-get update
343+
sudo apt-get install -y qemu-system-x86 zstd cpio
344+
- name: Run GNU SMACK tests
345+
run: |
346+
cd uutils
347+
bash util/run-gnu-tests-smack-ci.sh "$GITHUB_WORKSPACE/gnu" "$GITHUB_WORKSPACE/gnu/tests-smack"
348+
- name: Extract testing info into JSON
349+
run: |
350+
python3 uutils/util/gnu-json-result.py gnu/tests-smack > ${{ env.TEST_SMACK_FULL_SUMMARY_FILE }}
351+
- name: Upload SMACK json results
352+
uses: actions/upload-artifact@v6
353+
with:
354+
name: smack-gnu-full-result
355+
path: ${{ env.TEST_SMACK_FULL_SUMMARY_FILE }}
356+
- name: Compress SMACK test logs
357+
run: gzip gnu/tests-smack/*/*.log 2>/dev/null || true
358+
- name: Upload SMACK test logs
359+
uses: actions/upload-artifact@v6
360+
with:
361+
name: smack-test-logs
362+
path: |
363+
gnu/tests-smack/*.log
364+
gnu/tests-smack/*/*.log.gz
365+
321366
aggregate:
322-
needs: [native, selinux]
367+
needs: [native, selinux, smack]
323368
permissions:
324369
actions: read # for dawidd6/action-download-artifact to query and download artifacts
325370
contents: read # for actions/checkout to fetch code
@@ -384,6 +429,12 @@ jobs:
384429
name: selinux-root-gnu-full-result
385430
path: results
386431
merge-multiple: true
432+
- name: Download smack json results
433+
uses: actions/download-artifact@v7
434+
with:
435+
name: smack-gnu-full-result
436+
path: results
437+
merge-multiple: true
387438
- name: Extract/summarize testing info
388439
id: summary
389440
shell: bash
@@ -394,8 +445,8 @@ jobs:
394445
path_UUTILS='uutils'
395446
396447
json_count=$(ls -l results/*.json | wc -l)
397-
if [[ "$json_count" -ne 5 ]]; then
398-
echo "::error ::Failed to download all results json files (expected 4 files, found $json_count); failing early"
448+
if [[ "$json_count" -ne 6 ]]; then
449+
echo "::error ::Failed to download all results json files (expected 6 files, found $json_count); failing early"
399450
ls -lR results || true
400451
exit 1
401452
fi

.github/workflows/openbsd.yml

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,14 @@ jobs:
4444
# We need jq and GNU coreutils to run show-utils.sh and bash to use inline shell string replacement
4545
# Use sudo-- to get the default sudo package without ambiguity
4646
# Install rust and cargo from OpenBSD packages
47-
prepare: pkg_add curl sudo-- jq coreutils bash rust rust-clippy rust-rustfmt llvm--
47+
prepare: |
48+
# Clean up disk space before installing packages
49+
df -h
50+
rm -rf /usr/share/doc/* /usr/share/man/* /var/cache/* /tmp/* || true
51+
pkg_add curl sudo-- jq coreutils bash rust rust-clippy rust-rustfmt llvm--
52+
# Clean up package cache after installation
53+
pkg_delete -a || true
54+
df -h
4855
run: |
4956
## Prepare, build, and test
5057
# implementation modelled after ref: <https://github.com/rust-lang/rustup/pull/2783>
@@ -106,8 +113,10 @@ jobs:
106113
# * convert any warnings to GHA UI annotations; ref: <https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message>
107114
S=\$(cargo clippy --all-targets \${CARGO_UTILITY_LIST_OPTIONS} -- -D warnings 2>&1) && printf "%s\n" "\$S" || { printf "%s\n" "\$S" ; printf "%s" "\$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*\$/::\${FAULT_TYPE} file=\2,line=\3,col=\4::\${FAULT_PREFIX}: \\\`cargo clippy\\\`: \1 (file:'\2', line:\3)/p;" -e '}' ; FAULT=true ; }
108115
fi
109-
# Clean to avoid to rsync back the files
116+
# Clean to avoid to rsync back the files and free up disk space
110117
cargo clean
118+
# Additional cleanup to free disk space
119+
rm -rf ~/.cargo/registry/cache ~/.cargo/git/db || true
111120
if [ -n "\${FAIL_ON_FAULT}" ] && [ -n "\${FAULT}" ]; then exit 1 ; fi
112121
EOF
113122
@@ -132,7 +141,14 @@ jobs:
132141
copyback: false
133142
mem: 4096
134143
# Install rust and build dependencies from OpenBSD packages (llvm provides libclang for bindgen)
135-
prepare: pkg_add curl gmake sudo-- jq rust llvm--
144+
prepare: |
145+
# Clean up disk space before installing packages
146+
df -h
147+
rm -rf /usr/share/doc/* /usr/share/man/* /var/cache/* /tmp/* || true
148+
pkg_add curl gmake sudo-- jq rust llvm--
149+
# Clean up package cache after installation
150+
pkg_delete -a || true
151+
df -h
136152
run: |
137153
## Prepare, build, and test
138154
# implementation modelled after ref: <https://github.com/rust-lang/rustup/pull/2783>
@@ -181,9 +197,13 @@ jobs:
181197
cd "${WORKSPACE}"
182198
unset FAULT
183199
cargo build || FAULT=1
200+
# Clean build artifacts to save disk space before testing
201+
rm -rf target/debug/build target/debug/incremental || true
184202
export PATH=~/.cargo/bin:${PATH}
185203
export RUST_BACKTRACE=1
186204
export CARGO_TERM_COLOR=always
205+
# Avoid filling disk space
206+
export RUSTFLAGS="-C strip=symbols"
187207
# Use cargo test since nextest might not support OpenBSD
188208
if (test -z "\$FAULT"); then cargo test --features '${{ matrix.job.features }}' || FAULT=1 ; fi
189209
# There is no systemd-logind on OpenBSD, so test all features except feat_systemd_logind
@@ -193,7 +213,9 @@ jobs:
193213
fi
194214
# Test building with make
195215
if (test -z "\$FAULT"); then make || FAULT=1 ; fi
196-
# Clean to avoid to rsync back the files
216+
# Clean to avoid to rsync back the files and free up disk space
197217
cargo clean
218+
# Additional cleanup to free disk space
219+
rm -rf ~/.cargo/registry/cache ~/.cargo/git/db target/debug/deps target/release/deps || true
198220
if (test -n "\$FAULT"); then exit 1 ; fi
199221
EOF

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ are some tips for writing good issues:
8787
- What platform are you on?
8888
- Provide a way to reliably reproduce the issue.
8989
- Be as specific as possible!
90+
- Please provide the output with LANG=C, except for locale-related bugs.
9091

9192
### Writing Documentation
9293

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ feat_selinux = [
6565
"selinux",
6666
"stat/selinux",
6767
]
68+
# "feat_smack" == enable support for SMACK Security Context (by using `--features feat_smack`)
69+
# NOTE:
70+
# * Running a uutils compiled with `feat_smack` requires a SMACK enabled Kernel at run time.
71+
feat_smack = ["ls/smack"]
6872
##
6973
## feature sets
7074
## (common/core and Tier1) feature sets

README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,6 @@ options might be missing or different behavior might be experienced.
3232
We provide prebuilt binaries at https://github.com/uutils/coreutils/releases/latest .
3333
It is recommended to install from main branch if you install from source.
3434

35-
To install it:
36-
37-
```shell
38-
cargo install --git https://github.com/uutils/coreutils coreutils
39-
# cargo install --git https://github.com/uutils/coreutils uu_true # for one util only
40-
~/.cargo/bin/coreutils
41-
```
42-
4335
</div>
4436

4537
<!-- markdownlint-disable-next-line MD026 -->

src/uu/date/src/locale.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,23 @@ cfg_langinfo! {
2929
use std::ffi::CStr;
3030
use std::sync::OnceLock;
3131
use nix::libc;
32+
33+
#[cfg(test)]
34+
use std::sync::Mutex;
3235
}
3336

3437
cfg_langinfo! {
3538
/// Cached locale date/time format string
3639
static DEFAULT_FORMAT_CACHE: OnceLock<&'static str> = OnceLock::new();
3740

41+
/// Mutex to serialize setlocale() calls during tests.
42+
///
43+
/// setlocale() is process-global, so parallel tests that call it can
44+
/// interfere with each other. This mutex ensures only one test accesses
45+
/// locale functions at a time.
46+
#[cfg(test)]
47+
static LOCALE_MUTEX: Mutex<()> = Mutex::new(());
48+
3849
/// Returns the default date format string for the current locale.
3950
///
4051
/// The format respects locale preferences for time display (12-hour vs 24-hour),
@@ -61,6 +72,11 @@ cfg_langinfo! {
6172

6273
/// Retrieves the date/time format string from the system locale
6374
fn get_locale_format_string() -> Option<String> {
75+
// In tests, acquire mutex to prevent race conditions with setlocale()
76+
// which is process-global and not thread-safe
77+
#[cfg(test)]
78+
let _lock = LOCALE_MUTEX.lock().unwrap();
79+
6480
unsafe {
6581
// Set locale from environment variables
6682
let _locale_result = libc::setlocale(libc::LC_TIME, c"".as_ptr());
@@ -213,11 +229,24 @@ mod tests {
213229

214230
#[test]
215231
fn test_c_locale_format() {
216-
// Save original locale
232+
// Acquire mutex to prevent interference with other tests
233+
let _lock = LOCALE_MUTEX.lock().unwrap();
234+
235+
// Save original locale (both environment and process locale)
217236
let original_lc_all = std::env::var("LC_ALL").ok();
218237
let original_lc_time = std::env::var("LC_TIME").ok();
219238
let original_lang = std::env::var("LANG").ok();
220239

240+
// Save current process locale
241+
let original_process_locale = unsafe {
242+
let ptr = libc::setlocale(libc::LC_TIME, std::ptr::null());
243+
if ptr.is_null() {
244+
None
245+
} else {
246+
CStr::from_ptr(ptr).to_str().ok().map(|s| s.to_string())
247+
}
248+
};
249+
221250
unsafe {
222251
// Set C locale
223252
std::env::set_var("LC_ALL", "C");
@@ -232,7 +261,7 @@ mod tests {
232261
if d_t_fmt_ptr.is_null() {
233262
None
234263
} else {
235-
std::ffi::CStr::from_ptr(d_t_fmt_ptr).to_str().ok()
264+
CStr::from_ptr(d_t_fmt_ptr).to_str().ok()
236265
}
237266
};
238267

@@ -245,7 +274,7 @@ mod tests {
245274
assert!(uses_24_hour, "C locale should use 24-hour format, got: {locale_format}");
246275
}
247276

248-
// Restore original locale
277+
// Restore original environment variables
249278
unsafe {
250279
if let Some(val) = original_lc_all {
251280
std::env::set_var("LC_ALL", val);
@@ -263,6 +292,17 @@ mod tests {
263292
std::env::remove_var("LANG");
264293
}
265294
}
295+
296+
// Restore original process locale
297+
unsafe {
298+
if let Some(locale) = original_process_locale {
299+
let c_locale = std::ffi::CString::new(locale).unwrap();
300+
libc::setlocale(libc::LC_TIME, c_locale.as_ptr());
301+
} else {
302+
// Restore from environment
303+
libc::setlocale(libc::LC_TIME, c"".as_ptr());
304+
}
305+
}
266306
}
267307

268308
#[test]

src/uu/ls/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ harness = false
6060

6161
[features]
6262
feat_selinux = ["selinux", "uucore/selinux"]
63+
smack = ["uucore/smack"]

src/uu/ls/locales/en-US.ftl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,13 @@ ls-invalid-columns-width = ignoring invalid width in environment variable COLUMN
124124
ls-invalid-ignore-pattern = Invalid pattern for ignore: {$pattern}
125125
ls-invalid-hide-pattern = Invalid pattern for hide: {$pattern}
126126
ls-total = total {$size}
127+
128+
# Security context warnings
129+
ls-warning-failed-to-get-security-context = failed to get security context of: {$path}
130+
ls-warning-getting-security-context = getting security context of: {$path}: {$error}
131+
132+
# SMACK error messages (used by uucore::smack when called from ls)
133+
smack-error-not-enabled = SMACK is not enabled on this system
134+
smack-error-label-retrieval-failure = failed to get SMACK label: { $error }
135+
smack-error-label-set-failure = failed to set SMACK label to '{ $context }': { $error }
136+
smack-error-no-label-set = no SMACK label set

0 commit comments

Comments
 (0)