Merge branch 'master' into iss1769

This commit is contained in:
Jan Scheer
2021-03-25 23:23:08 +01:00
committed by GitHub
81 changed files with 3800 additions and 1436 deletions
+58 -25
View File
@@ -34,46 +34,74 @@ jobs:
shell: bash
run: |
sudo apt-get update
sudo apt-get install autoconf autopoint bison texinfo gperf gcc g++ gdb python-pyinotify expect python3-sphinx
sudo apt-get install autoconf autopoint bison texinfo gperf gcc g++ gdb python-pyinotify python3-sphinx
pushd uutils
make PROFILE=release
BUILDDIR="$PWD/target/release/"
cp "${BUILDDIR}/install" "${BUILDDIR}/ginstall" # The GNU tests rename this script before running, to avoid confusion with the make target
# Create *sum binaries
for sum in b2sum md5sum sha1sum sha224sum sha256sum sha384sum sha512sum
do
sum_path="${BUILDDIR}/${sum}"
test -f "${sum_path}" || cp "${BUILDDIR}/hashsum" "${sum_path}"
done
test -f "${BUILDDIR}/[" || cp "${BUILDDIR}/test" "${BUILDDIR}/["
popd
GNULIB_SRCDIR="$PWD/gnulib"
pushd gnu/
# Any binaries that aren't built become `false` so their tests fail
for binary in $(./build-aux/gen-lists-of-programs.sh --list-progs)
do
bin_path="${BUILDDIR}/${binary}"
test -f "${bin_path}" || { echo "'${binary}' was not built with uutils, using the 'false' program"; cp "${BUILDDIR}/false" "${bin_path}"; }
done
./bootstrap --gnulib-srcdir="$GNULIB_SRCDIR"
./configure --quiet --disable-gcc-warnings
#Add timeout to to protect against hangs
sed -i 's|"\$@|/usr/bin/timeout 600 "\$@|' build-aux/test-driver
# Change the PATH in the Makefile to test the uutils coreutils instead of the GNU coreutils
sed -i "s/^[[:blank:]]*PATH=.*/ PATH='${BUILDDIR//\//\\/}\$(PATH_SEPARATOR)'\"\$\$PATH\" \\\/" Makefile
sed -i 's| tr | /usr/bin/tr |' tests/init.sh
make
# Generate the factor tests, so they can be fixed
for i in $(seq -w 1 36)
for i in {00..36}
do
make tests/factor/t${i}.sh
done
grep -rl 'path_prepend_' tests/* | xargs sed -i 's|path_prepend_ ./src||'
sed -i -e 's|^seq |/usr/bin/seq |' tests/factor/t*sh
sed -i -e '/tests\/misc\/cat-self.sh/ D' Makefile # issue #1707
sed -i -e '/tests\/misc\/numfmt.pl/ D' Makefile # issue #1708
sed -i -e '/tests\/chown\/preserve-root.sh/ D' Makefile # issue #1709
sed -i -e '/tests\/cp\/file-perm-race.sh/ D' Makefile # issue #1710
sed -i -e '/tests\/cp\/special-f.sh/ D' Makefile # issue #1710
sed -i -e '/tests\/mv\/mv-special-1.sh/ D' Makefile # issue #1710
sed -i -e '/tests\/dd\/stats.sh/ D' Makefile # issue #1710
sed -i -e '/tests\/cp\/existing-perm-race.sh/ D' Makefile # hangs, cp doesn't implement --copy-contents
# Remove tests that rely on seq with large numbers. See issue #1703
sed -i -e '/tests\/misc\/seq.pl/ D' \
-e '/tests\/misc\/seq-precision.sh/D' \
Makefile
sed -i -e 's|^seq |/usr/bin/seq |' -e 's|sha1sum |/usr/bin/sha1sum |' tests/factor/t*sh
# Remove tests checking for --version & --help
# Not really interesting for us and logs are too big
sed -i -e '/tests\/misc\/invalid-opt.pl/ D' \
-e '/tests\/misc\/help-version.sh/ D' \
-e '/tests\/misc\/help-version-getopt.sh/ D' \
Makefile
sed -i -e '/tests\/tail-2\/pid.sh/ D' Makefile # hangs on github, tail doesn't support -f
sed -i -e'/incompat4/ D' -e"/options '-co' are incompatible/ d" tests/misc/sort.pl # Sort doesn't correctly check for incompatible options, waits for input
# Use the system coreutils where the test fails due to error in a util that is not the one being tested
sed -i 's|stat|/usr/bin/stat|' tests/chgrp/basic.sh tests/cp/existing-perm-dir.sh tests/touch/60-seconds.sh tests/misc/sort-compress-proc.sh
sed -i 's|ls -|/usr/bin/ls -|' tests/chgrp/posix-H.sh tests/chown/deref.sh tests/cp/same-file.sh tests/misc/mknod.sh tests/mv/part-symlink.sh tests/du/8gb.sh
sed -i 's|mkdir |/usr/bin/mkdir |' tests/cp/existing-perm-dir.sh tests/rm/empty-inacc.sh
sed -i 's|timeout \([[:digit:]]\)| /usr/bin/timeout \1|' tests/tail-2/inotify-rotate.sh tests/tail-2/inotify-dir-recreate.sh tests/tail-2/inotify-rotate-resources.sh tests/cp/parent-perm-race.sh tests/ls/infloop.sh tests/misc/sort-exit-early.sh tests/misc/sort-NaN-infloop.sh tests/misc/uniq-perf.sh tests/tail-2/inotify-only-regular.sh tests/tail-2/pipe-f2.sh tests/tail-2/retry.sh tests/tail-2/symlink.sh tests/tail-2/wait.sh tests/tail-2/pid.sh tests/dd/stats.sh tests/tail-2/follow-name.sh # Don't break the function called 'grep_timeout'
sed -i 's|chmod |/usr/bin/chmod |' tests/du/inacc-dir.sh tests/mkdir/p-3.sh tests/tail-2/tail-n0f.sh tests/cp/fail-perm.sh tests/du/inaccessible-cwd.sh tests/mv/i-2.sh tests/chgrp/basic.sh
sed -i 's|sort |/usr/bin/sort |' tests/ls/hyperlink.sh tests/misc/test-N.sh
sed -i 's|split |/usr/bin/split |' tests/misc/factor-parallel.sh
sed -i 's|truncate |/usr/bin/truncate |' tests/split/fail.sh
sed -i 's|dd |/usr/bin/dd |' tests/du/8gb.sh tests/tail-2/big-4gb.sh tests/cp/fiemap-2.sh init.cfg
sed -i 's|id -|/usr/bin/id -|' tests/misc/runcon-no-reorder.sh
sed -i 's|touch |/usr/bin/touch |' tests/cp/preserve-link.sh tests/cp/reflink-perm.sh tests/ls/block-size.sh tests/ls/abmon-align.sh tests/ls/rt-1.sh tests/mv/update.sh tests/misc/ls-time.sh tests/misc/stat-nanoseconds.sh tests/misc/time-style.sh tests/misc/test-N.sh
sed -i 's|ln -|/usr/bin/ln -|' tests/cp/link-deref.sh
sed -i 's|printf |/usr/bin/printf |' tests/dd/ascii.sh
sed -i 's|cp |/usr/bin/cp |' tests/mv/hard-2.sh
sed -i 's|paste |/usr/bin/paste |' tests/misc/od-endian.sh
sed -i 's|seq |/usr/bin/seq |' tests/misc/sort-discrim.sh
#Add specific timeout to tests that currently hang to limit time spent waiting
sed -i 's|seq \$|/usr/bin/timeout 0.1 seq \$|' tests/misc/seq-precision.sh tests/misc/seq-long-double.sh
sed -i 's|cat |/usr/bin/timeout 0.1 cat |' tests/misc/cat-self.sh
test -f "${BUILDDIR}/getlimits" || cp src/getlimits "${BUILDDIR}"
- name: Run GNU tests
@@ -83,17 +111,22 @@ jobs:
GNULIB_DIR="${PWD}/gnulib"
pushd gnu
unbuffer timeout -sKILL 3600 make -j "$(nproc)" check SUBDIRS=. RUN_EXPENSIVE_TESTS=yes RUN_VERY_EXPENSIVE_TESTS=yes VERBOSE=no || :
timeout -sKILL 2h make -j "$(nproc)" check SUBDIRS=. RUN_EXPENSIVE_TESTS=yes RUN_VERY_EXPENSIVE_TESTS=yes VERBOSE=no || : # Kill after 4 hours in case something gets stuck in make
- name: Extract tests info
shell: bash
run: |
TOTAL=$( grep "# TOTAL:" gnu/tests/test-suite.log|cut -d' ' -f2-)
PASS=$( grep "# PASS:" gnu/tests/test-suite.log|cut -d' ' -f2-)
SKIP=$( grep "# SKIP:" gnu/tests/test-suite.log|cut -d' ' -f2-)
FAIL=$( grep "# FAIL:" gnu/tests/test-suite.log|cut -d' ' -f2-)
XPASS=$( grep "# XPASS:" gnu/tests/test-suite.log|cut -d' ' -f2-)
ERROR=$( grep "# ERROR:" gnu/tests/test-suite.log|cut -d' ' -f2-)
echo "::warning ::GNU testsuite = $TOTAL / $PASS / $FAIL / $ERROR"
if test -f gnu/tests/test-suite.log
then
TOTAL=$( grep "# TOTAL:" gnu/tests/test-suite.log|cut -d' ' -f2-)
PASS=$( grep "# PASS:" gnu/tests/test-suite.log|cut -d' ' -f2-)
SKIP=$( grep "# SKIP:" gnu/tests/test-suite.log|cut -d' ' -f2-)
FAIL=$( grep "# FAIL:" gnu/tests/test-suite.log|cut -d' ' -f2-)
XPASS=$( grep "# XPASS:" gnu/tests/test-suite.log|cut -d' ' -f2-)
ERROR=$( grep "# ERROR:" gnu/tests/test-suite.log|cut -d' ' -f2-)
echo "::warning ::GNU testsuite = $TOTAL / $PASS / $FAIL / $ERROR"
else
echo "::error ::Failed to get summary of test results"
fi
- uses: actions/upload-artifact@v2
with:
Generated
+65 -79
View File
@@ -59,11 +59,6 @@ name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.2.1"
@@ -95,7 +90,7 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.124 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -193,7 +188,7 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -300,6 +295,7 @@ dependencies = [
"uu_whoami 0.0.4",
"uu_yes 0.0.4",
"uucore 0.0.7",
"walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -404,13 +400,13 @@ dependencies = [
"oorandom 11.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"plotters 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.124 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.124 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
"tinytemplate 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -472,7 +468,7 @@ dependencies = [
"csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.124 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -517,7 +513,7 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -657,10 +653,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "js-sys"
version = "0.3.48"
version = "0.3.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"wasm-bindgen 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -726,17 +722,6 @@ dependencies = [
"autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
version = "0.13.1"
@@ -854,8 +839,8 @@ dependencies = [
"num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"plotters-backend 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plotters-svg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"web-sys 0.3.48 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
"web-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1035,7 +1020,7 @@ dependencies = [
[[package]]
name = "regex"
version = "1.4.4"
version = "1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1115,7 +1100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.124"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1124,12 +1109,12 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.124 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive"
version = "1.0.124"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1144,7 +1129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.124 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1301,7 +1286,7 @@ name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.124 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1397,7 +1382,7 @@ version = "0.0.4"
dependencies = [
"uucore 0.0.7",
"uucore_procs 0.0.5",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1407,7 +1392,7 @@ dependencies = [
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1418,14 +1403,14 @@ dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "uu_chroot"
version = "0.0.4"
dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
]
@@ -1460,7 +1445,7 @@ dependencies = [
"quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1471,7 +1456,7 @@ version = "0.0.4"
dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
@@ -1491,8 +1476,10 @@ version = "0.0.4"
dependencies = [
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1538,6 +1525,7 @@ dependencies = [
name = "uu_echo"
version = "0.0.4"
dependencies = [
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
]
@@ -1557,7 +1545,7 @@ dependencies = [
name = "uu_expand"
version = "0.0.4"
dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
@@ -1634,7 +1622,7 @@ dependencies = [
"hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"md5 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)",
"sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1745,7 +1733,7 @@ name = "uu_ls"
version = "0.0.4"
dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"number_prefix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term_grid 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1802,7 +1790,7 @@ name = "uu_more"
version = "0.0.4"
dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
@@ -1838,7 +1826,7 @@ dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
@@ -1848,7 +1836,7 @@ dependencies = [
name = "uu_nohup"
version = "0.0.4"
dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
@@ -1879,7 +1867,7 @@ name = "uu_od"
version = "0.0.4"
dependencies = [
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"half 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
@@ -1939,7 +1927,7 @@ dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
@@ -1990,7 +1978,7 @@ dependencies = [
"remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2140,7 +2128,7 @@ dependencies = [
name = "uu_tee"
version = "0.0.4"
dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
@@ -2209,7 +2197,7 @@ dependencies = [
name = "uu_tsort"
version = "0.0.4"
dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
]
@@ -2238,7 +2226,7 @@ dependencies = [
name = "uu_unexpand"
version = "0.0.4"
dependencies = [
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.7",
"uucore_procs 0.0.5",
@@ -2357,7 +2345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
version = "2.3.1"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2372,16 +2360,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wasm-bindgen"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bumpalo 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2390,42 +2378,42 @@ dependencies = [
"proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro-support 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro-support 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-backend 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-backend 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "web-sys"
version = "0.3.48"
version = "0.3.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"js-sys 0.3.48 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"js-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2490,7 +2478,6 @@ dependencies = [
"checksum autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
"checksum bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
"checksum bit-vec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814"
@@ -2549,7 +2536,7 @@ dependencies = [
"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
"checksum itoa 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
"checksum js-sys 0.3.48 (registry+https://github.com/rust-lang/crates.io-index)" = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78"
"checksum js-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)" = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3"
@@ -2561,7 +2548,6 @@ dependencies = [
"checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
"checksum memoffset 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b"
"checksum nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "47e49f6982987135c5e9620ab317623e723bd06738fd85377e8d55f57c8b6487"
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
"checksum num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
"checksum num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
@@ -2598,7 +2584,7 @@ dependencies = [
"checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
"checksum redox_syscall 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
"checksum redox_termios 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f"
"checksum regex 1.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "54fd1046a3107eb58f42de31d656fee6853e5d276c455fd943742dce89fc3dd3"
"checksum regex 1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
"checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
"checksum regex-syntax 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)" = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
"checksum remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
@@ -2610,9 +2596,9 @@ dependencies = [
"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.124 (registry+https://github.com/rust-lang/crates.io-index)" = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
"checksum serde 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)" = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
"checksum serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
"checksum serde_derive 1.0.124 (registry+https://github.com/rust-lang/crates.io-index)" = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b"
"checksum serde_derive 1.0.125 (registry+https://github.com/rust-lang/crates.io-index)" = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
"checksum serde_json 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)" = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a"
@@ -2640,14 +2626,14 @@ dependencies = [
"checksum users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486"
"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
"checksum walkdir 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum wasm-bindgen 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7"
"checksum wasm-bindgen-backend 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8"
"checksum wasm-bindgen-macro 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b"
"checksum wasm-bindgen-macro-support 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e"
"checksum wasm-bindgen-shared 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1"
"checksum web-sys 0.3.48 (registry+https://github.com/rust-lang/crates.io-index)" = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b"
"checksum wasm-bindgen 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe"
"checksum wasm-bindgen-backend 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3"
"checksum wasm-bindgen-macro 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b"
"checksum wasm-bindgen-macro-support 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d"
"checksum wasm-bindgen-shared 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa"
"checksum web-sys 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310"
"checksum wild 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+1
View File
@@ -347,6 +347,7 @@ tempfile = "= 3.1.0"
time = "0.1"
unindent = "0.1"
uucore = { version=">=0.0.7", package="uucore", path="src/uucore", features=["entries"] }
walkdir = "2.2"
[target.'cfg(unix)'.dev-dependencies]
rust-users = { version="0.10", package="users" }
+3 -5
View File
@@ -23,9 +23,8 @@ Why?
Many GNU, Linux and other utilities are useful, and obviously
[some](http://gnuwin32.sourceforge.net) [effort](http://unxutils.sourceforge.net)
has been spent in the past to port them to Windows. However, those projects
are either old and abandoned, are hosted on CVS (which makes it more difficult
for new contributors to contribute to them), are written in platform-specific C, or
suffer from other issues.
are written in platform-specific C, a language considered unsafe compared to Rust, and
have other issues.
Rust provides a good, platform-agnostic way of writing systems utilities that are easy
to compile anywhere, and this is as good a way as any to try and learn it.
@@ -301,7 +300,7 @@ Utilities
| csplit | date | |
| cut | join | |
| dircolors | df | |
| dirname | | |
| dirname | tac | |
| du | | |
| echo | | |
| env | | |
@@ -354,7 +353,6 @@ Utilities
| stdbuf | | |
| sum | | |
| sync | | |
| tac | | |
| tee | | |
| timeout | | |
| touch | | |
+1 -1
View File
@@ -15,7 +15,7 @@ edition = "2018"
path = "src/chroot.rs"
[dependencies]
getopts = "0.2.18"
clap= "2.33"
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries"] }
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
+74 -50
View File
@@ -10,60 +10,81 @@
#[macro_use]
extern crate uucore;
use uucore::entries;
use uucore::libc::{self, chroot, setgid, setgroups, setuid};
use clap::{App, Arg};
use std::ffi::CString;
use std::io::Error;
use std::path::Path;
use std::process::Command;
use uucore::entries;
use uucore::libc::{self, chroot, setgid, setgroups, setuid};
static VERSION: &str = env!("CARGO_PKG_VERSION");
static NAME: &str = "chroot";
static ABOUT: &str = "Run COMMAND with root directory set to NEWROOT.";
static SYNTAX: &str = "[OPTION]... NEWROOT [COMMAND [ARG]...]";
static SUMMARY: &str = "Run COMMAND with root directory set to NEWROOT.";
static LONG_HELP: &str = "
If COMMAND is not specified, it defaults to '$(SHELL) -i'.
If $(SHELL) is not set, /bin/sh is used.
";
mod options {
pub const NEWROOT: &str = "newroot";
pub const USER: &str = "user";
pub const GROUP: &str = "group";
pub const GROUPS: &str = "groups";
pub const USERSPEC: &str = "userspec";
}
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optopt(
"u",
"user",
"User (ID or name) to switch before running the program",
"USER",
let matches = App::new(executable!())
.version(VERSION)
.about(ABOUT)
.usage(SYNTAX)
.arg(Arg::with_name(options::NEWROOT).hidden(true).required(true))
.arg(
Arg::with_name(options::USER)
.short("u")
.long(options::USER)
.help("User (ID or name) to switch before running the program")
.value_name("USER"),
)
.optopt("g", "group", "Group (ID or name) to switch to", "GROUP")
.optopt(
"G",
"groups",
"Comma-separated list of groups to switch to",
"GROUP1,GROUP2...",
.arg(
Arg::with_name(options::GROUP)
.short("g")
.long(options::GROUP)
.help("Group (ID or name) to switch to")
.value_name("GROUP"),
)
.optopt(
"",
"userspec",
"Colon-separated user and group to switch to. \
.arg(
Arg::with_name(options::GROUPS)
.short("G")
.long(options::GROUPS)
.help("Comma-separated list of groups to switch to")
.value_name("GROUP1,GROUP2..."),
)
.arg(
Arg::with_name(options::USERSPEC)
.long(options::USERSPEC)
.help(
"Colon-separated user and group to switch to. \
Same as -u USER -g GROUP. \
Userspec has higher preference than -u and/or -g",
"USER:GROUP",
)
.value_name("USER:GROUP"),
)
.parse(args);
if matches.free.is_empty() {
println!("Missing operand: NEWROOT");
println!("Try `{} --help` for more information.", NAME);
return 1;
}
.get_matches_from(args);
let default_shell: &'static str = "/bin/sh";
let default_option: &'static str = "-i";
let user_shell = std::env::var("SHELL");
let newroot = Path::new(&matches.free[0][..]);
let newroot: &Path = match matches.value_of(options::NEWROOT) {
Some(v) => Path::new(v),
None => crash!(
1,
"Missing operand: NEWROOT\nTry '{} --help' for more information.",
NAME
),
};
if !newroot.is_dir() {
crash!(
1,
@@ -72,7 +93,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
);
}
let command: Vec<&str> = match matches.free.len() {
let command: Vec<&str> = match matches.args.len() {
1 => {
let shell: &str = match user_shell {
Err(_) => default_shell,
@@ -80,7 +101,14 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
};
vec![shell, default_option]
}
_ => matches.free[1..].iter().map(|x| &x[..]).collect(),
_ => {
let mut vector: Vec<&str> = Vec::new();
for (&k, v) in matches.args.iter() {
vector.push(k.clone());
vector.push(&v.vals[0].to_str().unwrap());
}
vector
}
};
set_context(&newroot, &matches);
@@ -97,30 +125,26 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
}
}
fn set_context(root: &Path, options: &getopts::Matches) {
let userspec_str = options.opt_str("userspec");
let user_str = options.opt_str("user").unwrap_or_default();
let group_str = options.opt_str("group").unwrap_or_default();
let groups_str = options.opt_str("groups").unwrap_or_default();
fn set_context(root: &Path, options: &clap::ArgMatches) {
let userspec_str = options.value_of(options::USERSPEC);
let user_str = options.value_of(options::USER).unwrap_or_default();
let group_str = options.value_of(options::GROUP).unwrap_or_default();
let groups_str = options.value_of(options::GROUPS).unwrap_or_default();
let userspec = match userspec_str {
Some(ref u) => {
let s: Vec<&str> = u.split(':').collect();
if s.len() != 2 {
if s.len() != 2 || s.iter().any(|&spec| spec == "") {
crash!(1, "invalid userspec: `{}`", u)
};
s
}
None => Vec::new(),
};
let user = if userspec.is_empty() {
&user_str[..]
let (user, group) = if userspec.is_empty() {
(&user_str[..], &group_str[..])
} else {
&userspec[0][..]
};
let group = if userspec.is_empty() {
&group_str[..]
} else {
&userspec[1][..]
(&userspec[0][..], &userspec[1][..])
};
enter_chroot(root);
@@ -164,7 +188,7 @@ fn set_main_group(group: &str) {
}
}
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
fn set_groups(groups: Vec<libc::gid_t>) -> libc::c_int {
unsafe { setgroups(groups.len() as libc::c_int, groups.as_ptr()) }
}
-46
View File
@@ -1,46 +0,0 @@
// This file is part of the uutils coreutils package.
//
// (c) Alex Lyon <arcterus@mail.com>
// (c) Michael Gehring <mg@ebfe.org>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
const CRC_TABLE_LEN: usize = 256;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let mut table = Vec::with_capacity(CRC_TABLE_LEN);
for num in 0..CRC_TABLE_LEN {
table.push(crc_entry(num as u8) as u32);
}
let file = File::create(&Path::new(&out_dir).join("crc_table.rs")).unwrap();
write!(
&file,
"#[allow(clippy::unreadable_literal)]\nconst CRC_TABLE: [u32; {}] = {:?};",
CRC_TABLE_LEN, table
)
.unwrap();
}
#[inline]
fn crc_entry(input: u8) -> u32 {
let mut crc = (input as u32) << 24;
for _ in 0..8 {
if crc & 0x8000_0000 != 0 {
crc <<= 1;
crc ^= 0x04c1_1db7;
} else {
crc <<= 1;
}
}
crc
}
+94 -5
View File
@@ -14,11 +14,101 @@ use std::fs::File;
use std::io::{self, stdin, BufReader, Read};
use std::path::Path;
include!(concat!(env!("OUT_DIR"), "/crc_table.rs"));
// NOTE: CRC_TABLE_LEN *must* be <= 256 as we cast 0..CRC_TABLE_LEN to u8
const CRC_TABLE_LEN: usize = 256;
const CRC_TABLE: [u32; CRC_TABLE_LEN] = generate_crc_table();
static SYNTAX: &str = "[OPTIONS] [FILE]...";
static SUMMARY: &str = "Print CRC and size for each file";
static LONG_HELP: &str = "";
const SYNTAX: &str = "[OPTIONS] [FILE]...";
const SUMMARY: &str = "Print CRC and size for each file";
const LONG_HELP: &str = "";
// this is basically a hack to get "loops" to work on Rust 1.33. Once we update to Rust 1.46 or
// greater, we can just use while loops
macro_rules! unroll {
(256, |$i:ident| $s:expr) => {{
unroll!(@ 32, 0 * 32, $i, $s);
unroll!(@ 32, 1 * 32, $i, $s);
unroll!(@ 32, 2 * 32, $i, $s);
unroll!(@ 32, 3 * 32, $i, $s);
unroll!(@ 32, 4 * 32, $i, $s);
unroll!(@ 32, 5 * 32, $i, $s);
unroll!(@ 32, 6 * 32, $i, $s);
unroll!(@ 32, 7 * 32, $i, $s);
}};
(8, |$i:ident| $s:expr) => {{
unroll!(@ 8, 0, $i, $s);
}};
(@ 32, $start:expr, $i:ident, $s:expr) => {{
unroll!(@ 8, $start + 0 * 8, $i, $s);
unroll!(@ 8, $start + 1 * 8, $i, $s);
unroll!(@ 8, $start + 2 * 8, $i, $s);
unroll!(@ 8, $start + 3 * 8, $i, $s);
}};
(@ 8, $start:expr, $i:ident, $s:expr) => {{
unroll!(@ 4, $start, $i, $s);
unroll!(@ 4, $start + 4, $i, $s);
}};
(@ 4, $start:expr, $i:ident, $s:expr) => {{
unroll!(@ 2, $start, $i, $s);
unroll!(@ 2, $start + 2, $i, $s);
}};
(@ 2, $start:expr, $i:ident, $s:expr) => {{
unroll!(@ 1, $start, $i, $s);
unroll!(@ 1, $start + 1, $i, $s);
}};
(@ 1, $start:expr, $i:ident, $s:expr) => {{
let $i = $start;
let _ = $s;
}};
}
const fn generate_crc_table() -> [u32; CRC_TABLE_LEN] {
let mut table = [0; CRC_TABLE_LEN];
// NOTE: works on Rust 1.46
//let mut i = 0;
//while i < CRC_TABLE_LEN {
// table[i] = crc_entry(i as u8) as u32;
//
// i += 1;
//}
unroll!(256, |i| {
table[i] = crc_entry(i as u8) as u32;
});
table
}
const fn crc_entry(input: u8) -> u32 {
let mut crc = (input as u32) << 24;
// NOTE: this does not work on Rust 1.33, but *does* on 1.46
//let mut i = 0;
//while i < 8 {
// if crc & 0x8000_0000 != 0 {
// crc <<= 1;
// crc ^= 0x04c1_1db7;
// } else {
// crc <<= 1;
// }
//
// i += 1;
//}
unroll!(8, |_i| {
let if_cond = crc & 0x8000_0000;
let if_body = (crc << 1) ^ 0x04c1_1db7;
let else_body = crc << 1;
// NOTE: i feel like this is easier to understand than emulating an if statement in bitwise
// ops
let cond_table = [else_body, if_body];
crc = cond_table[(if_cond != 0) as usize];
});
crc
}
#[inline]
fn crc_update(crc: u32, input: u8) -> u32 {
@@ -68,7 +158,6 @@ fn cksum(fname: &str) -> io::Result<(u32, usize)> {
Err(err) => return Err(err),
}
}
//Ok((0 as u32,0 as usize))
}
pub fn uumain(args: impl uucore::Args) -> i32 {
+7 -6
View File
@@ -112,7 +112,7 @@ macro_rules! or_continue(
})
);
/// Prompts the user yes/no and returns `true` they if successfully
/// Prompts the user yes/no and returns `true` if they successfully
/// answered yes.
macro_rules! prompt_yes(
($($args:tt)+) => ({
@@ -431,6 +431,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.arg(Arg::with_name(OPT_NO_DEREFERENCE_PRESERVE_LINKS)
.short("d")
.help("same as --no-dereference --preserve=links"))
.arg(Arg::with_name(OPT_ONE_FILE_SYSTEM)
.short("x")
.long(OPT_ONE_FILE_SYSTEM)
.help("stay on this file system"))
// TODO: implement the following args
.arg(Arg::with_name(OPT_COPY_CONTENTS)
@@ -442,10 +446,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.takes_value(true)
.value_name("WHEN")
.help("NotImplemented: control creation of sparse files. See below"))
.arg(Arg::with_name(OPT_ONE_FILE_SYSTEM)
.short("x")
.long(OPT_ONE_FILE_SYSTEM)
.help("NotImplemented: stay on this file system"))
.arg(Arg::with_name(OPT_CONTEXT)
.long(OPT_CONTEXT)
.takes_value(true)
@@ -563,6 +563,7 @@ impl Options {
let not_implemented_opts = vec![
OPT_COPY_CONTENTS,
OPT_SPARSE,
#[cfg(not(any(windows, unix)))]
OPT_ONE_FILE_SYSTEM,
OPT_CONTEXT,
#[cfg(windows)]
@@ -937,7 +938,7 @@ fn copy_directory(root: &Path, target: &Target, options: &Options) -> CopyResult
#[cfg(any(windows, target_os = "redox"))]
let mut hard_links: Vec<(String, u64)> = vec![];
for path in WalkDir::new(root) {
for path in WalkDir::new(root).same_file_system(options.one_file_system) {
let p = or_continue!(path);
let is_symlink = fs::symlink_metadata(p.path())?.file_type().is_symlink();
let path = if (options.no_dereference || options.dereference) && is_symlink {
+6
View File
@@ -20,6 +20,12 @@ clap = "2.33"
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
[target.'cfg(unix)'.dependencies]
libc = "0.2"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["minwinbase", "sysinfoapi", "minwindef"] }
[[bin]]
name = "date"
path = "src/main.rs"
+108 -19
View File
@@ -12,13 +12,20 @@
#[macro_use]
extern crate uucore;
use chrono::{DateTime, FixedOffset, Local, Offset, Utc};
#[cfg(windows)]
use chrono::{Datelike, Timelike};
use clap::{App, Arg};
use chrono::offset::Utc;
use chrono::{DateTime, FixedOffset, Local, Offset};
#[cfg(all(unix, not(target_os = "macos")))]
use libc::{clock_settime, timespec, CLOCK_REALTIME};
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;
#[cfg(windows)]
use winapi::{
shared::minwindef::WORD,
um::{minwinbase::SYSTEMTIME, sysinfoapi::SetSystemTime},
};
// Options
const DATE: &str = "date";
@@ -62,6 +69,11 @@ static RFC_3339_HELP_STRING: &str = "output date/time in RFC 3339 format.
for date and time to the indicated precision.
Example: 2006-08-14 02:34:56-06:00";
#[cfg(not(target_os = "macos"))]
static OPT_SET_HELP_STRING: &str = "set time described by STRING";
#[cfg(target_os = "macos")]
static OPT_SET_HELP_STRING: &str = "set time described by STRING (not available on mac yet)";
/// Settings for this program, parsed from the command line
struct Settings {
utc: bool,
@@ -186,7 +198,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.short("s")
.long(OPT_SET)
.takes_value(true)
.help("set time described by STRING"),
.help(OPT_SET_HELP_STRING),
)
.arg(
Arg::with_name(OPT_UNIVERSAL)
@@ -222,18 +234,31 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
DateSource::Now
};
let set_to = match matches.value_of(OPT_SET).map(parse_date) {
None => None,
Some(Err((input, _err))) => {
eprintln!("date: invalid date '{}'", input);
return 1;
}
Some(Ok(date)) => Some(date),
};
let settings = Settings {
utc: matches.is_present(OPT_UNIVERSAL),
format,
date_source,
// TODO: Handle this option:
set_to: None,
set_to,
};
if let Some(_time) = settings.set_to {
unimplemented!();
// Probably need to use this syscall:
// https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/fn.clock_settime.html
if let Some(date) = settings.set_to {
// All set time functions expect UTC datetimes.
let date: DateTime<Utc> = if settings.utc {
date.with_timezone(&Utc)
} else {
date.into()
};
return set_system_datetime(date);
} else {
// Declare a file here because it needs to outlive the `dates` iterator.
let file: File;
@@ -247,15 +272,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
now.with_timezone(now.offset())
};
/// Parse a `String` into a `DateTime`.
/// If it fails, return a tuple of the `String` along with its `ParseError`.
fn parse_date(
s: String,
) -> Result<DateTime<FixedOffset>, (String, chrono::format::ParseError)> {
// TODO: The GNU date command can parse a wide variety of inputs.
s.parse().map_err(|e| (s, e))
}
// Iterate over all dates - whether it's a single date or a file.
let dates: Box<dyn Iterator<Item = _>> = match settings.date_source {
DateSource::Custom(ref input) => {
@@ -314,3 +330,76 @@ fn make_format_string(settings: &Settings) -> &str {
Format::Default => "%c",
}
}
/// Parse a `String` into a `DateTime`.
/// If it fails, return a tuple of the `String` along with its `ParseError`.
fn parse_date<S: AsRef<str> + Clone>(
s: S,
) -> Result<DateTime<FixedOffset>, (String, chrono::format::ParseError)> {
// TODO: The GNU date command can parse a wide variety of inputs.
s.as_ref().parse().map_err(|e| (s.as_ref().into(), e))
}
#[cfg(not(any(unix, windows)))]
fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
unimplemented!("setting date not implemented (unsupported target)");
}
#[cfg(target_os = "macos")]
fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
eprintln!("date: setting the date is not supported by macOS");
return 1;
}
#[cfg(all(unix, not(target_os = "macos")))]
/// System call to set date (unix).
/// See here for more:
/// https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/fn.clock_settime.html
/// https://linux.die.net/man/3/clock_settime
/// https://www.gnu.org/software/libc/manual/html_node/Time-Types.html
fn set_system_datetime(date: DateTime<Utc>) -> i32 {
let timespec = timespec {
tv_sec: date.timestamp() as _,
tv_nsec: date.timestamp_subsec_nanos() as _,
};
let result = unsafe { clock_settime(CLOCK_REALTIME, &timespec) };
if result != 0 {
let error = std::io::Error::last_os_error();
eprintln!("date: cannot set date: {}", error);
error.raw_os_error().unwrap()
} else {
0
}
}
#[cfg(windows)]
/// System call to set date (Windows).
/// See here for more:
/// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-setsystemtime
/// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
fn set_system_datetime(date: DateTime<Utc>) -> i32 {
let system_time = SYSTEMTIME {
wYear: date.year() as WORD,
wMonth: date.month() as WORD,
// Ignored
wDayOfWeek: 0,
wDay: date.day() as WORD,
wHour: date.hour() as WORD,
wMinute: date.minute() as WORD,
wSecond: date.second() as WORD,
// TODO: be careful of leap seconds - valid range is [0, 999] - how to handle?
wMilliseconds: ((date.nanosecond() / 1_000_000) % 1000) as WORD,
};
let result = unsafe { SetSystemTime(&system_time) };
if result == 0 {
let error = std::io::Error::last_os_error();
eprintln!("date: cannot set date: {}", error);
error.raw_os_error().unwrap()
} else {
0
}
}
+11 -11
View File
@@ -32,15 +32,15 @@ use std::ffi::CString;
#[cfg(unix)]
use std::mem;
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
use libc::c_int;
#[cfg(target_os = "macos")]
#[cfg(target_vendor = "apple")]
use libc::statfs;
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
use std::ffi::CStr;
#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "windows"))]
#[cfg(any(target_vendor = "apple", target_os = "freebsd", target_os = "windows"))]
use std::ptr;
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
use std::slice;
#[cfg(target_os = "freebsd")]
@@ -137,7 +137,7 @@ struct MountInfo {
#[cfg(all(
target_os = "freebsd",
not(all(target_os = "macos", target_arch = "x86_64"))
not(all(target_vendor = "apple", target_arch = "x86_64"))
))]
#[repr(C)]
#[derive(Copy, Clone)]
@@ -209,20 +209,20 @@ fn get_usage() -> String {
format!("{0} [OPTION]... [FILE]...", executable!())
}
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
#[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
extern "C" {
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
#[cfg(all(target_vendor = "apple", target_arch = "x86_64"))]
#[link_name = "getmntinfo$INODE64"]
fn getmntinfo(mntbufp: *mut *mut statfs, flags: c_int) -> c_int;
#[cfg(any(
all(target_os = "freebsd"),
all(target_os = "macos", target_arch = "aarch64")
all(target_vendor = "apple", target_arch = "aarch64")
))]
fn getmntinfo(mntbufp: *mut *mut statfs, flags: c_int) -> c_int;
}
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
#[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
impl From<statfs> for MountInfo {
fn from(statfs: statfs) -> Self {
let mut info = MountInfo {
@@ -585,7 +585,7 @@ fn read_fs_list() -> Vec<MountInfo> {
})
.collect::<Vec<_>>()
}
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
#[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
{
let mut mptr: *mut statfs = ptr::null_mut();
let len = unsafe { getmntinfo(&mut mptr, 1 as c_int) };
+1
View File
@@ -15,6 +15,7 @@ edition = "2018"
path = "src/echo.rs"
[dependencies]
clap = "2.33"
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
+58 -14
View File
@@ -9,14 +9,17 @@
#[macro_use]
extern crate uucore;
use clap::{crate_version, App, Arg};
use std::io::{self, Write};
use std::iter::Peekable;
use std::str::Chars;
const SYNTAX: &str = "[OPTIONS]... [STRING]...";
const SUMMARY: &str = "display a line of text";
const HELP: &str = r#"
static NAME: &str = "echo";
static USAGE: &str = "[OPTIONS]... [STRING]...";
static SUMMARY: &str = "display a line of text";
static AFTER_HELP: &str = r#"
Echo the STRING(s) to standard output.
If -e is in effect, the following sequences are recognized:
\\\\ backslash
@@ -33,6 +36,13 @@ const HELP: &str = r#"
\\xHH byte with hexadecimal value HH (1 to 2 digits)
"#;
mod options {
pub static STRING: &str = "STRING";
pub static NO_NEWLINE: &str = "no_newline";
pub static ENABLE_BACKSLASH_ESCAPE: &str = "enable_backslash_escape";
pub static DISABLE_BACKSLASH_ESCAPE: &str = "disable_backslash_escape";
}
fn parse_code(
input: &mut Peekable<Chars>,
base: u32,
@@ -105,20 +115,54 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result<bool> {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, HELP)
.optflag("n", "", "do not output the trailing newline")
.optflag("e", "", "enable interpretation of backslash escapes")
.optflag(
"E",
"",
"disable interpretation of backslash escapes (default)",
let matches = App::new(executable!())
.name(NAME)
// TrailingVarArg specifies the final positional argument is a VarArg
// and it doesn't attempts the parse any further args.
// Final argument must have multiple(true) or the usage string equivalent.
.setting(clap::AppSettings::TrailingVarArg)
.setting(clap::AppSettings::AllowLeadingHyphen)
.version(crate_version!())
.usage(USAGE)
.about(SUMMARY)
.after_help(AFTER_HELP)
.arg(
Arg::with_name(options::NO_NEWLINE)
.short("n")
.help("do not output the trailing newline")
.takes_value(false)
.display_order(1),
)
.parse(args);
.arg(
Arg::with_name(options::ENABLE_BACKSLASH_ESCAPE)
.short("e")
.help("enable interpretation of backslash escapes")
.takes_value(false)
.display_order(2),
)
.arg(
Arg::with_name(options::DISABLE_BACKSLASH_ESCAPE)
.short("E")
.help("disable interpretation of backslash escapes (default)")
.takes_value(false)
.display_order(3),
)
.arg(
Arg::with_name(options::STRING)
.hidden(true)
.multiple(true)
.allow_hyphen_values(true),
)
.get_matches_from(args);
let no_newline = matches.opt_present("n");
let escaped = matches.opt_present("e");
let no_newline = matches.is_present(options::NO_NEWLINE);
let escaped = matches.is_present(options::ENABLE_BACKSLASH_ESCAPE);
let values: Vec<String> = match matches.values_of(options::STRING) {
Some(s) => s.map(|s| s.to_string()).collect(),
None => vec!["".to_string()],
};
match execute(no_newline, escaped, matches.free) {
match execute(no_newline, escaped, values) {
Ok(_) => 0,
Err(f) => {
show_error!("{}", f);
+15 -15
View File
@@ -148,11 +148,11 @@ impl ASTNode {
|a: &String, b: &String| Ok(bool_as_string(a >= b)),
&operand_values,
),
"|" => infix_operator_or(&operand_values),
"&" => infix_operator_and(&operand_values),
"|" => Ok(infix_operator_or(&operand_values)),
"&" => Ok(infix_operator_and(&operand_values)),
":" | "match" => operator_match(&operand_values),
"length" => prefix_operator_length(&operand_values),
"index" => prefix_operator_index(&operand_values),
"length" => Ok(prefix_operator_length(&operand_values)),
"index" => Ok(prefix_operator_index(&operand_values)),
"substr" => prefix_operator_substr(&operand_values),
_ => Err(format!("operation not implemented: {}", op_type)),
@@ -465,20 +465,20 @@ where
}
}
fn infix_operator_or(values: &[String]) -> Result<String, String> {
fn infix_operator_or(values: &[String]) -> String {
assert!(values.len() == 2);
if value_as_bool(&values[0]) {
Ok(values[0].clone())
values[0].clone()
} else {
Ok(values[1].clone())
values[1].clone()
}
}
fn infix_operator_and(values: &[String]) -> Result<String, String> {
fn infix_operator_and(values: &[String]) -> String {
if value_as_bool(&values[0]) && value_as_bool(&values[1]) {
Ok(values[0].clone())
values[0].clone()
} else {
Ok(0.to_string())
0.to_string()
}
}
@@ -502,12 +502,12 @@ fn operator_match(values: &[String]) -> Result<String, String> {
}
}
fn prefix_operator_length(values: &[String]) -> Result<String, String> {
fn prefix_operator_length(values: &[String]) -> String {
assert!(values.len() == 1);
Ok(values[0].len().to_string())
values[0].len().to_string()
}
fn prefix_operator_index(values: &[String]) -> Result<String, String> {
fn prefix_operator_index(values: &[String]) -> String {
assert!(values.len() == 2);
let haystack = &values[0];
let needles = &values[1];
@@ -515,11 +515,11 @@ fn prefix_operator_index(values: &[String]) -> Result<String, String> {
for (current_idx, ch_h) in haystack.chars().enumerate() {
for ch_n in needles.chars() {
if ch_n == ch_h {
return Ok(current_idx.to_string());
return current_idx.to_string();
}
}
}
Ok("0".to_string())
"0".to_string()
}
fn prefix_operator_substr(values: &[String]) -> Result<String, String> {
+43 -102
View File
@@ -9,7 +9,7 @@ use smallvec::SmallVec;
use std::cell::RefCell;
use std::fmt;
use crate::numeric::{gcd, Arithmetic, Montgomery};
use crate::numeric::{Arithmetic, Montgomery};
use crate::{miller_rabin, rho, table};
type Exponent = u8;
@@ -29,20 +29,15 @@ impl Decomposition {
fn add(&mut self, factor: u64, exp: Exponent) {
debug_assert!(exp > 0);
// Assert the factor doesn't already exist in the Decomposition object
debug_assert_eq!(self.0.iter_mut().find(|(f, _)| *f == factor), None);
self.0.push((factor, exp))
}
fn is_one(&self) -> bool {
self.0.is_empty()
}
fn pop(&mut self) -> Option<(u64, Exponent)> {
self.0.pop()
if let Some((_, e)) = self.0.iter_mut().find(|(f, _)| *f == factor) {
*e += exp;
} else {
self.0.push((factor, exp))
}
}
#[cfg(test)]
fn product(&self) -> u64 {
self.0
.iter()
@@ -86,11 +81,11 @@ impl Factors {
self.0.borrow_mut().add(prime, exp)
}
#[cfg(test)]
pub fn push(&mut self, prime: u64) {
self.add(prime, 1)
}
#[cfg(test)]
fn product(&self) -> u64 {
self.0.borrow().product()
}
@@ -111,116 +106,62 @@ impl fmt::Display for Factors {
}
}
fn _find_factor<A: Arithmetic + miller_rabin::Basis>(num: u64) -> Option<u64> {
fn _factor<A: Arithmetic + miller_rabin::Basis>(num: u64, f: Factors) -> Factors {
use miller_rabin::Result::*;
// Shadow the name, so the recursion automatically goes from “Big” arithmetic to small.
let _factor = |n, f| {
if n < (1 << 32) {
_factor::<Montgomery<u32>>(n, f)
} else {
_factor::<A>(n, f)
}
};
if num == 1 {
return f;
}
let n = A::new(num);
match miller_rabin::test::<A>(n) {
Prime => None,
Composite(d) => Some(d),
Pseudoprime => Some(rho::find_divisor::<A>(n)),
}
let divisor = match miller_rabin::test::<A>(n) {
Prime => {
let mut r = f;
r.push(num);
return r;
}
Composite(d) => d,
Pseudoprime => rho::find_divisor::<A>(n),
};
let f = _factor(divisor, f);
_factor(num / divisor, f)
}
fn find_factor(num: u64) -> Option<u64> {
if num < (1 << 32) {
_find_factor::<Montgomery<u32>>(num)
} else {
_find_factor::<Montgomery<u64>>(num)
}
}
pub fn factor(num: u64) -> Factors {
pub fn factor(mut n: u64) -> Factors {
let mut factors = Factors::one();
if num < 2 {
if n < 2 {
return factors;
}
let mut n = num;
let n_zeros = num.trailing_zeros();
let n_zeros = n.trailing_zeros();
if n_zeros > 0 {
factors.add(2, n_zeros as Exponent);
n >>= n_zeros;
}
debug_assert_eq!(num, n * factors.product());
if n == 1 {
return factors;
}
table::factor(&mut n, &mut factors);
debug_assert_eq!(num, n * factors.product());
let (factors, n) = table::factor(n, factors);
if n == 1 {
return factors;
if n < (1 << 32) {
_factor::<Montgomery<u32>>(n, factors)
} else {
_factor::<Montgomery<u64>>(n, factors)
}
let mut dec = Decomposition::one();
dec.add(n, 1);
while !dec.is_one() {
// Check correctness invariant
debug_assert_eq!(num, factors.product() * dec.product());
let (factor, exp) = dec.pop().unwrap();
if let Some(divisor) = find_factor(factor) {
let mut gcd_queue = Decomposition::one();
let quotient = factor / divisor;
let mut trivial_gcd = quotient == divisor;
if trivial_gcd {
gcd_queue.add(divisor, exp + 1);
} else {
gcd_queue.add(divisor, exp);
gcd_queue.add(quotient, exp);
}
while !trivial_gcd {
debug_assert_eq!(factor, gcd_queue.product());
let mut tmp = Decomposition::one();
trivial_gcd = true;
for i in 0..gcd_queue.0.len() - 1 {
let (mut a, exp_a) = gcd_queue.0[i];
let (mut b, exp_b) = gcd_queue.0[i + 1];
if a == 1 {
continue;
}
let g = gcd(a, b);
if g != 1 {
trivial_gcd = false;
a /= g;
b /= g;
}
if a != 1 {
tmp.add(a, exp_a);
}
if g != 1 {
tmp.add(g, exp_a + exp_b);
}
if i + 1 != gcd_queue.0.len() - 1 {
gcd_queue.0[i + 1].0 = b;
} else if b != 1 {
tmp.add(b, exp_b);
}
}
gcd_queue = tmp;
}
debug_assert_eq!(factor, gcd_queue.product());
dec.0.extend(gcd_queue.0);
} else {
// factor is prime
factors.add(factor, exp);
}
}
factors
}
#[cfg(test)]
+2 -3
View File
@@ -14,8 +14,7 @@ use crate::Factors;
include!(concat!(env!("OUT_DIR"), "/prime_table.rs"));
pub(crate) fn factor(n: &mut u64, factors: &mut Factors) {
let mut num = *n;
pub(crate) fn factor(mut num: u64, mut factors: Factors) -> (Factors, u64) {
for &(prime, inv, ceil) in P_INVS_U64 {
if num == 1 {
break;
@@ -43,5 +42,5 @@ pub(crate) fn factor(n: &mut u64, factors: &mut Factors) {
}
}
*n = num;
(factors, num)
}
+19 -2
View File
@@ -29,6 +29,7 @@ enum FilterMode {
struct Settings {
mode: FilterMode,
verbose: bool,
zero_terminated: bool,
}
impl Default for Settings {
@@ -36,6 +37,7 @@ impl Default for Settings {
Settings {
mode: FilterMode::Lines(10),
verbose: false,
zero_terminated: false,
}
}
}
@@ -69,6 +71,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
)
.optflag("q", "quiet", "never print headers giving file names")
.optflag("v", "verbose", "always print headers giving file names")
.optflag("z", "zero-terminated", "line delimiter is NUL, not newline")
.optflag("h", "help", "display this help and exit")
.optflag("V", "version", "output version information and exit")
.parse(new_args);
@@ -113,6 +116,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let quiet = matches.opt_present("q");
let verbose = matches.opt_present("v");
settings.zero_terminated = matches.opt_present("z");
let files = matches.free;
// GNU implementation allows multiple declarations of "-q" and "-v" with the
@@ -145,6 +149,13 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
first_time = false;
let path = Path::new(file);
if path.is_dir() || !path.metadata().is_ok() {
eprintln!(
"cannot open '{}' for reading: No such file or directory",
&path.to_str().unwrap()
);
continue;
}
let reader = File::open(&path).unwrap();
let mut buffer = BufReader::new(reader);
if !head(&mut buffer, &settings) {
@@ -203,8 +214,14 @@ fn head<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> bool {
}
}
FilterMode::Lines(count) => {
for line in reader.lines().take(count) {
println!("{}", line.unwrap());
if settings.zero_terminated {
for line in reader.split(0).take(count) {
print!("{}\0", String::from_utf8(line.unwrap()).unwrap())
}
} else {
for line in reader.lines().take(count) {
println!("{}", line.unwrap());
}
}
}
FilterMode::NLines(count) => {
+1 -1
View File
@@ -291,7 +291,7 @@ fn pretty(possible_pw: Option<Passwd>) {
}
}
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
fn pline(possible_uid: Option<uid_t>) {
let uid = possible_uid.unwrap_or_else(getuid);
let pw = Passwd::locate(uid).unwrap();
+18 -11
View File
@@ -426,18 +426,25 @@ fn copy_files_into_dir(files: &[PathBuf], target_dir: &PathBuf, b: &Behavior) ->
let mut all_successful = true;
for sourcepath in files.iter() {
let targetpath = match sourcepath.as_os_str().to_str() {
Some(name) => target_dir.join(name),
None => {
show_error!(
"cannot stat '{}': No such file or directory",
sourcepath.display()
);
if !sourcepath.exists() {
show_info!(
"cannot stat '{}': No such file or directory",
sourcepath.display()
);
all_successful = false;
continue;
}
};
all_successful = false;
continue;
}
if sourcepath.is_dir() {
show_info!("omitting directory '{}'", sourcepath.display());
all_successful = false;
continue;
}
let mut targetpath = target_dir.clone().to_path_buf();
let filename = sourcepath.components().last().unwrap();
targetpath.push(filename);
if copy(sourcepath, &targetpath, b).is_err() {
all_successful = false;

Some files were not shown because too many files have changed in this diff Show More